import { BreakpointObserver, MediaMatcher } from '@angular/cdk/layout'; import { ChangeDetectorRef, Component, OnInit, ViewChild, ViewEncapsulation } from '@angular/core'; import { Subscription } from 'rxjs'; import { MatSidenav, MatSidenavContent } from '@angular/material/sidenav'; import { CoreService } from 'src/app/services/core.service'; import { AppSettings } from 'src/app/config'; import { filter } from 'rxjs/operators'; import { NavigationEnd, Router } from '@angular/router'; import { navItems } from './vertical/sidebar/sidebar-data'; import { NavService } from '../../services/nav.service'; import { AppNavItemComponent } from './vertical/sidebar/nav-item/nav-item.component'; import { RouterModule } from '@angular/router'; import { MaterialModule } from 'src/app/material.module'; import { CommonModule } from '@angular/common'; import { SidebarComponent } from './vertical/sidebar/sidebar.component'; import { NgScrollbarModule } from 'ngx-scrollbar'; import { TablerIconsModule } from 'angular-tabler-icons'; import { HeaderComponent } from './vertical/header/header.component'; import { AppHorizontalHeaderComponent } from './horizontal/header/header.component'; import { AppHorizontalSidebarComponent } from './horizontal/sidebar/sidebar.component'; import { AppBreadcrumbComponent } from './shared/breadcrumb/breadcrumb.component'; import { CustomizerComponent } from './shared/customizer/customizer.component'; const MOBILE_VIEW = 'screen and (max-width: 768px)'; const TABLET_VIEW = 'screen and (min-width: 769px) and (max-width: 1024px)'; const MONITOR_VIEW = 'screen and (min-width: 1024px)'; const BELOWMONITOR = 'screen and (max-width: 1023px)'; // for mobile app sidebar interface apps { id: number; img: string; title: string; subtitle: string; link: string; } interface quicklinks { id: number; title: string; link: string; } @Component({ selector: 'app-full', imports: [ RouterModule, AppNavItemComponent, MaterialModule, CommonModule, SidebarComponent, NgScrollbarModule, TablerIconsModule, HeaderComponent, AppHorizontalHeaderComponent, AppHorizontalSidebarComponent, AppBreadcrumbComponent, CustomizerComponent, ], templateUrl: './full.component.html', encapsulation: ViewEncapsulation.None }) export class FullComponent implements OnInit { navItems = navItems; @ViewChild('leftsidenav') public sidenav: MatSidenav; resView = false; @ViewChild('content', { static: true }) content!: MatSidenavContent; //get options from service options = this.settings.getOptions(); private layoutChangesSubscription = Subscription.EMPTY; private isMobileScreen = false; private isContentWidthFixed = true; private isCollapsedWidthFixed = false; private htmlElement!: HTMLHtmlElement; get isOver(): boolean { return this.isMobileScreen; } get isTablet(): boolean { return this.resView; } // for mobile app sidebar apps: apps[] = [ { id: 1, img: '/assets/images/svgs/icon-dd-chat.svg', title: 'Chat Application', subtitle: 'Messages & Emails', link: '/apps/chat', }, { id: 2, img: '/assets/images/svgs/icon-dd-cart.svg', title: 'Todo App', subtitle: 'Completed task', link: '/apps/todo', }, { id: 3, img: '/assets/images/svgs/icon-dd-invoice.svg', title: 'Invoice App', subtitle: 'Get latest invoice', link: '/apps/invoice', }, { id: 4, img: '/assets/images/svgs/icon-dd-date.svg', title: 'Calendar App', subtitle: 'Get Dates', link: '/apps/calendar', }, { id: 5, img: '/assets/images/svgs/icon-dd-mobile.svg', title: 'Contact Application', subtitle: '2 Unsaved Contacts', link: '/apps/contacts', }, { id: 6, img: '/assets/images/svgs/icon-dd-lifebuoy.svg', title: 'Tickets App', subtitle: 'Create new ticket', link: '/apps/tickets', }, { id: 7, img: '/assets/images/svgs/icon-dd-message-box.svg', title: 'Email App', subtitle: 'Get new emails', link: '/apps/email/inbox', }, { id: 8, img: '/assets/images/svgs/icon-dd-application.svg', title: 'Courses', subtitle: 'Create new course', link: '/apps/courses', }, ]; quicklinks: quicklinks[] = [ { id: 1, title: 'Pricing Page', link: '/theme-pages/pricing', }, { id: 2, title: 'Authentication Design', link: '/authentication/login', }, { id: 3, title: 'Register Now', link: '/authentication/side-register', }, { id: 4, title: '404 Error Page', link: '/authentication/error', }, { id: 5, title: 'Notes App', link: '/apps/notes', }, { id: 6, title: 'Employee App', link: '/apps/employee', }, { id: 7, title: 'Todo Application', link: '/apps/todo', }, { id: 8, title: 'Treeview', link: '/theme-pages/treeview', }, ]; constructor( private settings: CoreService, private mediaMatcher: MediaMatcher, private router: Router, private breakpointObserver: BreakpointObserver, private navService: NavService, private cdr: ChangeDetectorRef ) { this.htmlElement = document.querySelector('html')!; this.layoutChangesSubscription = this.breakpointObserver .observe([MOBILE_VIEW, TABLET_VIEW, MONITOR_VIEW, BELOWMONITOR]) .subscribe((state) => { // SidenavOpened must be reset true when layout changes this.options.sidenavOpened = true; this.isMobileScreen = state.breakpoints[BELOWMONITOR]; if (this.options.sidenavCollapsed == false) { this.options.sidenavCollapsed = state.breakpoints[TABLET_VIEW]; } this.isContentWidthFixed = state.breakpoints[MONITOR_VIEW]; this.resView = state.breakpoints[BELOWMONITOR]; }); // Initialize project theme with options this.receiveOptions(this.options); // This is for scroll to top this.router.events .pipe(filter((event) => event instanceof NavigationEnd)) .subscribe((e) => { this.content.scrollTo({ top: 0 }); }); } isFilterNavOpen = false; toggleFilterNav() { this.isFilterNavOpen = !this.isFilterNavOpen; console.log('Sidebar open:', this.isFilterNavOpen); this.cdr.detectChanges(); // Ensures Angular updates the view } ngOnInit(): void {} ngOnDestroy() { this.layoutChangesSubscription.unsubscribe(); } toggleCollapsed() { this.isContentWidthFixed = false; this.options.sidenavCollapsed = !this.options.sidenavCollapsed; this.resetCollapsedState(); } resetCollapsedState(timer = 400) { setTimeout(() => this.settings.setOptions(this.options), timer); } onSidenavClosedStart() { this.isContentWidthFixed = false; } onSidenavOpenedChange(isOpened: boolean) { this.isCollapsedWidthFixed = !this.isOver; this.options.sidenavOpened = isOpened; this.settings.setOptions(this.options); } receiveOptions(options: AppSettings): void { this.toggleDarkTheme(options); this.toggleColorsTheme(options); } toggleDarkTheme(options: AppSettings) { if (options.theme === 'dark') { this.htmlElement.classList.add('dark-theme'); this.htmlElement.classList.remove('light-theme'); } else { this.htmlElement.classList.remove('dark-theme'); this.htmlElement.classList.add('light-theme'); } } toggleColorsTheme(options: AppSettings) { // Remove any existing theme class dynamically this.htmlElement.classList.forEach((className) => { if (className.endsWith('_theme')) { this.htmlElement.classList.remove(className); } }); // Add the selected theme class this.htmlElement.classList.add(options.activeTheme); } }