- 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
55 lines
1.6 KiB
TypeScript
55 lines
1.6 KiB
TypeScript
'use client';
|
|
|
|
/* WorkerStatusRow — phase 03 (DASH-03).
|
|
*
|
|
* Compact 3-cell read-only status row showing analyzer worker, RMM worker,
|
|
* and backup success rate. Each cell is a next/link to the corresponding
|
|
* desktop admin page. status='ok' = emerald dot, 'warn' = amber, 'down' =
|
|
* destructive. */
|
|
|
|
import Link from 'next/link';
|
|
import { ExternalLink } from 'lucide-react';
|
|
|
|
export type WorkerStatus = 'ok' | 'warn' | 'down';
|
|
|
|
export interface WorkerStatusEntry {
|
|
id: string;
|
|
label: string;
|
|
value: string;
|
|
status: WorkerStatus;
|
|
href: string;
|
|
}
|
|
|
|
interface WorkerStatusRowProps {
|
|
entries: WorkerStatusEntry[];
|
|
}
|
|
|
|
const DOT_COLOR: Record<WorkerStatus, string> = {
|
|
ok: 'bg-emerald-500',
|
|
warn: 'bg-amber-500',
|
|
down: 'bg-destructive',
|
|
};
|
|
|
|
export function WorkerStatusRow({ entries }: WorkerStatusRowProps) {
|
|
return (
|
|
<div>
|
|
<p className="text-xs font-semibold text-muted-foreground uppercase tracking-wider mb-2">
|
|
Workers & backups
|
|
</p>
|
|
<div className="rounded-2xl border divide-y overflow-hidden">
|
|
{entries.map(e => (
|
|
<Link
|
|
key={e.id}
|
|
href={e.href}
|
|
className="flex items-center gap-3 px-4 py-3 hover:bg-accent transition-colors"
|
|
>
|
|
<span className={`inline-block w-2 h-2 rounded-full shrink-0 ${DOT_COLOR[e.status]}`} aria-hidden="true" />
|
|
<span className="text-sm font-medium flex-1">{e.label}</span>
|
|
<span className="text-sm tabular-nums text-muted-foreground">{e.value}</span>
|
|
<ExternalLink className="w-3.5 h-3.5 text-muted-foreground shrink-0" />
|
|
</Link>
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|