work in progress

This commit is contained in:
Igor Hrenowitsch Propisnov 2024-09-09 21:38:09 +02:00
parent 53311438ae
commit eb33c9bbdf
2 changed files with 171 additions and 215 deletions

View File

@ -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>

View File

@ -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);
});
}