"use client"; import { useState, useMemo } from "react"; import { useLocale, useTranslations } from "@/lib/i18n"; import { LEARNING_PATH, VERSION_META } from "@/lib/constants"; import { Card, CardHeader, CardTitle } from "@/components/ui/card"; import { LayerBadge } from "@/components/ui/badge"; import { CodeDiff } from "@/components/diff/code-diff"; import { ArchDiagram } from "@/components/architecture/arch-diagram"; import { ArrowRight, FileCode, Wrench, Box, FunctionSquare } from "lucide-react"; import type { VersionIndex } from "@/types/agent-data"; import versionData from "@/data/generated/versions.json"; const data = versionData as VersionIndex; export default function ComparePage() { const t = useTranslations("compare"); const locale = useLocale(); const [versionA, setVersionA] = useState(""); const [versionB, setVersionB] = useState(""); const infoA = useMemo(() => data.versions.find((v) => v.id === versionA), [versionA]); const infoB = useMemo(() => data.versions.find((v) => v.id === versionB), [versionB]); const metaA = versionA ? VERSION_META[versionA] : null; const metaB = versionB ? VERSION_META[versionB] : null; const comparison = useMemo(() => { if (!infoA || !infoB) return null; const toolsA = new Set(infoA.tools); const toolsB = new Set(infoB.tools); const onlyA = infoA.tools.filter((t) => !toolsB.has(t)); const onlyB = infoB.tools.filter((t) => !toolsA.has(t)); const shared = infoA.tools.filter((t) => toolsB.has(t)); const classesA = new Set(infoA.classes.map((c) => c.name)); const classesB = new Set(infoB.classes.map((c) => c.name)); const newClasses = infoB.classes.map((c) => c.name).filter((c) => !classesA.has(c)); const funcsA = new Set(infoA.functions.map((f) => f.name)); const funcsB = new Set(infoB.functions.map((f) => f.name)); const newFunctions = infoB.functions.map((f) => f.name).filter((f) => !funcsA.has(f)); return { locDelta: infoB.loc - infoA.loc, toolsOnlyA: onlyA, toolsOnlyB: onlyB, toolsShared: shared, newClasses, newFunctions, }; }, [infoA, infoB]); return (

{t("title")}

{t("subtitle")}

{/* Selectors */}
{/* Results */} {infoA && infoB && comparison && (
{/* Side-by-side version info */}
{metaA?.title || versionA}

{metaA?.subtitle}

{infoA.loc} LOC

{infoA.tools.length} tools

{metaA && {metaA.layer}}
{metaB?.title || versionB}

{metaB?.subtitle}

{infoB.loc} LOC

{infoB.tools.length} tools

{metaB && {metaB.layer}}
{/* Side-by-side Architecture Diagrams */}

{t("architecture")}

{metaA?.title || versionA}

{metaB?.title || versionB}

{/* Structural diff */}
{t("loc_delta")}
= 0 ? "text-green-600 dark:text-green-400" : "text-red-600 dark:text-red-400"}> {comparison.locDelta >= 0 ? "+" : ""}{comparison.locDelta} {t("lines")}
{t("new_tools_in_b")}
{comparison.toolsOnlyB.length} {comparison.toolsOnlyB.length > 0 && (
{comparison.toolsOnlyB.map((tool) => ( {tool} ))}
)}
{t("new_classes_in_b")}
{comparison.newClasses.length} {comparison.newClasses.length > 0 && (
{comparison.newClasses.map((cls) => ( {cls} ))}
)}
{t("new_functions_in_b")}
{comparison.newFunctions.length} {comparison.newFunctions.length > 0 && (
{comparison.newFunctions.map((fn) => ( {fn} ))}
)}
{/* Tool comparison */} {t("tool_comparison")}

{t("only_in")} {metaA?.title || versionA}

{comparison.toolsOnlyA.length === 0 ? (

{t("none")}

) : (
{comparison.toolsOnlyA.map((tool) => ( {tool} ))}
)}

{t("shared")}

{comparison.toolsShared.length === 0 ? (

{t("none")}

) : (
{comparison.toolsShared.map((tool) => ( {tool} ))}
)}

{t("only_in")} {metaB?.title || versionB}

{comparison.toolsOnlyB.length === 0 ? (

{t("none")}

) : (
{comparison.toolsOnlyB.map((tool) => ( {tool} ))}
)}
{/* Code Diff */}

{t("source_diff")}

)} {/* Empty state */} {(!versionA || !versionB) && (

{t("empty_hint")}

)}
); }