import React, { useState, useEffect, useRef } from "react"; import { X, Maximize2, ChevronDown, Plus } from "lucide-react"; const Panel = ({ height, terminalOutput = [], isRunning = false, waitingForInput = false, activeRunningFile = null, initialTab = "terminal", onClose, userInput = "", onUserInputChange, onInputSubmit, }) => { const [activeTab, setActiveTab] = useState(initialTab); const terminalRef = useRef(null); const [inputBuffer, setInputBuffer] = useState(""); // Update active tab when initialTab changes useEffect(() => { setActiveTab(initialTab); }, [initialTab]); // Auto-scroll terminal to the bottom when content changes useEffect(() => { if (terminalRef.current) { terminalRef.current.scrollTop = terminalRef.current.scrollHeight; } }, [terminalOutput]); // Handle keyboard input for the terminal useEffect(() => { const handleKeyDown = (e) => { if (!isRunning) return; if (e.key === "Enter") { if (inputBuffer.trim() && onInputSubmit) { e.preventDefault(); // Update parent's userInput state directly and call submit in the same function // instead of using setTimeout which creates a race condition onUserInputChange(inputBuffer); onInputSubmit(inputBuffer); // Pass inputBuffer directly to avoid race condition setInputBuffer(""); } } else if (e.key === "Backspace") { setInputBuffer((prev) => prev.slice(0, -1)); } else if (e.key.length === 1) { setInputBuffer((prev) => prev + e.key); } }; const terminalElement = terminalRef.current; terminalElement?.addEventListener("keydown", handleKeyDown); return () => { terminalElement?.removeEventListener("keydown", handleKeyDown); }; }, [isRunning, inputBuffer, onInputSubmit, onUserInputChange]); // Render the terminal tab const renderTerminal = () => (
terminalRef.current?.focus()} // Focus when clicked > {terminalOutput.length > 0 ? ( <> {terminalOutput.map((line, index) => { const typeClass = line.type === "warning" ? "terminal-warning" : line.type === "error" ? "terminal-error" : "terminal-output"; return (
{line.timestamp && ( {line.timestamp} )} {line.type === "command" && $} {line.content}
); })} {isRunning && (
$ {inputBuffer}
)} ) : (
$
)}
); // Render other tabs const renderProblems = () => (
No problems have been detected in the workspace.
); const renderOutput = () => (
[Extension Host] Extension host started.
[Language Server] Language server started.
{activeRunningFile && (
[Running] {activeRunningFile}
)}
); const renderDebugConsole = () => (
Debug session not yet started.
Press F5 to start debugging.
); const renderPorts = () => (
No forwarded ports detected.
); const renderComments = () => (
No comments have been added to this workspace.
); // Get content for the active tab const getTabContent = () => { switch (activeTab) { case "terminal": return renderTerminal(); case "problems": return renderProblems(); case "output": return renderOutput(); case "debug": return renderDebugConsole(); case "ports": return renderPorts(); case "comments": return renderComments(); default: return
Unknown tab
; } }; return (
{["problems", "output", "debug", "terminal", "ports", "comments"].map((tab) => (
setActiveTab(tab)} > {tab.toUpperCase()}
))}
{/* */}
{getTabContent()}
); }; export default Panel;