import { createContext, useCallback, useContext, useEffect, useMemo, useState } from "react"; import { Navigate, Route, Routes, useNavigate } from "react-router-dom"; import { ToastProvider } from "./components/ui"; import { UpdatePrompt } from "./components/UpdatePrompt"; import { api, authExpired, session } from "./lib/client"; import type { User, Workspace } from "./lib/types"; import { LoginPage } from "./pages/Login"; import { HomePage } from "./pages/Home"; import { WorkspacePage } from "./pages/Workspace"; import { TasksPage } from "./pages/Tasks"; import { BoardPage } from "./pages/Board"; import { TicketsPage } from "./pages/Tickets"; import { KnowledgePage } from "./pages/Knowledge"; import { NotificationsPage } from "./pages/Notifications"; import { JoinPage } from "./pages/Join"; import { AccountPage } from "./pages/Account"; import { SettingsPage } from "./pages/Settings"; interface AuthState { user: User | null; workspaces: Workspace[]; loading: boolean; reload: () => Promise; signOut: () => void; } const AuthContext = createContext(null); export function useAuth(): AuthState { const ctx = useContext(AuthContext); if (!ctx) throw new Error("useAuth 必须在 AuthProvider 内使用"); return ctx; } export function AuthProvider({ children }: { children: React.ReactNode }) { const [user, setUser] = useState(null); const [workspaces, setWorkspaces] = useState([]); const [loading, setLoading] = useState(true); const navigate = useNavigate(); const reload = useCallback(async () => { if (!session.access) { setUser(null); setWorkspaces([]); setLoading(false); return; } try { const me = await api.get<{ user: User; workspaces: Workspace[] }>("/auth/me"); setUser(me.user); setWorkspaces(me.workspaces); } catch { setUser(null); setWorkspaces([]); } finally { setLoading(false); } }, []); useEffect(() => { void reload(); const onExpired = () => { setUser(null); setWorkspaces([]); navigate("/login", { replace: true }); }; authExpired.addEventListener("expired", onExpired); return () => authExpired.removeEventListener("expired", onExpired); }, [reload, navigate]); const signOut = useCallback(() => { session.clear(); setUser(null); setWorkspaces([]); navigate("/login", { replace: true }); }, [navigate]); const value = useMemo( () => ({ user, workspaces, loading, reload, signOut }), [user, workspaces, loading, reload, signOut], ); return {children}; } export function App() { return ( } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> ); }