import { useState, useEffect, useRef, useMemo, useCallback } from "react"; import { useAPI } from "../contexts/APIProvider"; import { usePersistentState } from "../hooks/usePersistentState"; const LogViewer = () => { const { proxyLogs, upstreamLogs, enableAPIEvents } = useAPI(); useEffect(() => { enableAPIEvents(true); return () => { enableAPIEvents(false); }; }, []); return (
); }; interface LogPanelProps { id: string; title: string; logData: string; className?: string; } export const LogPanel = ({ id, title, logData, className }: LogPanelProps) => { const [isCollapsed, setIsCollapsed] = usePersistentState(`logPanel-${id}-isCollapsed`, false); const [filterRegex, setFilterRegex] = useState(""); const [fontSize, setFontSize] = usePersistentState<"xxs" | "xs" | "small" | "normal">( `logPanel-${id}-fontSize`, "normal" ); const [wrapText, setTextWrap] = usePersistentState(`logPanel-${id}-wrapText`, false); const textWrapClass = useMemo(() => { return wrapText ? "whitespace-pre-wrap" : "whitespace-pre"; }, [wrapText]); const toggleFontSize = useCallback(() => { setFontSize((prev) => { switch (prev) { case "xxs": return "xs"; case "xs": return "small"; case "small": return "normal"; case "normal": return "xxs"; } }); }, []); const fontSizeClass = useMemo(() => { switch (fontSize) { case "xxs": return "text-[0.5rem]"; // 0.5rem (8px) case "xs": return "text-[0.75rem]"; // 0.75rem (12px) case "small": return "text-[0.875rem]"; // 0.875rem (14px) case "normal": return "text-base"; // 1rem (16px) } }, [fontSize]); const filteredLogs = useMemo(() => { if (!filterRegex) return logData; try { const regex = new RegExp(filterRegex, "i"); const lines = logData.split("\n"); const filtered = lines.filter((line) => regex.test(line)); return filtered.join("\n"); } catch (e) { return logData; // Return unfiltered if regex is invalid } }, [logData, filterRegex]); // auto scroll to bottom const preTagRef = useRef(null); useEffect(() => { if (!preTagRef.current) return; preTagRef.current.scrollTop = preTagRef.current.scrollHeight; }, [filteredLogs]); return (
{/* Title - Always full width on mobile, normal on desktop */}
setIsCollapsed(!isCollapsed)}>

{title}

{/* Sizing Buttons - Stacks vertically on mobile */}
{/* Filtering Options - Full width on mobile, normal on desktop */}
setFilterRegex(e.target.value)} />
{!isCollapsed && (
            {filteredLogs}
          
)}
); }; export default LogViewer;