diff --git a/client/components/admin/AdminStatusOverview.tsx b/client/components/admin/AdminStatusOverview.tsx new file mode 100644 index 00000000..d48ed0b5 --- /dev/null +++ b/client/components/admin/AdminStatusOverview.tsx @@ -0,0 +1,141 @@ +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; +import { Badge } from "@/components/ui/badge"; +import { Button } from "@/components/ui/button"; +import type { LucideIcon } from "lucide-react"; + +export type AdminServiceStatus = { + name: string; + status: "operational" | "degraded" | "outage"; + uptime: string; + responseTime: number; + icon: LucideIcon; +}; + +export type AdminOverallStatus = { + label: string; + accentClass: string; + badgeClass: string; + Icon: LucideIcon; +}; + +interface AdminStatusOverviewProps { + services: AdminServiceStatus[]; + overall: AdminOverallStatus; + onViewStatus: () => void; +} + +const statusBadgeClass: Record = { + operational: + "border-emerald-500/30 bg-emerald-500/10 text-emerald-200", + degraded: "border-yellow-500/30 bg-yellow-500/10 text-yellow-200", + outage: "border-red-500/40 bg-red-500/10 text-red-200", +}; + +export default function AdminStatusOverview({ + services, + overall, + onViewStatus, +}: AdminStatusOverviewProps) { + const averageResponse = + services.length > 0 + ? Math.round( + services.reduce((total, service) => total + service.responseTime, 0) / + services.length, + ) + : null; + + const averageUptime = + services.length > 0 + ? services.reduce((total, service) => { + const asNumber = Number.parseFloat(service.uptime); + return Number.isFinite(asNumber) ? total + asNumber : total; + }, 0) / services.length + : null; + + const healthyServices = services.filter( + (service) => service.status === "operational", + ).length; + + return ( + + +
+
+
+ +
+
+ System health + + {overall.label} + +
+
+ +
+ + Live uptime, latency, and reliability snapshot across AeThex + infrastructure. + +
+ +
+
+

+ Avg response +

+

+ {averageResponse !== null ? `${averageResponse} ms` : "—"} +

+
+
+

+ Avg uptime +

+

+ {averageUptime !== null ? `${averageUptime.toFixed(2)}%` : "—"} +

+
+
+

+ Healthy services +

+

+ {services.length + ? `${healthyServices}/${services.length}` + : "—"} +

+
+
+
+ {services.map((service) => { + const ServiceIcon = service.icon; + return ( +
+
+
+ +
+
+

{service.name}

+

+ {service.responseTime} ms • {service.uptime} uptime +

+
+
+ + {service.status} + +
+ ); + })} +
+
+
+ ); +}