feat(frontend): group dashboard sidebar navigation into sections
Add section-based grouping to the sidebar navigation with headers and dividers. Menu items are now organized into 4 sections: - Allgemein (Übersicht, Zählpunkte, Mein Profil) - Community (Community beitreten, Meine Mitgliedschaften, Verbrauch) - Tarife & Einladungen (Meine Tarife, Einladungen) - Verwaltung (Admin-only: Mitgliedschaften, Benutzerverwaltung, etc.) Only sections with visible items for the current role are rendered. All 107 frontend tests passing.
This commit is contained in:
parent
fb53b169a2
commit
b1f38e752b
@ -21,15 +21,25 @@
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<nav class="flex-1 px-4 py-6 space-y-1 overflow-y-auto">
|
||||
@for (item of visibleNavItems(); track item.path) {
|
||||
<a [routerLink]="item.path"
|
||||
routerLinkActive="bg-emerald-50 text-emerald-700 font-medium"
|
||||
[routerLinkActiveOptions]="{exact: item.path === '/dashboard'}"
|
||||
(click)="closeMobileMenu()"
|
||||
class="block px-4 py-2.5 rounded-lg text-slate-600 hover:bg-slate-50 hover:text-slate-900 transition-colors">
|
||||
{{ item.label }}
|
||||
</a>
|
||||
<nav class="flex-1 px-4 py-6 space-y-4 overflow-y-auto">
|
||||
@for (group of navSections(); track group.section; let last = $last) {
|
||||
<div>
|
||||
<p class="px-4 mb-1 text-xs font-semibold uppercase tracking-wider text-slate-400">
|
||||
{{ group.section }}
|
||||
</p>
|
||||
@for (item of group.items; track item.path) {
|
||||
<a [routerLink]="item.path"
|
||||
routerLinkActive="bg-emerald-50 text-emerald-700 font-medium"
|
||||
[routerLinkActiveOptions]="{exact: item.path === '/dashboard'}"
|
||||
(click)="closeMobileMenu()"
|
||||
class="block px-4 py-2 rounded-lg text-slate-600 hover:bg-slate-50 hover:text-slate-900 transition-colors">
|
||||
{{ item.label }}
|
||||
</a>
|
||||
}
|
||||
</div>
|
||||
@if (!last) {
|
||||
<div class="border-t border-slate-100 mx-4"></div>
|
||||
}
|
||||
}
|
||||
</nav>
|
||||
</aside>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import {Component, computed, inject, signal} from '@angular/core';
|
||||
import {Router, RouterLink, RouterLinkActive, RouterOutlet} from '@angular/router';
|
||||
import {AuthService} from '../../services/auth';
|
||||
import {NAV_ITEMS} from './dashboard-nav-items';
|
||||
import {NAV_ITEMS, NAV_SECTIONS, NavItem} from './dashboard-nav-items';
|
||||
import {NotificationComponent} from '../../components/notification/notification';
|
||||
|
||||
@Component({
|
||||
@ -17,9 +17,17 @@ export class DashboardLayout {
|
||||
|
||||
isMobileMenuOpen = signal(false);
|
||||
|
||||
visibleNavItems = computed(() => {
|
||||
navSections = computed(() => {
|
||||
const role = this.authService.currentUserRole();
|
||||
return NAV_ITEMS.filter(item => role !== null && item.roles.includes(role));
|
||||
if (role === null) return [];
|
||||
|
||||
const visible = NAV_ITEMS.filter(item => item.roles.includes(role));
|
||||
return NAV_SECTIONS
|
||||
.map(section => ({
|
||||
section,
|
||||
items: visible.filter(item => item.section === section)
|
||||
}))
|
||||
.filter(group => group.items.length > 0);
|
||||
});
|
||||
|
||||
toggleMobileMenu() {
|
||||
|
||||
@ -2,21 +2,31 @@ export interface NavItem {
|
||||
label: string;
|
||||
path: string;
|
||||
roles: string[];
|
||||
section: string;
|
||||
}
|
||||
|
||||
export const NAV_SECTIONS = ['Allgemein', 'Community', 'Tarife & Einladungen', 'Verwaltung'] as const;
|
||||
|
||||
export const NAV_ITEMS: NavItem[] = [
|
||||
{label: 'Übersicht', path: '/dashboard', roles: ['ADMIN', 'MEMBER']},
|
||||
{label: 'Zählpunkte', path: '/dashboard/metering-points', roles: ['ADMIN', 'MEMBER']},
|
||||
{label: 'Community beitreten', path: '/dashboard/join-community', roles: ['MEMBER']},
|
||||
{label: 'Meine Mitgliedschaften', path: '/dashboard/my-memberships', roles: ['MEMBER']},
|
||||
{label: 'Verbrauch', path: '/dashboard/consumption', roles: ['MEMBER']},
|
||||
{label: 'Mitgliedschaften', path: '/dashboard/admin-memberships', roles: ['ADMIN']},
|
||||
{label: 'Mein Profil', path: '/dashboard/profile', roles: ['ADMIN', 'MEMBER']},
|
||||
{label: 'Benutzerverwaltung', path: '/dashboard/approvals', roles: ['ADMIN']},
|
||||
{label: 'Energiegemeinschaften', path: '/dashboard/energy-communities', roles: ['ADMIN']},
|
||||
{label: 'Tarife verwalten', path: '/dashboard/tariffs', roles: ['ADMIN']},
|
||||
{label: 'Messdaten-Upload', path: '/dashboard/upload-metering-data', roles: ['ADMIN']},
|
||||
{label: 'Meine Tarife', path: '/dashboard/my-tariffs', roles: ['MEMBER']},
|
||||
{label: 'Meine Einladungen', path: '/dashboard/producer-invites', roles: ['MEMBER']},
|
||||
{label: 'Offene Einladungen', path: '/dashboard/consumer-invites', roles: ['MEMBER']}
|
||||
// Allgemein
|
||||
{label: 'Übersicht', path: '/dashboard', roles: ['ADMIN', 'MEMBER'], section: 'Allgemein'},
|
||||
{label: 'Zählpunkte', path: '/dashboard/metering-points', roles: ['ADMIN', 'MEMBER'], section: 'Allgemein'},
|
||||
{label: 'Mein Profil', path: '/dashboard/profile', roles: ['ADMIN', 'MEMBER'], section: 'Allgemein'},
|
||||
|
||||
// Community
|
||||
{label: 'Community beitreten', path: '/dashboard/join-community', roles: ['MEMBER'], section: 'Community'},
|
||||
{label: 'Meine Mitgliedschaften', path: '/dashboard/my-memberships', roles: ['MEMBER'], section: 'Community'},
|
||||
{label: 'Verbrauch', path: '/dashboard/consumption', roles: ['MEMBER'], section: 'Community'},
|
||||
|
||||
// Tarife & Einladungen
|
||||
{label: 'Meine Tarife', path: '/dashboard/my-tariffs', roles: ['MEMBER'], section: 'Tarife & Einladungen'},
|
||||
{label: 'Meine Einladungen', path: '/dashboard/producer-invites', roles: ['MEMBER'], section: 'Tarife & Einladungen'},
|
||||
{label: 'Offene Einladungen', path: '/dashboard/consumer-invites', roles: ['MEMBER'], section: 'Tarife & Einladungen'},
|
||||
|
||||
// Verwaltung
|
||||
{label: 'Mitgliedschaften', path: '/dashboard/admin-memberships', roles: ['ADMIN'], section: 'Verwaltung'},
|
||||
{label: 'Benutzerverwaltung', path: '/dashboard/approvals', roles: ['ADMIN'], section: 'Verwaltung'},
|
||||
{label: 'Energiegemeinschaften', path: '/dashboard/energy-communities', roles: ['ADMIN'], section: 'Verwaltung'},
|
||||
{label: 'Tarife verwalten', path: '/dashboard/tariffs', roles: ['ADMIN'], section: 'Verwaltung'},
|
||||
{label: 'Messdaten-Upload', path: '/dashboard/upload-metering-data', roles: ['ADMIN'], section: 'Verwaltung'},
|
||||
];
|
||||
|
||||
Loading…
Reference in New Issue
Block a user