import React, { useEffect, useRef, useState } from 'react' import type { Observation } from '../types' import { panelStyle, titleStyle } from '../App' interface Props { obs: Observation | null } const lineColor = (l: string) => l.includes('CRITICAL') || l.includes('BREACH') ? '#f43f5e' : l.includes('ERROR') ? '#f87171' : l.includes('WARN') ? '#fbbf24' : l.includes('METRICS') ? '#60a5fa' : l.includes('BUTTERFLY') ? '#c084fc' : l.includes('CASCADE') ? '#fb923c' : l.includes('SECURITY') ? '#f43f5e' : l.includes('WORKSPACE') ? '#34d399' : '#475569' export function LogStream({ obs }: Props) { const ref = useRef(null) const [filter, setFilter] = useState('') const [autoScroll, setAutoScroll] = useState(true) useEffect(() => { if (autoScroll && ref.current) ref.current.scrollTop = ref.current.scrollHeight }, [obs?.recent_logs, autoScroll]) if (!obs) return null const logs = filter ? obs.recent_logs.filter(l => l.toLowerCase().includes(filter.toLowerCase())) : obs.recent_logs return (
📟 Log Stream
setFilter(e.target.value)} placeholder="filter..." style={{ background: '#080c18', border: '1px solid #1e2d4a', borderRadius: '0.3rem', padding: '0.2rem 0.5rem', color: '#94a3b8', fontSize: '0.7rem', width: '100px' }} />
{logs.map((l, i) => (
{l}
))} {logs.length === 0 &&
No matching logs.
}
) }