'use client' import { useEffect, useState, useRef } from 'react' import { Terminal, RefreshCw, Filter, Database, Radio, Cpu, AlertCircle } from 'lucide-react' interface LogEntry { type: string; level: string; source: string message: string; timestamp: string; from?: string; hash?: string } const TYPE_COLORS: Record = { memory: '#9C27B0', mesh: '#2979FF', broadcast: '#FF1D6C', error: '#ef4444', info: '#22c55e', warn: '#F5A623', } const TYPE_ICONS: Record = { memory: Database, mesh: Cpu, broadcast: Radio, error: AlertCircle, } function timeStr(iso: string) { try { return new Date(iso).toLocaleTimeString() } catch { return iso } } export default function LogsPage() { const [logs, setLogs] = useState([]) const [loading, setLoading] = useState(true) const [filter, setFilter] = useState('all') const [autoRefresh, setAutoRefresh] = useState(true) const [refreshing, setRefreshing] = useState(false) const bottomRef = useRef(null) const load = async () => { setRefreshing(true) try { const r = await fetch(`/api/logs?filter=${filter}`) const d = await r.json() setLogs(d.logs || []) } finally { setRefreshing(false); setLoading(false) } } useEffect(() => { load() }, [filter]) useEffect(() => { if (!autoRefresh) return const t = setInterval(load, 10000) return () => clearInterval(t) }, [autoRefresh, filter]) return (

Activity Log

{logs.length} entries · memory · mesh · agents {autoRefresh && '· auto-refresh 10s'}

{/* Filter bar */}
{[ { key: 'all', label: 'All', icon: Filter }, { key: 'memory', label: 'Memory', icon: Database }, { key: 'mesh', label: 'Mesh', icon: Cpu }, { key: 'broadcast', label: 'Broadcast', icon: Radio }, ].map(({ key, label, icon: Icon }) => ( ))}
{/* Log stream */}
{loading ? (
Loading…
) : logs.length === 0 ? (
No log entries found
) : logs.map((log, i) => { const color = TYPE_COLORS[log.type] || '#888' const Icon = TYPE_ICONS[log.type] || Terminal return (
{timeStr(log.timestamp)} {log.type} {log.source} {log.message} {log.hash && #{log.hash}}
) })}
) }