"use client"; import { useState, useEffect, useRef } from "react"; import { Card, Button } from "@/shared/components"; import { CONSOLE_LOG_CONFIG } from "@/shared/constants/config"; const LOG_LEVEL_COLORS = { LOG: "text-green-400", INFO: "text-blue-400", WARN: "text-yellow-400", ERROR: "text-red-400", DEBUG: "text-purple-400", }; function colorLine(line) { const match = line.match(/\[(\w+)\]/g); const levelTag = match ? match[1]?.replace(/\[|\]/g, "") : null; const color = LOG_LEVEL_COLORS[levelTag] || "text-green-400"; return {line}; } export default function ConsoleLogClient() { const [logs, setLogs] = useState([]); const [connected, setConnected] = useState(false); const logRef = useRef(null); const handleClear = async () => { try { await fetch("/api/translator/console-logs", { method: "DELETE" }); // UI cleared via SSE "clear" event } catch (err) { console.error("Failed to clear console logs:", err); } }; useEffect(() => { const es = new EventSource("/api/translator/console-logs/stream"); es.onopen = () => setConnected(true); es.onmessage = (e) => { const msg = JSON.parse(e.data); if (msg.type === "init") { setLogs(msg.logs.slice(-CONSOLE_LOG_CONFIG.maxLines)); } else if (msg.type === "line") { setLogs((prev) => { const next = [...prev, msg.line]; return next.length > CONSOLE_LOG_CONFIG.maxLines ? next.slice(-CONSOLE_LOG_CONFIG.maxLines) : next; }); } else if (msg.type === "clear") { setLogs([]); } }; es.onerror = () => setConnected(false); return () => es.close(); }, []); // Auto-scroll to bottom on new logs useEffect(() => { if (!logRef.current) return; logRef.current.scrollTop = logRef.current.scrollHeight; }, [logs]); return (