diff --git a/src/App.jsx b/src/App.jsx index b5be77a4..f412ad74 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,9 +1,13 @@ -import { useState } from "react"; +import { useState, useEffect } from "react"; import { NewTerminal } from "./Terminal.jsx"; -import AddHostModal from './AddHostModal.jsx'; -import {Button, ButtonGroup} from '@mui/joy'; -import { CssVarsProvider } from '@mui/joy'; -import theme from './theme'; +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); @@ -15,8 +19,24 @@ function App() { ip: "", user: "", password: "", - port: 22 + port: 22, }); + const [isLaunchpadOpen, setIsLaunchpadOpen] = useState(false); + + // Toggle Launchpad when "L" key is pressed + useEffect(() => { + const handleKeyDown = (e) => { + if (e.ctrlKey && e.key === "l") { + e.preventDefault(); + setIsLaunchpadOpen((prev) => !prev); + } + }; + + window.addEventListener("keydown", handleKeyDown); + return () => { + window.removeEventListener("keydown", handleKeyDown); + }; + }, []); const handleAddHost = () => { if (form.ip && form.user && form.password && form.port) { @@ -41,7 +61,7 @@ function App() { }; const closeTab = (id) => { - const newTerminals = terminals.filter(t => t.id !== id); + const newTerminals = terminals.filter((t) => t.id !== id); setTerminals(newTerminals); if (activeTab === id) { setActiveTab(newTerminals[0]?.id || null); @@ -51,74 +71,88 @@ function App() { return (
- {/* Sidebar */} -
-
-

Termix

+
+ {/* Topbar */} +
+ {/* Left: Title */} +
+ Termix Icon +

Termix

+
+ + {/* Middle: Tabs with scroll */} +
+
+ +
+
+ + {/* Open Launchpad Button */} + + + {/* Right: Create Host Button */}
-
- - {/* Main Content Area */} -
- {/* Topbar */} -
-
- {terminals.map((terminal, index) => ( -
- {/* Tab Button Group */} - - - - - - {/* Separator (except after the last tab) */} - {index !== terminals.length - 1 && ( -
- )} -
- ))} -
-
{/* Terminal Views */}
{terminals.map((terminal) => (
@@ -126,7 +160,6 @@ function App() {
- {/* Add Host Modal */} + + {/* Launchpad Component */} + {isLaunchpadOpen && ( + setIsLaunchpadOpen(false)} /> + )}
); diff --git a/src/Launchpad.jsx b/src/Launchpad.jsx new file mode 100644 index 00000000..10b4be47 --- /dev/null +++ b/src/Launchpad.jsx @@ -0,0 +1,34 @@ +import {Button} from "@mui/joy"; +import PropTypes from 'prop-types'; + +function Launchpad({ onClose }) { + return ( +
+
+

Launchpad

+

This is your all-in-one launchpad panel.

+ +
+
+ ); +} + +Launchpad.propTypes = { + onClose: PropTypes.func.isRequired, +}; + +export default Launchpad; \ No newline at end of file diff --git a/src/TabList.jsx b/src/TabList.jsx new file mode 100644 index 00000000..79073a6b --- /dev/null +++ b/src/TabList.jsx @@ -0,0 +1,60 @@ +import {Button, ButtonGroup} from "@mui/joy"; +import PropTypes from "prop-types"; + +function TabList({ terminals, activeTab, setActiveTab, closeTab, theme }) { + return ( +
+ {terminals.map((terminal, index) => ( +
+ + + + +
+ ))} +
+ ); +} + +TabList.propTypes = { + terminals: PropTypes.array.isRequired, + activeTab: PropTypes.any, + setActiveTab: PropTypes.func.isRequired, + closeTab: PropTypes.func.isRequired, + theme: PropTypes.object.isRequired, +}; + +export default TabList; \ No newline at end of file diff --git a/src/Terminal.jsx b/src/Terminal.jsx index cbddb960..eb01d1af 100644 --- a/src/Terminal.jsx +++ b/src/Terminal.jsx @@ -36,9 +36,8 @@ export function NewTerminal({ hostConfig }) { // Resize function const resizeTerminal = () => { const terminalContainer = terminalRef.current; - const sidebarWidth = 14 * 16; // Sidebar width in pixels - const topbarHeight = 64; // Topbar height in pixels - const availableWidth = window.innerWidth - sidebarWidth; + const topbarHeight = 65; + const availableWidth = window.innerWidth; const availableHeight = window.innerHeight - topbarHeight; terminalContainer.style.width = `${availableWidth}px`; diff --git a/src/images/launchpad_rocket.png b/src/images/launchpad_rocket.png new file mode 100644 index 00000000..2afda95b Binary files /dev/null and b/src/images/launchpad_rocket.png differ diff --git a/src/images/termix_icon.png b/src/images/termix_icon.png new file mode 100644 index 00000000..48dbc4f3 Binary files /dev/null and b/src/images/termix_icon.png differ