// src/pages/agent-office/components/LogTab.jsx import { useState, useEffect, useRef } from 'react'; import { getAgentLogs } from '../../../api'; const LEVEL_STYLE = { info: { color: '#60a5fa' }, warning: { color: '#fbbf24' }, error: { color: '#ef4444' }, }; const SOURCE_STYLE = { agent: { color: '#9ca3af', label: 'AGENT' }, access: { color: '#5eead4', label: 'ACCESS' }, log: { color: '#a78bfa', label: 'LOG' }, }; function formatTime(iso) { if (!iso) return ''; return new Date(iso).toLocaleTimeString('ko-KR', { hour: '2-digit', minute: '2-digit', second: '2-digit', }); } export default function LogTab({ agentId, refreshTrigger }) { const [logs, setLogs] = useState([]); const scrollRef = useRef(null); useEffect(() => { let cancelled = false; const fetchLogs = () => { getAgentLogs(agentId, 100).then(data => { if (cancelled) return; setLogs(Array.isArray(data) ? data : (data?.logs || [])); }).catch(() => {}); }; fetchLogs(); const interval = setInterval(fetchLogs, 5000); // 5초 폴링 return () => { cancelled = true; clearInterval(interval); }; }, [agentId, refreshTrigger]); useEffect(() => { if (scrollRef.current) { scrollRef.current.scrollTop = 0; } }, [logs]); return (
{logs.length === 0 &&
No logs yet
} {logs.map((log, i) => { const source = log.source || 'agent'; const sourceMeta = SOURCE_STYLE[source] || SOURCE_STYLE.agent; const levelStyle = LEVEL_STYLE[log.level] || LEVEL_STYLE.info; const time = formatTime(log.ts || log.created_at); return (
{time} [{sourceMeta.label}] [{log.level}] {log.message} {source === 'access' && ( {' '}({log.status} · {log.ms}ms) )}
); })}
); }