import {useCallback, useEffect, useState} from 'react'; import { formatAdminApiError, getAdminMe, isAdminApiError, loginAdmin, } from '../api/adminApiClient'; import type { AdminSessionPayload, ProfileRedeemCodeAdminResponse, } from '../api/adminApiTypes'; import { clearStoredAdminToken, getStoredAdminToken, setStoredAdminToken, } from '../auth/adminAuthStore'; import {AdminDebugHttpPage} from '../pages/AdminDebugHttpPage'; import {AdminLoginPage} from '../pages/AdminLoginPage'; import {AdminOverviewPage} from '../pages/AdminOverviewPage'; import {AdminRedeemCodePage} from '../pages/AdminRedeemCodePage'; import {AdminShell} from './AdminShell'; import type {AdminRouteId} from './adminRoutes'; import {resolveAdminRoute, routeHash} from './adminRoutes'; type SessionStatus = 'checking' | 'guest' | 'authenticated'; export function AdminApp() { const [status, setStatus] = useState('checking'); const [admin, setAdmin] = useState(null); const [token, setToken] = useState(''); const [routeId, setRouteId] = useState(() => resolveAdminRoute(window.location.hash), ); const [loginNotice, setLoginNotice] = useState(''); // 兑换码页会随页签切换卸载,最近操作记录需要放在会话层保留。 const [redeemResult, setRedeemResult] = useState(null); const clearSession = useCallback((message = '') => { clearStoredAdminToken(); setToken(''); setAdmin(null); setRedeemResult(null); setStatus('guest'); setLoginNotice(message); }, []); useEffect(() => { let isMounted = true; const storedToken = getStoredAdminToken(); if (!storedToken) { setStatus('guest'); return; } void getAdminMe(storedToken) .then((response) => { if (!isMounted) { return; } setToken(storedToken); setAdmin(response.admin); setStatus('authenticated'); }) .catch((error: unknown) => { if (!isMounted) { return; } clearStoredAdminToken(); setToken(''); setAdmin(null); setStatus('guest'); setLoginNotice( isAdminApiError(error) && error.status === 401 ? '登录状态已失效' : formatAdminApiError(error), ); }); return () => { isMounted = false; }; }, []); useEffect(() => { const handleHashChange = () => { setRouteId(resolveAdminRoute(window.location.hash)); }; window.addEventListener('hashchange', handleHashChange); return () => window.removeEventListener('hashchange', handleHashChange); }, []); const handleRouteChange = useCallback((nextRouteId: AdminRouteId) => { setRouteId(nextRouteId); const nextHash = routeHash(nextRouteId); if (window.location.hash !== nextHash) { window.location.hash = nextHash; } }, []); const handleLogin = useCallback(async (username: string, password: string) => { const response = await loginAdmin(username, password); setStoredAdminToken(response.token); setToken(response.token); setAdmin(response.admin); setRedeemResult(null); setLoginNotice(''); setStatus('authenticated'); }, []); const handleUnauthorized = useCallback( (message = '登录状态已失效') => { clearSession(message); }, [clearSession], ); const handleLogout = useCallback(() => { clearSession(''); }, [clearSession]); if (status === 'checking') { return (
正在校验会话
); } if (status === 'guest' || !admin || !token) { return ; } return ( {routeId === 'overview' ? ( ) : null} {routeId === 'debug' ? ( ) : null} {routeId === 'redeem' ? ( ) : null} ); }