import { Bar, BarChart, ReferenceLine, ResponsiveContainer, Tooltip, YAxis, type TooltipProps, } from "recharts"; import { cn } from "~/utils/cn"; import { formatDateTime } from "./DateTime"; import { Header3 } from "./Headers"; import TooltipPortal from "./TooltipPortal"; type UsageDatum = { date: Date; count: number }; type UnitLabel = { singular: string; plural: string }; export type UsageSparklineProps = { /** Equal-width time buckets, oldest first. */ data?: number[]; /** Epoch ms of the first bucket's start. When omitted, the last bucket is anchored to now. */ bucketStartMs?: number; /** Width of each bucket in ms. Defaults to one hour. */ bucketIntervalMs?: number; /** Bar colour. Defaults to blue. */ color?: string; /** Unit shown in the tooltip (e.g. calls, tokens). */ unitLabel?: UnitLabel; /** Format the trailing total. Defaults to `toLocaleString`. */ formatTotal?: (total: number) => string; /** Class for the trailing total label. */ totalClassName?: string; }; /** * Inline 24h sparkline for list rows. Renders a small bar chart plus a trailing * total, or an em-dash when there's no data. Shared by the prompts and models * lists — keep it presentational (the caller supplies the zero-filled buckets). */ export function UsageSparkline({ data, bucketStartMs, bucketIntervalMs, color = "var(--color-pending)", unitLabel = { singular: "call", plural: "calls" }, formatTotal, totalClassName = "text-blue-400", }: UsageSparklineProps) { if (!data || data.every((v) => v === 0)) { return –; } const total = data.reduce((a, b) => a + b, 0); const max = Math.max(...data); // Map each bucket to a dated point so the tooltip can show the window it // represents. Buckets are `intervalMs` wide; if the caller didn't pass the // first bucket's start, anchor the last bucket to now (hourly default). const intervalMs = bucketIntervalMs ?? 3600_000; const startMs = bucketStartMs ?? Date.now() - (data.length - 1) * intervalMs; const chartData: UsageDatum[] = data.map((count, i) => ({ date: new Date(startMs + i * intervalMs), count, })); return (