work in progress
This commit is contained in:
parent
53311438ae
commit
eb33c9bbdf
|
@ -1,156 +1,92 @@
|
|||
<div class="flex h-screen overflow-hidden">
|
||||
<div
|
||||
[ngStyle]="navigation"
|
||||
[class]="
|
||||
isCollapsed
|
||||
? 'bg-primary w-0 md:w-20 transition-all duration-300 ease-in-out shadow-[5px_0_20px_rgba(0,0,0,0.5)]'
|
||||
: showMobileMenu
|
||||
? 'bg-primary w-64 transition-all duration-300 ease-in-out shadow-[5px_0_20px_rgba(0,0,0,0.5)]'
|
||||
: isDesktopCollapsed
|
||||
? 'bg-primary w-48 md:w-14 transition-all duration-300 ease-in-out shadow-[5px_0_20px_rgba(0,0,0,0.5)]'
|
||||
: 'bg-primary w-48 md:w-48 transition-all duration-300 ease-in-out shadow-[5px_0_20px_rgba(0,0,0,0.5)]'
|
||||
"
|
||||
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) {
|
||||
<!-- app.component.html -->
|
||||
<div class="flex flex-col h-screen overflow-hidden">
|
||||
<!-- Header -->
|
||||
<header class="w-full navbar bg-primary text-primary-content z-20">
|
||||
<div class="flex-1">
|
||||
<a class="btn btn-ghost normal-case text-xl text-primary-content">
|
||||
[APP-NAME]
|
||||
</a>
|
||||
</div>
|
||||
<div class="flex-none lg:hidden">
|
||||
<label for="my-drawer" class="btn btn-square btn-ghost drawer-button">
|
||||
<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">
|
||||
class="inline-block w-6 h-6 stroke-current">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="m8.25 4.5 7.5 7.5-7.5 7.5" />
|
||||
</svg>
|
||||
} @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" />
|
||||
stroke-width="2"
|
||||
d="M4 6h16M4 12h16M4 18h16"></path>
|
||||
</svg>
|
||||
</label>
|
||||
</div>
|
||||
<div class="flex-none hidden lg:block">
|
||||
<!-- Zusätzliche Header-Elemente für große Bildschirme -->
|
||||
</div>
|
||||
</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>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
*ngIf="!isCollapsed"
|
||||
class="fixed inset-0 bg-black bg-opacity-50 z-10 md:hidden"
|
||||
(click)="toggleSidebar()"></div>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<!-- Drawer -->
|
||||
<div class="drawer-side h-full">
|
||||
<label for="my-drawer" class="drawer-overlay"></label>
|
||||
<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>
|
||||
|
|
|
@ -3,11 +3,18 @@ import {
|
|||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
ElementRef,
|
||||
HostListener,
|
||||
OnInit,
|
||||
} from '@angular/core';
|
||||
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 { BackgroundPatternService, ThemeService } from '../../shared/service';
|
||||
|
@ -30,7 +37,7 @@ interface BottomMenuItem {
|
|||
selector: 'app-layout',
|
||||
standalone: true,
|
||||
providers: [],
|
||||
imports: [RouterOutlet, CommonModule],
|
||||
imports: [RouterOutlet, CommonModule, RouterModule],
|
||||
templateUrl: './layout.component.html',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
|
@ -73,95 +80,108 @@ export class LayoutComponent implements OnInit {
|
|||
private readonly sanitizer: DomSanitizer,
|
||||
private readonly router: Router,
|
||||
private readonly backgroundPatternService: BackgroundPatternService,
|
||||
private readonly route: ActivatedRoute,
|
||||
private readonly themeService: ThemeService,
|
||||
private readonly el: ElementRef,
|
||||
private readonly authService: AuthService
|
||||
) {}
|
||||
|
||||
public ngOnInit(): void {
|
||||
this.setActiveItemBasedOnRoute();
|
||||
this.router.events.subscribe(() => {
|
||||
this.router.events
|
||||
.pipe(filter((event) => event instanceof NavigationEnd))
|
||||
.subscribe(() => {
|
||||
this.setActiveItemBasedOnRoute();
|
||||
});
|
||||
this.setBackground();
|
||||
this.onResize();
|
||||
|
||||
// Initial set
|
||||
this.setActiveItemBasedOnRoute();
|
||||
}
|
||||
|
||||
@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 navigateTo(route: string): void {
|
||||
this.router.navigate([route]);
|
||||
}
|
||||
|
||||
public executeAction(item: BottomMenuItem): void {
|
||||
if (item.action) {
|
||||
item.action();
|
||||
}
|
||||
}
|
||||
|
||||
public setBackground(): void {
|
||||
const theme = this.themeService.getTheme();
|
||||
let opacity: number;
|
||||
// @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;
|
||||
// }
|
||||
// }
|
||||
|
||||
if (theme === 'dark') {
|
||||
opacity = 0.05;
|
||||
} else {
|
||||
opacity = 0.1;
|
||||
}
|
||||
// public setBackground(): void {
|
||||
// const theme = this.themeService.getTheme();
|
||||
// let opacity: number;
|
||||
|
||||
const colorPrimary = getComputedStyle(
|
||||
this.el.nativeElement
|
||||
).getPropertyValue('--p');
|
||||
// if (theme === 'dark') {
|
||||
// opacity = 0.05;
|
||||
// } else {
|
||||
// opacity = 0.1;
|
||||
// }
|
||||
|
||||
const colorPrimaryC = getComputedStyle(
|
||||
this.el.nativeElement
|
||||
).getPropertyValue('--pc');
|
||||
// const colorPrimary = getComputedStyle(
|
||||
// this.el.nativeElement
|
||||
// ).getPropertyValue('--p');
|
||||
|
||||
const svgUrlMainContent = this.backgroundPatternService.getPlusPattern(
|
||||
colorPrimary,
|
||||
opacity
|
||||
);
|
||||
const svgUrlNavigation = this.backgroundPatternService.getBankNotePattern(
|
||||
colorPrimaryC,
|
||||
opacity
|
||||
);
|
||||
// const colorPrimaryC = getComputedStyle(
|
||||
// this.el.nativeElement
|
||||
// ).getPropertyValue('--pc');
|
||||
|
||||
this.mainContent = {
|
||||
'background-image': `url("${svgUrlMainContent}")`,
|
||||
};
|
||||
this.navigation = {
|
||||
'background-image': `url("${svgUrlNavigation}")`,
|
||||
};
|
||||
}
|
||||
// const svgUrlMainContent = this.backgroundPatternService.getPlusPattern(
|
||||
// colorPrimary,
|
||||
// opacity
|
||||
// );
|
||||
// const svgUrlNavigation = this.backgroundPatternService.getBankNotePattern(
|
||||
// colorPrimaryC,
|
||||
// opacity
|
||||
// );
|
||||
|
||||
public toggleSidebar(): void {
|
||||
if (window.innerWidth < 768) {
|
||||
this.showMobileMenu = !this.showMobileMenu;
|
||||
this.isCollapsed = !this.showMobileMenu;
|
||||
} else {
|
||||
this.isDesktopCollapsed = !this.isDesktopCollapsed;
|
||||
}
|
||||
}
|
||||
// this.mainContent = {
|
||||
// 'background-image': `url("${svgUrlMainContent}")`,
|
||||
// };
|
||||
// this.navigation = {
|
||||
// 'background-image': `url("${svgUrlNavigation}")`,
|
||||
// };
|
||||
// }
|
||||
|
||||
public toggleDesktopSidebar(): void {
|
||||
this.isDesktopCollapsed = !this.isDesktopCollapsed;
|
||||
}
|
||||
// public toggleSidebar(): void {
|
||||
// if (window.innerWidth < 768) {
|
||||
// this.showMobileMenu = !this.showMobileMenu;
|
||||
// this.isCollapsed = !this.showMobileMenu;
|
||||
// } else {
|
||||
// this.isDesktopCollapsed = !this.isDesktopCollapsed;
|
||||
// }
|
||||
// }
|
||||
|
||||
public setActive(item: TopMenuItem): void {
|
||||
this.menuItems.forEach((menu: TopMenuItem) => {
|
||||
menu.active = false;
|
||||
});
|
||||
this.router.navigate([item.route]);
|
||||
if (!this.isCollapsed && this.showMobileMenu) {
|
||||
this.toggleSidebar();
|
||||
}
|
||||
}
|
||||
// public toggleDesktopSidebar(): void {
|
||||
// this.isDesktopCollapsed = !this.isDesktopCollapsed;
|
||||
// }
|
||||
|
||||
// public setActive(item: TopMenuItem): void {
|
||||
// this.menuItems.forEach((menu: TopMenuItem) => {
|
||||
// menu.active = false;
|
||||
// });
|
||||
// this.router.navigate([item.route]);
|
||||
// if (!this.isCollapsed && this.showMobileMenu) {
|
||||
// this.toggleSidebar();
|
||||
// }
|
||||
// }
|
||||
|
||||
private setActiveItemBasedOnRoute(): void {
|
||||
const url = this.router.url;
|
||||
const currentRoute = this.router.url;
|
||||
|
||||
this.menuItems.forEach((item: TopMenuItem) => {
|
||||
item.active = url.startsWith(item.route);
|
||||
item.active = currentRoute.startsWith(item.route);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue