cloud-sre-arbiter / frontend /src /components /TelemetryGrid.tsx
Escanor925's picture
feat: complete v2 React UI rebuild and Hugging Face integration
734561b
import {
Area,
AreaChart,
CartesianGrid,
ResponsiveContainer,
Tooltip,
XAxis,
YAxis,
} from 'recharts';
import { Cpu, HardDrive, MemoryStick, Network } from 'lucide-react';
import type { ComponentType } from 'react';
import type { Observation, TelemetryPoint } from '../types';
interface TelemetryGridProps {
telemetry: TelemetryPoint[];
observation: Observation | null;
}
interface MetricCardConfig {
key: keyof Pick<TelemetryPoint, 'cpu' | 'memory' | 'network' | 'disk'>;
title: string;
tone: string;
Icon: ComponentType<{ className?: string }>;
}
const METRICS: MetricCardConfig[] = [
{ key: 'cpu', title: 'CPU', tone: '#22d3ee', Icon: Cpu },
{ key: 'memory', title: 'Memory', tone: '#a78bfa', Icon: MemoryStick },
{ key: 'network', title: 'Network', tone: '#34d399', Icon: Network },
{ key: 'disk', title: 'Disk I/O', tone: '#f97316', Icon: HardDrive },
];
export function TelemetryGrid({ telemetry, observation }: TelemetryGridProps) {
return (
<div className="grid grid-cols-1 gap-3 2xl:grid-cols-2">
{METRICS.map(({ key, title, tone, Icon }) => {
const latest = observation ? Math.round(telemetry[telemetry.length - 1]?.[key] ?? 0) : 0;
return (
<div key={key} className="rounded-xl border border-slate-800 bg-slate-900/70 p-3 shadow-lg shadow-slate-950/30">
<div className="mb-2 flex items-center justify-between">
<div className="flex items-center gap-2">
<Icon className="h-4 w-4" />
<span className="font-mono text-xs uppercase tracking-wider text-slate-400">{title}</span>
</div>
<span className="font-mono text-xs" style={{ color: tone }}>
{latest}%
</span>
</div>
<div className="h-28">
<ResponsiveContainer width="100%" height="100%">
<AreaChart data={telemetry} margin={{ top: 4, right: 2, left: -22, bottom: 0 }}>
<defs>
<linearGradient id={`fill-${key}`} x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor={tone} stopOpacity={0.5} />
<stop offset="95%" stopColor={tone} stopOpacity={0.05} />
</linearGradient>
</defs>
<CartesianGrid strokeDasharray="2 4" stroke="#1e293b" vertical={false} />
<XAxis
dataKey="turn"
tick={{ fill: '#64748b', fontSize: 10 }}
axisLine={{ stroke: '#334155' }}
tickLine={false}
/>
<YAxis
tick={{ fill: '#64748b', fontSize: 10 }}
axisLine={false}
tickLine={false}
domain={[0, 100]}
/>
<Tooltip
contentStyle={{
backgroundColor: '#020617',
border: '1px solid #1e293b',
borderRadius: 10,
color: '#cbd5e1',
fontSize: 12,
}}
labelStyle={{ color: '#94a3b8' }}
/>
<Area type="monotone" dataKey={key} stroke={tone} fill={`url(#fill-${key})`} strokeWidth={2} />
</AreaChart>
</ResponsiveContainer>
</div>
</div>
);
})}
</div>
);
}