import {RefreshCw} from 'lucide-react'; import {useCallback, useEffect, useState} from 'react'; import {getAdminOverview} from '../api/adminApiClient'; import type { AdminDatabaseTableStatPayload, AdminOverviewResponse, } from '../api/adminApiTypes'; import {handlePageError} from './pageUtils'; interface AdminOverviewPageProps { token: string; onUnauthorized: (message?: string) => void; } export function AdminOverviewPage({ token, onUnauthorized, }: AdminOverviewPageProps) { const [overview, setOverview] = useState(null); const [errorMessage, setErrorMessage] = useState(''); const [isLoading, setIsLoading] = useState(false); const loadOverview = useCallback(async () => { setIsLoading(true); setErrorMessage(''); try { const response = await getAdminOverview(token); setOverview(response); } catch (error: unknown) { handlePageError(error, onUnauthorized, setErrorMessage); } finally { setIsLoading(false); } }, [onUnauthorized, token]); useEffect(() => { void loadOverview(); }, [loadOverview]); return (

总览

服务与数据库状态

{errorMessage ? (
{errorMessage}
) : null}

表统计

{overview?.database.schemaTableNames.length ?? 0} tables
{(overview?.database.tableStats ?? []).map((stat) => ( ))} {overview && overview.database.tableStats.length === 0 ? ( ) : null}
行数 状态
暂无统计
{overview?.database.fetchErrors.length ? (

读取异常

{overview.database.fetchErrors.length}
    {overview.database.fetchErrors.map((message) => (
  • {message}
  • ))}
) : null}
); } function InfoPanel({ title, rows, }: { title: string; rows: Array<[string, string]>; }) { return (

{title}

{rows.map(([label, value]) => (
{label}
{value}
))}
); } function TableStatRow({stat}: {stat: AdminDatabaseTableStatPayload}) { return ( {typeof stat.rowCount === 'number' ? stat.rowCount : '-'} {stat.errorMessage ? ( {stat.errorMessage} ) : ( OK )} ); }