import type { ReactNode } from 'react'; import { cn } from '@/lib/format'; /** Operator labels for health statuses (SPEC §12): UP · DEGRADED · BROKEN · DISABLED · MAINTENANCE. */ const LABELS: Record = { healthy: { label: 'UP', cls: 'bg-gain-bg text-gain' }, degraded: { label: 'DEGRADED', cls: 'bg-alert-bg text-alert' }, failing: { label: 'BROKEN', cls: 'bg-loss-bg text-loss' }, paused: { label: 'DISABLED', cls: 'bg-inset text-muted' }, disabled: { label: 'DISABLED', cls: 'bg-inset text-muted' }, maintenance: { label: 'MAINTENANCE', cls: 'bg-index-bg text-index' }, unknown: { label: 'UNKNOWN', cls: 'bg-inset text-subtle' }, }; export function HealthLabel({ status, small = true }: { status: string | null | undefined; small?: boolean }) { const l = LABELS[status ?? 'unknown'] ?? LABELS.unknown!; return {l.label}; } /** Source favicon (Google s2 service, falls back to an initial). */ export function SourceLogo({ domain, name, logoUrl, size = 18 }: { domain: string | null | undefined; name: string; logoUrl?: string | null; size?: number }) { const src = logoUrl ?? (domain ? `https://www.google.com/s2/favicons?domain=${encodeURIComponent(domain)}&sz=${size * 2}` : null); if (!src) return {name.slice(0, 1).toUpperCase()}; // eslint-disable-next-line @next/next/no-img-element return ; } export function Pct({ value, digits = 0 }: { value: unknown; digits?: number }) { const x = Number(value); return <>{Number.isFinite(x) ? `${(x * 100).toFixed(digits)}%` : '—'}; } /** Thin progress bar for backfill campaigns. */ export function Progress({ percent, status }: { percent: number | null | undefined; status?: string | null }) { const p = percent === null || percent === undefined ? null : Math.max(0, Math.min(100, Number(percent))); return (
{p === null ? (status ?? '—') : `${p.toFixed(0)}% · ${status ?? ''}`}
); } export function Json({ value, className }: { value: unknown; className?: string }) { return
{typeof value === 'string' ? value : JSON.stringify(value, null, 2)}
; } export function Chip({ children, tone = 'neutral' }: { children: ReactNode; tone?: 'neutral' | 'index' | 'alert' }) { return {children}; }