import { useRef, useEffect, useState, type KeyboardEvent } from 'react'; interface TerminalLine { type: 'prompt' | 'stdout' | 'stderr' | 'info' | 'dim'; text: string; } interface TerminalPanelProps { lines: TerminalLine[]; onCommand: (cmd: string) => void; isRunning: boolean; onSendInput: (text: string) => void; } export type { TerminalLine }; export default function TerminalPanel({ lines, onCommand, isRunning, onSendInput }: TerminalPanelProps) { const [commandInput, setCommandInput] = useState(''); const [activeTab, setActiveTab] = useState<'terminal' | 'problems' | 'output'>('terminal'); const scrollRef = useRef(null); const inputRef = useRef(null); useEffect(() => { if (scrollRef.current) { scrollRef.current.scrollTop = scrollRef.current.scrollHeight; } }, [lines, commandInput, isRunning]); useEffect(() => { if (activeTab === 'terminal' && inputRef.current) { inputRef.current.focus(); } }, [isRunning, activeTab, lines]); const handleKeyDown = (e: KeyboardEvent) => { if (e.key === 'Enter') { if (isRunning) { onSendInput(commandInput); } else if (commandInput.trim()) { onCommand(commandInput.trim()); } setCommandInput(''); } }; return (
{/* Tab bar */}
{(['terminal', 'problems', 'output'] as const).map((tab) => ( ))}
{/* Terminal body — unified output + inline input */}
inputRef.current?.focus()} className={`flex-1 overflow-auto min-h-0 p-3 ryp-compiler-scroll ryp-terminal ${activeTab !== 'terminal' ? 'hidden' : ''}`} > {lines.map((line, i) => (
{line.type === 'prompt' && {line.text}} {line.type === 'stdout' && {line.text}} {line.type === 'stderr' && {line.text}} {line.type === 'info' && {line.text}} {line.type === 'dim' && {line.text}}
))} {/* Inline input line — last line of the terminal, scrolls with output */}
{!isRunning && ~/ryp $} setCommandInput(e.target.value)} onKeyDown={handleKeyDown} className="flex-1 bg-transparent border-none outline-none p-0 m-0 font-mono text-sm" style={{ color: '#e2e2f0', caretColor: '#e2e2f0', fontFamily: "'JetBrains Mono', 'Fira Code', Consolas, 'Courier New', monospace", }} spellCheck={false} autoComplete="off" autoFocus />
{/* Problems Tab Content */}
No problems detected.
{/* Output Tab Content */}
Execution output will appear here.
); }