"use client" import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" import { Badge } from "@/components/ui/badge" import { Button } from "@/components/ui/button" import { MoreHorizontal, Eye, ExternalLink, Award, TrendingUp, Calendar, Building } from "lucide-react" import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu" import { useRouter } from "next/navigation" import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip" import type { CategoryType } from "@/lib/benchmark-schema" import { EVALUATION_CATEGORIES } from "@/lib/benchmark-schema" export type BenchmarkEvaluationCardData = { id: string model_name: string model_id: string developer: string evaluations_count: number benchmarks_count: number categories: CategoryType[] category_stats: Record latest_timestamp: string // Quick stats top_scores: Array<{ benchmark: string score: number metric: string unit?: string }> // Links source_urls: string[] detail_urls: string[] // Model Metadata model_url?: string release_date?: string input_modalities?: string[] output_modalities?: string[] architecture?: string params?: string inference_engine?: string inference_platform?: string } interface BenchmarkEvaluationCardProps { data: BenchmarkEvaluationCardData onDelete?: (id: string) => void } export function BenchmarkEvaluationCard({ data, onDelete }: BenchmarkEvaluationCardProps) { const router = useRouter() const formatDate = (isoString: string) => { try { return new Date(isoString).toLocaleDateString('en-US', { year: 'numeric', month: 'short', day: 'numeric' }) } catch { return isoString } } const getCategoryColor = (category: CategoryType, index: number): string => { const colors = [ "bg-emerald-500", "bg-blue-500", "bg-indigo-500", "bg-violet-500", "bg-fuchsia-500", "bg-pink-500", "bg-rose-500", "bg-orange-500", "bg-amber-500", "bg-yellow-500", "bg-lime-500", "bg-teal-500" ] // Use a consistent hash or just the index if the list is stable return colors[index % colors.length] } const getCategoryLabel = (category: CategoryType): string => { return category.split('-').map(w => w.charAt(0).toUpperCase() + w.slice(1)).join(' ') } const renderCategoryDistribution = () => { const totalBenchmarks = data.categories.reduce((acc, cat) => acc + (data.category_stats[cat] || 0), 0) return (
Category Breakdown ({EVALUATION_CATEGORIES.length} categories, {totalBenchmarks} benchmarks)
{EVALUATION_CATEGORIES.map((category, idx) => { const count = data.category_stats[category] || 0 const isZero = count === 0 return (

{getCategoryLabel(category)}

{count} benchmarks

) })}
) } const completeness = Math.round((data.categories.length / EVALUATION_CATEGORIES.length) * 100) return ( router.push(`/benchmark/${encodeURIComponent(data.id)}`)} >
{data.model_name}
{data.developer}
{((data.input_modalities?.length || 0) > 1 || (data.output_modalities?.length || 0) > 1) && ( 🤖 Multimodal )}
router.push(`/benchmark/${encodeURIComponent(data.id)}`)}> View Details {data.source_urls.length > 0 && ( window.open(data.source_urls[0], '_blank')}> View Source )} {onDelete && ( onDelete(data.id)} className="text-destructive" > Remove )}
{/* Completeness & Date Row */}
Completeness
{data.categories.length}/{EVALUATION_CATEGORIES.length} categories
Submitted
{formatDate(data.latest_timestamp)}
{/* Broken Bars */}
{renderCategoryDistribution()}
) }