import { useRef, useEffect } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; import { Terminal as TerminalIcon, CheckCircle2, XCircle, AlertCircle } from 'lucide-react'; function parseLineColor(line) { if (line.includes('PASS') || line.includes('OK') || line.includes('passed')) return 'text-emerald-400'; if (line.includes('FAIL') || line.includes('Error') || line.includes('error') || line.includes('✗')) return 'text-red-400'; if (line.includes('---') || line.includes('Ran ') || line.includes('===')) return 'text-[var(--text-muted)]'; if (line.startsWith('>') || line.startsWith('$')) return 'text-emerald-300'; return 'text-[var(--text-secondary)]'; } export default function Terminal({ logs, isRunning }) { const scrollRef = useRef(null); useEffect(() => { if (scrollRef.current) { scrollRef.current.scrollTop = scrollRef.current.scrollHeight; } }, [logs]); const hasErrors = logs.some(l => l.type === 'error'); const hasSuccess = logs.some(l => l.type === 'success'); return (
{/* ── Header ─────────────── */}
Terminal Output
{hasSuccess && } {hasErrors && } {isRunning && ( running )}
{/* ── Log Output ─────────── */}
{logs.length === 0 ? (

Waiting for execution…

Click "Run Step" to submit code

) : ( {logs.map((log, i) => ( {log.prefix && ( {log.prefix} )} {log.text} ))} )} {isRunning && ( )}
); }