diff --git a/src/client/index.tsx b/src/client/index.tsx index 5d737bf..6439b94 100644 --- a/src/client/index.tsx +++ b/src/client/index.tsx @@ -5,6 +5,7 @@ import { theme } from './themes' // UI state (survives re-renders) let selectedApp: string | null = localStorage.getItem('selectedApp') +let sidebarCollapsed: boolean = localStorage.getItem('sidebarCollapsed') === 'true' // Server state (from SSE) let apps: App[] = [] @@ -30,12 +31,36 @@ const Logo = define('Logo', { height: 64, display: 'flex', alignItems: 'center', + justifyContent: 'space-between', padding: '0 16px', fontSize: 20, fontWeight: 'bold', borderBottom: `1px solid ${theme('colors-border')}`, }) +const HamburgerButton = define('HamburgerButton', { + base: 'button', + background: 'none', + border: 'none', + cursor: 'pointer', + padding: 4, + display: 'flex', + flexDirection: 'column', + justifyContent: 'center', + gap: 4, + selectors: { + '&:hover span': { background: theme('colors-text') }, + }, +}) + +const HamburgerLine = define('HamburgerLine', { + width: 18, + height: 2, + background: theme('colors-textMuted'), + borderRadius: 1, + transition: 'background 0.15s', +}) + const SectionLabel = define('SectionLabel', { padding: '16px 16px 8px', fontSize: 12, @@ -141,7 +166,7 @@ const HeaderActions = define('HeaderActions', { const MainContent = define('MainContent', { flex: 1, - padding: 24, + padding: '10px 24px', overflow: 'auto', }) @@ -251,6 +276,40 @@ const LogTime = define('LogTime', { display: 'inline', }) +let selectedTab: 'overview' | 'todo' = 'overview' + +const TabContent = define('TabContent', { + display: 'none', + + variants: { + active: { + display: 'block' + } + } +}) + +const NavButton = define('NavButton', { + render({ props }) { + return ( + + ) + } +}) + +function setSelectedTab(tab: 'overview' | 'todo') { + selectedTab = tab + render() +} + +const Nav = () => { + return <> + setSelectedTab('overview')}>Overview + setSelectedTab('todo')}>TODO + +} + const stateLabels: Record = { invalid: 'Invalid', stopped: 'Stopped', @@ -270,6 +329,12 @@ const selectApp = (name: string) => { render() } +const toggleSidebar = () => { + sidebarCollapsed = !sidebarCollapsed + localStorage.setItem('sidebarCollapsed', String(sidebarCollapsed)) + render() +} + const AppDetail = ({ app }: { app: App }) => ( <> @@ -284,79 +349,87 @@ const AppDetail = ({ app }: { app: App }) => ( -
- Status - - State - - - {stateLabels[app.state]} - {app.port ? ` on :${app.port}` : ''} - - - {app.state === 'running' && app.port && ( +
- - {app.state === 'stopped' && ( - - )} - {app.state === 'running' && ( - <> - - - - )} - {(app.state === 'starting' || app.state === 'stopping') && ( - - )} - + )} + {app.state === 'running' && ( + <> + + + + )} + {(app.state === 'starting' || app.state === 'stopping') && ( + + )} + + + + +

hardy har har

+
) @@ -367,28 +440,39 @@ const Dashboard = () => { return ( - - 🐾 Toes - Apps + + + {!sidebarCollapsed && 🐾 Toes} + + + + + + + {!sidebarCollapsed && Apps} {apps.map(app => ( selectApp(app.name)} selected={app.name === selectedApp ? true : undefined} + style={sidebarCollapsed ? { justifyContent: 'center', padding: '10px 12px' } : undefined} + title={sidebarCollapsed ? app.name : undefined} > {app.state === 'running' && app.icon ? ( - {app.icon} + {app.icon} ) : ( )} - {app.name} + {!sidebarCollapsed && app.name} ))} - - + New App - + {!sidebarCollapsed && ( + + + New App + + )}
{selected ? (