QuantumShield / frontend /components /ProcessingStatsCard.tsx
SantoshKumar1310's picture
Upload folder using huggingface_hub
49e53ae verified
'use client';
import { Clock } from 'lucide-react';
interface ProcessingStatsCardProps {
avgLatency: number;
peakHour: number;
throughput: number;
uptime: number;
}
export default function ProcessingStatsCard({
avgLatency,
peakHour,
throughput,
uptime
}: ProcessingStatsCardProps) {
// Generate radial chart data for 24-hour processing
const hours = Array.from({ length: 24 }, (_, i) => {
const baseLoad = 40 + Math.random() * 30;
const peakBoost = Math.abs(i - peakHour) < 3 ? 20 : 0;
return Math.min(100, baseLoad + peakBoost);
});
return (
<div className="card-light rounded-3xl p-6 card-hover h-full">
{/* Header */}
<div className="flex items-center justify-between mb-4">
<div className="flex items-center gap-3">
<div className="w-10 h-10 rounded-xl bg-gray-900/10 flex items-center justify-center">
<Clock className="w-5 h-5 text-gray-700" />
</div>
<div>
<h3 className="text-xl font-bold text-gray-800">PROCESSING</h3>
<p className="text-xs text-gray-500">Real-time Statistics</p>
</div>
</div>
<span className="text-xs bg-emerald-100 text-emerald-700 px-2 py-1 rounded-full font-medium">
Online
</span>
</div>
{/* Radial Chart */}
<div className="relative w-40 h-40 mx-auto mb-4">
<svg className="w-full h-full" viewBox="0 0 100 100">
{/* Background circle */}
<circle cx="50" cy="50" r="45" fill="none" stroke="#e5e7eb" strokeWidth="2" />
{/* Hour marks and bars */}
{hours.map((load, hour) => {
const angle = (hour * 15) - 90;
const radians = (angle * Math.PI) / 180;
const innerRadius = 20;
const outerRadius = 20 + (load / 100) * 25;
const x1 = 50 + innerRadius * Math.cos(radians);
const y1 = 50 + innerRadius * Math.sin(radians);
const x2 = 50 + outerRadius * Math.cos(radians);
const y2 = 50 + outerRadius * Math.sin(radians);
const isPeak = hour === peakHour;
return (
<line
key={hour}
x1={x1}
y1={y1}
x2={x2}
y2={y2}
stroke={isPeak ? '#f97316' : '#6b7280'}
strokeWidth={isPeak ? 3 : 2}
strokeLinecap="round"
opacity={0.6 + (load / 100) * 0.4}
/>
);
})}
{/* Center */}
<circle cx="50" cy="50" r="16" fill="white" />
<text x="50" y="48" textAnchor="middle" className="text-xs font-bold fill-gray-800">
{avgLatency}
</text>
<text x="50" y="56" textAnchor="middle" className="text-[8px] fill-gray-500">
ms avg
</text>
</svg>
{/* Hour labels */}
<div className="absolute top-0 left-1/2 -translate-x-1/2 text-xs text-gray-400">00</div>
<div className="absolute bottom-0 left-1/2 -translate-x-1/2 text-xs text-gray-400">12</div>
<div className="absolute left-0 top-1/2 -translate-y-1/2 text-xs text-gray-400">18</div>
<div className="absolute right-0 top-1/2 -translate-y-1/2 text-xs text-gray-400">06</div>
</div>
{/* Stats Grid */}
<div className="grid grid-cols-3 gap-2">
<div className="text-center p-2 bg-gray-100 rounded-xl">
<p className="text-lg font-bold text-gray-800">{throughput}</p>
<p className="text-xs text-gray-500">TPS</p>
</div>
<div className="text-center p-2 bg-orange-100 rounded-xl">
<p className="text-lg font-bold text-orange-600">{peakHour}:00</p>
<p className="text-xs text-gray-500">Peak</p>
</div>
<div className="text-center p-2 bg-emerald-100 rounded-xl">
<p className="text-lg font-bold text-emerald-600">{uptime}%</p>
<p className="text-xs text-gray-500">Uptime</p>
</div>
</div>
</div>
);
}