"use client"; import { useState, useMemo } from "react"; import { motion, AnimatePresence } from "framer-motion"; import type { Finding, Severity } from "@/lib/types"; import SeverityBadge from "./SeverityBadge"; const AGENT_ICON: Record = { security: ( ), performance: ( ), style: ( ), }; const SEVERITY_ORDER: Record = { critical: 0, high: 1, medium: 2, low: 3, }; type SortKey = "severity" | "agent" | "file_path" | "category" | "title"; export default function FindingsTable({ findings, }: { findings: Finding[]; }) { const [sortKey, setSortKey] = useState("severity"); const [sortAsc, setSortAsc] = useState(true); const [expandedIdx, setExpandedIdx] = useState(null); const sorted = useMemo(() => { const copy = [...findings]; copy.sort((a, b) => { let cmp = 0; if (sortKey === "severity") { cmp = SEVERITY_ORDER[a.severity] - SEVERITY_ORDER[b.severity]; } else { cmp = (a[sortKey] as string).localeCompare(b[sortKey] as string); } return sortAsc ? cmp : -cmp; }); return copy; }, [findings, sortKey, sortAsc]); function handleSort(key: SortKey) { if (key === sortKey) setSortAsc((v) => !v); else { setSortKey(key); setSortAsc(true); } } const arrow = (key: SortKey) => sortKey === key ? (sortAsc ? " \u25B2" : " \u25BC") : ""; return ( {( [ ["severity", "Severity"], ["agent", "Agent"], ["file_path", "File"], ["category", "Category"], ["title", "Title"], ] as [SortKey, string][] ).map(([key, label]) => ( ))} {sorted.map((f, i) => { const isExpanded = expandedIdx === i; return ( ); })}
handleSort(key)} className="px-4 py-3.5 cursor-pointer select-none hover:text-zinc-300 transition-colors font-medium" > {label} {arrow(key)}
{isExpanded && (

Description

{f.description}

{f.suggested_fix && (

Suggested Fix

                                {f.suggested_fix}
                              
)}
{f.cwe_id && ( {f.cwe_id} )} Confidence:{" "} {(f.confidence * 100).toFixed(0)}% Lines{" "} {f.line_start}–{f.line_end}
)}
); }