WIP
This commit is contained in:
@@ -33,36 +33,46 @@
|
||||
|
||||
<nav class="sidebar-nav">
|
||||
<div class="nav-section">
|
||||
<h4 *ngIf="!sidebarCollapsed">Overview</h4>
|
||||
<a routerLink="/user-portal/dashboard" routerLinkActive="active" class="nav-item"
|
||||
(click)="onNavigationClick()">
|
||||
<h4 *ngIf="!sidebarCollapsed">Main</h4>
|
||||
<a *ngFor="let item of mainNavItems" class="nav-item" [class.active]="item.active"
|
||||
[title]="item.text" (click)="navigateTo(item.path)">
|
||||
<div class="nav-icon">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<rect x="3" y="3" width="7" height="7"></rect>
|
||||
<rect x="14" y="3" width="7" height="7"></rect>
|
||||
<rect x="14" y="14" width="7" height="7"></rect>
|
||||
<rect x="3" y="14" width="7" height="7"></rect>
|
||||
</svg>
|
||||
<kendo-svgicon [icon]="item.icon"></kendo-svgicon>
|
||||
</div>
|
||||
<span *ngIf="!sidebarCollapsed">Dashboard</span>
|
||||
<span *ngIf="!sidebarCollapsed">{{ item.text }}</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="nav-section" *ngIf="showAdminSection">
|
||||
<h4 *ngIf="!sidebarCollapsed">Administration</h4>
|
||||
<a routerLink="/user-portal/admin/users" routerLinkActive="active" class="nav-item"
|
||||
(click)="onNavigationClick()">
|
||||
<div class="nav-section">
|
||||
<h4 *ngIf="!sidebarCollapsed">Management</h4>
|
||||
<a *ngFor="let item of managementNavItems" class="nav-item" [class.active]="item.active"
|
||||
[title]="item.text" (click)="navigateTo(item.path)">
|
||||
<div class="nav-icon">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"></path>
|
||||
<circle cx="9" cy="7" r="4"></circle>
|
||||
<path d="M22 21v-2a4 4 0 0 0-3-3.87"></path>
|
||||
<path d="M16 3.13a4 4 0 0 1 0 7.75"></path>
|
||||
</svg>
|
||||
<kendo-svgicon [icon]="item.icon"></kendo-svgicon>
|
||||
</div>
|
||||
<span *ngIf="!sidebarCollapsed">User Management</span>
|
||||
<span *ngIf="!sidebarCollapsed">{{ item.text }}</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="nav-section" *ngIf="showMemberAdminSection || showUserAdminSection">
|
||||
<h4 *ngIf="!sidebarCollapsed">Administration</h4>
|
||||
<a *ngFor="let item of memberAdminNavItems" class="nav-item" [class.active]="item.active"
|
||||
[title]="item.text" (click)="navigateTo(item.path)">
|
||||
<div class="nav-icon">
|
||||
<kendo-svgicon [icon]="item.icon"></kendo-svgicon>
|
||||
</div>
|
||||
<span *ngIf="!sidebarCollapsed">{{ item.text }}</span>
|
||||
</a>
|
||||
<ng-container *ngIf="showUserAdminSection">
|
||||
<a *ngFor="let item of userAdminNavItems" class="nav-item" [class.active]="item.active"
|
||||
[title]="item.text" (click)="navigateTo(item.path)">
|
||||
<div class="nav-icon">
|
||||
<kendo-svgicon [icon]="item.icon"></kendo-svgicon>
|
||||
</div>
|
||||
<span *ngIf="!sidebarCollapsed">{{ item.text }}</span>
|
||||
</a>
|
||||
</ng-container>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="sidebar-footer" *ngIf="!sidebarCollapsed">
|
||||
|
||||
@@ -1,19 +1,26 @@
|
||||
import { Component, OnInit, OnDestroy, HostListener } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Router, NavigationEnd, RouterModule, RouterLink, RouterLinkActive } from '@angular/router';
|
||||
import { RouterOutlet } from '@angular/router';
|
||||
import { Router, NavigationEnd, RouterModule, RouterOutlet } from '@angular/router';
|
||||
import { IconsModule } from '@progress/kendo-angular-icons';
|
||||
import { SVGIcon, homeIcon, calendarIcon, userIcon, groupIcon } from '@progress/kendo-svg-icons';
|
||||
import { AuthService, UserInfo } from '../../shared/services/auth.service';
|
||||
import { Subject, takeUntil, filter } from 'rxjs';
|
||||
|
||||
interface NavItem {
|
||||
text: string;
|
||||
icon: SVGIcon;
|
||||
path: string;
|
||||
active?: boolean;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app-user-portal',
|
||||
standalone: true,
|
||||
imports: [
|
||||
CommonModule,
|
||||
RouterModule,
|
||||
RouterLink,
|
||||
RouterLinkActive,
|
||||
RouterOutlet
|
||||
RouterOutlet,
|
||||
IconsModule,
|
||||
],
|
||||
templateUrl: './user-portal.component.html',
|
||||
styleUrls: ['./user-portal.component.scss']
|
||||
@@ -23,10 +30,49 @@ export class UserPortalComponent implements OnInit, OnDestroy {
|
||||
isMobile = false;
|
||||
currentUser: UserInfo | null = null;
|
||||
currentPageTitle = 'Dashboard';
|
||||
showAdminSection = false;
|
||||
unreadMessages = 3;
|
||||
unreadNotifications = 2;
|
||||
|
||||
public homeIcon: SVGIcon = homeIcon;
|
||||
public calendarIcon: SVGIcon = calendarIcon;
|
||||
public peopleIcon: SVGIcon = userIcon;
|
||||
public bedIcon: SVGIcon = userIcon;
|
||||
public userIcon: SVGIcon = userIcon;
|
||||
public pillIcon: SVGIcon = userIcon;
|
||||
public chartIcon: SVGIcon = userIcon;
|
||||
public buildingIcon: SVGIcon = userIcon;
|
||||
public creditCardIcon: SVGIcon = userIcon;
|
||||
public supportIcon: SVGIcon = userIcon;
|
||||
|
||||
public mainNavItems: NavItem[] = [
|
||||
{ text: 'Dashboard', icon: this.homeIcon, path: '/user-portal/dashboard' },
|
||||
// { text: 'Schedule', icon: this.calendarIcon, path: '/user-portal/schedule' },
|
||||
// { text: 'Patients', icon: this.peopleIcon, path: '/user-portal/patients' },
|
||||
];
|
||||
|
||||
public managementNavItems: NavItem[] = [
|
||||
// { text: 'Staff', icon: this.userIcon, path: '/user-portal/staff' },
|
||||
// { text: 'Pharmacy', icon: this.pillIcon, path: '/user-portal/pharmacy' },
|
||||
// { text: 'Reports', icon: this.chartIcon, path: '/user-portal/reports' },1124
|
||||
// { text: 'Departments', icon: this.buildingIcon, path: '/user-portal/departments' },
|
||||
// { text: 'Payments', icon: this.creditCardIcon, path: '/user-portal/payments' },
|
||||
];
|
||||
|
||||
public supportNavItems: NavItem[] = [
|
||||
{ text: 'Support', icon: this.supportIcon, path: '/user-portal/support' },
|
||||
];
|
||||
|
||||
public memberAdminNavItems: NavItem[] = [
|
||||
{ text: 'Members', icon: groupIcon, path: '/user-portal/admin/members' },
|
||||
];
|
||||
|
||||
public userAdminNavItems: NavItem[] = [
|
||||
{ text: 'User Management', icon: userIcon, path: '/user-portal/admin/users' },
|
||||
];
|
||||
|
||||
public showMemberAdminSection = false;
|
||||
public showUserAdminSection = false;
|
||||
|
||||
private destroy$ = new Subject<void>();
|
||||
|
||||
constructor(
|
||||
@@ -65,7 +111,9 @@ export class UserPortalComponent implements OnInit, OnDestroy {
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
.subscribe(user => {
|
||||
this.currentUser = user;
|
||||
this.showAdminSection = !!user?.roles?.includes('super_admin');
|
||||
const roles = user?.roles ?? [];
|
||||
this.showMemberAdminSection = roles.some(r => r === 'super_admin' || r === 'secretary');
|
||||
this.showUserAdminSection = roles.includes('super_admin');
|
||||
});
|
||||
}
|
||||
|
||||
@@ -75,17 +123,40 @@ export class UserPortalComponent implements OnInit, OnDestroy {
|
||||
filter(event => event instanceof NavigationEnd),
|
||||
takeUntil(this.destroy$)
|
||||
)
|
||||
.subscribe(() => {
|
||||
.subscribe((event: NavigationEnd) => {
|
||||
this.updateActiveStates(event.url);
|
||||
this.updatePageTitle();
|
||||
});
|
||||
|
||||
this.updateActiveStates(this.router.url);
|
||||
this.updatePageTitle();
|
||||
}
|
||||
|
||||
public navigateTo(path: string): void {
|
||||
this.router.navigate([path]);
|
||||
this.onNavigationClick();
|
||||
}
|
||||
|
||||
private updateActiveStates(currentUrl: string): void {
|
||||
const allItems = [
|
||||
...this.mainNavItems,
|
||||
...this.managementNavItems,
|
||||
...this.supportNavItems,
|
||||
...this.memberAdminNavItems,
|
||||
...this.userAdminNavItems,
|
||||
];
|
||||
allItems.forEach(item => (item.active = false));
|
||||
|
||||
const activeItem = allItems.find(item => currentUrl.startsWith(item.path));
|
||||
if (activeItem) {
|
||||
activeItem.active = true;
|
||||
}
|
||||
}
|
||||
|
||||
private updatePageTitle(): void {
|
||||
const url = this.router.url;
|
||||
const url = this.router.url;
|
||||
const segments = url.split('/').filter(s => s);
|
||||
const key = segments.length >= 3
|
||||
const key = segments.length >= 3
|
||||
? `${segments[1]}/${segments[2]}` // e.g. 'admin/members'
|
||||
: segments[1] ?? '';
|
||||
this.currentPageTitle = this.getPageTitle(key);
|
||||
@@ -93,15 +164,24 @@ export class UserPortalComponent implements OnInit, OnDestroy {
|
||||
|
||||
private getPageTitle(page: string): string {
|
||||
const titles: { [key: string]: string } = {
|
||||
'dashboard': 'Dashboard',
|
||||
'transactions': 'Escrow Transactions',
|
||||
'tasks': 'Tasks & Todos',
|
||||
'contacts': 'Contacts',
|
||||
'documents': 'Documents',
|
||||
'messages': 'Messages',
|
||||
'settings': 'Settings',
|
||||
'admin/members': 'Member Management',
|
||||
'admin/users': 'User Management',
|
||||
'dashboard': 'Dashboard',
|
||||
'schedule': 'Schedule',
|
||||
'patients': 'Patients',
|
||||
'bed-management': 'Bed Management',
|
||||
'staff': 'Staff',
|
||||
'pharmacy': 'Pharmacy',
|
||||
'reports': 'Reports',
|
||||
'departments': 'Departments',
|
||||
'payments': 'Payments',
|
||||
'support': 'Support',
|
||||
'transactions': 'Escrow Transactions',
|
||||
'tasks': 'Tasks & Todos',
|
||||
'contacts': 'Contacts',
|
||||
'documents': 'Documents',
|
||||
'messages': 'Messages',
|
||||
'settings': 'Settings',
|
||||
'admin/members': 'Member Management',
|
||||
'admin/users': 'User Management',
|
||||
};
|
||||
return titles[page] ?? 'Dashboard';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user