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,66 @@
|
||||
import type { ReactNode } from "react";
|
||||
|
||||
/**
|
||||
* Rahmen aller öffentlichen Landingpages.
|
||||
*
|
||||
* Diese Seiten sehen Leute, die einen Code gescannt haben — meist auf dem
|
||||
* Handy, oft unterwegs, ohne Bezug zu dieser Anwendung. Deshalb: eine Spalte,
|
||||
* große Schrift, keine Navigation, kein Hinweis auf die Verwaltung.
|
||||
*/
|
||||
export function LandingShell({
|
||||
title,
|
||||
subtitle,
|
||||
children,
|
||||
footer,
|
||||
}: {
|
||||
title: string;
|
||||
subtitle?: string | null;
|
||||
children: ReactNode;
|
||||
footer?: ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<div className="flex min-h-full flex-col bg-slate-50">
|
||||
<main className="mx-auto w-full max-w-lg flex-1 px-4 py-10 sm:px-6 sm:py-14">
|
||||
<header className="mb-7 text-center">
|
||||
<h1 className="text-2xl font-bold tracking-tight text-balance text-slate-900 sm:text-3xl">
|
||||
{title}
|
||||
</h1>
|
||||
{subtitle ? (
|
||||
<p className="mt-2.5 text-pretty text-slate-600">{subtitle}</p>
|
||||
) : null}
|
||||
</header>
|
||||
{children}
|
||||
</main>
|
||||
{footer ? (
|
||||
<footer className="px-4 pb-8 text-center text-xs text-slate-400">
|
||||
{footer}
|
||||
</footer>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ein Fehlerbild im selben Gewand — etwa wenn ein Code gelöscht wurde.
|
||||
* Bewusst ohne Schuldzuweisung: wer hier landet, kann nichts dafür.
|
||||
*/
|
||||
export function LandingNotice({
|
||||
title,
|
||||
children,
|
||||
}: {
|
||||
title: string;
|
||||
children: ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<div className="grid min-h-full place-items-center bg-slate-50 px-4 py-16">
|
||||
<div className="max-w-md text-center">
|
||||
<h1 className="text-xl font-bold text-slate-900 sm:text-2xl">
|
||||
{title}
|
||||
</h1>
|
||||
<p className="mt-3 leading-relaxed text-pretty text-slate-600">
|
||||
{children}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user