feature/refactor-login #19
|
@ -12,36 +12,89 @@
|
||||||
<button
|
<button
|
||||||
(click)="toggleDrawer()"
|
(click)="toggleDrawer()"
|
||||||
class="btn btn-square btn-ghost drawer-button">
|
class="btn btn-square btn-ghost drawer-button">
|
||||||
<svg
|
<div
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
[@burgerAnimation]="isDrawerOpen ? 'open' : 'closed'"
|
||||||
fill="none"
|
class="w-6 h-6">
|
||||||
viewBox="0 0 24 24"
|
<svg
|
||||||
class="inline-block w-6 h-6 stroke-current">
|
*ngIf="!isDrawerOpen"
|
||||||
<path
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
stroke-linecap="round"
|
width="24"
|
||||||
stroke-linejoin="round"
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
stroke-width="2"
|
stroke-width="2"
|
||||||
d="M4 6h16M4 12h16M4 18h16"></path>
|
stroke-linecap="round"
|
||||||
</svg>
|
stroke-linejoin="round">
|
||||||
|
<line x1="3" y1="12" x2="21" y2="12"></line>
|
||||||
|
<line x1="3" y1="6" x2="21" y2="6"></line>
|
||||||
|
<line x1="3" y1="18" x2="21" y2="18"></line>
|
||||||
|
</svg>
|
||||||
|
<svg
|
||||||
|
*ngIf="isDrawerOpen"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round">
|
||||||
|
<line x1="18" y1="6" x2="6" y2="18"></line>
|
||||||
|
<line x1="6" y1="6" x2="18" y2="18"></line>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Compact Mode Toggle Button für Desktop -->
|
<!-- Compact Mode Toggle Button für Desktop -->
|
||||||
<div class="hidden lg:flex items-center space-x-2 mr-4">
|
<div class="hidden lg:flex items-center space-x-2 mr-4">
|
||||||
<button (click)="toggleCompactMode()" class="btn btn-square btn-ghost">
|
<button (click)="toggleCompactMode()" class="btn btn-square btn-ghost">
|
||||||
<svg
|
<div
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
[@compactAnimation]="isCompact ? 'compact' : 'normal'"
|
||||||
viewBox="0 0 24 24"
|
class="relative w-6 h-6">
|
||||||
fill="none"
|
<svg
|
||||||
stroke="currentColor"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
stroke-width="2"
|
viewBox="0 0 24 24"
|
||||||
stroke-linecap="round"
|
fill="none"
|
||||||
stroke-linejoin="round"
|
stroke="currentColor"
|
||||||
class="inline-block w-6 h-6">
|
stroke-width="2"
|
||||||
<rect x="3" y="3" width="18" height="18" rx="2" ry="2" />
|
stroke-linecap="round"
|
||||||
<line x1="9" y1="3" x2="9" y2="21" />
|
stroke-linejoin="round"
|
||||||
<path d="M13 8l3 3-3 3" />
|
class="absolute inset-0 w-6 h-6">
|
||||||
</svg>
|
<!-- Sidebar outline -->
|
||||||
|
<rect x="3" y="3" width="18" height="18" rx="2" ry="2" />
|
||||||
|
|
||||||
|
<!-- Icon representation -->
|
||||||
|
<circle cx="7" cy="8" r="1" />
|
||||||
|
<circle cx="7" cy="12" r="1" />
|
||||||
|
<circle cx="7" cy="16" r="1" />
|
||||||
|
|
||||||
|
<!-- Text representation -->
|
||||||
|
<line
|
||||||
|
x1="11"
|
||||||
|
y1="8"
|
||||||
|
x2="19"
|
||||||
|
y2="8"
|
||||||
|
class="transition-opacity duration-300"
|
||||||
|
[class.opacity-0]="isCompact" />
|
||||||
|
<line
|
||||||
|
x1="11"
|
||||||
|
y1="12"
|
||||||
|
x2="19"
|
||||||
|
y2="12"
|
||||||
|
class="transition-opacity duration-300"
|
||||||
|
[class.opacity-0]="isCompact" />
|
||||||
|
<line
|
||||||
|
x1="11"
|
||||||
|
y1="16"
|
||||||
|
x2="19"
|
||||||
|
y2="16"
|
||||||
|
class="transition-opacity duration-300"
|
||||||
|
[class.opacity-0]="isCompact" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
@ -79,15 +132,116 @@
|
||||||
[routerLink]="item.route"
|
[routerLink]="item.route"
|
||||||
[class.active]="item.active"
|
[class.active]="item.active"
|
||||||
class="flex items-center w-full px-4 py-3 transition-colors duration-200 ease-in-out focus:outline-none hover:bg-base-300 hover:text-primary"
|
class="flex items-center w-full px-4 py-3 transition-colors duration-200 ease-in-out focus:outline-none hover:bg-base-300 hover:text-primary"
|
||||||
[class.bg-base-100]="item.active"
|
[ngClass]="{
|
||||||
[class.text-base-content]="item.active"
|
'bg-base-100': item.active,
|
||||||
[class.text-primary]="item.active"
|
'text-base-content': item.active,
|
||||||
[class.font-semibold]="item.active"
|
'text-primary': item.active,
|
||||||
|
'font-semibold': item.active,
|
||||||
|
'justify-center': isCompact,
|
||||||
|
'px-4': !isCompact
|
||||||
|
}"
|
||||||
role="menuitem"
|
role="menuitem"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
(click)="onLinkClick()">
|
(click)="onLinkClick()">
|
||||||
<span
|
<span
|
||||||
class="flex-shrink-0 w-6 h-6 mr-3"
|
class="flex-shrink-0 w-6 h-6"
|
||||||
|
[ngClass]="{ 'mr-3': !isCompact }"
|
||||||
|
[innerHTML]="item.icon"></span>
|
||||||
|
<span class="flex-grow" *ngIf="!isCompact">
|
||||||
|
{{ item.name }}
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</ng-container>
|
||||||
|
<ng-template #submenu>
|
||||||
|
<div
|
||||||
|
(click)="toggleSubmenu(item, $event)"
|
||||||
|
class="flex items-center w-full px-4 py-3 transition-colors duration-200 ease-in-out focus:outline-none hover:bg-base-300 hover:text-primary cursor-pointer"
|
||||||
|
[ngClass]="{
|
||||||
|
'bg-base-300': item.active,
|
||||||
|
'text-primary': item.active,
|
||||||
|
'font-semibold': item.active,
|
||||||
|
'bg-base-100': item.isOpen,
|
||||||
|
'text-base-content': item.isOpen,
|
||||||
|
'justify-center': isCompact,
|
||||||
|
'px-4': !isCompact
|
||||||
|
}">
|
||||||
|
<span
|
||||||
|
class="flex-shrink-0 w-6 h-6"
|
||||||
|
[ngClass]="{ 'mr-3': !isCompact }"
|
||||||
|
[innerHTML]="item.icon"></span>
|
||||||
|
<span class="flex-grow" *ngIf="!isCompact">
|
||||||
|
{{ item.name }}
|
||||||
|
</span>
|
||||||
|
<svg
|
||||||
|
*ngIf="!isCompact"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-width="1.5"
|
||||||
|
stroke="currentColor"
|
||||||
|
class="w-4 h-4 transition-transform"
|
||||||
|
[class.rotate-180]="item.isOpen">
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
d="M19.5 8.25l-7.5 7.5-7.5-7.5" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
[@submenuAnimation]="item.isOpen ? 'open' : 'closed'"
|
||||||
|
class="overflow-hidden">
|
||||||
|
<ul class="bg-base-100">
|
||||||
|
<li
|
||||||
|
*ngFor="let subItem of item.subitems"
|
||||||
|
class="w-full">
|
||||||
|
<a
|
||||||
|
[routerLink]="subItem.route"
|
||||||
|
[class.active]="subItem.active"
|
||||||
|
class="flex items-center w-full px-4 py-2 transition-colors duration-200 ease-in-out focus:outline-none hover:bg-base-300 hover:text-primary"
|
||||||
|
[ngClass]="{
|
||||||
|
'bg-base-300': subItem.active,
|
||||||
|
'text-primary': subItem.active,
|
||||||
|
'font-semibold': subItem.active,
|
||||||
|
'bg-base-100': item.isOpen,
|
||||||
|
'text-base-content': item.isOpen,
|
||||||
|
'justify-center': isCompact,
|
||||||
|
'px-4 pl-8': !isCompact
|
||||||
|
}"
|
||||||
|
role="menuitem"
|
||||||
|
tabindex="0"
|
||||||
|
(click)="onLinkClick()">
|
||||||
|
<span
|
||||||
|
class="flex-shrink-0 w-5 h-5"
|
||||||
|
[ngClass]="{ 'mr-2': !isCompact }"
|
||||||
|
[innerHTML]="subItem.icon"></span>
|
||||||
|
<span *ngIf="!isCompact">{{ subItem.name }}</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</ng-template>
|
||||||
|
</li>
|
||||||
|
</ng-container>
|
||||||
|
<!-- <ng-container *ngFor="let item of menuItems">
|
||||||
|
<li class="w-full">
|
||||||
|
<ng-container *ngIf="!item.subitems; else submenu">
|
||||||
|
<a
|
||||||
|
[routerLink]="item.route"
|
||||||
|
[class.active]="item.active"
|
||||||
|
class="flex items-center w-full px-4 py-3 transition-colors duration-200 ease-in-out focus:outline-none hover:bg-base-300 hover:text-primary"
|
||||||
|
[ngClass]="{
|
||||||
|
'bg-base-100': item.active,
|
||||||
|
'text-base-content': item.active,
|
||||||
|
'text-primary': item.active,
|
||||||
|
'font-semibold': item.active,
|
||||||
|
'flex justify-center': isCompact
|
||||||
|
}"
|
||||||
|
role="menuitem"
|
||||||
|
tabindex="0"
|
||||||
|
(click)="onLinkClick()">
|
||||||
|
<span
|
||||||
|
class="flex-shrink-0 w-6 h-6"
|
||||||
|
[ngClass]="{ 'mr-3': !isCompact }"
|
||||||
[innerHTML]="item.icon"></span>
|
[innerHTML]="item.icon"></span>
|
||||||
<span class="flex-grow" *ngIf="isDrawerOpen">
|
<span class="flex-grow" *ngIf="isDrawerOpen">
|
||||||
{{ item.name }}
|
{{ item.name }}
|
||||||
|
@ -99,13 +253,17 @@
|
||||||
<div
|
<div
|
||||||
(click)="toggleSubmenu(item, $event)"
|
(click)="toggleSubmenu(item, $event)"
|
||||||
class="flex items-center w-full px-4 py-3 transition-colors duration-200 ease-in-out focus:outline-none hover:bg-base-300 hover:text-primary cursor-pointer"
|
class="flex items-center w-full px-4 py-3 transition-colors duration-200 ease-in-out focus:outline-none hover:bg-base-300 hover:text-primary cursor-pointer"
|
||||||
[class.bg-base-300]="item.active"
|
[ngClass]="{
|
||||||
[class.text-primary]="item.active"
|
'bg-base-300': item.active,
|
||||||
[class.font-semibold]="item.active"
|
'text-primary': item.active,
|
||||||
[class.bg-base-100]="item.isOpen"
|
'font-semibold': item.active,
|
||||||
[class.text-base-content]="item.isOpen">
|
'bg-base-100': item.isOpen,
|
||||||
|
'text-base-content': item.isOpen,
|
||||||
|
'flex justify-center': isCompact
|
||||||
|
}">
|
||||||
<span
|
<span
|
||||||
class="flex-shrink-0 w-6 h-6 mr-3"
|
class="flex-shrink-0 w-6 h-6"
|
||||||
|
[ngClass]="{ 'mr-3': !isCompact }"
|
||||||
[innerHTML]="item.icon"></span>
|
[innerHTML]="item.icon"></span>
|
||||||
<span class="flex-grow" *ngIf="isDrawerOpen">
|
<span class="flex-grow" *ngIf="isDrawerOpen">
|
||||||
{{ item.name }}
|
{{ item.name }}
|
||||||
|
@ -135,16 +293,20 @@
|
||||||
[routerLink]="subItem.route"
|
[routerLink]="subItem.route"
|
||||||
[class.active]="subItem.active"
|
[class.active]="subItem.active"
|
||||||
class="flex items-center w-full px-4 pl-8 py-2 transition-colors duration-200 ease-in-out focus:outline-none hover:bg-base-300 hover:text-primary"
|
class="flex items-center w-full px-4 pl-8 py-2 transition-colors duration-200 ease-in-out focus:outline-none hover:bg-base-300 hover:text-primary"
|
||||||
[class.bg-base-300]="subItem.active"
|
[ngClass]="{
|
||||||
[class.text-primary]="subItem.active"
|
'bg-base-300': subItem.active,
|
||||||
[class.font-semibold]="subItem.active"
|
'text-primary': subItem.active,
|
||||||
[class.bg-base-100]="item.isOpen"
|
'font-semibold': subItem.active,
|
||||||
[class.text-base-content]="item.isOpen"
|
'bg-base-100': item.isOpen,
|
||||||
|
'text-base-content': item.isOpen,
|
||||||
|
'flex justify-center': isCompact
|
||||||
|
}"
|
||||||
role="menuitem"
|
role="menuitem"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
(click)="onLinkClick()">
|
(click)="onLinkClick()">
|
||||||
<span
|
<span
|
||||||
class="flex-shrink-0 w-5 h-5 mr-2"
|
class="flex-shrink-0 w-5 h-5"
|
||||||
|
[ngClass]="{ 'mr-2': !isCompact }"
|
||||||
[innerHTML]="subItem.icon"></span>
|
[innerHTML]="subItem.icon"></span>
|
||||||
{{ subItem.name }}
|
{{ subItem.name }}
|
||||||
</a>
|
</a>
|
||||||
|
@ -153,13 +315,13 @@
|
||||||
</div>
|
</div>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</li>
|
</li>
|
||||||
</ng-container>
|
</ng-container> -->
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<hr class="border-t border-base-100" />
|
<hr class="border-t border-base-100" />
|
||||||
|
|
||||||
<div style="background-color: rgba(0, 0, 0, 0.2)">
|
<div style="background-color: rgba(0, 0, 0, 0.25)">
|
||||||
<ul class="w-full px-2 py-4">
|
<ul class="w-full px-2 py-2">
|
||||||
<ng-container *ngFor="let item of bottomMenuItems">
|
<ng-container *ngFor="let item of bottomMenuItems">
|
||||||
<li>
|
<li>
|
||||||
<button
|
<button
|
||||||
|
|
|
@ -59,6 +59,26 @@ interface BottomMenuItem {
|
||||||
templateUrl: './layout.component.html',
|
templateUrl: './layout.component.html',
|
||||||
changeDetection: ChangeDetectionStrategy.Default,
|
changeDetection: ChangeDetectionStrategy.Default,
|
||||||
animations: [
|
animations: [
|
||||||
|
trigger('compactAnimation', [
|
||||||
|
state(
|
||||||
|
'normal',
|
||||||
|
style({
|
||||||
|
transform: 'scaleX(1)',
|
||||||
|
})
|
||||||
|
),
|
||||||
|
state(
|
||||||
|
'compact',
|
||||||
|
style({
|
||||||
|
transform: 'scaleX(1)',
|
||||||
|
})
|
||||||
|
),
|
||||||
|
transition('normal <=> compact', [animate('300ms ease-in-out')]),
|
||||||
|
]),
|
||||||
|
trigger('burgerAnimation', [
|
||||||
|
state('closed', style({ transform: 'rotate(0deg)' })),
|
||||||
|
state('open', style({ transform: 'rotate(180deg)' })),
|
||||||
|
transition('closed <=> open', [animate('0.3s ease-in-out')]),
|
||||||
|
]),
|
||||||
trigger('submenuAnimation', [
|
trigger('submenuAnimation', [
|
||||||
state(
|
state(
|
||||||
'closed',
|
'closed',
|
||||||
|
@ -95,7 +115,7 @@ interface BottomMenuItem {
|
||||||
width: '0',
|
width: '0',
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
transition('closed <=> open', [animate('300ms ease-in-out')]),
|
transition('closed <=> open', [animate('200ms ease-in-out')]),
|
||||||
transition('open <=> compact', [animate('200ms ease-in-out')]),
|
transition('open <=> compact', [animate('200ms ease-in-out')]),
|
||||||
transition('compact <=> closed', [animate('200ms ease-in-out')]),
|
transition('compact <=> closed', [animate('200ms ease-in-out')]),
|
||||||
]),
|
]),
|
||||||
|
@ -234,6 +254,7 @@ export class LayoutComponent implements OnInit, OnDestroy {
|
||||||
public onLinkClick(): void {
|
public onLinkClick(): void {
|
||||||
if (window.innerWidth < 1024 && this.isDrawerOpen) {
|
if (window.innerWidth < 1024 && this.isDrawerOpen) {
|
||||||
this.isDrawerOpen = false;
|
this.isDrawerOpen = false;
|
||||||
|
this.isCompact = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue