UI Overhaul (Switch to tailwindcss and MUI)

This commit is contained in:
Karmaa
2025-02-23 22:46:30 -06:00
parent 08dbfdaf8f
commit b43ca54fa0
10 changed files with 2545 additions and 407 deletions

View File

@@ -1,13 +1,22 @@
import { useState } from "react";
import "./App.css";
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';
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 [form, setForm] = useState({
name: "",
ip: "",
user: "",
password: "",
port: 22
});
const handleAddHost = () => {
if (form.ip && form.user && form.password && form.port) {
@@ -18,14 +27,14 @@ function App() {
ip: form.ip,
user: form.user,
password: form.password,
port: form.port,
port: Number(form.port),
},
};
setTerminals([...terminals, newTerminal]);
setActiveTab(nextId);
setNextId(nextId + 1);
setIsAddHostHidden(true);
setForm({ name: "", ip: "", user: "", password: "", port: "22" });
setForm({ name: "", ip: "", user: "", password: "", port: 22 });
} else {
alert("Please fill out all fields.");
}
@@ -40,72 +49,93 @@ function App() {
};
return (
<>
<div className="sidebar">
<h2>Termix</h2>
<button onClick={() => setIsAddHostHidden(!isAddHostHidden)}>Create Host</button>
</div>
<div className="topbar">
{terminals.map((terminal) => (
<div key={terminal.id} className="tab-item">
<button
onClick={() => setActiveTab(terminal.id)}
className={activeTab === terminal.id ? "active-tab" : ""}
<CssVarsProvider theme={theme}>
<div className="flex h-screen bg-neutral-900 overflow-hidden">
{/* Sidebar */}
<div className="w-64 bg-neutral-800 text-white p-6 flex flex-col justify-between fixed left-0 top-0 bottom-0">
<div className="flex flex-col items-center">
<h2 className="text-2xl font-bold mb-8">Termix</h2>
<Button
onClick={() => setIsAddHostHidden(false)}
sx={{
backgroundColor: theme.palette.neutral[500],
'&:hover': {
backgroundColor: theme.palette.neutral[900],
},
}}
>
{terminal.title}
</button>
<button className="tab-close" onClick={() => closeTab(terminal.id)}>×</button>
Create Host
</Button>
</div>
))}
</div>
<div className="terminal-wrapper">
{terminals.map((terminal) => (
<div
key={terminal.id}
className={`terminal-tab ${terminal.id === activeTab ? "active" : ""}`}
>
{terminal.hostConfig && <NewTerminal hostConfig={terminal.hostConfig}/>}
</div>
{/* Main Content Area */}
<div className="flex-1 flex flex-col ml-64 overflow-hidden">
{/* Topbar */}
<div className="bg-neutral-800 text-white p-4 flex justify-between items-center space-x-2 overflow-x-auto whitespace-nowrap min-h-[64px]">
<div className="flex items-center gap-2">
{terminals.map((terminal, index) => (
<div key={terminal.id} className="flex items-center gap-2">
{/* Tab Button Group */}
<ButtonGroup>
<Button
onClick={() => setActiveTab(terminal.id)}
sx={{
backgroundColor: terminal.id === activeTab ? theme.palette.neutral[500] : theme.palette.neutral[900],
color: theme.palette.text.primary,
'&:hover': {
backgroundColor: theme.palette.neutral[300],
},
}}
>
{terminal.title}
</Button>
<Button
onClick={() => closeTab(terminal.id)}
sx={{
backgroundColor: theme.palette.neutral[700],
color: theme.palette.text.primary,
'&:hover': {
backgroundColor: theme.palette.neutral[300],
},
}}
>
×
</Button>
</ButtonGroup>
{/* Separator (except after the last tab) */}
{index !== terminals.length - 1 && (
<div className="w-px h-6 bg-gray-600"></div>
)}
</div>
))}
</div>
</div>
))}
{/* Terminal Views */}
<div className="flex-1 relative pt-12 overflow-hidden">
{terminals.map((terminal) => (
<div
key={terminal.id}
className={`absolute top-0 left-0 right-0 bottom-0 ${terminal.id === activeTab ? "block" : "hidden"}`}
>
<NewTerminal hostConfig={terminal.hostConfig} />
</div>
))}
</div>
</div>
{/* Add Host Modal */}
<AddHostModal
isHidden={isAddHostHidden}
form={form}
setForm={setForm}
handleAddHost={handleAddHost}
setIsAddHostHidden={setIsAddHostHidden}
/>
</div>
<div className={`add-host ${isAddHostHidden ? "hidden" : ""}`}>
<h2>Add Host</h2>
<button onClick={() => setIsAddHostHidden(true)} className="add-host-close">
×
</button>
<input
type="text"
placeholder="Host Name"
value={form.name}
onChange={(e) => setForm({ ...form, name: e.target.value })}
/>
<input
type="text"
placeholder="Host IP"
value={form.ip}
onChange={(e) => setForm({ ...form, ip: e.target.value })}
/>
<input
type="text"
placeholder="Host User"
value={form.user}
onChange={(e) => setForm({ ...form, user: e.target.value })}
/>
<input
type="password"
placeholder="Host Password"
value={form.password}
onChange={(e) => setForm({ ...form, password: e.target.value })}
/>
<input
type="number"
placeholder="Host Port"
value={form.port}
onChange={(e) => setForm({ ...form, port: e.target.value })}
/>
<button onClick={handleAddHost}>Add</button>
</div>
</>
</CssVarsProvider>
);
}