import { Component, OnInit, OnDestroy, HostListener } from '@angular/core'; import { CommonModule } from '@angular/common'; import { Router, NavigationEnd, RouterModule, RouterOutlet } from '@angular/router'; import { IconsModule } from '@progress/kendo-angular-icons'; import { SVGIcon, homeIcon, calendarIcon, userIcon, groupIcon, usersOutlineIcon, bedOutlineIcon, pillsOutlineIcon, graphIcon, buildingsOutlineIcon, banknoteOutlineIcon, questionCircleIcon, dollarIcon, categorizeIcon, moneyExchangeIcon, fileReportIcon, walletOutlineIcon, handIcon, } 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, RouterOutlet, IconsModule, ], templateUrl: './user-portal.component.html', styleUrls: ['./user-portal.component.scss'] }) export class UserPortalComponent implements OnInit, OnDestroy { sidebarCollapsed = false; isMobile = false; currentUser: UserInfo | null = null; currentPageTitle = 'Dashboard'; unreadMessages = 3; unreadNotifications = 2; public homeIcon: SVGIcon = homeIcon; public calendarIcon: SVGIcon = calendarIcon; public peopleIcon: SVGIcon = usersOutlineIcon; public bedIcon: SVGIcon = bedOutlineIcon; public userIcon: SVGIcon = userIcon; public pillIcon: SVGIcon = pillsOutlineIcon; public chartIcon: SVGIcon = graphIcon; public buildingIcon: SVGIcon = buildingsOutlineIcon; public creditCardIcon: SVGIcon = banknoteOutlineIcon; public supportIcon: SVGIcon = questionCircleIcon; 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 financeNavItems: NavItem[] = [ { text: 'Finance Dashboard', icon: graphIcon, path: '/user-portal/finance/dashboard' }, { text: 'Offering Entry', icon: handIcon, path: '/user-portal/finance/offering-session' }, { text: 'Givings', icon: dollarIcon, path: '/user-portal/finance/givings' }, { text: 'Giving Types', icon: categorizeIcon, path: '/user-portal/finance/giving-categories' }, { text: 'Expenses', icon: moneyExchangeIcon, path: '/user-portal/finance/expenses' }, { text: 'Expense Categories', icon: categorizeIcon, path: '/user-portal/finance/expense-categories' }, { text: 'Disbursements', icon: banknoteOutlineIcon, path: '/user-portal/finance/disbursements' }, { text: 'Check Register', icon: walletOutlineIcon, path: '/user-portal/finance/check-register' }, { text: 'Monthly Statement', icon: fileReportIcon, path: '/user-portal/finance/monthly-statement' }, { text: 'Church Profile', icon: buildingsOutlineIcon, path: '/user-portal/finance/church-profile' }, ]; public personalNavItems: NavItem[] = [ { text: 'My Reimbursements', icon: walletOutlineIcon, path: '/user-portal/reimbursements' }, ]; public showMemberAdminSection = false; public showUserAdminSection = false; public showFinanceSection = false; private destroy$ = new Subject(); constructor( private authService: AuthService, private router: Router ) { } ngOnInit(): void { this.checkScreenSize(); this.setupUserSubscription(); this.setupRouteSubscription(); } ngOnDestroy(): void { this.destroy$.next(); this.destroy$.complete(); } @HostListener('window:resize', ['$event']) onResize(event: any): void { this.checkScreenSize(); } private checkScreenSize(): void { this.isMobile = window.innerWidth <= 768; if (this.isMobile) { this.sidebarCollapsed = true; } else { // On desktop, start with sidebar expanded this.sidebarCollapsed = false; } } private setupUserSubscription(): void { this.authService.currentUser$ .pipe(takeUntil(this.destroy$)) .subscribe(user => { this.currentUser = user; const roles = user?.roles ?? []; this.showMemberAdminSection = roles.some(r => r === 'super_admin' || r === 'secretary'); this.showUserAdminSection = roles.includes('super_admin'); this.showFinanceSection = roles.some(r => r === 'finance' || r === 'super_admin'); }); } private setupRouteSubscription(): void { this.router.events .pipe( filter(event => event instanceof NavigationEnd), takeUntil(this.destroy$) ) .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, ...this.financeNavItems, ...this.personalNavItems, ]; 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 segments = url.split('/').filter(s => s); const key = segments.length >= 3 ? `${segments[1]}/${segments[2]}` // e.g. 'admin/members' : segments[1] ?? ''; this.currentPageTitle = this.getPageTitle(key); } private getPageTitle(page: string): string { const titles: { [key: string]: string } = { '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', 'finance/dashboard': 'Finance Dashboard', 'finance/offering-session': 'Sunday Offering Entry', 'finance/givings': 'Givings', 'finance/giving-categories': 'Giving Types', 'reimbursements': 'My Reimbursements', 'finance/expenses': 'Expenses', 'finance/expense-categories': 'Expense Categories', 'finance/disbursements': 'Disbursement Management', 'finance/check-register': 'Check Register', 'finance/monthly-statement': 'Monthly Statement', 'finance/church-profile': 'Church Profile', }; return titles[page] ?? 'Dashboard'; } toggleSidebar(): void { this.sidebarCollapsed = !this.sidebarCollapsed; } get mainContentClass(): string { return this.sidebarCollapsed ? 'main-content sidebar-collapsed' : 'main-content'; } onSidebarOverlayClick(): void { if (this.isMobile && !this.sidebarCollapsed) { this.sidebarCollapsed = true; } } onNavigationClick(): void { if (this.isMobile) { this.sidebarCollapsed = true; } } logout(): void { this.authService.logout(); this.router.navigate(['/login']); } getDisplayName(): string { return this.currentUser?.email || ''; } }