work in progress
This commit is contained in:
parent
53311438ae
commit
eb33c9bbdf
|
@ -1,156 +1,92 @@
|
||||||
<div class="flex h-screen overflow-hidden">
|
<!-- app.component.html -->
|
||||||
<div
|
<div class="flex flex-col h-screen overflow-hidden">
|
||||||
[ngStyle]="navigation"
|
<!-- Header -->
|
||||||
[class]="
|
<header class="w-full navbar bg-primary text-primary-content z-20">
|
||||||
isCollapsed
|
<div class="flex-1">
|
||||||
? 'bg-primary w-0 md:w-20 transition-all duration-300 ease-in-out shadow-[5px_0_20px_rgba(0,0,0,0.5)]'
|
<a class="btn btn-ghost normal-case text-xl text-primary-content">
|
||||||
: showMobileMenu
|
[APP-NAME]
|
||||||
? 'bg-primary w-64 transition-all duration-300 ease-in-out shadow-[5px_0_20px_rgba(0,0,0,0.5)]'
|
</a>
|
||||||
: isDesktopCollapsed
|
</div>
|
||||||
? 'bg-primary w-48 md:w-14 transition-all duration-300 ease-in-out shadow-[5px_0_20px_rgba(0,0,0,0.5)]'
|
<div class="flex-none lg:hidden">
|
||||||
: 'bg-primary w-48 md:w-48 transition-all duration-300 ease-in-out shadow-[5px_0_20px_rgba(0,0,0,0.5)]'
|
<label for="my-drawer" class="btn btn-square btn-ghost drawer-button">
|
||||||
"
|
|
||||||
class="transform h-full z-20 overflow-y-auto fixed md:relative flex flex-col">
|
|
||||||
<div
|
|
||||||
[ngClass]="showMobileMenu ? 'justify-center' : 'justify-between'"
|
|
||||||
[ngStyle]="navigation"
|
|
||||||
class="p-1 w-full h-16 z-50 bg-base-100 flex items-center relative">
|
|
||||||
<div class="flex items-center justify-center h-full w-full">
|
|
||||||
<div class="flex items-center space-x-4">
|
|
||||||
@if (!isCollapsed && !isDesktopCollapsed) {
|
|
||||||
<div class="text-primary">LOGO</div>
|
|
||||||
}
|
|
||||||
|
|
||||||
@if (!isCollapsed && !showMobileMenu) {
|
|
||||||
<button
|
|
||||||
(click)="toggleDesktopSidebar()"
|
|
||||||
class="flex items-center justify-center w-10 h-10 rounded-full">
|
|
||||||
@if (isDesktopCollapsed) {
|
|
||||||
<svg
|
<svg
|
||||||
class="stroke-current text-primary w-6 h-6"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
fill="none"
|
fill="none"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
stroke-width="3">
|
class="inline-block w-6 h-6 stroke-current">
|
||||||
<path
|
<path
|
||||||
stroke-linecap="round"
|
stroke-linecap="round"
|
||||||
stroke-linejoin="round"
|
stroke-linejoin="round"
|
||||||
d="m8.25 4.5 7.5 7.5-7.5 7.5" />
|
stroke-width="2"
|
||||||
</svg>
|
d="M4 6h16M4 12h16M4 18h16"></path>
|
||||||
} @else {
|
|
||||||
<svg
|
|
||||||
class="stroke-current text-primary w-6 h-6"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
stroke-width="3">
|
|
||||||
<path
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
d="M15.75 19.5 8.25 12l7.5-7.5" />
|
|
||||||
</svg>
|
|
||||||
}
|
|
||||||
</button>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<ul class="m-1">
|
|
||||||
<li
|
|
||||||
class="cursor-pointer rounded-btn mt-2"
|
|
||||||
[ngClass]="{
|
|
||||||
'bg-base-100 text-primary': item.active,
|
|
||||||
'text-primary-content hover:text-accent-content hover:bg-accent':
|
|
||||||
!item.active
|
|
||||||
}"
|
|
||||||
(click)="setActive(item)"
|
|
||||||
(keydown.enter)="setActive(item)"
|
|
||||||
(keydown.space)="setActive(item)"
|
|
||||||
tabindex="0"
|
|
||||||
role="button"
|
|
||||||
*ngFor="let item of menuItems">
|
|
||||||
<div
|
|
||||||
class="flex justify-center p-1"
|
|
||||||
*ngIf="isDesktopCollapsed && !showMobileMenu">
|
|
||||||
<span class="p-1" [innerHTML]="item.icon"></span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="flex items-center rounded-btn justify-between cursor-pointer px-1 py-2"
|
|
||||||
*ngIf="!isDesktopCollapsed || showMobileMenu">
|
|
||||||
<div class="flex items-center">
|
|
||||||
<span [innerHTML]="item.icon" class="mx-2"></span>
|
|
||||||
<span>{{ item.name }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<ul class="m-1 mt-auto">
|
|
||||||
<li
|
|
||||||
class="cursor-pointer bg-base-100 text-base-content rounded-btn mb-2"
|
|
||||||
*ngFor="let item of bottomMenuItems"
|
|
||||||
(click)="item.action ? item.action() : null"
|
|
||||||
(keydown.enter)="item.action ? item.action() : null"
|
|
||||||
(keydown.space)="item.action ? item.action() : null"
|
|
||||||
tabindex="0"
|
|
||||||
role="button">
|
|
||||||
<div
|
|
||||||
class="flex justify-center p-1"
|
|
||||||
*ngIf="isDesktopCollapsed && !showMobileMenu">
|
|
||||||
<span class="p-1" [innerHTML]="item.icon"></span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="flex items-center rounded-btn justify-between cursor-pointer px-1 py-2"
|
|
||||||
*ngIf="!isDesktopCollapsed || showMobileMenu">
|
|
||||||
<div class="flex items-center">
|
|
||||||
<span [innerHTML]="item.icon" class="mx-2"></span>
|
|
||||||
<span>{{ item.name }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex flex-col flex-grow">
|
|
||||||
<header
|
|
||||||
[ngStyle]="navigation"
|
|
||||||
class="p-4 z-0 md:z-20 relative bg-primary text-primary-content flex items-center h-16 shadow-[0_5px_20px_rgba(0,0,0,0.5)]">
|
|
||||||
<div class="w-10 flex items-center justify-center md:hidden">
|
|
||||||
<label class="btn btn-ghost swap swap-rotate">
|
|
||||||
<input
|
|
||||||
type="checkbox"
|
|
||||||
(change)="toggleSidebar()"
|
|
||||||
[checked]="!isCollapsed" />
|
|
||||||
<svg
|
|
||||||
class="swap-off fill-current"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
width="24"
|
|
||||||
height="24"
|
|
||||||
viewBox="0 0 512 512">
|
|
||||||
<path
|
|
||||||
d="M64,384H448V341.33H64Zm0-106.67H448V234.67H64ZM64,128v42.67H448V128Z" />
|
|
||||||
</svg>
|
|
||||||
<svg
|
|
||||||
class="swap-on fill-current"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
width="24"
|
|
||||||
height="24"
|
|
||||||
viewBox="0 0 512 512">
|
|
||||||
<polygon
|
|
||||||
points="400 145.49 366.51 112 256 222.51 145.49 112 112 145.49 222.51 256 112 366.51 145.49 400 256 289.49 366.51 400 400 366.51 289.49 256 400 145.49" />
|
|
||||||
</svg>
|
</svg>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex-none hidden lg:block">
|
||||||
|
<!-- Zusätzliche Header-Elemente für große Bildschirme -->
|
||||||
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div [ngStyle]="mainContent" class="overflow-y-auto h-screen">
|
<!-- Hauptcontainer -->
|
||||||
|
<div class="drawer lg:drawer-open flex-1 overflow-hidden">
|
||||||
|
<input id="my-drawer" type="checkbox" class="drawer-toggle" />
|
||||||
|
|
||||||
|
<!-- Hauptinhalt -->
|
||||||
|
<div class="drawer-content flex flex-col bg-base-100">
|
||||||
|
<main class="flex-1 overflow-y-auto p-4">
|
||||||
|
<div class="w-full h-full flex items-center justify-center">
|
||||||
|
<div class="w-full max-w-5xl">
|
||||||
<router-outlet></router-outlet>
|
<router-outlet></router-outlet>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div
|
<!-- Drawer -->
|
||||||
*ngIf="!isCollapsed"
|
<div class="drawer-side h-full">
|
||||||
class="fixed inset-0 bg-black bg-opacity-50 z-10 md:hidden"
|
<label for="my-drawer" class="drawer-overlay"></label>
|
||||||
(click)="toggleSidebar()"></div>
|
<aside class="bg-primary text-primary-content w-64 h-full flex flex-col">
|
||||||
|
<div class="flex-1 overflow-y-auto py-4 pt-0">
|
||||||
|
<ul class="w-full p-0 m-0 [&_li>*]:rounded-none">
|
||||||
|
<ng-container *ngFor="let item of menuItems">
|
||||||
|
<li class="w-full">
|
||||||
|
<a
|
||||||
|
[routerLink]="item.route"
|
||||||
|
routerLinkActive="bg-base-100 text-base-content"
|
||||||
|
[routerLinkActiveOptions]="{ exact: false }"
|
||||||
|
class="flex items-center w-full px-4 py-3 text-base-content transition-colors duration-200 ease-in-out focus:outline-none"
|
||||||
|
role="menuitem"
|
||||||
|
tabindex="0"
|
||||||
|
(keydown.enter)="
|
||||||
|
$event.preventDefault(); navigateTo(item.route)
|
||||||
|
">
|
||||||
|
<span
|
||||||
|
class="flex-shrink-0 w-6 h-6 mr-3"
|
||||||
|
[innerHTML]="item.icon"></span>
|
||||||
|
<span class="flex-grow">{{ item.name }}</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ng-container>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="p-4">
|
||||||
|
<ul class="menu w-full">
|
||||||
|
<ng-container *ngFor="let item of bottomMenuItems">
|
||||||
|
<li>
|
||||||
|
<button
|
||||||
|
(click)="executeAction(item)"
|
||||||
|
(keydown.enter)="executeAction(item)"
|
||||||
|
class="flex items-center space-x-2 hover:bg-primary-focus focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-focus w-full text-left"
|
||||||
|
role="menuitem"
|
||||||
|
tabindex="0">
|
||||||
|
<span [innerHTML]="item.icon"></span>
|
||||||
|
<span>{{ item.name }}</span>
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</ng-container>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</aside>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -3,11 +3,18 @@ import {
|
||||||
ChangeDetectionStrategy,
|
ChangeDetectionStrategy,
|
||||||
Component,
|
Component,
|
||||||
ElementRef,
|
ElementRef,
|
||||||
HostListener,
|
|
||||||
OnInit,
|
OnInit,
|
||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
|
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
|
||||||
import { Router, RouterOutlet } from '@angular/router';
|
import {
|
||||||
|
ActivatedRoute,
|
||||||
|
NavigationEnd,
|
||||||
|
Router,
|
||||||
|
RouterModule,
|
||||||
|
RouterOutlet,
|
||||||
|
} from '@angular/router';
|
||||||
|
|
||||||
|
import { filter } from 'rxjs';
|
||||||
|
|
||||||
import { SuccessDtoApiModel } from '../../api';
|
import { SuccessDtoApiModel } from '../../api';
|
||||||
import { BackgroundPatternService, ThemeService } from '../../shared/service';
|
import { BackgroundPatternService, ThemeService } from '../../shared/service';
|
||||||
|
@ -30,7 +37,7 @@ interface BottomMenuItem {
|
||||||
selector: 'app-layout',
|
selector: 'app-layout',
|
||||||
standalone: true,
|
standalone: true,
|
||||||
providers: [],
|
providers: [],
|
||||||
imports: [RouterOutlet, CommonModule],
|
imports: [RouterOutlet, CommonModule, RouterModule],
|
||||||
templateUrl: './layout.component.html',
|
templateUrl: './layout.component.html',
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
})
|
})
|
||||||
|
@ -73,95 +80,108 @@ export class LayoutComponent implements OnInit {
|
||||||
private readonly sanitizer: DomSanitizer,
|
private readonly sanitizer: DomSanitizer,
|
||||||
private readonly router: Router,
|
private readonly router: Router,
|
||||||
private readonly backgroundPatternService: BackgroundPatternService,
|
private readonly backgroundPatternService: BackgroundPatternService,
|
||||||
|
private readonly route: ActivatedRoute,
|
||||||
private readonly themeService: ThemeService,
|
private readonly themeService: ThemeService,
|
||||||
private readonly el: ElementRef,
|
private readonly el: ElementRef,
|
||||||
private readonly authService: AuthService
|
private readonly authService: AuthService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
public ngOnInit(): void {
|
public ngOnInit(): void {
|
||||||
this.setActiveItemBasedOnRoute();
|
this.router.events
|
||||||
this.router.events.subscribe(() => {
|
.pipe(filter((event) => event instanceof NavigationEnd))
|
||||||
|
.subscribe(() => {
|
||||||
this.setActiveItemBasedOnRoute();
|
this.setActiveItemBasedOnRoute();
|
||||||
});
|
});
|
||||||
this.setBackground();
|
|
||||||
this.onResize();
|
// Initial set
|
||||||
|
this.setActiveItemBasedOnRoute();
|
||||||
}
|
}
|
||||||
|
|
||||||
@HostListener('window:resize', ['$event'])
|
public navigateTo(route: string): void {
|
||||||
public onResize(): void {
|
this.router.navigate([route]);
|
||||||
if (window.innerWidth >= 768) {
|
}
|
||||||
this.showMobileMenu = false;
|
|
||||||
this.isCollapsed = false;
|
public executeAction(item: BottomMenuItem): void {
|
||||||
} else {
|
if (item.action) {
|
||||||
this.isDesktopCollapsed = false;
|
item.action();
|
||||||
this.isCollapsed = true;
|
|
||||||
this.showMobileMenu = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public setBackground(): void {
|
// @HostListener('window:resize', ['$event'])
|
||||||
const theme = this.themeService.getTheme();
|
// public onResize(): void {
|
||||||
let opacity: number;
|
// if (window.innerWidth >= 768) {
|
||||||
|
// this.showMobileMenu = false;
|
||||||
|
// this.isCollapsed = false;
|
||||||
|
// } else {
|
||||||
|
// this.isDesktopCollapsed = false;
|
||||||
|
// this.isCollapsed = true;
|
||||||
|
// this.showMobileMenu = false;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
if (theme === 'dark') {
|
// public setBackground(): void {
|
||||||
opacity = 0.05;
|
// const theme = this.themeService.getTheme();
|
||||||
} else {
|
// let opacity: number;
|
||||||
opacity = 0.1;
|
|
||||||
}
|
|
||||||
|
|
||||||
const colorPrimary = getComputedStyle(
|
// if (theme === 'dark') {
|
||||||
this.el.nativeElement
|
// opacity = 0.05;
|
||||||
).getPropertyValue('--p');
|
// } else {
|
||||||
|
// opacity = 0.1;
|
||||||
|
// }
|
||||||
|
|
||||||
const colorPrimaryC = getComputedStyle(
|
// const colorPrimary = getComputedStyle(
|
||||||
this.el.nativeElement
|
// this.el.nativeElement
|
||||||
).getPropertyValue('--pc');
|
// ).getPropertyValue('--p');
|
||||||
|
|
||||||
const svgUrlMainContent = this.backgroundPatternService.getPlusPattern(
|
// const colorPrimaryC = getComputedStyle(
|
||||||
colorPrimary,
|
// this.el.nativeElement
|
||||||
opacity
|
// ).getPropertyValue('--pc');
|
||||||
);
|
|
||||||
const svgUrlNavigation = this.backgroundPatternService.getBankNotePattern(
|
|
||||||
colorPrimaryC,
|
|
||||||
opacity
|
|
||||||
);
|
|
||||||
|
|
||||||
this.mainContent = {
|
// const svgUrlMainContent = this.backgroundPatternService.getPlusPattern(
|
||||||
'background-image': `url("${svgUrlMainContent}")`,
|
// colorPrimary,
|
||||||
};
|
// opacity
|
||||||
this.navigation = {
|
// );
|
||||||
'background-image': `url("${svgUrlNavigation}")`,
|
// const svgUrlNavigation = this.backgroundPatternService.getBankNotePattern(
|
||||||
};
|
// colorPrimaryC,
|
||||||
}
|
// opacity
|
||||||
|
// );
|
||||||
|
|
||||||
public toggleSidebar(): void {
|
// this.mainContent = {
|
||||||
if (window.innerWidth < 768) {
|
// 'background-image': `url("${svgUrlMainContent}")`,
|
||||||
this.showMobileMenu = !this.showMobileMenu;
|
// };
|
||||||
this.isCollapsed = !this.showMobileMenu;
|
// this.navigation = {
|
||||||
} else {
|
// 'background-image': `url("${svgUrlNavigation}")`,
|
||||||
this.isDesktopCollapsed = !this.isDesktopCollapsed;
|
// };
|
||||||
}
|
// }
|
||||||
}
|
|
||||||
|
|
||||||
public toggleDesktopSidebar(): void {
|
// public toggleSidebar(): void {
|
||||||
this.isDesktopCollapsed = !this.isDesktopCollapsed;
|
// if (window.innerWidth < 768) {
|
||||||
}
|
// this.showMobileMenu = !this.showMobileMenu;
|
||||||
|
// this.isCollapsed = !this.showMobileMenu;
|
||||||
|
// } else {
|
||||||
|
// this.isDesktopCollapsed = !this.isDesktopCollapsed;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
public setActive(item: TopMenuItem): void {
|
// public toggleDesktopSidebar(): void {
|
||||||
this.menuItems.forEach((menu: TopMenuItem) => {
|
// this.isDesktopCollapsed = !this.isDesktopCollapsed;
|
||||||
menu.active = false;
|
// }
|
||||||
});
|
|
||||||
this.router.navigate([item.route]);
|
// public setActive(item: TopMenuItem): void {
|
||||||
if (!this.isCollapsed && this.showMobileMenu) {
|
// this.menuItems.forEach((menu: TopMenuItem) => {
|
||||||
this.toggleSidebar();
|
// menu.active = false;
|
||||||
}
|
// });
|
||||||
}
|
// this.router.navigate([item.route]);
|
||||||
|
// if (!this.isCollapsed && this.showMobileMenu) {
|
||||||
|
// this.toggleSidebar();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
private setActiveItemBasedOnRoute(): void {
|
private setActiveItemBasedOnRoute(): void {
|
||||||
const url = this.router.url;
|
const currentRoute = this.router.url;
|
||||||
|
|
||||||
this.menuItems.forEach((item: TopMenuItem) => {
|
this.menuItems.forEach((item: TopMenuItem) => {
|
||||||
item.active = url.startsWith(item.route);
|
item.active = currentRoute.startsWith(item.route);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue