Add non-destructive dev seed on startup

This commit is contained in:
t.indorf
2026-05-06 22:31:07 +02:00
parent 9f452fccac
commit b686e714ff
77 changed files with 10862 additions and 87 deletions
+131
View File
@@ -0,0 +1,131 @@
"use client";
import { useActionState } from "react";
import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { completeOnboardingAction, type OnboardingState } from "./actions";
const initialState: OnboardingState = {};
export function OnboardingForm() {
const [state, formAction, pending] = useActionState(
completeOnboardingAction,
initialState,
);
return (
<form action={formAction} className="space-y-8">
{/* ----- Schritt 1: Name ----- */}
<fieldset className="space-y-4">
<legend className="text-sm font-semibold text-muted-foreground">
Schritt 1 · Grunddaten
</legend>
<div className="space-y-1.5">
<Label htmlFor="kitaName">Name des Elternvereins / der Kita</Label>
<Input
id="kitaName"
name="kitaName"
required
placeholder="z.B. Waldameisen e.V."
aria-invalid={!!state.errors?.kitaName}
/>
{state.errors?.kitaName?.[0] && (
<p className="text-xs text-destructive">{state.errors.kitaName[0]}</p>
)}
</div>
</fieldset>
{/* ----- Schritt 2: Module ----- */}
<fieldset className="space-y-3">
<legend className="text-sm font-semibold text-muted-foreground">
Schritt 2 · Module aktivieren
</legend>
<ModuleCheckbox
name="notdienstModuleEnabled"
label="Notdienst-Planung"
description="Verfügbarkeiten erfassen, Plan generieren, bei Krankheitsausfall alarmieren."
defaultChecked
/>
<ModuleCheckbox
name="terminModuleEnabled"
label="Terminkalender"
description="Kita-Feste, Schließtage und private Anfragen koordinieren."
defaultChecked
/>
<ModuleCheckbox
name="adressbuchModuleEnabled"
label="Eltern-Adressbuch"
description="Eltern können sich auf Opt-In-Basis untereinander finden."
defaultChecked
/>
</fieldset>
{/* ----- Schritt 3: Notdienst-Regeln ----- */}
<fieldset className="space-y-4">
<legend className="text-sm font-semibold text-muted-foreground">
Schritt 3 · Notdienst-Regel
</legend>
<div className="space-y-1.5">
<Label htmlFor="notdienstMinPerChildPerMonth">
Mindest-Verfügbarkeiten pro Kind und Monat
</Label>
<Input
id="notdienstMinPerChildPerMonth"
name="notdienstMinPerChildPerMonth"
type="number"
min={0}
max={31}
defaultValue={2}
required
aria-invalid={!!state.errors?.notdienstMinPerChildPerMonth}
/>
<p className="text-xs text-muted-foreground">
Wie viele Tage müssen Eltern pro Monat als verfügbar markieren?
Diesen Wert kannst du später jederzeit ändern.
</p>
{state.errors?.notdienstMinPerChildPerMonth?.[0] && (
<p className="text-xs text-destructive">
{state.errors.notdienstMinPerChildPerMonth[0]}
</p>
)}
</div>
</fieldset>
{state.errors?._form?.[0] && (
<p className="rounded-md border border-destructive/50 bg-destructive/10 p-3 text-sm text-destructive">
{state.errors._form[0]}
</p>
)}
<Button type="submit" className="w-full" disabled={pending} size="lg">
{pending ? "Wird eingerichtet…" : "Kita einrichten & loslegen"}
</Button>
</form>
);
}
function ModuleCheckbox({
name,
label,
description,
defaultChecked,
}: {
name: string;
label: string;
description: string;
defaultChecked?: boolean;
}) {
return (
<label className="flex items-start gap-3 rounded-md border p-4 transition-colors hover:bg-muted/40">
<Checkbox name={name} defaultChecked={defaultChecked} className="mt-0.5" />
<div className="grid gap-1 leading-none">
<span className="text-sm font-medium">{label}</span>
<span className="text-xs text-muted-foreground">{description}</span>
</div>
</label>
);
}