style(web): dunkle App-Leiste und Fluent-Seitenleiste
Kopfzeile 48 px dunkel mit Seitentitel statt immer Startseite, Dashboard-Reiter mit Akzent-Unterstrich; Seitenleiste mit Auswahlpille, Modul-Kacheln, aufgeklappten Kategorien und gefuelltem Suchfeld; eingeklappt nur Kacheln. Einheitlicher PageHeader. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
import { create } from 'zustand';
|
||||
|
||||
export interface NavModule {
|
||||
id: string;
|
||||
slug: string;
|
||||
name: string;
|
||||
category: string;
|
||||
}
|
||||
|
||||
interface NavState {
|
||||
/** Freigegebene Module, wie die Seitenleiste sie geladen hat. */
|
||||
modules: NavModule[];
|
||||
setModules: (modules: NavModule[]) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Geteilter Stand der Seitenleiste: die Kopfzeile liest daraus den
|
||||
* Modulnamen fuer den Seitentitel, ohne selbst noch einmal zu laden.
|
||||
*/
|
||||
export const useNavStore = create<NavState>()((set) => ({
|
||||
modules: [],
|
||||
setModules: (modules) => set({ modules }),
|
||||
}));
|
||||
|
||||
/** Ersatztitel, solange die Seitenleiste die Module noch nicht geladen hat. */
|
||||
const MODULE_TITLE_KEYS: Record<string, string> = {
|
||||
proxmox: 'proxmox.title',
|
||||
domaincheck: 'domaincheck.title',
|
||||
'cert-manager': 'certManager.title',
|
||||
'dkv-fleet': 'dkvFleet.pageTitle',
|
||||
'tender-radar': 'tenderRadar.page.title',
|
||||
};
|
||||
|
||||
/**
|
||||
* Seitentitel der Kopfzeile zu einem Pfad. `null` auf der Startseite (dort
|
||||
* stehen die Dashboard-Reiter), sonst ein Uebersetzungsschluessel oder ein
|
||||
* fertiger Modulname.
|
||||
*/
|
||||
export function resolvePageTitle(
|
||||
pathname: string,
|
||||
modules: NavModule[],
|
||||
): { key: string } | { text: string } | null {
|
||||
if (pathname === '/') return null;
|
||||
if (pathname.startsWith('/marketplace')) return { key: 'sidebar.marketplace' };
|
||||
if (pathname.startsWith('/settings')) return { key: 'sidebar.settings' };
|
||||
if (pathname.startsWith('/changelog')) return { key: 'sidebar.whatsNew' };
|
||||
if (pathname.startsWith('/admin')) return { key: 'sidebar.admin' };
|
||||
if (pathname.startsWith('/change-password')) return { key: 'auth.changePassword.title' };
|
||||
if (pathname.startsWith('/modules/')) {
|
||||
const segments = pathname.split('/').filter(Boolean).slice(1);
|
||||
for (const segment of segments) {
|
||||
const mod = modules.find((m) => m.slug === segment);
|
||||
if (mod) return { text: mod.name };
|
||||
}
|
||||
for (const segment of segments) {
|
||||
const key = MODULE_TITLE_KEYS[segment];
|
||||
if (key) return { key };
|
||||
}
|
||||
return { text: '' };
|
||||
}
|
||||
return { key: 'header.breadcrumb.home' };
|
||||
}
|
||||
Reference in New Issue
Block a user