import { useEffect, useRef, useState } from "react"; import { forgesight } from "@/lib/api"; import { Activity, Cpu, Zap, Thermometer, BarChart3, Database } from "lucide-react"; /* ── helpers ─────────────────────────────────────────────────────────────── */ function arc(pct, r = 38) { const clamp = Math.min(100, Math.max(0, pct)); const angle = (clamp / 100) * 270 - 135; // 270° sweep, start -135° const rad = (a) => (a * Math.PI) / 180; const x = 50 + r * Math.cos(rad(angle)); const y = 50 + r * Math.sin(rad(angle)); const large = clamp > 50 ? 1 : 0; const sx = 50 + r * Math.cos(rad(-135)); const sy = 50 + r * Math.sin(rad(-135)); return `M ${sx} ${sy} A ${r} ${r} 0 ${large} 1 ${x} ${y}`; } function ArcGauge({ pct = 0, label, value, icon: Icon, color = "#ED1C24" }) { const prev = useRef(pct); const [displayed, setDisplayed] = useState(pct); useEffect(() => { // smooth interpolation const start = prev.current; const end = pct; const dur = 600; const t0 = performance.now(); let raf; const step = (now) => { const progress = Math.min((now - t0) / dur, 1); const eased = 1 - Math.pow(1 - progress, 3); setDisplayed(start + (end - start) * eased); if (progress < 1) raf = requestAnimationFrame(step); else prev.current = end; }; raf = requestAnimationFrame(step); return () => cancelAnimationFrame(raf); }, [pct]); const bgPath = arc(100); const fgPath = arc(displayed); return (
{/* Track */} {/* Value */} {/* Center icon */}
{Icon && }
{value}
{label}
); } function StatRow({ label, value, pct, color = "#ED1C24" }) { return (
{label} {value}
); } /* ── main component ──────────────────────────────────────────────────────── */ export default function TelemetryWidget() { const [t, setT] = useState(null); const [blink, setBlink] = useState(false); useEffect(() => { let alive = true; const tick = async () => { try { const data = await forgesight.getTelemetry(); if (alive) { setT(data); setBlink((b) => !b); } } catch {} }; tick(); const id = setInterval(tick, 2000); return () => { alive = false; clearInterval(id); }; }, []); const status = t?.status ?? "—"; const isLive = status === "Connected"; const isLimited = status === "Limited"; const statusColor = isLive ? "#10B981" : isLimited ? "#F59E0B" : "#71717A"; const statusLabel = isLive ? "LIVE" : isLimited ? "LIMITED" : "OFFLINE"; const vramPct = t ? (t.vram_used_gb / t.vram_total_gb) * 100 : 0; const tokensPct = t ? (t.tokens_per_sec / 4000) * 100 : 0; const powerPct = t ? (t.power_watts / 750) * 100 : 0; return (
{/* Header */}
Live Telemetry
{/* Pulse dot */} {statusLabel}
{/* Device */}
{t?.device ?? "AMD Instinct MI300X"} {t?.persistence && ( {t.persistence} )}
{/* Arc gauges row */}
{/* Bar stats */}
); }