import { useState, useEffect, useRef } from 'react' import { useQuery } from '@tanstack/react-query' import { Terminal, ChevronDown, ChevronUp } from 'lucide-react' import { getRenderLog } from '../api/worker' import type { RenderLogEntry } from '../api/worker' const LEVEL_COLORS: Record = { info: 'text-gray-300', error: 'text-red-400', success: 'text-green-400', warn: 'text-yellow-400', } /** * Live render log panel — polls Redis-backed log entries every 2s. * Shows a compact terminal-style output for a render job. * * Always does an initial fetch to check if entries exist (so failed jobs * still show their log). Polls only when isActive. */ export default function LiveRenderLog({ orderLineId, isActive, compact = false, }: { orderLineId: string /** Whether the render is still processing — enables polling */ isActive: boolean /** Compact mode (inline, no border) for table rows */ compact?: boolean }) { const [expanded, setExpanded] = useState(isActive) const scrollRef = useRef(null) // Always fetch once to probe for existing entries; poll only when active const { data } = useQuery({ queryKey: ['render-log', orderLineId], queryFn: () => getRenderLog(orderLineId), refetchInterval: isActive ? 2000 : false, }) const entries: RenderLogEntry[] = data?.entries ?? [] const hasEntries = entries.length > 0 // Auto-scroll to bottom when new entries arrive useEffect(() => { if (scrollRef.current && isActive) { scrollRef.current.scrollTop = scrollRef.current.scrollHeight } }, [entries.length, isActive]) // Auto-expand when active useEffect(() => { if (isActive) setExpanded(true) }, [isActive]) // Nothing to show at all if (!hasEntries && !isActive) return null if (compact) { return (
{expanded && hasEntries && ( )}
) } return (
{expanded && ( )}
) } function LogPanel({ entries, isActive, scrollRef, maxHeight, }: { entries: RenderLogEntry[] isActive: boolean scrollRef: React.RefObject maxHeight: string }) { return (
{entries.map((entry, i) => (
{entry.t} {entry.msg}
))} {isActive && entries.length > 0 && (
...
)} {entries.length === 0 && (
No log entries yet
)}
) }