diff --git a/frontend/src/app/app.component.spec.ts b/frontend/src/app/app.component.spec.ts deleted file mode 100644 index d300ba8..0000000 --- a/frontend/src/app/app.component.spec.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { TestBed } from '@angular/core/testing'; - -import { AppComponent } from './app.component'; - -describe('AppComponent', () => { - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [AppComponent], - }).compileComponents(); - }); - - it('should create the app', () => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.componentInstance; - - expect(app).toBeTruthy(); - }); - - it('should have the "frontend" title', () => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.componentInstance; - - expect(app.title).toEqual('frontend'); - }); - - it('should render title', () => { - const fixture = TestBed.createComponent(AppComponent); - - fixture.detectChanges(); - const compiled = fixture.nativeElement as HTMLElement; - - expect(compiled.querySelector('h1')?.textContent).toContain( - 'Hello, frontend' - ); - }); -}); diff --git a/frontend/src/app/app.component.ts b/frontend/src/app/app.component.ts index 7b793bb..b43877d 100644 --- a/frontend/src/app/app.component.ts +++ b/frontend/src/app/app.component.ts @@ -1,16 +1,14 @@ -import { Component } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; import { RouterOutlet } from '@angular/router'; -import { ThemeService } from './shared/service'; - @Component({ selector: 'app-root', standalone: true, providers: [], - imports: [RouterOutlet], + imports: [RouterOutlet, CommonModule], templateUrl: './app.component.html', styleUrl: './app.component.scss', + changeDetection: ChangeDetectionStrategy.OnPush, }) -export class AppComponent { - public constructor(private readonly themeService: ThemeService) {} -} +export class AppComponent {} diff --git a/frontend/src/app/app.routes.ts b/frontend/src/app/app.routes.ts index 3f90917..248a466 100644 --- a/frontend/src/app/app.routes.ts +++ b/frontend/src/app/app.routes.ts @@ -1,15 +1,8 @@ import { Routes } from '@angular/router'; -const publicRoutes: Routes = [ +const simpleLayoutRoutes: Routes = [ { path: '', - loadComponent: () => - import('./pages/home-root/home-root.component').then( - (m) => m.HomeComponent - ), - }, - { - path: 'welcome', loadComponent: () => import('./pages/register-root/register-root.component').then( (m) => m.RegisterRootComponent @@ -38,10 +31,27 @@ const protectedRoutes: Routes = [ export const routes: Routes = [ { path: '', + loadComponent: () => + import('./layout/simple-layout/simple-layout.component').then( + (m) => m.LayoutSimpleComponent + ), + children: simpleLayoutRoutes, + }, + { + path: '', + loadComponent: () => + import('./layout/main-layout/layout.component').then( + (m) => m.LayoutComponent + ), children: [ - ...publicRoutes, - ...protectedRoutes, - { path: '', redirectTo: '', pathMatch: 'full' }, + { + path: '', + children: [ + ...protectedRoutes, + { path: '', redirectTo: 'dashboard', pathMatch: 'full' }, + ], + }, ], }, + { path: '**', redirectTo: '' }, ]; diff --git a/frontend/src/app/layout/main-layout/layout.component.html b/frontend/src/app/layout/main-layout/layout.component.html new file mode 100644 index 0000000..e0ec047 --- /dev/null +++ b/frontend/src/app/layout/main-layout/layout.component.html @@ -0,0 +1,127 @@ +
+ +
+
+
+
+ @if (!isCollapsed && !isDesktopCollapsed) { +
Logo
+ } + + @if (!isCollapsed && !showMobileMenu) { + + } +
+
+
+ +
+ +
+
+
+ +
+
+ +
+ +
+
+ +
+
diff --git a/frontend/src/app/layout/main-layout/layout.component.ts b/frontend/src/app/layout/main-layout/layout.component.ts new file mode 100644 index 0000000..f7afb6e --- /dev/null +++ b/frontend/src/app/layout/main-layout/layout.component.ts @@ -0,0 +1,139 @@ +import { CommonModule } from '@angular/common'; +import { + ChangeDetectionStrategy, + Component, + ElementRef, + HostListener, + OnInit, +} from '@angular/core'; +import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; +import { Router, RouterOutlet } from '@angular/router'; + +import { BackgroundPatternService, ThemeService } from '../../shared/service'; + +interface MenuItem { + name: string; + icon: SafeHtml; + route: string; + active?: boolean; +} + +@Component({ + selector: 'app-layout', + standalone: true, + providers: [], + imports: [RouterOutlet, CommonModule], + templateUrl: './layout.component.html', + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class LayoutComponent implements OnInit { + public isCollapsed: boolean = false; + public isDesktopCollapsed: boolean = false; + public showMobileMenu: boolean = false; + public userHasInteracted: boolean = false; + public menuItems: MenuItem[] = [ + { + name: 'Dashboard', + route: '/dashboard', + icon: this.sanitizer + .bypassSecurityTrustHtml(` + + `), + }, + ]; + public mainContent: { 'background-image': string } | null = null; + public navigation: { 'background-image': string } | null = null; + + public constructor( + private readonly sanitizer: DomSanitizer, + private readonly router: Router, + private readonly backgroundPatternService: BackgroundPatternService, + private readonly themeService: ThemeService, + private readonly el: ElementRef + ) {} + + public ngOnInit(): void { + this.setActiveItemBasedOnRoute(); + this.router.events.subscribe(() => { + this.setActiveItemBasedOnRoute(); + }); + this.setBackground(); + this.onResize(); + } + + @HostListener('window:resize', ['$event']) + public onResize(): void { + if (window.innerWidth >= 768) { + this.showMobileMenu = false; + this.isCollapsed = false; + } else { + this.isDesktopCollapsed = false; + this.isCollapsed = true; + this.showMobileMenu = false; + } + } + + public setBackground(): void { + const theme = this.themeService.getTheme(); + let opacity: number; + + if (theme === 'dark') { + opacity = 0.05; + } else { + opacity = 0.1; + } + + const colorPrimary = getComputedStyle( + this.el.nativeElement + ).getPropertyValue('--p'); + + const colorPrimaryC = getComputedStyle( + this.el.nativeElement + ).getPropertyValue('--pc'); + + const svgUrlMainContent = this.backgroundPatternService.getPlusPattern( + colorPrimary, + opacity + ); + const svgUrlNavigation = this.backgroundPatternService.getBankNotePattern( + colorPrimaryC, + opacity + ); + + this.mainContent = { + 'background-image': `url("${svgUrlMainContent}")`, + }; + this.navigation = { + 'background-image': `url("${svgUrlNavigation}")`, + }; + } + + public toggleSidebar(): void { + if (window.innerWidth < 768) { + this.showMobileMenu = !this.showMobileMenu; + this.isCollapsed = !this.showMobileMenu; + } else { + this.isDesktopCollapsed = !this.isDesktopCollapsed; + } + this.userHasInteracted = true; + } + + public toggleDesktopSidebar(): void { + this.isDesktopCollapsed = !this.isDesktopCollapsed; + } + + public setActive(item: MenuItem): void { + this.menuItems.forEach((menu: MenuItem) => { + menu.active = false; + }); + item.active = true; + } + + private setActiveItemBasedOnRoute(): void { + const url = this.router.url; + + this.menuItems.forEach((item: MenuItem) => { + item.active = url.startsWith(item.route); + }); + } +} diff --git a/frontend/src/app/layout/simple-layout/simple-layout.component.ts b/frontend/src/app/layout/simple-layout/simple-layout.component.ts new file mode 100644 index 0000000..5d6fca1 --- /dev/null +++ b/frontend/src/app/layout/simple-layout/simple-layout.component.ts @@ -0,0 +1,12 @@ +import { Component } from '@angular/core'; +import { RouterOutlet } from '@angular/router'; + +@Component({ + selector: 'app-simple-layout', + standalone: true, + imports: [RouterOutlet], + template: ` + + `, +}) +export class LayoutSimpleComponent {} diff --git a/frontend/src/app/pages/dashboard-root/dashboard-root.component.html b/frontend/src/app/pages/dashboard-root/dashboard-root.component.html index 1adfd5f..4b9b192 100644 --- a/frontend/src/app/pages/dashboard-root/dashboard-root.component.html +++ b/frontend/src/app/pages/dashboard-root/dashboard-root.component.html @@ -1,129 +1 @@ -
- -
-
-
-
- @if (!isCollapsed && !isDesktopCollapsed) { -
Logo
- } - - @if (!isCollapsed && !showMobileMenu) { - - } -
-
-
- -
- -
-
-
- -
-
- -
-

isCollapsed: {{ isCollapsed }}

-

showMobileMenu: {{ showMobileMenu }}

-

isDesktopCollapsed: {{ isDesktopCollapsed }}

-
-
- -
-
+

Dashboard Works

diff --git a/frontend/src/app/pages/dashboard-root/dashboard-root.component.ts b/frontend/src/app/pages/dashboard-root/dashboard-root.component.ts index 3d88fdb..bcce9d1 100644 --- a/frontend/src/app/pages/dashboard-root/dashboard-root.component.ts +++ b/frontend/src/app/pages/dashboard-root/dashboard-root.component.ts @@ -1,22 +1,5 @@ import { CommonModule } from '@angular/common'; -import { - ChangeDetectionStrategy, - Component, - ElementRef, - HostListener, - OnInit, -} from '@angular/core'; -import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; -import { Router } from '@angular/router'; - -import { BackgroundPatternService, ThemeService } from '../../shared/service'; - -interface MenuItem { - name: string; - icon: SafeHtml; - route: string; - active?: boolean; -} +import { ChangeDetectionStrategy, Component } from '@angular/core'; @Component({ selector: 'app-dashboard-root', @@ -27,116 +10,4 @@ interface MenuItem { styleUrl: './dashboard-root.component.scss', changeDetection: ChangeDetectionStrategy.OnPush, }) -export class DashboardRootComponent implements OnInit { - public isCollapsed: boolean = false; - public isDesktopCollapsed: boolean = false; - public showMobileMenu: boolean = false; - public userHasInteracted: boolean = false; - public menuItems: MenuItem[] = [ - { - name: 'Dashboard', - route: '/dashboard', - icon: this.sanitizer - .bypassSecurityTrustHtml(` - - `), - }, - ]; - public mainContent: { 'background-image': string } | null = null; - public navigation: { 'background-image': string } | null = null; - - public constructor( - private readonly sanitizer: DomSanitizer, - private readonly router: Router, - private readonly backgroundPatternService: BackgroundPatternService, - private readonly themeService: ThemeService, - private readonly el: ElementRef - ) {} - - public ngOnInit(): void { - this.setActiveItemBasedOnRoute(); - this.router.events.subscribe(() => { - this.setActiveItemBasedOnRoute(); - }); - this.setBackground(); - this.onResize(); - } - - @HostListener('window:resize', ['$event']) - public onResize(): void { - if (window.innerWidth >= 768) { - this.showMobileMenu = false; - this.isCollapsed = false; - } else { - this.isDesktopCollapsed = false; - this.isCollapsed = true; - this.showMobileMenu = false; - } - } - - public setBackground(): void { - const theme = this.themeService.getTheme(); - let opacity: number; - - if (theme === 'dark') { - opacity = 0.05; - } else { - opacity = 0.1; - } - - const colorPrimary = getComputedStyle( - this.el.nativeElement - ).getPropertyValue('--p'); - - const colorPrimaryC = getComputedStyle( - this.el.nativeElement - ).getPropertyValue('--pc'); - - const svgUrlMainContent = this.backgroundPatternService.getPlusPattern( - colorPrimary, - opacity - ); - const svgUrlNavigation = this.backgroundPatternService.getBankNotePattern( - colorPrimaryC, - opacity - ); - - console.log(this.mainContent, this.navigation); - - this.mainContent = { - 'background-image': `url("${svgUrlMainContent}")`, - }; - this.navigation = { - 'background-image': `url("${svgUrlNavigation}")`, - }; - } - - public toggleSidebar(): void { - if (window.innerWidth < 768) { - this.showMobileMenu = !this.showMobileMenu; - this.isCollapsed = !this.showMobileMenu; - } else { - this.isDesktopCollapsed = !this.isDesktopCollapsed; - } - this.userHasInteracted = true; - } - - public toggleDesktopSidebar(): void { - this.isDesktopCollapsed = !this.isDesktopCollapsed; - } - - public setActive(item: MenuItem): void { - this.menuItems.forEach((menu: MenuItem) => { - menu.active = false; - }); - item.active = true; - } - - private setActiveItemBasedOnRoute(): void { - const url = this.router.url; - - this.menuItems.forEach((item: MenuItem) => { - item.active = url.startsWith(item.route); - }); - } -} +export class DashboardRootComponent {}