Landingpages als eigene Gattung, erster Typ: Mehrere Links
Die sechs noch offenen Typen haben kein fremdes Ziel, auf das man weiterleiten koennte — sie brauchen eine Seite. Dafuer bekommt der Typ-Vertrag `hasLandingPage`: /r/[slug] schickt solche Codes auf /s/[slug], statt `redirectTarget` zu befragen. Die oeffentlichen Seiten duerfen die Navigation der Anwendung nicht zeigen — wer einen Code scannt, hat mit „Verwaltung" nichts zu tun. Deshalb liegt das App-Chrome jetzt in der Routengruppe (app); das Wurzel-Layout traegt nur noch html und body. Die URLs aendern sich dadurch nicht.
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
import type { Metadata } from "next";
|
||||
import { redirect } from "next/navigation";
|
||||
|
||||
import { LoginForm, SetupForm } from "@/components/auth-forms";
|
||||
import { Icon } from "@/components/icons";
|
||||
import { Notice } from "@/components/ui";
|
||||
import { getActor, isAuthEnabled, isSetupOpen } from "@/lib/auth/actor";
|
||||
import { MIN_PASSWORD_LENGTH } from "@/lib/auth/password";
|
||||
|
||||
export const metadata: Metadata = { title: "Anmelden" };
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
export default async function SignInPage() {
|
||||
// Ohne Anmeldung gibt es hier nichts zu tun.
|
||||
if (!isAuthEnabled()) redirect("/");
|
||||
|
||||
const actor = await getActor();
|
||||
if (actor.kind === "user") redirect("/");
|
||||
|
||||
const setup = await isSetupOpen();
|
||||
|
||||
return (
|
||||
<div className="mx-auto flex max-w-md flex-col gap-6 px-4 py-14 sm:px-6">
|
||||
<div className="text-center">
|
||||
<span className="mx-auto flex size-12 items-center justify-center rounded-xl bg-indigo-600 text-white">
|
||||
<Icon name={setup ? "lock" : "qr"} className="size-6" />
|
||||
</span>
|
||||
<h1 className="mt-4 text-2xl font-bold tracking-tight text-slate-900">
|
||||
{setup ? "Ersteinrichtung" : "Anmelden"}
|
||||
</h1>
|
||||
<p className="mt-2 text-sm text-slate-600">
|
||||
{setup
|
||||
? "Es gibt noch keinen Benutzer. Lege jetzt den ersten Administrator an — danach ist diese Seite geschlossen."
|
||||
: "Bitte melde dich an, um QR-Codes zu erstellen und zu verwalten."}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{setup ? <SetupForm minLength={MIN_PASSWORD_LENGTH} /> : <LoginForm />}
|
||||
|
||||
{setup ? (
|
||||
<Notice tone="info">
|
||||
Der erste Benutzer wird Administrator der Installation und darf
|
||||
Gruppen, Benutzer und die QR-Typen verwalten.
|
||||
</Notice>
|
||||
) : (
|
||||
<p className="text-center text-sm text-slate-500">
|
||||
Passwort vergessen? Ein Administrator kann es unter Verwaltung →
|
||||
Benutzer zurücksetzen.
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user