import React from 'react'; /** * Headline figures for AI Insight cards. * Matches NEW dashboard gray card patterns (white + border-gray-100). */ export type InsightStatus = 'ok' | 'warning' | 'critical' | 'unknown'; const STATUS_CHIP: Record = { ok: { cls: 'bg-green-50 text-green-800 border-green-200', glyph: '✓' }, warning: { cls: 'bg-amber-50 text-amber-800 border-amber-200', glyph: '!' }, critical: { cls: 'bg-red-50 text-red-800 border-red-200', glyph: '⚠' }, unknown: { cls: 'bg-gray-50 text-gray-500 border-gray-200', glyph: '–' }, }; interface DeltaChipProps { status: InsightStatus; label: string; } export const DeltaChip: React.FC = ({ status, label }) => { const chip = STATUS_CHIP[status]; return ( {label} ); }; /** Axis-less sparkline — shape only; the tile number carries the value. */ export const Sparkline: React.FC<{ values: number[]; className?: string }> = ({ values, className, }) => { const clean = values.filter((v) => typeof v === 'number' && Number.isFinite(v)); if (clean.length < 2) return null; const width = 88; const height = 28; const min = Math.min(...clean); const max = Math.max(...clean); const span = max - min || 1; const step = width / (clean.length - 1); const points = clean .map((value, index) => { const x = index * step; const y = height - 2 - ((value - min) / span) * (height - 4); return `${x.toFixed(1)},${y.toFixed(1)}`; }) .join(' '); return ( ); }; interface HeroFigureProps { label: string; value: string; unit?: string; context?: string | null; status?: InsightStatus; deltaLabel?: string | null; sparkline?: number[]; } export const HeroFigure: React.FC = ({ label, value, unit, context, status = 'unknown', deltaLabel, sparkline, }) => (
{label}
{value} {unit ? {unit} : null}
{deltaLabel ? : null} {context ? {context} : null}
{sparkline && sparkline.length > 1 ? ( ) : null}
); interface StatTileProps { label: string; value: string; unit?: string; hint?: string | null; status?: InsightStatus; deltaLabel?: string | null; sparkline?: number[]; } export const StatTile: React.FC = ({ label, value, unit, hint, status = 'unknown', deltaLabel, sparkline, }) => (
{label} {hint ? {hint} : null}
{value} {unit ? {unit} : null}
{deltaLabel ? (
) : null} {sparkline && sparkline.length > 1 ? ( ) : null}
); /** Secondary figures: subordinate to hero / tiles. */ export const MutedStatRow: React.FC<{ label: string; hint?: string | null; value: string }> = ({ label, hint, value, }) => (
{label} {hint ? {hint} : null} {value}
);