dev_arc_aws/src/components/Sidebar.tsx

117 lines
4.4 KiB
TypeScript
Raw Normal View History

2026-06-18 08:14:00 -04:00
import {
LayoutGrid,
Server,
Globe,
Bookmark,
Terminal,
Settings,
ChevronLeft,
ChevronRight,
} from 'lucide-react'
interface SidebarProps {
collapsed: boolean
onToggle: () => void
}
const navItems = [
{ icon: LayoutGrid, label: 'Glance', route: '/', active: true },
{ icon: Server, label: 'Infrastructure', route: '/infrastructure', active: false },
{ icon: Globe, label: 'Network', route: '/network', active: false },
{ icon: Bookmark, label: 'BookNest', route: '/booknest', active: false },
{ icon: Terminal, label: 'Terminal', route: '/terminal', active: false },
{ icon: Settings, label: 'Settings', route: '/settings', active: false },
]
export default function Sidebar({ collapsed, onToggle }: SidebarProps) {
const width = collapsed ? 60 : 140
return (
<aside
className="fixed left-0 top-0 z-50 h-screen overflow-hidden flex flex-col items-center py-5"
style={{ width: `${width}px`, backgroundColor: '#0A0B0D' }}
>
{/* Logo — larger, aligned with top bar */}
<div className="flex flex-col items-center mb-6" style={{ paddingTop: '8px' }}>
<img
src="/archnest-logo.png"
alt="ArchNest"
className="mb-1.5"
style={{
width: collapsed ? '28px' : '44px',
height: collapsed ? '28px' : '44px',
filter: 'drop-shadow(0 0 8px rgba(200,164,52,0.5))',
}}
/>
{!collapsed && (
<span style={{ fontSize: '9px', fontWeight: 700, letterSpacing: '2.5px', color: '#C8A434', textTransform: 'uppercase' }}>
ArchNest
</span>
)}
</div>
{/* Nav Items */}
<nav className="flex-1 flex flex-col justify-center gap-6 w-full">
{navItems.map((item) => {
const Icon = item.icon
return (
<a
key={item.label}
href={item.route}
className="relative flex w-full flex-col items-center justify-center gap-1.5 px-2 py-2 text-center no-underline transition-all duration-200"
style={{ color: item.active ? '#C8A434' : '#7A7D85' }}
title={collapsed ? item.label : undefined}
onMouseEnter={(e) => { if (!item.active) e.currentTarget.style.backgroundColor = 'rgba(200,164,52,0.05)'; e.currentTarget.style.color = '#C8A434' }}
onMouseLeave={(e) => { e.currentTarget.style.backgroundColor = 'transparent'; if (!item.active) e.currentTarget.style.color = '#7A7D85' }}
>
{item.active && (
<div
className="absolute left-0 top-1/2 -translate-y-1/2 rounded-r"
style={{ width: '3px', height: '26px', backgroundColor: '#C8A434', boxShadow: '0 0 6px rgba(200,164,52,0.5)' }}
/>
)}
<Icon className="h-5 w-5 shrink-0" strokeWidth={item.active ? 2 : 1.5} />
{!collapsed && (
<span className="max-w-[90px] truncate leading-tight font-medium" style={{ fontSize: '10px' }}>
{item.label}
</span>
)}
</a>
)
})}
</nav>
{/* Collapse Toggle */}
<button
onClick={onToggle}
className="p-1.5 rounded cursor-pointer bg-transparent transition-colors"
style={{ border: '1px solid #1E2025', color: '#7A7D85', marginBottom: '12px' }}
>
{collapsed ? <ChevronRight size={12} /> : <ChevronLeft size={12} />}
</button>
{/* System Status — rounded block, fits inside nav with breathing room */}
<div style={{ width: '100%', padding: '0 12px 16px 12px' }}>
<div
style={{
border: '1px solid rgba(122, 125, 133, 0.2)',
borderRadius: '10px',
padding: '10px 12px',
backgroundColor: 'rgba(20, 21, 24, 0.5)',
}}
>
<div className="flex items-center gap-2">
<div style={{ width: '12px', height: '12px', borderRadius: '50%', border: '2px solid #2ECC71', flexShrink: 0 }} />
{!collapsed && (
<div>
<span style={{ fontSize: '9px', color: '#E8E6E0', display: 'block', lineHeight: 1.3, fontWeight: 500 }}>System Status</span>
<span style={{ fontSize: '8px', color: '#2ECC71', display: 'block', lineHeight: 1.3 }}>All Systems Operational</span>
</div>
)}
</div>
</div>
</div>
</aside>
)
}