toes/src/client/components/Sidebar.tsx
Chris Wanstrath bde7a2c287 tools!
2026-01-30 16:59:32 -08:00

94 lines
2.6 KiB
TypeScript

import { openNewAppModal } from '../modals'
import {
apps,
selectedApp,
setSelectedApp,
setSidebarCollapsed,
setSidebarSection,
sidebarCollapsed,
sidebarSection,
} from '../state'
import {
AppItem,
AppList,
HamburgerButton,
HamburgerLine,
Logo,
NewAppButton,
SectionSwitcher,
SectionTab,
Sidebar as SidebarContainer,
SidebarFooter,
StatusDot,
} from '../styles'
export function Sidebar({ render }: { render: () => void }) {
const selectApp = (name: string) => {
setSelectedApp(name)
render()
}
const toggleSidebar = () => {
setSidebarCollapsed(!sidebarCollapsed)
render()
}
const switchSection = (section: 'apps' | 'tools') => {
setSidebarSection(section)
render()
}
const regularApps = apps.filter(app => !app.tool)
const toolApps = apps.filter(app => app.tool)
const activeApps = sidebarSection === 'apps' ? regularApps : toolApps
return (
<SidebarContainer style={sidebarCollapsed ? { width: 'auto' } : undefined}>
<Logo>
{!sidebarCollapsed && <span>🐾 Toes</span>}
<HamburgerButton onClick={toggleSidebar} title={sidebarCollapsed ? 'Show sidebar' : 'Hide sidebar'}>
<HamburgerLine />
<HamburgerLine />
<HamburgerLine />
</HamburgerButton>
</Logo>
{!sidebarCollapsed && toolApps.length > 0 && (
<SectionSwitcher>
<SectionTab active={sidebarSection === 'apps' ? true : undefined} onClick={() => switchSection('apps')}>
Apps
</SectionTab>
<SectionTab active={sidebarSection === 'tools' ? true : undefined} onClick={() => switchSection('tools')}>
Tools
</SectionTab>
</SectionSwitcher>
)}
<AppList>
{activeApps.map(app => (
<AppItem
key={app.name}
onClick={() => selectApp(app.name)}
selected={app.name === selectedApp ? true : undefined}
style={sidebarCollapsed ? { justifyContent: 'center', padding: '10px 12px' } : undefined}
title={sidebarCollapsed ? app.name : undefined}
>
{sidebarCollapsed ? (
<span style={{ fontSize: 18 }}>{app.icon}</span>
) : (
<>
<span style={{ fontSize: 14 }}>{app.icon}</span>
{app.name}
<StatusDot state={app.state} style={{ marginLeft: 'auto' }} />
</>
)}
</AppItem>
))}
</AppList>
{!sidebarCollapsed && (
<SidebarFooter>
<NewAppButton onClick={openNewAppModal}>+ New App</NewAppButton>
</SidebarFooter>
)}
</SidebarContainer>
)
}