"use client" import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" import { Badge } from "@/components/ui/badge" import { Button } from "@/components/ui/button" import type { SystemInfo, CategoryScore } from "@/components/ai-evaluation-dashboard" import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, PieChart, Pie, Cell } from "recharts" import { Download, AlertTriangle, CheckCircle, AlertCircle, XCircle, Globe, Calendar, User, Building, Cpu, MonitorSpeaker, Database, Hash, Tags, Clock, Activity, Headphones, Settings } from "lucide-react" interface Category { id: string name: string type: "capability" | "risk" } interface ResultsDashboardProps { systemInfo: SystemInfo | null categories: Category[] selectedCategories: string[] categoryScores: Record excludedCategoryReasons?: Record } const STATUS_COLORS = { strong: "#22c55e", adequate: "#3b82f6", weak: "#f59e0b", insufficient: "#ef4444", } const STATUS_ICONS = { strong: CheckCircle, adequate: CheckCircle, weak: AlertCircle, insufficient: XCircle, } export function ResultsDashboard({ systemInfo, categories, selectedCategories, categoryScores, excludedCategoryReasons, }: ResultsDashboardProps) { const safeCategories = categories || [] const safeSelectedCategories = selectedCategories || [] const safeCategoryScores = categoryScores || {} console.log("[v0] ResultsDashboard rendering with:", { systemInfo, categoriesCount: safeCategories.length, selectedCount: safeSelectedCategories.length, scoresCount: Object.keys(safeCategoryScores).length, scores: safeCategoryScores, }) const selectedCategoryObjects = safeCategories.filter((c) => safeSelectedCategories.includes(c.id)) const getStatusCounts = () => { const scores = Object.values(safeCategoryScores) return { strong: scores.filter((s) => s.status === "strong").length, adequate: scores.filter((s) => s.status === "adequate").length, weak: scores.filter((s) => s.status === "weak").length, insufficient: scores.filter((s) => s.status === "insufficient").length, } } const getCapabilityRiskBreakdown = () => { const capability = selectedCategoryObjects.filter((c) => c.type === "capability") const risk = selectedCategoryObjects.filter((c) => c.type === "risk") const capabilityScores = capability.map((c) => safeCategoryScores[c.id]).filter(Boolean) const riskScores = risk.map((c) => safeCategoryScores[c.id]).filter(Boolean) const avgCapability = capabilityScores.length > 0 ? capabilityScores.reduce((sum, s) => sum + (s.totalScore || 0), 0) / capabilityScores.length : 0 const avgRisk = riskScores.length > 0 ? riskScores.reduce((sum, s) => sum + (s.totalScore || 0), 0) / riskScores.length : 0 const safeCapability = isNaN(avgCapability) || !isFinite(avgCapability) ? 0 : avgCapability const safeRisk = isNaN(avgRisk) || !isFinite(avgRisk) ? 0 : avgRisk console.log("[v0] Capability/Risk breakdown:", { capabilityScores: capabilityScores.length, riskScores: riskScores.length, avgCapability, avgRisk, safeCapability, safeRisk, }) return { capability: safeCapability, risk: safeRisk, } } const getChartData = () => { return selectedCategoryObjects .map((category) => { const score = safeCategoryScores[category.id] return { name: category.name.length > 20 ? category.name.substring(0, 20) + "..." : category.name, fullName: category.name, benchmarkScore: score?.benchmarkScore || 0, processScore: score?.processScore || 0, totalScore: score?.totalScore || 0, type: category.type, } }) .sort((a, b) => b.totalScore - a.totalScore) } const getPieData = () => { const counts = getStatusCounts() return [ { name: "Strong (12-15)", value: counts.strong, color: STATUS_COLORS.strong }, { name: "Adequate (8-11)", value: counts.adequate, color: STATUS_COLORS.adequate }, { name: "Weak (4-7)", value: counts.weak, color: STATUS_COLORS.weak }, { name: "Insufficient (0-3)", value: counts.insufficient, color: STATUS_COLORS.insufficient }, ].filter((item) => item.value > 0) } const statusCounts = getStatusCounts() const breakdown = getCapabilityRiskBreakdown() const chartData = getChartData() const pieData = getPieData() const totalEvaluated = Object.keys(safeCategoryScores).length const overallAverage = totalEvaluated > 0 ? Object.values(safeCategoryScores).reduce((sum, s) => sum + (s.totalScore || 0), 0) / totalEvaluated : 0 const safeOverallAverage = isNaN(overallAverage) || !isFinite(overallAverage) ? 0 : overallAverage console.log("[v0] Overall average calculation:", { totalEvaluated, overallAverage, safeOverallAverage, }) const safeToFixed = (value: number, digits = 1): string => { if (isNaN(value) || !isFinite(value)) { console.log("[v0] Warning: Invalid value for toFixed:", value) return "0.0" } return value.toFixed(digits) } const exportResults = () => { const results = { systemInfo, evaluationDate: new Date().toISOString(), summary: { totalCategories: safeSelectedCategories.length, evaluatedCategories: totalEvaluated, overallAverage: safeOverallAverage.toFixed(1), statusBreakdown: statusCounts, }, categoryResults: safeCategories.map((category) => ({ ...category, score: safeCategoryScores[category.id] || null, excludedReason: !safeSelectedCategories.includes(category.id) ? excludedCategoryReasons?.[category.id] || null : null, })), } const blob = new Blob([JSON.stringify(results, null, 2)], { type: "application/json" }) const url = URL.createObjectURL(blob) const a = document.createElement("a") a.href = url a.download = `ai-evaluation-${systemInfo?.name || "system"}-${new Date().toISOString().split("T")[0]}.json` a.click() URL.revokeObjectURL(url) } return (
{/* System Overview */}
Evaluation Results Comprehensive assessment results for {systemInfo?.name}
{totalEvaluated}
Categories Evaluated
{safeToFixed(safeOverallAverage)}/15
Overall Average
{safeToFixed(breakdown.capability)}/15
Capability Average
{safeToFixed(breakdown.risk)}/15
Risk Average
{/* System Information (detailed) */}
System Information A summary of metadata provided for the evaluated system
{/* Left Column */}
System Name
{(systemInfo as any)?.systemName || systemInfo?.name || "—"}
System Version
{systemInfo?.version || (systemInfo as any)?.modelTag || "—"}
Provider
{systemInfo?.provider || "—"}
URL
{systemInfo?.url ? ( {systemInfo.url} ) : ( "—" )}
Model Type
{systemInfo?.modelType ? ( {systemInfo.modelType === "foundational" ? "Foundational Model" : systemInfo.modelType === "fine-tuned" ? "Fine-tuned Model" : "Not Applicable"} ) : "—"}
{/* Right Column */}
Deployment Context
{(systemInfo as any)?.deploymentContext || (systemInfo?.deploymentContexts && systemInfo.deploymentContexts.join(", ")) || "—"}
Input Modalities
{systemInfo?.inputModalities?.length ? (
{systemInfo.inputModalities.map((modality: string, idx: number) => ( {modality} ))}
) : "—"}
Output Modalities
{systemInfo?.outputModalities?.length ? (
{systemInfo.outputModalities.map((modality: string, idx: number) => ( {modality} ))}
) : "—"}
Knowledge Cutoff
{systemInfo?.knowledgeCutoff || "—"}
Evaluator
{(systemInfo as any)?.evaluator || "—"}
{/* Bottom Row - Metadata Cards */}
System ID
{(systemInfo as any)?.id || "—"}
System Types
{(systemInfo as any)?.systemTypes?.length ? (systemInfo as any).systemTypes.join(", ") : "—"}
Evaluation Date
{(systemInfo as any)?.evaluationDate || "—"}
{/* Status Overview */}
{Object.entries(statusCounts).map(([status, count]) => { const key = (status as string) as keyof typeof STATUS_ICONS const Icon = STATUS_ICONS[key] ?? AlertTriangle return (
{count}
{status}
) })}
{/* Charts */}
{/* Score Distribution */} Score Distribution Categories by evaluation status `${name}: ${value}`} > {pieData.map((entry, index) => ( ))} {/* Category Scores */} Category Scores Benchmark vs Process scores by category chartData.find((d) => d.name === label)?.fullName || label} />
{/* Detailed Results */} Detailed Category Results Complete breakdown of all evaluated categories
{selectedCategoryObjects.map((category) => { const score = safeCategoryScores[category.id] if (!score) return null const key = (score.status as string) as keyof typeof STATUS_ICONS const Icon = (STATUS_ICONS as any)[key] ?? AlertTriangle const color = (STATUS_COLORS as any)[key] ?? STATUS_COLORS.insufficient return (
{category.name}
{category.type} Benchmark: {score.benchmarkScore}/7 | Process: {score.processScore}/8
{score.totalScore}/15
{score.status}
) })}
{/* Excluded Categories with Reasons */} Excluded Categories & Reasons Categories you marked as not applicable and the rationale provided
{safeCategories .filter((c) => !safeSelectedCategories.includes(c.id)) .map((c) => (
{c.name}
{excludedCategoryReasons?.[c.id] || "No reason provided"}
))}
{/* Priority Actions */} Priority Action Areas Categories requiring immediate attention
{statusCounts.insufficient > 0 && (

Critical - Insufficient Categories ({statusCounts.insufficient})

{selectedCategoryObjects .filter((c) => safeCategoryScores[c.id]?.status === "insufficient") .map((category) => ( {category.name} ))}
)} {statusCounts.weak > 0 && (

High Priority - Weak Categories ({statusCounts.weak})

{selectedCategoryObjects .filter((c) => safeCategoryScores[c.id]?.status === "weak") .map((category) => ( {category.name} ))}
)} {statusCounts.insufficient === 0 && statusCounts.weak === 0 && (

No critical priority areas identified. All categories scored adequate or above.

)}
) }