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,15 @@
|
||||
import type { Metadata } from "next";
|
||||
import { Platzhalterseite } from "@/components/huelle/Platzhalterseite";
|
||||
|
||||
export const metadata: Metadata = { title: "Einstellungen" };
|
||||
|
||||
export default function Einstellungen() {
|
||||
return (
|
||||
<Platzhalterseite
|
||||
titel="Einstellungen"
|
||||
untertitel="Deployment-Key, eigene Vorlagen, Benachrichtigungen"
|
||||
phase={3}
|
||||
issue="#019"
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import type { Metadata } from "next";
|
||||
import { Platzhalterseite } from "@/components/huelle/Platzhalterseite";
|
||||
|
||||
export const metadata: Metadata = { title: "Hostgruppen" };
|
||||
|
||||
export default function Hostgruppen() {
|
||||
return (
|
||||
<Platzhalterseite
|
||||
titel="Hostgruppen"
|
||||
untertitel="Hosts bündeln, um Schlüssel gemeinsam zuzuweisen"
|
||||
phase={1}
|
||||
issue="#008"
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import type { Metadata } from "next";
|
||||
import { Platzhalterseite } from "@/components/huelle/Platzhalterseite";
|
||||
|
||||
export const metadata: Metadata = { title: "Hosts" };
|
||||
|
||||
export default function Hosts() {
|
||||
return (
|
||||
<Platzhalterseite
|
||||
titel="Hosts"
|
||||
untertitel="Verwaltete Server, Host-Keys und Erreichbarkeit"
|
||||
phase={1}
|
||||
issue="#008"
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import type { HuellenBenutzer } from "@/components/huelle/typen";
|
||||
|
||||
/**
|
||||
* Liefert den Benutzer, den die Seitenleiste anzeigt.
|
||||
*
|
||||
* TODO (#004): durch die echte Sitzung ersetzen (Benutzer + Rolle aus der Datenbank,
|
||||
* Herkunft „authentik“ oder „Notfall-Admin“) und ohne Sitzung zur Anmeldung umleiten.
|
||||
* Bis dahin ein fester Beispielbenutzer, damit der Prototyp ohne Anmeldung läuft.
|
||||
* async schon jetzt, damit sich die Aufrufer beim Umstieg nicht ändern müssen.
|
||||
*/
|
||||
export async function huellenBenutzerErmitteln(): Promise<HuellenBenutzer> {
|
||||
return { name: "Florian Wilde", rolle: "ADMIN", herkunft: "authentik" };
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import type { ReactNode } from "react";
|
||||
import { Huelle } from "@/components/huelle/Huelle";
|
||||
import { huellenBenutzerErmitteln } from "./huellen-benutzer";
|
||||
|
||||
/** Alle angemeldeten Seiten teilen sich die Hülle mit Seitenleiste (#002). */
|
||||
export default async function AppLayout({ children }: { children: ReactNode }) {
|
||||
const benutzer = await huellenBenutzerErmitteln();
|
||||
return <Huelle benutzer={benutzer}>{children}</Huelle>;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import type { Metadata } from "next";
|
||||
import { Platzhalterseite } from "@/components/huelle/Platzhalterseite";
|
||||
|
||||
export const metadata: Metadata = { title: "Personen" };
|
||||
|
||||
export default function Personen() {
|
||||
return (
|
||||
<Platzhalterseite titel="Personen" untertitel="Wem welche Schlüssel gehören" phase={2} issue="#013" />
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import type { Metadata } from "next";
|
||||
import { Platzhalterseite } from "@/components/huelle/Platzhalterseite";
|
||||
|
||||
export const metadata: Metadata = { title: "Audit-Log" };
|
||||
|
||||
export default function Protokoll() {
|
||||
return (
|
||||
<Platzhalterseite
|
||||
titel="Audit-Log"
|
||||
untertitel="Lückenloses, verkettetes Protokoll aller Aktionen"
|
||||
phase={5}
|
||||
issue="#027"
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import type { Metadata } from "next";
|
||||
import Link from "next/link";
|
||||
import { Platzhalterseite } from "@/components/huelle/Platzhalterseite";
|
||||
|
||||
export const metadata: Metadata = { title: "Schlüssel" };
|
||||
|
||||
export default function Schluessel() {
|
||||
return (
|
||||
<div className="flex flex-col gap-5">
|
||||
<Platzhalterseite
|
||||
titel="Schlüssel"
|
||||
untertitel="SSH-Schlüssel erzeugen, importieren und ausrollen"
|
||||
phase={2}
|
||||
issue="#012"
|
||||
/>
|
||||
<p className="text-muted text-[14px]">
|
||||
Prototyp ansehen:{" "}
|
||||
<Link href="/schluessel/beispiel" className="text-accent font-medium hover:underline">
|
||||
Schlüsseldetail mit Beispieldaten
|
||||
</Link>
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import type { Metadata } from "next";
|
||||
import { Platzhalterseite } from "@/components/huelle/Platzhalterseite";
|
||||
|
||||
export const metadata: Metadata = { title: "Vorlagen" };
|
||||
|
||||
export default function Vorlagen() {
|
||||
return (
|
||||
<Platzhalterseite
|
||||
titel="Vorlagen"
|
||||
untertitel="Wiederkehrende Zugänge wie Deployment oder Backup"
|
||||
phase={3}
|
||||
issue="#019"
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import type { Metadata } from "next";
|
||||
import { Platzhalterseite } from "@/components/huelle/Platzhalterseite";
|
||||
|
||||
export const metadata: Metadata = { title: "Zuweisungen" };
|
||||
|
||||
export default function Zuweisungen() {
|
||||
return (
|
||||
<Platzhalterseite
|
||||
titel="Zuweisungen"
|
||||
untertitel="Welcher Schlüssel auf welchem Host-Konto gilt"
|
||||
phase={2}
|
||||
issue="#016"
|
||||
/>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user