import { Server, Wifi, AlertTriangle, Activity } from 'lucide-react' import { Card, CardContent } from '@/components/ui/card' import { useAnimatedCounter } from '@/hooks/useAnimatedCounter' import { cn } from '@/lib/utils' export interface KpiCardsProps { totalDevices: number onlinePercent: number // 0-100 activeAlerts: number totalBandwidthBps: number // bytes per second } /** * Formats bytes-per-second into a human-readable bandwidth string. * Auto-scales through bps, Kbps, Mbps, Gbps. */ // eslint-disable-next-line react-refresh/only-export-components export function formatBandwidth(bps: number): { value: number; unit: string } { if (bps < 1_000) return { value: bps, unit: 'bps' } if (bps < 1_000_000) return { value: bps / 1_000, unit: 'Kbps' } if (bps < 1_000_000_000) return { value: bps / 1_000_000, unit: 'Mbps' } return { value: bps / 1_000_000_000, unit: 'Gbps' } } interface KpiCardProps { icon: React.ReactNode label: string value: number suffix?: string decimals?: number colorClass: string highlight?: boolean } function KpiCard({ icon, label, value, suffix, decimals = 0, colorClass, highlight, }: KpiCardProps) { const animatedValue = useAnimatedCounter(value, 800, decimals) return (
{label}
{decimals > 0 ? animatedValue.toFixed(decimals) : animatedValue} {suffix && ( {suffix} )}
) } export function KpiCards({ totalDevices, onlinePercent, activeAlerts, totalBandwidthBps, }: KpiCardsProps) { const bandwidth = formatBandwidth(totalBandwidthBps) // Determine appropriate decimal places for bandwidth display const bwDecimals = bandwidth.value < 10 ? 2 : bandwidth.value < 100 ? 1 : 0 return (
} label="Total Devices" value={totalDevices} colorClass="text-accent" /> } label="Online" value={onlinePercent} suffix="%" decimals={1} colorClass="text-success" /> } label="Active Alerts" value={activeAlerts} colorClass={activeAlerts > 0 ? 'text-warning' : 'text-text-muted'} highlight={activeAlerts > 0} /> } label="Total Bandwidth" value={bandwidth.value} suffix={bandwidth.unit} decimals={bwDecimals} colorClass="text-accent" />
) }