import { Component, inject, signal } from '@angular/core'; import { RouterOutlet, RouterLink, RouterLinkActive } from '@angular/router'; import { CommonModule } from '@angular/common'; import { AuthService } from '../../core/services/auth.service'; import { FooterComponent } from '../footer/footer.component'; @Component({ selector: 'app-shell', standalone: true, imports: [RouterOutlet, RouterLink, RouterLinkActive, CommonModule, FooterComponent], template: `
@if (!collapsed()) { MediCode }
@if (!collapsed()) { Dashboard } @if (!collapsed()) { Code Search } @if (!collapsed()) { Patients } @if (!collapsed()) { Reports }
{{ initials() }}
@if (!collapsed()) {
{{ auth.currentUser()?.name }} {{ auth.currentUser()?.role }}
}
`, styles: [` .shell { display:flex; min-height:100vh; background:#f1f5f9; font-family:'Inter',system-ui,sans-serif; } .sidebar { width:240px; background:#0f172a; display:flex; flex-direction:column; transition:width 0.2s ease; flex-shrink:0; } .sidebar.collapsed { width:64px; } .sidebar-header { display:flex; align-items:center; justify-content:space-between; padding:1.25rem 1rem; border-bottom:1px solid rgba(255,255,255,0.07); } .brand { display:flex; align-items:center; gap:0.625rem; overflow:hidden; } .brand svg { width:32px; height:32px; flex-shrink:0; } .brand-name { color:white; font-weight:700; font-size:1.125rem; white-space:nowrap; } .collapse-btn { background:none; border:none; cursor:pointer; color:#64748b; padding:0.25rem; border-radius:4px; display:flex; transition:color 0.15s; } .collapse-btn:hover { color:#94a3b8; } .collapse-btn svg { width:16px; height:16px; } .sidebar-nav { flex:1; padding:1rem 0.5rem; display:flex; flex-direction:column; gap:0.25rem; } .nav-item { display:flex; align-items:center; gap:0.75rem; padding:0.7rem 0.75rem; border-radius:8px; color:#94a3b8; text-decoration:none; font-size:0.9rem; font-weight:500; transition:background 0.15s, color 0.15s; white-space:nowrap; overflow:hidden; } .nav-item svg { width:20px; height:20px; flex-shrink:0; } .nav-item:hover { background:rgba(255,255,255,0.07); color:#e2e8f0; } .nav-item.active { background:rgba(14,165,233,0.15); color:#38bdf8; } .sidebar-footer { padding:0.75rem 0.5rem; border-top:1px solid rgba(255,255,255,0.07); display:flex; align-items:center; justify-content:space-between; gap:0.5rem; } .user-info { display:flex; align-items:center; gap:0.625rem; overflow:hidden; min-width:0; } .avatar { width:32px; height:32px; border-radius:50%; background:#0EA5E9; color:white; font-size:0.75rem; font-weight:700; display:flex; align-items:center; justify-content:center; flex-shrink:0; } .user-meta { display:flex; flex-direction:column; overflow:hidden; } .user-name { color:#e2e8f0; font-size:0.8rem; font-weight:600; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; } .user-role { color:#64748b; font-size:0.7rem; text-transform:capitalize; } .logout-btn { background:none; border:none; cursor:pointer; color:#64748b; padding:0.4rem; border-radius:6px; display:flex; flex-shrink:0; transition:color 0.15s; } .logout-btn:hover { color:#f87171; } .logout-btn svg { width:18px; height:18px; } /* ── Fix footer positioning ── */ .main-content { flex: 1; overflow: auto; display: flex; flex-direction: column; /* ← key: stack page + footer vertically */ } .page-wrapper { flex: 1; /* ← key: page content expands, footer stays at bottom */ } `], }) export class ShellComponent { auth = inject(AuthService); collapsed = signal(false); toggleCollapsed() { this.collapsed.update(v => !v); } initials() { const name = this.auth.currentUser()?.name || ''; return name.split(' ').map(n => n[0]).slice(0, 2).join('').toUpperCase(); } }