"use client"; import { cx } from "@/ui/utils"; /** * The page's only chart, and it is deliberately a row of divs. * * Everything else on Usage is an unbounded count, which belongs in a column of * a table where it can be read exactly. Two things are genuinely shapes rather * than numbers — when in the day the box is busy, and whether a model's traffic * is growing — and both are answered by relative bar heights, so they get bars. * Doing it with a charting library would buy axes and tooltips we do not want * and a bundle we would have to pay for on every page load. */ export type UsageBar = { key: string; /** Shown under the bar when `labels` is on; kept to two or three glyphs. */ label: string; value: number; /** The full sentence, on hover — this is where the exact numbers live. */ title: string; }; export function UsageBarRow({ bars, labels = false, heightClass = "h-24", }: { bars: readonly UsageBar[]; labels?: boolean; heightClass?: string; }) { const peak = bars.reduce((max, bar) => Math.max(max, bar.value), 0); return (
{bars.map((bar) => (
0 ? "bg-(--accent)/45 hover:bg-(--accent)/70" : "bg-(--ui-surface-2)", )} // A zero bar still draws a 2px floor: an empty hour is data, and a // gap in the row reads as a rendering failure instead. style={{ height: peak > 0 ? `${Math.max(2, (bar.value / peak) * 100)}%` : "2px" }} />
))}
{labels ? (
{bars.map((bar, index) => ( {index % 3 === 0 ? bar.label : ""} ))}
) : null}
); }