码桶

发现社区成员的开源项目

奶狗 /

ng-webot

公开
main
ng-webot/web/src/App.tsx
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>
  )
}