import { useEffect, useState, useCallback, useRef } from 'react'; import type { AuditLog } from '../api/client'; import { api } from '../api/client'; import { useWebSocket } from '../api/useWebSocket'; const ACTION_COLORS: Record = { PROJECT_CREATED: 'text-green-400', WORKFLOW_STARTED: 'text-blue-400', WORKFLOW_PAUSED: 'text-yellow-400', WORKFLOW_STOPPED: 'text-red-400', WORKFLOW_RESET: 'text-purple-400', STATUS_CHANGED: 'text-fox-500', TASK_CREATED: 'text-teal-400', QA_APPROVED: 'text-green-400', QA_REJECTED: 'text-red-400', DEPLOYED: 'text-green-400', ROLLBACK: 'text-red-400', }; export default function LogsPage() { const [logs, setLogs] = useState([]); const [loading, setLoading] = useState(true); const [agentFilter, setAgentFilter] = useState(''); const [autoScroll, setAutoScroll] = useState(true); const listRef = useRef(null); const fetchLogs = useCallback(async () => { const params: Record = { limit: '200' }; if (agentFilter) params.agent = agentFilter; try { setLogs(await api.listLogs(params)); } catch { /* ignore */ } setLoading(false); }, [agentFilter]); useEffect(() => { fetchLogs(); }, [fetchLogs]); // Live updates const { connected } = useWebSocket(useCallback((msg) => { if (msg.type === 'log' || msg.type === 'project_update') fetchLogs(); }, [fetchLogs])); useEffect(() => { if (autoScroll && listRef.current) { listRef.current.scrollTop = 0; } }, [logs, autoScroll]); if (loading) { return
🦊
; } return (

📜 Logs en temps réel

{logs.length === 0 ? (

Aucun log disponible

) : ( {logs.map((l) => ( ))}
Heure Agent Action Cible Message
{new Date(l.timestamp).toLocaleString('fr-FR', { month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit', second: '2-digit' })} {l.agent} {l.action} {l.target || '—'} {l.message || '—'}
)}
); }