Files
cc-switch/src/components/usage/ModelStatsTable.tsx
T
YoVinchen 434ffd559d feat(ui): add usage dashboard components
Add UsageDashboard with summary cards, trend chart, and data tables.
Implement model pricing configuration panel.
Add request log viewer with filtering and detail panel.
2025-12-03 00:25:41 +08:00

76 lines
2.3 KiB
TypeScript

import { useTranslation } from "react-i18next";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
import { useModelStats } from "@/lib/query/usage";
export function ModelStatsTable() {
const { t } = useTranslation();
const { data: stats, isLoading } = useModelStats();
if (isLoading) {
return <div className="h-[400px] animate-pulse rounded bg-gray-100" />;
}
return (
<div className="rounded-md bg-card/60 shadow-sm">
<Table>
<TableHeader>
<TableRow>
<TableHead>{t("usage.model", "模型")}</TableHead>
<TableHead className="text-right">
{t("usage.requests", "请求数")}
</TableHead>
<TableHead className="text-right">
{t("usage.tokens", "Tokens")}
</TableHead>
<TableHead className="text-right">
{t("usage.totalCost", "总成本")}
</TableHead>
<TableHead className="text-right">
{t("usage.avgCost", "平均成本")}
</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{stats?.length === 0 ? (
<TableRow>
<TableCell
colSpan={5}
className="text-center text-muted-foreground"
>
{t("usage.noData", "暂无数据")}
</TableCell>
</TableRow>
) : (
stats?.map((stat) => (
<TableRow key={stat.model}>
<TableCell className="font-mono text-sm">
{stat.model}
</TableCell>
<TableCell className="text-right">
{stat.requestCount.toLocaleString()}
</TableCell>
<TableCell className="text-right">
{stat.totalTokens.toLocaleString()}
</TableCell>
<TableCell className="text-right">
${parseFloat(stat.totalCost).toFixed(4)}
</TableCell>
<TableCell className="text-right">
${parseFloat(stat.avgCostPerRequest).toFixed(6)}
</TableCell>
</TableRow>
))
)}
</TableBody>
</Table>
</div>
);
}