import * as React from 'react'; import { ArrowDownRight, ArrowUpRight, Minus } from 'lucide-react'; import { cn } from '@/lib/utils'; /** * MetricStrip — a row of operational figures. * * The Admin surface reports six to eight numbers at once. As individual cards * that becomes a wall of boxes competing with the content below it, so this * presents them as one banded strip: hairline dividers instead of borders, one * shared surface, numbers aligned on a baseline. Dense enough for an operations * console, still readable. * * `items: [{ label, value, delta?, deltaLabel?, invertTrend?, sub?, icon?, tone? }]` * * `invertTrend` exists because up is not always good: time-to-hire rising is * bad, and colouring it green would misinform. */ const TONE = { default: 'text-ink-1', brand: 'text-krow-blue', success: 'text-success', warning: 'text-warning', risk: 'text-destructive', }; function Delta({ delta, label, invert }) { if (typeof delta !== 'number') return null; const flat = delta === 0; const good = invert ? delta < 0 : delta > 0; const Icon = flat ? Minus : delta > 0 ? ArrowUpRight : ArrowDownRight; return ( {flat ? '0%' : `${Math.abs(delta)}%`} {label && {label}} ); } export function MetricStrip({ items = [], columns, className, loading = false }) { // Column count follows the data by default, so the strip divides evenly // instead of leaving an orphan cell. const count = columns ?? Math.min(items.length, 6); /** * Five and six columns wait for `xl` rather than `lg`. * * The strip lives in the Admin main column, which is narrower than the * viewport whenever the Owliver workspace is open — roughly 400px narrower. A * `lg` breakpoint measures the window and so cheerfully packs six cells into a * 580px column, where every label clips. Two rows of three is the better * answer at that width. */ const gridCols = { 2: 'sm:grid-cols-2', 3: 'sm:grid-cols-3', 4: 'grid-cols-2 sm:grid-cols-4', 5: 'grid-cols-2 sm:grid-cols-3 xl:grid-cols-5', 6: 'grid-cols-2 sm:grid-cols-3 xl:grid-cols-6', }[count] || 'sm:grid-cols-3'; return (
{item.label}
{item.sub}
}