"use client"; import { useEffect, useState } from "react"; const TYPE_STYLES: Record = { Function: { color: "var(--accent)", bg: "var(--accent-glow)" }, Class: { color: "var(--green)", bg: "var(--green-dim)" }, Method: { color: "var(--yellow)", bg: "var(--yellow-dim)" }, }; const REL_COLORS: Record = { CALLS: "var(--accent)", IMPORTS: "var(--green)", EXTENDS: "var(--red)", HAS_METHOD: "var(--cyan)", DEFINED_IN: "var(--text-dim)", CONTAINS: "var(--yellow)", }; interface Props { uid: string; } export function SymbolDetail({ uid }: Props) { const [data, setData] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { setLoading(true); fetch(`/api/symbol/${encodeURIComponent(uid)}`) .then((r) => r.json()) .then((d) => { setData(d); setLoading(false); }) .catch(() => setLoading(false)); }, [uid]); if (loading) { return (
{[1, 2, 3].map((i) => (
))}
); } if (!data?.symbol) { return (
?

Symbol not found

); } const sym = data.symbol; const style = TYPE_STYLES[sym.node_type] || TYPE_STYLES.Function; return (
{/* Symbol header */}
{sym.node_type} {sym.name}
{sym.signature && ( {sym.signature} )}
{sym.file_path}:{sym.line_start}
{sym.docstring && (

{sym.docstring}

)}
{/* Outgoing */} {data.outgoing && Object.keys(data.outgoing).length > 0 && (
{Object.entries(data.outgoing).map(([rel, targets]: [string, any]) => ( ))}
)} {/* Incoming */} {data.incoming && Object.keys(data.incoming).length > 0 && (
{Object.entries(data.incoming).map(([rel, sources]: [string, any]) => ( ))}
)}
); } function Section({ title, icon, children }: { title: string; icon: string; children: React.ReactNode }) { return (
{icon}

{title}

{children}
); } function RelGroup({ rel, items }: { rel: string; items: any[] }) { const color = REL_COLORS[rel] || "var(--text-dim)"; return (
{rel} {items.length}
    {items.slice(0, 10).map((item, i) => (
  • {item.name} {item.file_path || item.file}
  • ))} {items.length > 10 && (
  • +{items.length - 10} more
  • )}
); }