import { useState, useEffect } from "react"; import { NewTerminal } from "./Terminal.jsx"; import AddHostModal from "./AddHostModal.jsx"; import { Button } from "@mui/joy"; import { CssVarsProvider } from "@mui/joy"; import theme from "./theme"; import TabList from "./TabList.jsx"; import Launchpad from "./Launchpad.jsx"; import TermixIcon from "./images/termix_icon.png"; import RocketIcon from './images/launchpad_rocket.png'; function App() { const [isAddHostHidden, setIsAddHostHidden] = useState(true); const [terminals, setTerminals] = useState([]); const [activeTab, setActiveTab] = useState(null); const [nextId, setNextId] = useState(1); const [form, setForm] = useState({ name: "", ip: "", user: "", password: "", port: 22, }); const [isLaunchpadOpen, setIsLaunchpadOpen] = useState(false); const [splitTabIds, setSplitTabIds] = useState([]); useEffect(() => { const handleKeyDown = (e) => { if (e.ctrlKey && e.key === "l") { e.preventDefault(); setIsLaunchpadOpen((prev) => !prev); } }; window.addEventListener("keydown", handleKeyDown); return () => { window.removeEventListener("keydown", handleKeyDown); }; }, []); useEffect(() => { terminals.forEach((terminal) => { if ( (terminal.id === activeTab || splitTabIds.includes(terminal.id)) && terminal.terminalRef?.resizeTerminal ) { terminal.terminalRef.resizeTerminal(); } }); }, [splitTabIds, activeTab, terminals]); useEffect(() => { const handleResize = () => { terminals.forEach((terminal) => { if ( (terminal.id === activeTab || splitTabIds.includes(terminal.id)) && terminal.terminalRef?.resizeTerminal ) { terminal.terminalRef.resizeTerminal(); } }); }; window.addEventListener("resize", handleResize); return () => { window.removeEventListener("resize", handleResize); }; }, [splitTabIds, activeTab, terminals]); useEffect(() => { terminals.forEach((terminal) => { if ( (terminal.id === activeTab || splitTabIds.includes(terminal.id)) && terminal.terminalRef?.resizeTerminal ) { terminal.terminalRef.resizeTerminal(); } }); }, [splitTabIds]); const handleAddHost = () => { if (form.ip && form.user && form.password && form.port) { const newTerminal = { id: nextId, title: form.name || form.ip, hostConfig: { ip: form.ip, user: form.user, password: form.password, port: Number(form.port), }, terminalRef: null, }; setTerminals([...terminals, newTerminal]); setActiveTab(nextId); setNextId(nextId + 1); setIsAddHostHidden(true); setForm({ name: "", ip: "", user: "", password: "", port: 22 }); } else { alert("Please fill out all fields."); } }; const closeTab = (id) => { const newTerminals = terminals.filter((t) => t.id !== id); setTerminals(newTerminals); if (activeTab === id) { setActiveTab(newTerminals[0]?.id || null); } }; const toggleSplit = (id) => { if (splitTabIds.includes(id)) { setSplitTabIds((prev) => prev.filter((splitId) => splitId !== id)); return; } if (splitTabIds.length >= 3) return; setSplitTabIds((prev) => prev.includes(id) ? prev.filter((splitId) => splitId !== id) : [...prev, id] ); }; const handleSetActiveTab = (tabId) => { setActiveTab(tabId); }; const getLayoutStyle = () => { if (splitTabIds.length === 1) { return "flex flex-row h-full gap-4"; } else if (splitTabIds.length > 1) { return "grid grid-cols-2 grid-rows-2 gap-4 h-full overflow-hidden"; } return "flex flex-col h-full"; }; return (
{/* Topbar */}
Termix Icon

Termix

{/* Launchpad Button */} {/* Add Host Button */}
{/* Terminal Views */}
{terminals.map((terminal) => (
{ if (ref && !terminal.terminalRef) { setTerminals((prev) => prev.map((t) => t.id === terminal.id ? { ...t, terminalRef: ref } : t ) ); } }} />
))}
{/* Modals */} {isLaunchpadOpen && setIsLaunchpadOpen(false)} />}
); } export default App;