/** * Admin: Nur Gruppen in der Shell-Navigation; konkrete Seiten wählt man auf der Hub-Seite (/admin/g/:id). * @typedef {{ to: string, label: string, description?: string }} AdminGroupItem * @typedef {{ id: string, label: string, description: string, items: AdminGroupItem[] }} AdminGroup */ /** @type {AdminGroup[]} */ export const ADMIN_GROUPS = [ { id: 'users', label: 'Benutzerverwaltung', description: 'Profile anlegen, Rollen setzen und Recovery-E-Mails pflegen.', items: [ { to: '/admin/users', label: 'Profile & Rollen', description: 'Neue Profile, Admin-Rolle, PIN und E-Mail pro Nutzer.', }, ], }, { id: 'features', label: 'Features', description: 'Feature-Registry, Kontingente und individuelle Overrides.', items: [ { to: '/admin/features', label: 'Feature-Registry', description: 'Features definieren und Kategorien zuordnen.', }, { to: '/admin/tier-limits', label: 'Tier-Limits', description: 'Limit-Matrix pro Tier bearbeiten.', }, { to: '/admin/user-restrictions', label: 'User-Overrides', description: 'Individuelle Feature-Limits setzen.', }, { to: '/admin/widget-features', label: 'Widgets × Features', description: 'Dashboard-Widgets den Registry-Features zuordnen (AND).', }, ], }, { id: 'subscription', label: 'Subscription', description: 'Tiers und Gutscheine für das Freemium-System.', items: [ { to: '/admin/tiers', label: 'Tiers', description: 'Abo-Stufen und Zuordnung.' }, { to: '/admin/coupons', label: 'Coupons', description: 'Gutscheincodes verwalten.' }, ], }, { id: 'training', label: 'Trainingstypen', description: 'Trainingstypen, Mappings und Trainings-Profile.', items: [ { to: '/admin/training-types', label: 'Trainingstypen', description: 'Kategorien und Typen verwalten.', }, { to: '/admin/activity-mappings', label: 'Activity-Mappings', description: 'Lernendes Zuordnungssystem (Sprache / Apple Health).', }, { to: '/admin/training-profiles', label: 'Trainings-Profile', description: 'Training-Type-Profile (#15).', }, { to: '/admin/activity-attribute-profiles', label: 'Session-Metriken (EAV)', description: 'Messgrößen-Katalog und Zuordnung zu Kategorie / Trainingstyp.', }, ], }, { id: 'goals', label: 'Ziele & Fokus', description: 'Ziel-Typen und Focus Areas.', items: [ { to: '/admin/goal-types', label: 'Ziel-Typen', description: 'Custom Goal Types mit oder ohne Datenquelle.', }, { to: '/admin/focus-areas', label: 'Focus Areas', description: 'Dynamische Fokusbereiche und Kategorien.', }, { to: '/admin/reference-value-types', label: 'Referenz-Kennwerte', description: 'Typen für persönliche Referenzwerte (Schlüssel, Namen, Metadaten).', }, ], }, { id: 'prompts', label: 'KI-Prompts', description: 'Pipeline- und Basis-Prompts für die KI-Analyse.', items: [ { to: '/admin/prompts', label: 'KI-Prompts verwalten', description: 'Prompts bearbeiten, Stages, Test & Export.', }, ], }, { id: 'system', label: 'Basiseinstellungen', description: 'System-E-Mail und Platzhalter-Metadaten.', items: [ { to: '/admin/system', label: 'SMTP & Metadaten-Export', description: 'SMTP-Status, Test-Mail und Placeholder-Katalog (JSON/ZIP).', }, { to: '/admin/dashboard-product-default', label: 'Produkt-Dashboard (Standard)', description: 'Globales Standard-Layout der Startseite (DB oder Code-Fallback).', }, { to: '/admin/csv-templates', label: 'CSV-Import-Vorlagen', description: 'System-Vorlagen per CSV-Analyse anlernen, Spalten zuordnen, pflegen.', }, ], }, ] export function adminGroupHubPath(groupId) { return `/admin/g/${groupId}` } /** * Shell-Navigation: Übersicht + eine Zeile/Spalte pro Gruppe (ohne Einzelseiten). * @typedef {{ id: string, label: string, to: string, end?: boolean }} AdminShellNavEntry * @returns {AdminShellNavEntry[]} */ export function getAdminShellNavEntries() { return [ { id: 'overview', label: 'Übersicht', to: '/admin', end: true }, ...ADMIN_GROUPS.map((g) => ({ id: g.id, label: g.label, to: adminGroupHubPath(g.id), end: false, })), ] } /** Aktiver Shell-Eintrag inkl. Leaf-Routen der Gruppe (z. B. /admin/features → Gruppe „Features“). */ export function adminShellEntryIsActive(pathname, entry) { if (entry.id === 'overview') { return pathname === '/admin' } const group = ADMIN_GROUPS.find((x) => x.id === entry.id) if (!group) return false if (pathname === adminGroupHubPath(group.id)) return true return group.items.some((it) => pathname === it.to) } /** Anzahl Unterseiten für Chip-Badge (wie KI-Analyse). */ export function adminShellEntryItemCount(entry) { if (entry.id === 'overview') return 0 const g = ADMIN_GROUPS.find((x) => x.id === entry.id) return g ? g.items.length : 0 }