From 81d1db09e4fe462c116542cea1edcf849c75c8cf Mon Sep 17 00:00:00 2001 From: LukeGus Date: Thu, 14 Aug 2025 01:24:05 -0500 Subject: [PATCH 01/22] Initial UI commit for 1.3 --- .env | 2 +- src/App.tsx | 123 +++++++++++++----- src/apps/SSH/Manager/SSHManagerSidebar.tsx | 59 --------- src/apps/Template/Template.tsx | 18 --- src/apps/Template/TemplateSidebar.tsx | 58 --------- src/components/ui/sidebar.tsx | 4 +- src/{apps => ui}/Homepage/Homepage.tsx | 53 ++++---- .../Homepage/HomepageAlertCard.tsx} | 8 +- .../Homepage/HomepageAlertManager.tsx} | 11 +- src/{apps => ui}/Homepage/HomepageAuth.tsx | 11 +- .../Homepage/HompageUpdateLog.tsx | 0 .../Navigation/Sidebar.tsx} | 39 ++++-- .../SSH/Config Editor/ConfigCodeEditor.tsx | 0 .../SSH/Config Editor/ConfigEditor.tsx | 12 +- .../SSH/Config Editor/ConfigEditorSidebar.tsx | 2 +- .../Config Editor/ConfigFileSidebarViewer.tsx | 0 .../SSH/Config Editor/ConfigHomeView.tsx | 0 .../SSH/Config Editor/ConfigTabList.tsx | 0 .../SSH/Config Editor/ConfigTopbar.tsx | 0 src/{apps => ui}/SSH/Manager/SSHManager.tsx | 25 ++-- .../SSH/Manager/SSHManagerHostEditor.tsx | 21 ++- .../SSH/Manager/SSHManagerHostViewer.tsx | 2 +- src/{apps => ui}/SSH/Terminal/Terminal.tsx | 4 +- .../SSH/Terminal/TerminalComponent.tsx | 0 .../SSH/Terminal/TerminalSidebar.tsx | 2 +- .../SSH/Terminal/TerminalTabList.tsx | 0 .../SSH/Terminal/TerminalTopbar.tsx | 2 +- src/{apps => ui}/SSH/Tunnel/SSHTunnel.tsx | 6 +- .../SSH/Tunnel/SSHTunnelObject.tsx | 0 .../SSH/Tunnel/SSHTunnelSidebar.tsx | 0 .../SSH/Tunnel/SSHTunnelViewer.tsx | 0 src/{apps => ui}/SSH/ssh-axios.ts | 0 tsconfig.app.json | 6 - 33 files changed, 196 insertions(+), 272 deletions(-) delete mode 100644 src/apps/SSH/Manager/SSHManagerSidebar.tsx delete mode 100644 src/apps/Template/Template.tsx delete mode 100644 src/apps/Template/TemplateSidebar.tsx rename src/{apps => ui}/Homepage/Homepage.tsx (64%) rename src/{apps/Homepage/AlertCard.tsx => ui/Homepage/HomepageAlertCard.tsx} (95%) rename src/{apps/Homepage/AlertManager.tsx => ui/Homepage/HomepageAlertManager.tsx} (95%) rename src/{apps => ui}/Homepage/HomepageAuth.tsx (99%) rename src/{apps => ui}/Homepage/HompageUpdateLog.tsx (100%) rename src/{apps/Homepage/HomepageSidebar.tsx => ui/Navigation/Sidebar.tsx} (97%) rename src/{apps => ui}/SSH/Config Editor/ConfigCodeEditor.tsx (100%) rename src/{apps => ui}/SSH/Config Editor/ConfigEditor.tsx (98%) rename src/{apps => ui}/SSH/Config Editor/ConfigEditorSidebar.tsx (99%) rename src/{apps => ui}/SSH/Config Editor/ConfigFileSidebarViewer.tsx (100%) rename src/{apps => ui}/SSH/Config Editor/ConfigHomeView.tsx (100%) rename src/{apps => ui}/SSH/Config Editor/ConfigTabList.tsx (100%) rename src/{apps => ui}/SSH/Config Editor/ConfigTopbar.tsx (100%) rename src/{apps => ui}/SSH/Manager/SSHManager.tsx (77%) rename src/{apps => ui}/SSH/Manager/SSHManagerHostEditor.tsx (98%) rename src/{apps => ui}/SSH/Manager/SSHManagerHostViewer.tsx (99%) rename src/{apps => ui}/SSH/Terminal/Terminal.tsx (99%) rename src/{apps => ui}/SSH/Terminal/TerminalComponent.tsx (100%) rename src/{apps => ui}/SSH/Terminal/TerminalSidebar.tsx (99%) rename src/{apps => ui}/SSH/Terminal/TerminalTabList.tsx (100%) rename src/{apps => ui}/SSH/Terminal/TerminalTopbar.tsx (97%) rename src/{apps => ui}/SSH/Tunnel/SSHTunnel.tsx (96%) rename src/{apps => ui}/SSH/Tunnel/SSHTunnelObject.tsx (100%) rename src/{apps => ui}/SSH/Tunnel/SSHTunnelSidebar.tsx (100%) rename src/{apps => ui}/SSH/Tunnel/SSHTunnelViewer.tsx (100%) rename src/{apps => ui}/SSH/ssh-axios.ts (100%) diff --git a/.env b/.env index 27929cde..07925e7a 100644 --- a/.env +++ b/.env @@ -1 +1 @@ -VERSION=1.1.1 \ No newline at end of file +VERSION=1.3 \ No newline at end of file diff --git a/src/App.tsx b/src/App.tsx index c4510ae9..26f0717a 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,14 +1,64 @@ -import React from "react" +import React, { useState, useEffect } from "react" +import { Sidebar } from "@/ui/Navigation/Sidebar.tsx" +import { Homepage } from "@/ui/Homepage/Homepage.tsx" +import { Terminal } from "@/ui/SSH/Terminal/Terminal.tsx" +import { SSHTunnel } from "@/ui/SSH/Tunnel/SSHTunnel.tsx" +import { ConfigEditor } from "@/ui/SSH/Config Editor/ConfigEditor.tsx" +import { SSHManager } from "@/ui/SSH/Manager/SSHManager.tsx" +import axios from "axios" -import {Homepage} from "@/apps/Homepage/Homepage.tsx" -import {Terminal} from "@/apps/SSH/Terminal/Terminal.tsx" -import {SSHTunnel} from "@/apps/SSH/Tunnel/SSHTunnel.tsx"; -import {ConfigEditor} from "@/apps/SSH/Config Editor/ConfigEditor.tsx"; -import {SSHManager} from "@/apps/SSH/Manager/SSHManager.tsx" +const apiBase = import.meta.env.DEV ? "http://localhost:8081/users" : "/users"; +const API = axios.create({ baseURL: apiBase }); + +function getCookie(name: string) { + return document.cookie.split('; ').reduce((r, v) => { + const parts = v.split('='); + return parts[0] === name ? decodeURIComponent(parts[1]) : r; + }, ""); +} function App() { const [view, setView] = React.useState("homepage") const [mountedViews, setMountedViews] = React.useState>(new Set(["homepage"])) + const [isAuthenticated, setIsAuthenticated] = useState(false) + const [username, setUsername] = useState(null) + const [isAdmin, setIsAdmin] = useState(false) + const [authLoading, setAuthLoading] = useState(true) + + useEffect(() => { + const checkAuth = () => { + const jwt = getCookie("jwt"); + if (jwt) { + setAuthLoading(true); + API.get("/me", {headers: {Authorization: `Bearer ${jwt}`}}) + .then((meRes) => { + setIsAuthenticated(true); + setIsAdmin(!!meRes.data.is_admin); + setUsername(meRes.data.username || null); + }) + .catch((err) => { + setIsAuthenticated(false); + setIsAdmin(false); + setUsername(null); + // Clear invalid JWT + document.cookie = 'jwt=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;'; + }) + .finally(() => setAuthLoading(false)); + } else { + setIsAuthenticated(false); + setIsAdmin(false); + setUsername(null); + setAuthLoading(false); + } + } + + checkAuth() + + const handleStorageChange = () => checkAuth() + window.addEventListener('storage', handleStorageChange) + + return () => window.removeEventListener('storage', handleStorageChange) + }, []) const handleSelectView = (nextView: string) => { setMountedViews((prev) => { @@ -21,35 +71,38 @@ function App() { } return ( -
-
- {mountedViews.has("homepage") && ( -
- -
- )} - {mountedViews.has("ssh_manager") && ( -
- -
- )} - {mountedViews.has("terminal") && ( -
- -
- )} - {mountedViews.has("tunnel") && ( -
- -
- )} - {mountedViews.has("config_editor") && ( -
- -
- )} -
-
+ + {mountedViews.has("homepage") && ( +
+ +
+ )} + {mountedViews.has("ssh_manager") && ( +
+ +
+ )} + {mountedViews.has("terminal") && ( +
+ +
+ )} + {mountedViews.has("tunnel") && ( +
+ +
+ )} + {mountedViews.has("config_editor") && ( +
+ +
+ )} +
) } diff --git a/src/apps/SSH/Manager/SSHManagerSidebar.tsx b/src/apps/SSH/Manager/SSHManagerSidebar.tsx deleted file mode 100644 index 819830f3..00000000 --- a/src/apps/SSH/Manager/SSHManagerSidebar.tsx +++ /dev/null @@ -1,59 +0,0 @@ -import React from 'react'; - -import { - CornerDownLeft -} from "lucide-react" - -import { - Button -} from "@/components/ui/button.tsx" - -import { - Sidebar, - SidebarContent, - SidebarGroup, - SidebarGroupContent, - SidebarGroupLabel, - SidebarMenu, - SidebarMenuItem, SidebarProvider, -} from "@/components/ui/sidebar.tsx" - -import { - Separator, -} from "@/components/ui/separator.tsx" - -interface SidebarProps { - onSelectView: (view: string) => void; -} - -export function SSHManagerSidebar({onSelectView}: SidebarProps): React.ReactElement { - return ( - - - - - - Termix / SSH Manager - - - - - - {/* Sidebar Items */} - - - - - - - - - - - - ) -} \ No newline at end of file diff --git a/src/apps/Template/Template.tsx b/src/apps/Template/Template.tsx deleted file mode 100644 index 09c02a2e..00000000 --- a/src/apps/Template/Template.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import React from "react"; -import {TemplateSidebar} from "@/apps/Template/TemplateSidebar.tsx"; - -interface ConfigEditorProps { - onSelectView: (view: string) => void; -} - -export function Template({onSelectView}: ConfigEditorProps): React.ReactElement { - return ( -
- - - Template -
- ) -} \ No newline at end of file diff --git a/src/apps/Template/TemplateSidebar.tsx b/src/apps/Template/TemplateSidebar.tsx deleted file mode 100644 index eb4f903b..00000000 --- a/src/apps/Template/TemplateSidebar.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import React from 'react'; - -import { - CornerDownLeft -} from "lucide-react" - -import { - Button -} from "@/components/ui/button.tsx" - -import { - Sidebar, - SidebarContent, - SidebarGroup, - SidebarGroupContent, - SidebarGroupLabel, - SidebarMenu, - SidebarMenuItem, SidebarProvider, -} from "@/components/ui/sidebar.tsx" - -import { - Separator, -} from "@/components/ui/separator.tsx" - -interface SidebarProps { - onSelectView: (view: string) => void; -} - -export function TemplateSidebar({onSelectView}: SidebarProps): React.ReactElement { - return ( - - - - - - Termix / Template - - - - - - - - - - - - - - - - - ) -} \ No newline at end of file diff --git a/src/components/ui/sidebar.tsx b/src/components/ui/sidebar.tsx index ad864e24..66aace69 100644 --- a/src/components/ui/sidebar.tsx +++ b/src/components/ui/sidebar.tsx @@ -234,7 +234,7 @@ function Sidebar({ // Adjust the padding for floating and inset variants. variant === "floating" || variant === "inset" ? "p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]" - : "group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l", + : "group-data-[collapsible=icon]:w-(--sidebar-width-icon)", className )} {...props} @@ -242,7 +242,7 @@ function Sidebar({
{children}
diff --git a/src/apps/Homepage/Homepage.tsx b/src/ui/Homepage/Homepage.tsx similarity index 64% rename from src/apps/Homepage/Homepage.tsx rename to src/ui/Homepage/Homepage.tsx index 299203fd..00967404 100644 --- a/src/apps/Homepage/Homepage.tsx +++ b/src/ui/Homepage/Homepage.tsx @@ -1,9 +1,8 @@ -import {HomepageSidebar} from "@/apps/Homepage/HomepageSidebar.tsx"; import React, {useEffect, useState} from "react"; -import {HomepageAuth} from "@/apps/Homepage/HomepageAuth.tsx"; +import {HomepageAuth} from "@/ui/Homepage/HomepageAuth.tsx"; import axios from "axios"; -import {HomepageUpdateLog} from "@/apps/Homepage/HompageUpdateLog.tsx"; -import {AlertManager} from "@/apps/Homepage/AlertManager.tsx"; +import {HomepageUpdateLog} from "@/ui/Homepage/HompageUpdateLog.tsx"; +import {HomepageAlertManager} from "@/ui/Homepage/HomepageAlertManager.tsx"; interface HomepageProps { onSelectView: (view: string) => void; @@ -70,35 +69,27 @@ export function Homepage({onSelectView}: HomepageProps): React.ReactElement { }, []); return ( - -
-
- - -
- - {/* Alert Manager - replaces the old welcome card */} - +
+ +
- + + +
); } \ No newline at end of file diff --git a/src/apps/Homepage/AlertCard.tsx b/src/ui/Homepage/HomepageAlertCard.tsx similarity index 95% rename from src/apps/Homepage/AlertCard.tsx rename to src/ui/Homepage/HomepageAlertCard.tsx index c6850f6e..d2f34722 100644 --- a/src/apps/Homepage/AlertCard.tsx +++ b/src/ui/Homepage/HomepageAlertCard.tsx @@ -1,7 +1,7 @@ import React from "react"; -import {Card, CardContent, CardFooter, CardHeader, CardTitle} from "@/components/ui/card"; -import {Button} from "@/components/ui/button"; -import {Badge} from "@/components/ui/badge"; +import {Card, CardContent, CardFooter, CardHeader, CardTitle} from "@/components/ui/card.tsx"; +import {Button} from "@/components/ui/button.tsx"; +import {Badge} from "@/components/ui/badge.tsx"; import {X, ExternalLink, AlertTriangle, Info, CheckCircle, AlertCircle} from "lucide-react"; interface TermixAlert { @@ -63,7 +63,7 @@ const getTypeBadgeVariant = (type?: string) => { } }; -export function AlertCard({alert, onDismiss, onClose}: AlertCardProps): React.ReactElement { +export function HomepageAlertCard({alert, onDismiss, onClose}: AlertCardProps): React.ReactElement { if (!alert) { return null; } diff --git a/src/apps/Homepage/AlertManager.tsx b/src/ui/Homepage/HomepageAlertManager.tsx similarity index 95% rename from src/apps/Homepage/AlertManager.tsx rename to src/ui/Homepage/HomepageAlertManager.tsx index a9eb0fd1..07772d2a 100644 --- a/src/apps/Homepage/AlertManager.tsx +++ b/src/ui/Homepage/HomepageAlertManager.tsx @@ -1,6 +1,6 @@ import React, {useEffect, useState} from "react"; -import {AlertCard} from "./AlertCard"; -import {Button} from "@/components/ui/button"; +import {HomepageAlertCard} from "./HomepageAlertCard.tsx"; +import {Button} from "@/components/ui/button.tsx"; import axios from "axios"; interface TermixAlert { @@ -25,7 +25,7 @@ const API = axios.create({ baseURL: apiBase, }); -export function AlertManager({userId, loggedIn}: AlertManagerProps): React.ReactElement { +export function HomepageAlertManager({userId, loggedIn}: AlertManagerProps): React.ReactElement { const [alerts, setAlerts] = useState([]); const [currentAlertIndex, setCurrentAlertIndex] = useState(0); const [loading, setLoading] = useState(false); @@ -154,14 +154,12 @@ export function AlertManager({userId, loggedIn}: AlertManagerProps): React.React return (
- {/* Current Alert */} - - {/* Navigation Controls */} {hasMultipleAlerts && (
+ + + - - Termix - - @@ -893,6 +904,14 @@ export function HomepageSidebar({ {children} + + {!isSidebarOpen && ( +
setIsSidebarOpen(true)} + className="absolute top-0 left-0 w-[10px] h-full bg-[#18181b] cursor-pointer z-20 flex items-center justify-center"> + +
+ )}
) } \ No newline at end of file diff --git a/src/apps/SSH/Config Editor/ConfigCodeEditor.tsx b/src/ui/SSH/Config Editor/ConfigCodeEditor.tsx similarity index 100% rename from src/apps/SSH/Config Editor/ConfigCodeEditor.tsx rename to src/ui/SSH/Config Editor/ConfigCodeEditor.tsx diff --git a/src/apps/SSH/Config Editor/ConfigEditor.tsx b/src/ui/SSH/Config Editor/ConfigEditor.tsx similarity index 98% rename from src/apps/SSH/Config Editor/ConfigEditor.tsx rename to src/ui/SSH/Config Editor/ConfigEditor.tsx index 7251ba77..6ac5eb6f 100644 --- a/src/apps/SSH/Config Editor/ConfigEditor.tsx +++ b/src/ui/SSH/Config Editor/ConfigEditor.tsx @@ -1,10 +1,10 @@ import React, {useState, useEffect, useRef} from "react"; -import {ConfigEditorSidebar} from "@/apps/SSH/Config Editor/ConfigEditorSidebar.tsx"; -import {ConfigTabList} from "@/apps/SSH/Config Editor/ConfigTabList.tsx"; -import {ConfigHomeView} from "@/apps/SSH/Config Editor/ConfigHomeView.tsx"; -import {ConfigCodeEditor} from "@/apps/SSH/Config Editor/ConfigCodeEditor.tsx"; +import {ConfigEditorSidebar} from "@/ui/SSH/Config Editor/ConfigEditorSidebar.tsx"; +import {ConfigTabList} from "@/ui/SSH/Config Editor/ConfigTabList.tsx"; +import {ConfigHomeView} from "@/ui/SSH/Config Editor/ConfigHomeView.tsx"; +import {ConfigCodeEditor} from "@/ui/SSH/Config Editor/ConfigCodeEditor.tsx"; import {Button} from '@/components/ui/button.tsx'; -import {ConfigTopbar} from "@/apps/SSH/Config Editor/ConfigTopbar.tsx"; +import {ConfigTopbar} from "@/ui/SSH/Config Editor/ConfigTopbar.tsx"; import {cn} from '@/lib/utils.ts'; import { getConfigEditorRecent, @@ -20,7 +20,7 @@ import { writeSSHFile, getSSHStatus, connectSSH -} from '@/apps/SSH/ssh-axios.ts'; +} from '@/ui/SSH/ssh-axios.ts'; interface Tab { id: string | number; diff --git a/src/apps/SSH/Config Editor/ConfigEditorSidebar.tsx b/src/ui/SSH/Config Editor/ConfigEditorSidebar.tsx similarity index 99% rename from src/apps/SSH/Config Editor/ConfigEditorSidebar.tsx rename to src/ui/SSH/Config Editor/ConfigEditorSidebar.tsx index 571182f3..22579660 100644 --- a/src/apps/SSH/Config Editor/ConfigEditorSidebar.tsx +++ b/src/ui/SSH/Config Editor/ConfigEditorSidebar.tsx @@ -22,7 +22,7 @@ import { getConfigEditorPinned, addConfigEditorPinned, removeConfigEditorPinned -} from '@/apps/SSH/ssh-axios.ts'; +} from '@/ui/SSH/ssh-axios.ts'; interface SSHHost { id: number; diff --git a/src/apps/SSH/Config Editor/ConfigFileSidebarViewer.tsx b/src/ui/SSH/Config Editor/ConfigFileSidebarViewer.tsx similarity index 100% rename from src/apps/SSH/Config Editor/ConfigFileSidebarViewer.tsx rename to src/ui/SSH/Config Editor/ConfigFileSidebarViewer.tsx diff --git a/src/apps/SSH/Config Editor/ConfigHomeView.tsx b/src/ui/SSH/Config Editor/ConfigHomeView.tsx similarity index 100% rename from src/apps/SSH/Config Editor/ConfigHomeView.tsx rename to src/ui/SSH/Config Editor/ConfigHomeView.tsx diff --git a/src/apps/SSH/Config Editor/ConfigTabList.tsx b/src/ui/SSH/Config Editor/ConfigTabList.tsx similarity index 100% rename from src/apps/SSH/Config Editor/ConfigTabList.tsx rename to src/ui/SSH/Config Editor/ConfigTabList.tsx diff --git a/src/apps/SSH/Config Editor/ConfigTopbar.tsx b/src/ui/SSH/Config Editor/ConfigTopbar.tsx similarity index 100% rename from src/apps/SSH/Config Editor/ConfigTopbar.tsx rename to src/ui/SSH/Config Editor/ConfigTopbar.tsx diff --git a/src/apps/SSH/Manager/SSHManager.tsx b/src/ui/SSH/Manager/SSHManager.tsx similarity index 77% rename from src/apps/SSH/Manager/SSHManager.tsx rename to src/ui/SSH/Manager/SSHManager.tsx index 90c11750..7c3348f3 100644 --- a/src/apps/SSH/Manager/SSHManager.tsx +++ b/src/ui/SSH/Manager/SSHManager.tsx @@ -1,9 +1,9 @@ import React, {useState} from "react"; -import {SSHManagerSidebar} from "@/apps/SSH/Manager/SSHManagerSidebar.tsx"; -import {SSHManagerHostViewer} from "@/apps/SSH/Manager/SSHManagerHostViewer.tsx" +import {SSHManagerHostViewer} from "@/ui/SSH/Manager/SSHManagerHostViewer.tsx" import {Tabs, TabsContent, TabsList, TabsTrigger} from "@/components/ui/tabs.tsx"; import {Separator} from "@/components/ui/separator.tsx"; -import {SSHManagerHostEditor} from "@/apps/SSH/Manager/SSHManagerHostEditor.tsx"; +import {SSHManagerHostEditor} from "@/ui/SSH/Manager/SSHManagerHostEditor.tsx"; +import {useSidebar} from "@/components/ui/sidebar.tsx"; interface ConfigEditorProps { onSelectView: (view: string) => void; @@ -35,6 +35,7 @@ interface SSHHost { export function SSHManager({onSelectView}: ConfigEditorProps): React.ReactElement { const [activeTab, setActiveTab] = useState("host_viewer"); const [editingHost, setEditingHost] = useState(null); + const {state: sidebarState} = useSidebar(); const handleEditHost = (host: SSHHost) => { setEditingHost(host); @@ -55,29 +56,25 @@ export function SSHManager({onSelectView}: ConfigEditorProps): React.ReactElemen return (
- - -
-
- +
+ className={`flex-1 bg-[#18181b] m-[8px] text-white p-4 pt-0 rounded-lg border border-[#303032] flex flex-col min-h-0 ${ + sidebarState === 'collapsed' ? 'ml-6' : '' + }`}> - + Host Viewer {editingHost ? "Edit Host" : "Add Host"} - + - +
- + General @@ -396,7 +396,7 @@ export function SSHManagerHostEditor({editingHost, onFormSubmit}: SSHManagerHost Tunnel Config Editor - + Connection Details
-
- - +
+ +
diff --git a/src/apps/SSH/Manager/SSHManagerHostViewer.tsx b/src/ui/SSH/Manager/SSHManagerHostViewer.tsx similarity index 99% rename from src/apps/SSH/Manager/SSHManagerHostViewer.tsx rename to src/ui/SSH/Manager/SSHManagerHostViewer.tsx index 25f53247..76da3e66 100644 --- a/src/apps/SSH/Manager/SSHManagerHostViewer.tsx +++ b/src/ui/SSH/Manager/SSHManagerHostViewer.tsx @@ -6,7 +6,7 @@ import {ScrollArea} from "@/components/ui/scroll-area"; import {Input} from "@/components/ui/input"; import {Accordion, AccordionContent, AccordionItem, AccordionTrigger} from "@/components/ui/accordion"; import {Tooltip, TooltipContent, TooltipProvider, TooltipTrigger} from "@/components/ui/tooltip"; -import {getSSHHosts, deleteSSHHost, bulkImportSSHHosts} from "@/apps/SSH/ssh-axios"; +import {getSSHHosts, deleteSSHHost, bulkImportSSHHosts} from "@/ui/SSH/ssh-axios"; import { Edit, Trash2, diff --git a/src/apps/SSH/Terminal/Terminal.tsx b/src/ui/SSH/Terminal/Terminal.tsx similarity index 99% rename from src/apps/SSH/Terminal/Terminal.tsx rename to src/ui/SSH/Terminal/Terminal.tsx index e6e92600..a812f41c 100644 --- a/src/apps/SSH/Terminal/Terminal.tsx +++ b/src/ui/SSH/Terminal/Terminal.tsx @@ -1,7 +1,7 @@ import React, {useState, useRef, useEffect} from "react"; -import {TerminalSidebar} from "@/apps/SSH/Terminal/TerminalSidebar.tsx"; +import {TerminalSidebar} from "@/ui/SSH/Terminal/TerminalSidebar.tsx"; import {TerminalComponent} from "./TerminalComponent.tsx"; -import {TerminalTopbar} from "@/apps/SSH/Terminal/TerminalTopbar.tsx"; +import {TerminalTopbar} from "@/ui/SSH/Terminal/TerminalTopbar.tsx"; import {ResizablePanelGroup, ResizablePanel, ResizableHandle} from '@/components/ui/resizable.tsx'; import * as ResizablePrimitive from "react-resizable-panels"; import {ChevronDown, ChevronRight} from "lucide-react"; diff --git a/src/apps/SSH/Terminal/TerminalComponent.tsx b/src/ui/SSH/Terminal/TerminalComponent.tsx similarity index 100% rename from src/apps/SSH/Terminal/TerminalComponent.tsx rename to src/ui/SSH/Terminal/TerminalComponent.tsx diff --git a/src/apps/SSH/Terminal/TerminalSidebar.tsx b/src/ui/SSH/Terminal/TerminalSidebar.tsx similarity index 99% rename from src/apps/SSH/Terminal/TerminalSidebar.tsx rename to src/ui/SSH/Terminal/TerminalSidebar.tsx index 90318520..03d901cd 100644 --- a/src/apps/SSH/Terminal/TerminalSidebar.tsx +++ b/src/ui/SSH/Terminal/TerminalSidebar.tsx @@ -37,7 +37,7 @@ import { } from "@/components/ui/accordion.tsx"; import {ScrollArea} from "@/components/ui/scroll-area.tsx"; import {Input} from "@/components/ui/input.tsx"; -import {getSSHHosts} from "@/apps/SSH/ssh-axios"; +import {getSSHHosts} from "@/ui/SSH/ssh-axios"; import {Checkbox} from "@/components/ui/checkbox.tsx"; interface SSHHost { diff --git a/src/apps/SSH/Terminal/TerminalTabList.tsx b/src/ui/SSH/Terminal/TerminalTabList.tsx similarity index 100% rename from src/apps/SSH/Terminal/TerminalTabList.tsx rename to src/ui/SSH/Terminal/TerminalTabList.tsx diff --git a/src/apps/SSH/Terminal/TerminalTopbar.tsx b/src/ui/SSH/Terminal/TerminalTopbar.tsx similarity index 97% rename from src/apps/SSH/Terminal/TerminalTopbar.tsx rename to src/ui/SSH/Terminal/TerminalTopbar.tsx index 036ae622..7bc30aba 100644 --- a/src/apps/SSH/Terminal/TerminalTopbar.tsx +++ b/src/ui/SSH/Terminal/TerminalTopbar.tsx @@ -1,4 +1,4 @@ -import {TerminalTabList} from "@/apps/SSH/Terminal/TerminalTabList.tsx"; +import {TerminalTabList} from "@/ui/SSH/Terminal/TerminalTabList.tsx"; import React from "react"; import {ChevronUp} from "lucide-react"; diff --git a/src/apps/SSH/Tunnel/SSHTunnel.tsx b/src/ui/SSH/Tunnel/SSHTunnel.tsx similarity index 96% rename from src/apps/SSH/Tunnel/SSHTunnel.tsx rename to src/ui/SSH/Tunnel/SSHTunnel.tsx index 83221fa2..fe9cc13a 100644 --- a/src/apps/SSH/Tunnel/SSHTunnel.tsx +++ b/src/ui/SSH/Tunnel/SSHTunnel.tsx @@ -1,7 +1,7 @@ import React, {useState, useEffect, useCallback} from "react"; -import {SSHTunnelSidebar} from "@/apps/SSH/Tunnel/SSHTunnelSidebar.tsx"; -import {SSHTunnelViewer} from "@/apps/SSH/Tunnel/SSHTunnelViewer.tsx"; -import {getSSHHosts, getTunnelStatuses, connectTunnel, disconnectTunnel, cancelTunnel} from "@/apps/SSH/ssh-axios"; +import {SSHTunnelSidebar} from "@/ui/SSH/Tunnel/SSHTunnelSidebar.tsx"; +import {SSHTunnelViewer} from "@/ui/SSH/Tunnel/SSHTunnelViewer.tsx"; +import {getSSHHosts, getTunnelStatuses, connectTunnel, disconnectTunnel, cancelTunnel} from "@/ui/SSH/ssh-axios"; interface ConfigEditorProps { onSelectView: (view: string) => void; diff --git a/src/apps/SSH/Tunnel/SSHTunnelObject.tsx b/src/ui/SSH/Tunnel/SSHTunnelObject.tsx similarity index 100% rename from src/apps/SSH/Tunnel/SSHTunnelObject.tsx rename to src/ui/SSH/Tunnel/SSHTunnelObject.tsx diff --git a/src/apps/SSH/Tunnel/SSHTunnelSidebar.tsx b/src/ui/SSH/Tunnel/SSHTunnelSidebar.tsx similarity index 100% rename from src/apps/SSH/Tunnel/SSHTunnelSidebar.tsx rename to src/ui/SSH/Tunnel/SSHTunnelSidebar.tsx diff --git a/src/apps/SSH/Tunnel/SSHTunnelViewer.tsx b/src/ui/SSH/Tunnel/SSHTunnelViewer.tsx similarity index 100% rename from src/apps/SSH/Tunnel/SSHTunnelViewer.tsx rename to src/ui/SSH/Tunnel/SSHTunnelViewer.tsx diff --git a/src/apps/SSH/ssh-axios.ts b/src/ui/SSH/ssh-axios.ts similarity index 100% rename from src/apps/SSH/ssh-axios.ts rename to src/ui/SSH/ssh-axios.ts diff --git a/tsconfig.app.json b/tsconfig.app.json index 0c7eded9..d9340376 100644 --- a/tsconfig.app.json +++ b/tsconfig.app.json @@ -6,16 +6,12 @@ "lib": ["ES2022", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, - - /* Bundler mode */ "moduleResolution": "bundler", "allowImportingTsExtensions": true, "verbatimModuleSyntax": true, "moduleDetection": "force", "noEmit": true, "jsx": "react-jsx", - - /* Linting - Made extremely permissive */ "strict": false, "noUnusedLocals": false, "noUnusedParameters": false, @@ -31,8 +27,6 @@ "allowUnreachableCode": true, "noImplicitOverride": false, "noEmitOnError": false, - - /* shadcn */ "baseUrl": ".", "paths": { "@/*": [ From 1b076cc61263fe1c1acdcd796eb2c675f954dc71 Mon Sep 17 00:00:00 2001 From: LukeGus Date: Thu, 14 Aug 2025 01:28:47 -0500 Subject: [PATCH 02/22] Build error fixes --- package-lock.json | 193 ++++++++++++++++-- package.json | 4 +- src/App.tsx | 6 +- src/components/ui/sidebar.tsx | 9 +- .../{Sidebar.tsx => LeftSidebar.tsx} | 2 +- 5 files changed, 187 insertions(+), 27 deletions(-) rename src/ui/Navigation/{Sidebar.tsx => LeftSidebar.tsx} (99%) diff --git a/package-lock.json b/package-lock.json index 262b5166..96ec5142 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,7 @@ "@radix-ui/react-avatar": "^1.1.10", "@radix-ui/react-checkbox": "^1.3.2", "@radix-ui/react-collapsible": "^1.1.11", - "@radix-ui/react-dialog": "^1.1.14", + "@radix-ui/react-dialog": "^1.1.15", "@radix-ui/react-dropdown-menu": "^2.1.15", "@radix-ui/react-label": "^2.1.7", "@radix-ui/react-popover": "^1.1.14", @@ -24,7 +24,7 @@ "@radix-ui/react-slot": "^1.2.3", "@radix-ui/react-switch": "^1.2.5", "@radix-ui/react-tabs": "^1.1.12", - "@radix-ui/react-tooltip": "^1.2.7", + "@radix-ui/react-tooltip": "^1.2.8", "@tailwindcss/vite": "^4.1.11", "@types/bcryptjs": "^2.4.6", "@types/multer": "^2.0.0", @@ -1739,20 +1739,20 @@ } }, "node_modules/@radix-ui/react-dialog": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.14.tgz", - "integrity": "sha512-+CpweKjqpzTmwRwcYECQcNYbI8V9VSQt0SNFKeEBLgfucbsLssU6Ppq7wUdNXEGb573bMjFhVjKVll8rmV6zMw==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.15.tgz", + "integrity": "sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", + "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-dismissable-layer": "1.1.10", - "@radix-ui/react-focus-guards": "1.1.2", + "@radix-ui/react-dismissable-layer": "1.1.11", + "@radix-ui/react-focus-guards": "1.1.3", "@radix-ui/react-focus-scope": "1.1.7", "@radix-ui/react-id": "1.1.1", "@radix-ui/react-portal": "1.1.9", - "@radix-ui/react-presence": "1.1.4", + "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", @@ -1774,6 +1774,78 @@ } } }, + "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/primitive": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz", + "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==", + "license": "MIT" + }, + "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.11.tgz", + "integrity": "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-escape-keydown": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-focus-guards": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.3.tgz", + "integrity": "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-presence": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz", + "integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-direction": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz", @@ -2345,19 +2417,19 @@ } }, "node_modules/@radix-ui/react-tooltip": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.2.7.tgz", - "integrity": "sha512-Ap+fNYwKTYJ9pzqW+Xe2HtMRbQ/EeWkj2qykZ6SuEV4iS/o1bZI5ssJbk4D2r8XuDuOBVz/tIx2JObtuqU+5Zw==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.2.8.tgz", + "integrity": "sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.2", + "@radix-ui/primitive": "1.1.3", "@radix-ui/react-compose-refs": "1.1.2", "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-dismissable-layer": "1.1.10", + "@radix-ui/react-dismissable-layer": "1.1.11", "@radix-ui/react-id": "1.1.1", - "@radix-ui/react-popper": "1.2.7", + "@radix-ui/react-popper": "1.2.8", "@radix-ui/react-portal": "1.1.9", - "@radix-ui/react-presence": "1.1.4", + "@radix-ui/react-presence": "1.1.5", "@radix-ui/react-primitive": "2.1.3", "@radix-ui/react-slot": "1.2.3", "@radix-ui/react-use-controllable-state": "1.2.2", @@ -2378,6 +2450,95 @@ } } }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/primitive": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz", + "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==", + "license": "MIT" + }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.11.tgz", + "integrity": "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.3", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-escape-keydown": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-popper": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.8.tgz", + "integrity": "sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==", + "license": "MIT", + "dependencies": { + "@floating-ui/react-dom": "^2.0.0", + "@radix-ui/react-arrow": "1.1.7", + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-context": "1.1.2", + "@radix-ui/react-primitive": "2.1.3", + "@radix-ui/react-use-callback-ref": "1.1.1", + "@radix-ui/react-use-layout-effect": "1.1.1", + "@radix-ui/react-use-rect": "1.1.1", + "@radix-ui/react-use-size": "1.1.1", + "@radix-ui/rect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-presence": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz", + "integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.2", + "@radix-ui/react-use-layout-effect": "1.1.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-use-callback-ref": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz", diff --git a/package.json b/package.json index 16eabebe..1edabae8 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "@radix-ui/react-avatar": "^1.1.10", "@radix-ui/react-checkbox": "^1.3.2", "@radix-ui/react-collapsible": "^1.1.11", - "@radix-ui/react-dialog": "^1.1.14", + "@radix-ui/react-dialog": "^1.1.15", "@radix-ui/react-dropdown-menu": "^2.1.15", "@radix-ui/react-label": "^2.1.7", "@radix-ui/react-popover": "^1.1.14", @@ -28,7 +28,7 @@ "@radix-ui/react-slot": "^1.2.3", "@radix-ui/react-switch": "^1.2.5", "@radix-ui/react-tabs": "^1.1.12", - "@radix-ui/react-tooltip": "^1.2.7", + "@radix-ui/react-tooltip": "^1.2.8", "@tailwindcss/vite": "^4.1.11", "@types/bcryptjs": "^2.4.6", "@types/multer": "^2.0.0", diff --git a/src/App.tsx b/src/App.tsx index 26f0717a..d0d4606e 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,5 +1,5 @@ import React, { useState, useEffect } from "react" -import { Sidebar } from "@/ui/Navigation/Sidebar.tsx" +import { LeftSidebar } from "@/ui/Navigation/LeftSidebar.tsx" import { Homepage } from "@/ui/Homepage/Homepage.tsx" import { Terminal } from "@/ui/SSH/Terminal/Terminal.tsx" import { SSHTunnel } from "@/ui/SSH/Tunnel/SSHTunnel.tsx" @@ -71,7 +71,7 @@ function App() { } return ( -
)} - + ) } diff --git a/src/components/ui/sidebar.tsx b/src/components/ui/sidebar.tsx index 66aace69..5d8d3cad 100644 --- a/src/components/ui/sidebar.tsx +++ b/src/components/ui/sidebar.tsx @@ -1,6 +1,6 @@ import * as React from "react" import { Slot } from "@radix-ui/react-slot" -import { cva, type VariantProps } from "class-variance-authority" +import { cva, VariantProps } from "class-variance-authority" import { PanelLeftIcon } from "lucide-react" import { useIsMobile } from "@/hooks/use-mobile" @@ -137,7 +137,7 @@ function SidebarProvider({ } as React.CSSProperties } className={cn( - "group/sidebar-wrapper has-data-[variant=inset]:bg-sidebar flex h-full w-full", + "group/sidebar-wrapper has-data-[variant=inset]:bg-sidebar flex min-h-svh w-full", className )} {...props} @@ -234,7 +234,7 @@ function Sidebar({ // Adjust the padding for floating and inset variants. variant === "floating" || variant === "inset" ? "p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]" - : "group-data-[collapsible=icon]:w-(--sidebar-width-icon)", + : "group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l", className )} {...props} @@ -242,7 +242,7 @@ function Sidebar({
{children}
@@ -720,6 +720,5 @@ export { SidebarRail, SidebarSeparator, SidebarTrigger, - // eslint-disable-next-line react-refresh/only-export-components useSidebar, } diff --git a/src/ui/Navigation/Sidebar.tsx b/src/ui/Navigation/LeftSidebar.tsx similarity index 99% rename from src/ui/Navigation/Sidebar.tsx rename to src/ui/Navigation/LeftSidebar.tsx index b56eddce..6ee63189 100644 --- a/src/ui/Navigation/Sidebar.tsx +++ b/src/ui/Navigation/LeftSidebar.tsx @@ -74,7 +74,7 @@ const API = axios.create({ baseURL: apiBase, }); -export function Sidebar({ +export function LeftSidebar({ onSelectView, getView, disabled, From 07367b24b6407c3a0167fbce95d3a07b049a4f61 Mon Sep 17 00:00:00 2001 From: LukeGus Date: Thu, 14 Aug 2025 01:47:22 -0500 Subject: [PATCH 03/22] Added navbar --- src/App.tsx | 88 ++++++++++++++++--------------- src/ui/Navigation/TopNavbar.tsx | 19 +++++++ src/ui/SSH/Manager/SSHManager.tsx | 2 +- 3 files changed, 66 insertions(+), 43 deletions(-) create mode 100644 src/ui/Navigation/TopNavbar.tsx diff --git a/src/App.tsx b/src/App.tsx index d0d4606e..7381b0d4 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,14 +1,15 @@ -import React, { useState, useEffect } from "react" -import { LeftSidebar } from "@/ui/Navigation/LeftSidebar.tsx" -import { Homepage } from "@/ui/Homepage/Homepage.tsx" -import { Terminal } from "@/ui/SSH/Terminal/Terminal.tsx" -import { SSHTunnel } from "@/ui/SSH/Tunnel/SSHTunnel.tsx" -import { ConfigEditor } from "@/ui/SSH/Config Editor/ConfigEditor.tsx" -import { SSHManager } from "@/ui/SSH/Manager/SSHManager.tsx" +import React, {useState, useEffect} from "react" +import {LeftSidebar} from "@/ui/Navigation/LeftSidebar.tsx" +import {Homepage} from "@/ui/Homepage/Homepage.tsx" +import {Terminal} from "@/ui/SSH/Terminal/Terminal.tsx" +import {SSHTunnel} from "@/ui/SSH/Tunnel/SSHTunnel.tsx" +import {ConfigEditor} from "@/ui/SSH/Config Editor/ConfigEditor.tsx" +import {SSHManager} from "@/ui/SSH/Manager/SSHManager.tsx" import axios from "axios" +import {TopNavbar} from "@/ui/Navigation/TopNavbar.tsx"; const apiBase = import.meta.env.DEV ? "http://localhost:8081/users" : "/users"; -const API = axios.create({ baseURL: apiBase }); +const API = axios.create({baseURL: apiBase}); function getCookie(name: string) { return document.cookie.split('; ').reduce((r, v) => { @@ -51,12 +52,12 @@ function App() { setAuthLoading(false); } } - + checkAuth() const handleStorageChange = () => checkAuth() window.addEventListener('storage', handleStorageChange) - + return () => window.removeEventListener('storage', handleStorageChange) }, []) @@ -71,38 +72,41 @@ function App() { } return ( - - {mountedViews.has("homepage") && ( -
- -
- )} - {mountedViews.has("ssh_manager") && ( -
- -
- )} - {mountedViews.has("terminal") && ( -
- -
- )} - {mountedViews.has("tunnel") && ( -
- -
- )} - {mountedViews.has("config_editor") && ( -
- -
- )} -
+
+ + {mountedViews.has("homepage") && ( +
+ +
+ )} + {mountedViews.has("ssh_manager") && ( +
+ +
+ )} + {mountedViews.has("terminal") && ( +
+ +
+ )} + {mountedViews.has("tunnel") && ( +
+ +
+ )} + {mountedViews.has("config_editor") && ( +
+ +
+ )} + +
+
) } diff --git a/src/ui/Navigation/TopNavbar.tsx b/src/ui/Navigation/TopNavbar.tsx new file mode 100644 index 00000000..235f7d1f --- /dev/null +++ b/src/ui/Navigation/TopNavbar.tsx @@ -0,0 +1,19 @@ +import React from "react"; +import { useSidebar } from "@/components/ui/sidebar"; + +export function TopNavbar(): React.ReactElement { + const { state } = useSidebar(); + + return ( +
+ +
+ ) +} \ No newline at end of file diff --git a/src/ui/SSH/Manager/SSHManager.tsx b/src/ui/SSH/Manager/SSHManager.tsx index 7c3348f3..3209f11b 100644 --- a/src/ui/SSH/Manager/SSHManager.tsx +++ b/src/ui/SSH/Manager/SSHManager.tsx @@ -58,7 +58,7 @@ export function SSHManager({onSelectView}: ConfigEditorProps): React.ReactElemen
Date: Fri, 15 Aug 2025 01:01:04 -0500 Subject: [PATCH 04/22] UI upadte, added host system, better flex scaling, improved login. --- src/App.tsx | 133 ++++++++--- src/components/ui/button-group.tsx | 53 +++++ src/components/ui/shadcn-io/status/index.tsx | 62 +++++ src/components/ui/sidebar.tsx | 2 +- src/ui/Homepage/Homepage.tsx | 73 +++--- src/ui/Homepage/HomepageAlertManager.tsx | 15 +- src/ui/Homepage/HomepageAuth.tsx | 47 ++-- src/ui/Navigation/Hosts/FolderCard.tsx | 80 +++++++ src/ui/Navigation/Hosts/Host.tsx | 67 ++++++ src/ui/Navigation/LeftSidebar.tsx | 236 +++++++++++++++---- src/ui/Navigation/TopNavbar.tsx | 53 ++++- 11 files changed, 669 insertions(+), 152 deletions(-) create mode 100644 src/components/ui/button-group.tsx create mode 100644 src/components/ui/shadcn-io/status/index.tsx create mode 100644 src/ui/Navigation/Hosts/FolderCard.tsx create mode 100644 src/ui/Navigation/Hosts/Host.tsx diff --git a/src/App.tsx b/src/App.tsx index 7381b0d4..8d16f38f 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -18,13 +18,19 @@ function getCookie(name: string) { }, ""); } +function setCookie(name: string, value: string, days = 7) { + const expires = new Date(Date.now() + days * 864e5).toUTCString(); + document.cookie = `${name}=${encodeURIComponent(value)}; expires=${expires}; path=/`; +} + function App() { - const [view, setView] = React.useState("homepage") - const [mountedViews, setMountedViews] = React.useState>(new Set(["homepage"])) + const [view, setView] = useState("homepage") + const [mountedViews, setMountedViews] = useState>(new Set(["homepage"])) const [isAuthenticated, setIsAuthenticated] = useState(false) const [username, setUsername] = useState(null) const [isAdmin, setIsAdmin] = useState(false) const [authLoading, setAuthLoading] = useState(true) + const [isTopbarOpen, setIsTopbarOpen] = useState(true) useEffect(() => { const checkAuth = () => { @@ -71,41 +77,102 @@ function App() { setView(nextView) } + const handleAuthSuccess = (authData: { isAdmin: boolean; username: string | null; userId: string | null }) => { + setIsAuthenticated(true) + setIsAdmin(authData.isAdmin) + setUsername(authData.username) + } + return (
- - {mountedViews.has("homepage") && ( -
- + {/* Enhanced background overlay - detailed pattern when not authenticated */} + {!isAuthenticated && !authLoading && ( +