Baustein 1: Grundgeruest, Datenbank, Anmeldung, zwei Rollen
Legt das Fundament der Lern-Bar an: - Next.js 15 (App Router), React 19, TypeScript, ESLint, Vitest - SQLite ueber Drizzle hinter einer Repository-Schicht - Eigener Migrationslauf mit Pruefsummen, beim Start angewendet - Argon2id, serverseitige Sitzungen, HttpOnly-Cookie, SameSite=Lax - Rollen Ausbilder und Azubi, Rechteregeln als reine Funktionen - Verwaltung: Azubikonto und Ausbildung anlegen, Passwort, Sperren - Gestaltung Petrol/Bernstein, helle und dunkle Darstellung - Dockerfile, docker-compose, Lebenszeichen, update.sh mit Rueckfall - Sicherung und Wiederherstellung als Shell-Skripte - 29 Tests fuer Rechte, Zeitrechnung und Migrationslauf Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
'use client';
|
||||
|
||||
import Link from 'next/link';
|
||||
import { usePathname } from 'next/navigation';
|
||||
import { ThemaUmschalter } from './ThemaUmschalter';
|
||||
|
||||
export type Navigationseintrag = { pfad: string; titel: string };
|
||||
|
||||
export function Kopfzeile({
|
||||
eintraege,
|
||||
name,
|
||||
rolle,
|
||||
abmeldeAktion,
|
||||
}: {
|
||||
eintraege: Navigationseintrag[];
|
||||
name: string;
|
||||
rolle: string;
|
||||
abmeldeAktion: () => Promise<void>;
|
||||
}) {
|
||||
const pfad = usePathname();
|
||||
|
||||
function istAktiv(ziel: string): boolean {
|
||||
if (ziel === '/') return pfad === '/';
|
||||
return pfad === ziel || pfad.startsWith(`${ziel}/`);
|
||||
}
|
||||
|
||||
return (
|
||||
<header className="kopf">
|
||||
<div className="kopf-innen">
|
||||
<Link href="/" className="marke">
|
||||
Lern<span className="marke-akzent">-Bar</span>
|
||||
</Link>
|
||||
|
||||
<nav className="hauptnavigation" aria-label="Hauptbereiche">
|
||||
{eintraege.map((e) => (
|
||||
<Link key={e.pfad} href={e.pfad} aria-current={istAktiv(e.pfad) ? 'page' : undefined}>
|
||||
{e.titel}
|
||||
</Link>
|
||||
))}
|
||||
</nav>
|
||||
|
||||
<div className="kopf-rechts">
|
||||
<span className="leise" style={{ color: '#cfe2e9', fontSize: '0.85rem' }}>
|
||||
{name} · {rolle}
|
||||
</span>
|
||||
<ThemaUmschalter />
|
||||
<form action={abmeldeAktion}>
|
||||
<button type="submit" className="kopf-knopf">
|
||||
Abmelden
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user