Persist values, tighten validation, and a11y on /onboarding

- Server action echoes kitaName, the three module booleans, and the
  Mindest-Verfügbarkeiten value on every error path so failed submits no
  longer wipe what the user typed; OnboardingState gains an `attempt`
  counter that drives a per-field remount key on the client.
- Schema now rejects min=0 when the Notdienst module is active (via
  superRefine) — previously a kita could be created with 0 minimum days,
  which is fachlich sinnlos. When the module is off, 0 stays valid.
- Validation error messages reworded from terse fragments ("Nicht
  negativ.", "Bitte ganze Zahl.") to full sentences.
- Field error <p> elements gain role="alert" + aria-live="polite" so
  screen readers announce them on submit.
- CardTitle now accepts as="h1" and the onboarding page uses it for
  "Willkommen, …" — the page now has a real top-level heading.
- ModuleCheckbox uses aria-labelledby + aria-describedby so the
  accessible name is just the module title; the longer description is
  exposed as secondary info instead of being concatenated into the AN.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
t.indorf
2026-05-17 20:46:31 +02:00
parent 380c67963b
commit af2c3b245a
4 changed files with 156 additions and 44 deletions
+3 -1
View File
@@ -30,7 +30,9 @@ export default async function OnboardingPage() {
<div className="flex min-h-screen items-center justify-center bg-muted/30 px-4 py-12">
<Card className="w-full max-w-2xl">
<CardHeader className="space-y-2">
<CardTitle>Willkommen, {session.user.name?.split(" ")[0] ?? "Gründer:in"}!</CardTitle>
<CardTitle as="h1">
Willkommen, {session.user.name?.split(" ")[0] ?? "Gründer:in"}!
</CardTitle>
<CardDescription>
Lass uns deine Kita in 3 kurzen Schritten einrichten. Du kannst alle
Einstellungen später noch anpassen.