Files
Autonomous-Bug-Explorer/frontend/src/components/dashboard/KPICards.tsx

65 lines
1.7 KiB
TypeScript

import { Card, CardContent } from '@/components/ui/card'
import { Skeleton } from '@/components/ui/skeleton'
import type { Stats } from '../../types'
interface KPICardsProps {
stats: Stats | undefined
isLoading: boolean
}
interface KPICardProps {
title: string
value: number | string
isLoading: boolean
valueClass?: string
}
function KPICard({ title, value, isLoading, valueClass }: KPICardProps) {
return (
<Card>
<CardContent className="p-6">
{isLoading ? (
<>
<Skeleton className="h-8 w-16 mb-2" />
<Skeleton className="h-4 w-24" />
</>
) : (
<>
<p className={`text-3xl font-bold ${valueClass ?? ''}`}>{value}</p>
<p className="text-sm text-muted-foreground mt-1">{title}</p>
</>
)}
</CardContent>
</Card>
)
}
export function KPICards({ stats, isLoading }: KPICardsProps) {
return (
<div className="grid grid-cols-2 lg:grid-cols-4 gap-4">
<KPICard
title="Total Findings"
value={stats?.totalAnomalies ?? 0}
isLoading={isLoading}
/>
<KPICard
title="Critical / High"
value={stats?.criticalHighCount ?? 0}
isLoading={isLoading}
valueClass={stats && stats.criticalHighCount > 0 ? 'text-destructive' : undefined}
/>
<KPICard
title="Active Sessions"
value={stats?.runningSessions ?? 0}
isLoading={isLoading}
valueClass={stats && stats.runningSessions > 0 ? 'text-green-500' : undefined}
/>
<KPICard
title="Total Sessions"
value={stats?.totalSessions ?? 0}
isLoading={isLoading}
/>
</div>
)
}