"use client" import type { ComponentType, CSSProperties } from "react" import { useAudienceMode } from "@/components/audience-mode-provider" import { Badge } from "@/components/ui/badge" import { Card, CardContent, CardHeader } from "@/components/ui/card" import { useRouter } from "next/navigation" import { AlertTriangle, BadgeCheck, BookOpenText, ChartNoAxesColumn, FlaskConical, Scale, Users, } from "lucide-react" import type { BenchmarkEvalListItem } from "@/lib/eval-processing" import { getCategoryColor } from "@/lib/benchmark-schema" const LICENSE_COLORS: Record = { "mit": "bg-emerald-100 text-emerald-800 border-emerald-200 dark:bg-emerald-950/40 dark:text-emerald-200", "apache": "bg-sky-100 text-sky-800 border-sky-200 dark:bg-sky-950/40 dark:text-sky-200", "cc by": "bg-violet-100 text-violet-800 border-violet-200 dark:bg-violet-950/40 dark:text-violet-200", "cc0": "bg-teal-100 text-teal-800 border-teal-200 dark:bg-teal-950/40 dark:text-teal-200", "cc-by-sa": "bg-indigo-100 text-indigo-800 border-indigo-200 dark:bg-indigo-950/40 dark:text-indigo-200", } function licenseBadgeClass(license: string): string { const l = license.toLowerCase() for (const [key, cls] of Object.entries(LICENSE_COLORS)) { if (l.includes(key)) return cls } return "bg-muted text-muted-foreground border-border" } function shortenLicense(license: string): string { if (!license || license === "Not specified") return "" // Shorten known verbose license names if (license.toLowerCase().includes("creative commons attribution 4")) return "CC BY 4.0" if (license.toLowerCase().includes("creative commons zero")) return "CC0" if (license.toLowerCase().includes("apache license 2") || license.toLowerCase().includes("apache 2")) return "Apache 2.0" if (license.toLowerCase().includes("mit license")) return "MIT" if (license.toLowerCase().includes("cc-by-sa")) return "CC BY-SA" if (license.length > 24) return license.slice(0, 22) + "…" return license } interface EvalCardProps { summary: BenchmarkEvalListItem delayMs?: number } export function EvalCard({ summary, delayMs = 0 }: EvalCardProps) { const router = useRouter() const { mode } = useAudienceMode() const isResearchView = mode === "research" const scorePercent = `${Math.round(summary.avg_score_norm * 100)}%` const purpose = summary.factsheet?.purpose ?? "General single-benchmark evaluation" const card = summary.benchmark_card const domains: string[] = card?.benchmark_details?.domains ?? [] const license = card?.ethical_and_legal_considerations?.data_licensing ?? "" const shortLicense = shortenLicense(license) // Use the benchmark overview as a richer description when available const overviewText = card?.benchmark_details?.overview // Policy: rich context from metadata card const policyGoal = card?.purpose_and_intended_users?.goal const policyLimitations = card?.purpose_and_intended_users?.limitations const policyAudience = card?.purpose_and_intended_users?.audience const audienceText = Array.isArray(policyAudience) ? policyAudience.slice(0, 2).join("; ") : typeof policyAudience === "string" ? policyAudience : null // Research: score interpretation + similar benchmarks const scoreInterpretation = card?.methodology?.interpretation const rawSimilar = card?.benchmark_details?.similar_benchmarks const similarBenchmarks: string[] = Array.isArray(rawSimilar) ? rawSimilar : rawSimilar ? [rawSimilar] : [] return ( router.push(`/evals/${summary.evaluation_id}`)} >
Single Benchmark
{summary.category && ( {summary.category} )}
{shortLicense && ( {shortLicense} )}
{summary.evaluation_name}
Composite benchmark: {summary.composite_benchmark_name}
{overviewText ?? summary.metric_config.evaluation_description}
{domains.length > 0 && (
{domains.slice(0, 5).map((d) => ( {d} ))} {domains.length > 5 && ( +{domains.length - 5} )}
)}
{summary.third_party_ratio > 0 && ( Independently evaluated )} {summary.missing_generation_config_count > 0 && ( Partial config )}
{isResearchView ? ( <>
{/* Research: score interpretation from metadata */} {scoreInterpretation && (
Score interpretation

{scoreInterpretation}

)}
Methodology
{summary.factsheet?.principles_tested && summary.factsheet.principles_tested !== "Not specified" && ( )} {summary.latest_source_name && ( )} 0 ? `${summary.missing_generation_config_count} result${summary.missing_generation_config_count !== 1 ? "s" : ""} without config` : "Fully documented" } /> {similarBenchmarks.length > 0 && ( )}
) : ( <> {/* Policy: goal (from metadata card if available, otherwise factsheet purpose) */}
Purpose
{policyGoal ?? purpose}
{/* Policy: audience + limitations from metadata */} {(audienceText || policyLimitations) && (
{audienceText && (
Intended for: {audienceText}
)} {policyLimitations && (
Known limitation: {policyLimitations}
)}
)}
{summary.missing_generation_config_count > 0 && (

Some results lack documented generation settings — direct score comparisons should be read with care.

)}
)}
) } function MetricPill({ icon: Icon, label, value, tone, }: { icon: ComponentType<{ className?: string }> label: string value: string tone: string }) { return (
{label}
{value}
) } function DataRow({ label, value }: { label: string; value: string }) { return (
{label} {value}
) }