wulf-pulse/components/mobile/KpiCardMobile.tsx
lorentz bfe9549d02 feat(03-01): add KpiCardMobile, NeedsAttentionStrip, WorkerStatusRow components
- KpiCardMobile: phone-sized KPI card with label/value/caption; tone='attention' adds destructive left border
- NeedsAttentionStrip: horizontal-scroll strip of compact attention cards; renders null when items=[]
- WorkerStatusRow: 3-cell status row with emerald/amber/destructive status dots, each linking to desktop admin
- All three are pure presentational client components; no fetch, no recharts, no new state libraries
2026-05-03 16:50:35 -04:00

39 lines
1.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use client';
/* KpiCardMobile — phase 03 (DASH-01).
*
* Phone-sized KPI card for the 2×2 dashboard grid. Renders a label,
* a large numeric value, and an optional caption. tone="attention"
* adds a left-edge destructive border for SLA breaches > 0.
*
* Pure presentational — no fetch, no state. Parent provides values. */
import { Card, CardContent } from '@/components/ui/card';
import { cn } from '@/lib/utils';
export type KpiTone = 'default' | 'attention';
interface KpiCardMobileProps {
label: string;
value: number | string;
caption?: string;
tone?: KpiTone;
}
const TONE_BORDER: Record<KpiTone, string> = {
default: 'border-l-transparent',
attention: 'border-l-destructive',
};
export function KpiCardMobile({ label, value, caption, tone = 'default' }: KpiCardMobileProps) {
const display = typeof value === 'number' ? value.toLocaleString() : value;
return (
<Card className={cn('h-full border-l-2', TONE_BORDER[tone])}>
<CardContent className="p-4 flex flex-col gap-1">
<p className="text-[11px] font-semibold text-muted-foreground uppercase tracking-wider">{label}</p>
<p className="text-3xl font-bold tabular-nums">{display}</p>
{caption && <p className="text-xs text-muted-foreground">{caption}</p>}
</CardContent>
</Card>
);
}