import { useMemo } from "react"; import { useTranslation } from "react-i18next"; import { Card, CardContent } from "@/components/ui/card"; import { useUsageSummary } from "@/lib/query/usage"; import { Activity, DollarSign, Layers, Database, Loader2 } from "lucide-react"; import { motion } from "framer-motion"; interface UsageSummaryCardsProps { days: number; } export function UsageSummaryCards({ days }: UsageSummaryCardsProps) { const { t } = useTranslation(); const { startDate, endDate } = useMemo(() => { const end = Math.floor(Date.now() / 1000); const start = end - days * 24 * 60 * 60; return { startDate: start, endDate: end }; }, [days]); const { data: summary, isLoading } = useUsageSummary(startDate, endDate); const stats = useMemo(() => { const totalRequests = summary?.totalRequests ?? 0; const totalCost = parseFloat(summary?.totalCost || "0"); const inputTokens = summary?.totalInputTokens ?? 0; const outputTokens = summary?.totalOutputTokens ?? 0; const totalTokens = inputTokens + outputTokens; const cacheWriteTokens = summary?.totalCacheCreationTokens ?? 0; const cacheReadTokens = summary?.totalCacheReadTokens ?? 0; const totalCacheTokens = cacheWriteTokens + cacheReadTokens; return [ { title: t("usage.totalRequests", "总请求数"), value: totalRequests.toLocaleString(), icon: Activity, color: "text-blue-500", bg: "bg-blue-500/10", subValue: null, }, { title: t("usage.totalCost", "总成本"), value: `$${totalCost.toFixed(4)}`, icon: DollarSign, color: "text-green-500", bg: "bg-green-500/10", subValue: null, }, { title: t("usage.totalTokens", "总 Token 数"), value: totalTokens.toLocaleString(), icon: Layers, color: "text-purple-500", bg: "bg-purple-500/10", subValue: (
Input {(inputTokens / 1000).toFixed(1)}k
Output {(outputTokens / 1000).toFixed(1)}k
), }, { title: t("usage.cacheTokens", "缓存 Token"), value: totalCacheTokens.toLocaleString(), icon: Database, color: "text-orange-500", bg: "bg-orange-500/10", subValue: (
Write {(cacheWriteTokens / 1000).toFixed(1)}k
Read {(cacheReadTokens / 1000).toFixed(1)}k
), }, ]; }, [summary, t]); const container = { hidden: { opacity: 0 }, show: { opacity: 1, transition: { staggerChildren: 0.1, }, }, }; const item = { hidden: { opacity: 0, y: 20 }, show: { opacity: 1, y: 0 }, }; if (isLoading) { return (
{[...Array(4)].map((_, i) => ( ))}
); } return ( {stats.map((stat, i) => (

{stat.title}

{stat.value}

{stat.subValue || ( /* Placeholder to properly align cards if no subvalue (first 2 cards) - effectively adding empty space or using flex-1 equivalent */
)}
))}
); }