Files
CC-Switch/src/components/usage/ModelStatsTable.tsx
T
Dex Miller 87b80c66b2 feat(usage): enhance dashboard with auto-refresh control and robust formatting (#942)
* style: format code and apply clippy lint fixes

* feat(usage): enhance dashboard with auto-refresh control and robust formatting

- Add configurable auto-refresh interval toggle (off/5s/10s/30s/60s) to usage dashboard
- Extract shared format utilities (fmtUsd, fmtInt, parseFiniteNumber, getLocaleFromLanguage)
- Refactor request log time filtering to rolling vs fixed mode with validation
- Use stable serializable query keys instead of filter objects
- Handle NaN/Infinity safely in number formatting across all usage components
- Use RFC 3339 date format in backend trend data
2026-02-06 22:00:33 +08:00

83 lines
2.5 KiB
TypeScript

import { useTranslation } from "react-i18next";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/components/ui/table";
import { useModelStats } from "@/lib/query/usage";
import { fmtUsd } from "./format";
interface ModelStatsTableProps {
refreshIntervalMs: number;
}
export function ModelStatsTable({ refreshIntervalMs }: ModelStatsTableProps) {
const { t } = useTranslation();
const { data: stats, isLoading } = useModelStats({
refetchInterval: refreshIntervalMs > 0 ? refreshIntervalMs : false,
});
if (isLoading) {
return <div className="h-[400px] animate-pulse rounded bg-gray-100" />;
}
return (
<div className="rounded-lg border border-border/50 bg-card/40 backdrop-blur-sm overflow-hidden">
<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">
{fmtUsd(stat.totalCost, 4)}
</TableCell>
<TableCell className="text-right">
{fmtUsd(stat.avgCostPerRequest, 6)}
</TableCell>
</TableRow>
))
)}
</TableBody>
</Table>
</div>
);
}