import { useEffect, useRef, useState } from "react"; import { ChevronDown, Copy, Check, TerminalSquare } from "lucide-react"; // A terminal-style panel that "streams" the raw backend JSON line by line — // surfaces real confidence scores and coordinates for technical credibility. export default function RawOutput({ result }) { const [open, setOpen] = useState(true); const [shown, setShown] = useState(0); const [copied, setCopied] = useState(false); const bodyRef = useRef(null); const json = result ? JSON.stringify(result, null, 2) : ""; const lines = json ? json.split("\n") : []; // Reveal lines progressively whenever a new result arrives. useEffect(() => { if (!result) return; let intervalId; const resetId = setTimeout(() => { setShown(0); intervalId = setInterval(() => { setShown((n) => { if (n >= lines.length) { clearInterval(intervalId); return n; } return n + 1; }); }, 28); }, 0); return () => { clearTimeout(resetId); clearInterval(intervalId); }; }, [json]); // eslint-disable-line react-hooks/exhaustive-deps // Keep the newest line in view while streaming. useEffect(() => { if (open && bodyRef.current) bodyRef.current.scrollTop = bodyRef.current.scrollHeight; }, [shown, open]); if (!result) return null; const copy = () => { navigator.clipboard?.writeText(json); setCopied(true); setTimeout(() => setCopied(false), 1400); }; const streaming = shown < lines.length; return (
{lines.slice(0, shown).map((ln, i) => (
{i + 1}
{ln || " "}
))}
{streaming && }
)}