码桶
发现社区成员的开源项目
App.tsx3.9 KB
import { Routes, Route, Navigate } from 'react-router-dom'
import { useEffect } from 'react'
import { useAuth } from '@/lib/auth'
import { AppShell } from '@/components/layout/AppShell'
import Console from '@/pages/Console'
import Market from '@/pages/Market'
import UploadPlugin from '@/pages/UploadPlugin'
import Profile from '@/pages/Profile'
import McpPage from '@/pages/McpPage'
import SkillPage from '@/pages/SkillPage'
import AutomationPage from '@/pages/AutomationPage'
import SmartPage from '@/pages/SmartPage'
import LogConsole from '@/pages/LogConsole'
import ProxySettings from '@/pages/ProxySettings'
import SystemStats from '@/pages/SystemStats'
import Settings from '@/pages/Settings'
import Login from '@/pages/Login'
import NotFound from '@/pages/NotFound'
import Terms from '@/pages/Terms'
import Privacy from '@/pages/Privacy'
import { Toaster } from '@/components/ui/sonner'
import { ErrorBoundary } from '@/components/ErrorBoundary'
import { SiteProvider } from '@/lib/site'
import { ThemeProvider } from '@/lib/theme'
import { Loader2 } from 'lucide-react'
import { logStore } from '@/lib/logStore'
function GlobalErrorCapture() {
useEffect(() => {
// JS 运行时错误
const onError = (event: ErrorEvent) => {
logStore.add({
level: 'error',
type: 'error',
message: `${event.message} (${event.filename}:${event.lineno}:${event.colno})`,
})
}
// Promise 未捕获异常
const onReject = (event: PromiseRejectionEvent) => {
logStore.add({
level: 'error',
type: 'error',
message: `Promise 异常: ${event.reason?.message || event.reason || '未知原因'}`,
})
}
window.addEventListener('error', onError)
window.addEventListener('unhandledrejection', onReject)
// 启动日志
logStore.add({ level: 'info', type: 'system', message: '前端日志已就绪' })
return () => {
window.removeEventListener('error', onError)
window.removeEventListener('unhandledrejection', onReject)
}
}, [])
return null
}
export default function App() {
const { loading, me } = useAuth()
if (loading) {
return (
<div className="flex h-screen items-center justify-center">
<Loader2 className="h-6 w-6 animate-spin text-muted-foreground" />
</div>
)
}
// 未登录:始终展示登录页(防止直接打开后台)
if (!me) {
return <Login />
}
return (
<ErrorBoundary>
<ThemeProvider>
<SiteProvider>
<GlobalErrorCapture />
<Routes>
<Route path="/" element={<AppShell><Console /></AppShell>} />
<Route path="/market" element={<AppShell><Market /></AppShell>} />
<Route path="/market/upload" element={<AppShell><UploadPlugin /></AppShell>} />
<Route path="/profile" element={<AppShell><Profile /></AppShell>} />
<Route path="/login" element={<Login />} />
<Route path="/push-settings" element={<Navigate to="/profile" replace />} />
<Route path="/mcp" element={<AppShell><McpPage /></AppShell>} />
<Route path="/skill" element={<AppShell><SkillPage /></AppShell>} />
<Route path="/automation" element={<AppShell><AutomationPage /></AppShell>} />
<Route path="/smart" element={<AppShell><SmartPage /></AppShell>} />
<Route path="/logs" element={<AppShell><LogConsole /></AppShell>} />
<Route path="/proxy" element={<AppShell><ProxySettings /></AppShell>} />
<Route path="/stats" element={<AppShell><SystemStats /></AppShell>} />
<Route path="/settings" element={<AppShell><Settings /></AppShell>} />
<Route path="/terms" element={<Terms />} />
<Route path="/privacy" element={<Privacy />} />
<Route path="*" element={<NotFound />} />
</Routes>
<Toaster />
</SiteProvider>
</ThemeProvider>
</ErrorBoundary>
)
}