"use client" import { useState, useMemo, useEffect } from "react" import { Button } from "@/components/ui/button" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" import { Plus, Moon, Sun, Filter, ArrowUpDown } from "lucide-react" import { useTheme } from "next-themes" import { EvaluationCard, type EvaluationCardData } from "@/components/evaluation-card" import { BENCHMARK_QUESTIONS, PROCESS_QUESTIONS } from "@/lib/category-data" import { AIEvaluationDashboard } from "@/components/ai-evaluation-dashboard" const loadEvaluationData = async (): Promise => { const evaluationFiles = [ "/evaluations/gpt-4-turbo.json", "/evaluations/claude-3-sonnet.json", "/evaluations/gemini-pro.json", "/evaluations/fraud-detector.json", ] const additionalFiles = [] for (let i = 1; i <= 10; i++) { additionalFiles.push(`/evaluations/eval-${Date.now() - i * 86400000}.json`) // Check for files from last 10 days } const allFiles = [...evaluationFiles, ...additionalFiles] const evaluations: EvaluationCardData[] = [] for (const file of allFiles) { try { const response = await fetch(file) if (!response.ok) continue // Skip files that don't exist const data = await response.json() const cardData: EvaluationCardData = { id: data.id || `eval-${Date.now()}`, systemName: data.systemName || "Unknown System", provider: data.provider || "Unknown Provider", modality: data.modality || "Unknown", completedDate: data.evaluationDate || new Date().toISOString().split("T")[0], applicableCategories: data.overallStats?.totalApplicable || 0, completedCategories: data.overallStats?.totalApplicable || 0, status: data.overallStats?.strongCategories?.length >= (data.overallStats?.adequateCategories?.length || 0) ? "strong" : data.overallStats?.adequateCategories?.length >= (data.overallStats?.weakCategories?.length || 0) ? "adequate" : "weak", capabilityEval: { strong: (data.overallStats?.strongCategories || []).filter((cat: string) => [ "language-communication", "social-intelligence", "problem-solving", "creativity-innovation", "learning-memory", "perception-vision", "physical-manipulation", "metacognition", "robotic-intelligence", ].includes(cat), ).length, adequate: (data.overallStats?.adequateCategories || []).filter((cat: string) => [ "language-communication", "social-intelligence", "problem-solving", "creativity-innovation", "learning-memory", "perception-vision", "physical-manipulation", "metacognition", "robotic-intelligence", ].includes(cat), ).length, weak: (data.overallStats?.weakCategories || []).filter((cat: string) => [ "language-communication", "social-intelligence", "problem-solving", "creativity-innovation", "learning-memory", "perception-vision", "physical-manipulation", "metacognition", "robotic-intelligence", ].includes(cat), ).length, insufficient: (data.overallStats?.insufficientCategories || []).filter((cat: string) => [ "language-communication", "social-intelligence", "problem-solving", "creativity-innovation", "learning-memory", "perception-vision", "physical-manipulation", "metacognition", "robotic-intelligence", ].includes(cat), ).length, strongCategories: (data.overallStats?.strongCategories || []).filter((cat: string) => [ "language-communication", "social-intelligence", "problem-solving", "creativity-innovation", "learning-memory", "perception-vision", "physical-manipulation", "metacognition", "robotic-intelligence", ].includes(cat), ), adequateCategories: (data.overallStats?.adequateCategories || []).filter((cat: string) => [ "language-communication", "social-intelligence", "problem-solving", "creativity-innovation", "learning-memory", "perception-vision", "physical-manipulation", "metacognition", "robotic-intelligence", ].includes(cat), ), weakCategories: (data.overallStats?.weakCategories || []).filter((cat: string) => [ "language-communication", "social-intelligence", "problem-solving", "creativity-innovation", "learning-memory", "perception-vision", "physical-manipulation", "metacognition", "robotic-intelligence", ].includes(cat), ), insufficientCategories: (data.overallStats?.insufficientCategories || []).filter((cat: string) => [ "language-communication", "social-intelligence", "problem-solving", "creativity-innovation", "learning-memory", "perception-vision", "physical-manipulation", "metacognition", "robotic-intelligence", ].includes(cat), ), totalApplicable: data.overallStats?.capabilityApplicable || 0, }, riskEval: { strong: (data.overallStats?.strongCategories || []).filter((cat: string) => [ "harmful-content", "information-integrity", "privacy-data", "bias-fairness", "security-robustness", "dangerous-capabilities", "human-ai-interaction", "environmental-impact", "economic-displacement", "governance-accountability", "value-chain", ].includes(cat), ).length, adequate: (data.overallStats?.adequateCategories || []).filter((cat: string) => [ "harmful-content", "information-integrity", "privacy-data", "bias-fairness", "security-robustness", "dangerous-capabilities", "human-ai-interaction", "environmental-impact", "economic-displacement", "governance-accountability", "value-chain", ].includes(cat), ).length, weak: (data.overallStats?.weakCategories || []).filter((cat: string) => [ "harmful-content", "information-integrity", "privacy-data", "bias-fairness", "security-robustness", "dangerous-capabilities", "human-ai-interaction", "environmental-impact", "economic-displacement", "governance-accountability", "value-chain", ].includes(cat), ).length, insufficient: (data.overallStats?.insufficientCategories || []).filter((cat: string) => [ "harmful-content", "information-integrity", "privacy-data", "bias-fairness", "security-robustness", "dangerous-capabilities", "human-ai-interaction", "environmental-impact", "economic-displacement", "governance-accountability", "value-chain", ].includes(cat), ).length, strongCategories: (data.overallStats?.strongCategories || []).filter((cat: string) => [ "harmful-content", "information-integrity", "privacy-data", "bias-fairness", "security-robustness", "dangerous-capabilities", "human-ai-interaction", "environmental-impact", "economic-displacement", "governance-accountability", "value-chain", ].includes(cat), ), adequateCategories: (data.overallStats?.adequateCategories || []).filter((cat: string) => [ "harmful-content", "information-integrity", "privacy-data", "bias-fairness", "security-robustness", "dangerous-capabilities", "human-ai-interaction", "environmental-impact", "economic-displacement", "governance-accountability", "value-chain", ].includes(cat), ), weakCategories: (data.overallStats?.weakCategories || []).filter((cat: string) => [ "harmful-content", "information-integrity", "privacy-data", "bias-fairness", "security-robustness", "dangerous-capabilities", "human-ai-interaction", "environmental-impact", "economic-displacement", "governance-accountability", "value-chain", ].includes(cat), ), insufficientCategories: (data.overallStats?.insufficientCategories || []).filter((cat: string) => [ "harmful-content", "information-integrity", "privacy-data", "bias-fairness", "security-robustness", "dangerous-capabilities", "human-ai-interaction", "environmental-impact", "economic-displacement", "governance-accountability", "value-chain", ].includes(cat), ), totalApplicable: data.overallStats?.riskApplicable || 0, }, priorityAreas: data.overallStats?.priorityAreas || [], priorityDetails: (() => { // Build a richer structure: for each area, include yes questions and negative questions (no/na) with optional reason const pd: Record< string, { yes: string[] negative: { text: string; status: "no" | "na"; reason?: string }[] } > = {} const areas = data.overallStats?.priorityAreas || [] for (const area of areas) { const catEval = data.categoryEvaluations?.[area] if (!catEval) continue const yesList: string[] = [] const negList: { text: string; status: "no" | "na"; reason?: string }[] = [] // Helper to detect NA reason from category metadata const naReasonFromMeta = (): string | undefined => { if (typeof catEval.additionalAspects === "string" && /not applicable/i.test(catEval.additionalAspects)) { return catEval.additionalAspects } // look into processSources scopes for any note if (catEval.processSources) { for (const entries of Object.values(catEval.processSources)) { if (Array.isArray(entries)) { for (const ent of entries as any[]) { if (ent && typeof ent.scope === "string" && /not applicable/i.test(ent.scope)) { return ent.scope } } } } } return undefined } const naMeta = naReasonFromMeta() // check benchmarkAnswers (A1..A6) if (catEval.benchmarkAnswers) { for (const [qid, ans] of Object.entries(catEval.benchmarkAnswers)) { const answer = ans const isArray = Array.isArray(answer) const negative = answer === "no" || (isArray && (answer as any[]).includes("no")) const positive = answer === "yes" || (isArray && (answer as any[]).includes("yes")) const qText = BENCHMARK_QUESTIONS.find((x) => x.id === qid)?.text || qid if (positive) yesList.push(qText) if (negative) { const status = naMeta ? "na" : "no" negList.push({ text: qText, status, reason: naMeta }) } } } // check processAnswers (B1..B6) if (catEval.processAnswers) { for (const [qid, ans] of Object.entries(catEval.processAnswers)) { const answer = ans const isArray = Array.isArray(answer) const negative = answer === "no" || (isArray && (answer as any[]).includes("no")) const positive = answer === "yes" || (isArray && (answer as any[]).includes("yes")) const qText = PROCESS_QUESTIONS.find((x) => x.id === qid)?.text || qid if (positive) yesList.push(qText) if (negative) { const status = naMeta ? "na" : "no" negList.push({ text: qText, status, reason: naMeta }) } } } if (yesList.length || negList.length) pd[area] = { yes: yesList, negative: negList } } return pd })(), } evaluations.push(cardData) } catch (error) { continue } } return evaluations } export default function HomePage() { const { theme, setTheme } = useTheme() const [showNewEvaluation, setShowNewEvaluation] = useState(false) const [evaluationsData, setEvaluationsData] = useState([]) const [loading, setLoading] = useState(true) useEffect(() => { const loadData = async () => { const data = await loadEvaluationData() setEvaluationsData(data) setLoading(false) } loadData() }, []) const [sortBy, setSortBy] = useState<"date-newest" | "date-oldest">("date-newest") const [filterByProvider, setFilterByProvider] = useState("all") const [filterByModality, setFilterByModality] = useState("all") const uniqueProviders = useMemo(() => { const providers = [...new Set(evaluationsData.map((item) => item.provider))].sort() return providers }, [evaluationsData]) const uniqueModalities = useMemo(() => { const modalities = [...new Set(evaluationsData.map((item) => item.modality))].sort() return modalities }, [evaluationsData]) const filteredAndSortedEvaluations = useMemo(() => { let filtered = evaluationsData if (filterByProvider !== "all") { filtered = filtered.filter((item) => item.provider === filterByProvider) } if (filterByModality !== "all") { filtered = filtered.filter((item) => item.modality === filterByModality) } filtered = [...filtered].sort((a, b) => { const dateA = new Date(a.completedDate) const dateB = new Date(b.completedDate) if (sortBy === "date-newest") { return dateB.getTime() - dateA.getTime() } else { return dateA.getTime() - dateB.getTime() } }) return filtered }, [evaluationsData, sortBy, filterByProvider, filterByModality]) const handleViewEvaluation = (id: string) => {} const handleDeleteEvaluation = (id: string) => { setEvaluationsData((prev) => prev.filter((evaluation) => evaluation.id !== id)) } const handleSaveEvaluation = (newEvaluation: EvaluationCardData) => { setEvaluationsData((prev) => [newEvaluation, ...prev]) } if (showNewEvaluation) { return setShowNewEvaluation(false)} onSaveEvaluation={handleSaveEvaluation} /> } if (loading) { return (

Loading evaluations...

) } return (

AI Evaluation Dashboard

Manage and track your AI system evaluations

Evaluation Cards

{filteredAndSortedEvaluations.length} eval cards

Sort by:
Provider:
Modality:
{filteredAndSortedEvaluations.length > 0 ? (
{filteredAndSortedEvaluations.map((evaluation) => ( ))}
) : (

No evaluations match your filters

Try adjusting your filter criteria to see more results

)}
) }