feat(ui): Huelle mit Seitenleiste und Platzhalterseiten (#002)
Die Huelle bekommt Benutzer und optional den aktiven Pfad als Props und kennt weder Sitzung noch Datenbank; ohne Pfad ermittelt die Navigation ihn per usePathname(), weil ein Layout den Pfad nicht kennt. Die Benutzerermittlung steckt in huellenBenutzerErmitteln(), damit #004 nur diese Funktion ersetzen muss. Unter 1024 px klappt die Leiste ein; geschlossen ist sie invisible und damit auch nicht per Tab erreichbar. Alle Navigationsziele haben eine Platzhalterseite, damit nichts auf eine 404 fuehrt. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
"use client";
|
||||
|
||||
import { clsx } from "clsx";
|
||||
import Link from "next/link";
|
||||
import { usePathname } from "next/navigation";
|
||||
import { HAUPTNAVIGATION, istAktiv, NEBENNAVIGATION, type NavPunkt } from "./nav-punkte";
|
||||
|
||||
/**
|
||||
* Navigation der Seitenleiste. Client-Komponente, weil ein Layout den aktuellen Pfad
|
||||
* nicht kennt: Ohne `aktiverPfad` nimmt sie ihn aus usePathname(); Seiten oder Tests
|
||||
* können ihn ausdrücklich vorgeben.
|
||||
*/
|
||||
export function Navigation({ aktiverPfad }: { aktiverPfad?: string }) {
|
||||
const routerPfad = usePathname();
|
||||
const pfad = aktiverPfad ?? routerPfad ?? "/";
|
||||
return (
|
||||
<nav aria-label="Hauptnavigation" className="flex flex-col gap-1">
|
||||
<NavListe punkte={HAUPTNAVIGATION} pfad={pfad} />
|
||||
<hr className="border-border mx-2 my-3" />
|
||||
<NavListe punkte={NEBENNAVIGATION} pfad={pfad} />
|
||||
</nav>
|
||||
);
|
||||
}
|
||||
|
||||
function NavListe({ punkte, pfad }: { punkte: NavPunkt[]; pfad: string }) {
|
||||
return (
|
||||
<ul className="flex flex-col gap-1">
|
||||
{punkte.map(({ href, titel, icon: Icon }) => {
|
||||
const aktiv = istAktiv(href, pfad);
|
||||
return (
|
||||
<li key={href}>
|
||||
<Link
|
||||
href={href}
|
||||
aria-current={aktiv ? "page" : undefined}
|
||||
className={clsx(
|
||||
"rounded-box flex min-h-11 items-center gap-3 px-3 text-[14.5px] transition-colors",
|
||||
aktiv
|
||||
? "bg-raised text-accent font-semibold"
|
||||
: "text-muted hover:bg-raised/60 hover:text-text font-medium",
|
||||
)}
|
||||
>
|
||||
<Icon aria-hidden className="size-[18px] shrink-0" strokeWidth={aktiv ? 2.2 : 1.8} />
|
||||
{titel}
|
||||
</Link>
|
||||
</li>
|
||||
);
|
||||
})}
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user