import { Component, signal, output, input } from '@angular/core'; import { CommonModule } from '@angular/common'; interface NavItem { id: string; label: string; icon: string; route: string; } @Component({ selector: 'app-sidebar', standalone: true, imports: [CommonModule], template: ` `, styles: [` .sidebar { display: flex; flex-direction: column; width: var(--spacing-sidebar-expanded, 200px); height: 100vh; background: var(--color-surface-200); border-right: 1px solid rgb(37 37 66 / 0.2); transition: width 0.2s ease; } .sidebar.collapsed { width: var(--spacing-sidebar, 56px); } .sidebar-header { display: flex; align-items: center; justify-content: space-between; padding: 1rem; border-bottom: 1px solid rgb(37 37 66 / 0.2); } .logo { display: flex; align-items: center; gap: 0.75rem; } .logo-text { font-size: 1.125rem; font-weight: 600; color: white; } .collapse-btn { display: flex; align-items: center; justify-content: center; width: 28px; height: 28px; background: transparent; border: none; border-radius: 0.375rem; color: #94a3b8; cursor: pointer; transition: all 0.15s ease; } .collapse-btn:hover { background: rgb(37 37 66 / 0.5); color: white; } .collapsed .collapse-btn { margin: 0 auto; } .sidebar-nav { flex: 1; display: flex; flex-direction: column; padding: 0.5rem; gap: 0.25rem; overflow-y: auto; } .nav-item { display: flex; align-items: center; gap: 0.75rem; padding: 0.625rem 0.75rem; border-radius: 0.5rem; border: none; background: transparent; color: #94a3b8; cursor: pointer; transition: all 0.15s ease; width: 100%; text-align: left; } .nav-item:hover { color: white; background: rgb(37 37 66 / 0.5); } .nav-item.active { background: rgb(0 212 255 / 0.1); color: var(--color-accent-400); border-left: 2px solid var(--color-accent-500); } .collapsed .nav-item { justify-content: center; padding: 0.625rem; } .nav-icon { display: flex; align-items: center; justify-content: center; width: 20px; height: 20px; flex-shrink: 0; } .nav-icon :deep(svg) { width: 20px; height: 20px; } .nav-label { font-size: 0.875rem; font-weight: 500; } .sidebar-footer { padding: 1rem; border-top: 1px solid rgb(37 37 66 / 0.2); } .miner-status { display: flex; align-items: center; gap: 0.5rem; } .status-indicator { width: 8px; height: 8px; border-radius: 9999px; } .status-indicator.online { background: var(--color-success-500); box-shadow: 0 0 8px var(--color-success-500); } .status-text { font-size: 0.75rem; color: #94a3b8; } `] }) export class SidebarComponent { collapsed = signal(false); currentRoute = input('workers'); routeChange = output(); navItems: NavItem[] = [ { id: 'workers', label: 'Workers', route: 'workers', icon: '' }, { id: 'graphs', label: 'Graphs', route: 'graphs', icon: '' }, { id: 'console', label: 'Console', route: 'console', icon: '' }, { id: 'pools', label: 'Pools', route: 'pools', icon: '' }, { id: 'profiles', label: 'Profiles', route: 'profiles', icon: '' }, { id: 'miners', label: 'Miners', route: 'miners', icon: '' }, { id: 'nodes', label: 'Nodes', route: 'nodes', icon: '' } ]; toggleCollapse() { this.collapsed.update(v => !v); } navigate(route: string) { this.routeChange.emit(route); } }