Files
draw/src/App.tsx
2025-09-27 01:35:17 +08:00

154 lines
5.3 KiB
TypeScript

import React, { useEffect, useState } from 'react'
import { BrowserRouter as Router, Routes, Route, Navigate } from 'react-router-dom'
import { useAppStore } from './store'
import { ToastProvider } from './contexts/ToastContext'
import AuthService from './services/authService'
// 懒加载页面组件
const Login = React.lazy(() => import('./pages/Login'))
const Lottery = React.lazy(() => import('./pages/Lottery'))
const Home = React.lazy(() => import('./pages/Home'))
const Admin = React.lazy(() => import('./pages/Admin'))
const WinnerDetails = React.lazy(() => import('./pages/WinnerDetails'))
const ClearRecords = React.lazy(() => import('./pages/ClearRecords'))
const ConfettiDemo = React.lazy(() => import('./pages/ConfettiDemo'))
const CrudTest = React.lazy(() => import('./pages/CrudTest'))
const NetworkTest = React.lazy(() => import('./pages/NetworkTest'))
const SimpleNetworkTest = React.lazy(() => import('./pages/SimpleNetworkTest'))
function App() {
const { isAuthenticated, initializeApp, checkAuthStatus } = useAppStore()
const [isInitializing, setIsInitializing] = useState(true)
useEffect(() => {
const initApp = async () => {
try {
// 首先检查认证状态
checkAuthStatus()
// 然后初始化应用
await initializeApp()
} catch (error) {
console.error('应用初始化失败:', error)
} finally {
setIsInitializing(false)
}
}
initApp()
}, [initializeApp, checkAuthStatus])
// 监听页面可见性变化,恢复时检查认证状态
useEffect(() => {
const handleVisibilityChange = () => {
if (!document.hidden) {
checkAuthStatus()
}
}
document.addEventListener('visibilitychange', handleVisibilityChange)
return () => {
document.removeEventListener('visibilitychange', handleVisibilityChange)
}
}, [checkAuthStatus])
// 应用卸载时清理资源
useEffect(() => {
return () => {
const { cleanup } = useAppStore.getState()
cleanup()
}
}, [])
// 应用初始化中的加载状态
if (isInitializing) {
return (
<div className="min-h-screen bg-gradient-to-br from-purple-900 via-blue-900 to-indigo-900 flex items-center justify-center">
<div className="text-center">
<div className="w-16 h-16 border-4 border-white/30 border-t-white rounded-full animate-spin mx-auto mb-4"></div>
<p className="text-white text-lg">...</p>
</div>
</div>
)
}
return (
<ToastProvider>
<Router>
<div className="min-h-screen bg-gradient-to-br from-purple-900 via-blue-900 to-indigo-900">
{/* 背景装饰 */}
<div className="fixed inset-0 overflow-hidden pointer-events-none">
<div className="absolute top-1/4 left-1/4 w-96 h-96 bg-purple-500/10 rounded-full blur-3xl" />
<div className="absolute top-3/4 right-1/4 w-96 h-96 bg-blue-500/10 rounded-full blur-3xl" />
<div className="absolute bottom-1/4 left-1/2 w-96 h-96 bg-indigo-500/10 rounded-full blur-3xl" />
</div>
{/* 路由配置 */}
<React.Suspense fallback={
<div className="min-h-screen flex items-center justify-center">
<div className="text-center">
<div className="w-16 h-16 border-4 border-white/30 border-t-white rounded-full animate-spin mx-auto mb-4"></div>
<p className="text-white text-lg">...</p>
</div>
</div>
}>
<Routes>
<Route
path="/login"
element={isAuthenticated ? <Navigate to="/" replace /> : <Login />}
/>
<Route
path="/"
element={isAuthenticated ? <Lottery /> : <Navigate to="/login" replace />}
/>
<Route
path="/home"
element={isAuthenticated ? <Home /> : <Navigate to="/login" replace />}
/>
<Route
path="/admin"
element={isAuthenticated ? <Admin /> : <Navigate to="/login" replace />}
/>
<Route
path="/winners"
element={<WinnerDetails />}
/>
<Route
path="/clear-records"
element={isAuthenticated ? <ClearRecords /> : <Navigate to="/login" replace />}
/>
<Route
path="/confetti-demo"
element={isAuthenticated ? <ConfettiDemo /> : <Navigate to="/login" replace />}
/>
<Route
path="/crud-test"
element={<CrudTest />}
/>
<Route
path="/network-test"
element={<NetworkTest />}
/>
<Route
path="/simple-test"
element={<SimpleNetworkTest />}
/>
<Route
path="*"
element={<Navigate to={isAuthenticated ? "/" : "/login"} replace />}
/>
</Routes>
</React.Suspense>
</div>
</Router>
</ToastProvider>
)
}
export default App