Add non-destructive dev seed on startup
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
"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 { registerAction, type RegisterState } from "./actions";
|
||||
|
||||
const initialState: RegisterState = {};
|
||||
|
||||
export function RegisterForm() {
|
||||
const [state, formAction, pending] = useActionState(registerAction, initialState);
|
||||
|
||||
return (
|
||||
<form action={formAction} className="space-y-4">
|
||||
<div className="grid gap-4 sm:grid-cols-2">
|
||||
<FormField
|
||||
id="firstName"
|
||||
name="firstName"
|
||||
label="Vorname"
|
||||
autoComplete="given-name"
|
||||
required
|
||||
error={state.errors?.firstName?.[0]}
|
||||
/>
|
||||
<FormField
|
||||
id="lastName"
|
||||
name="lastName"
|
||||
label="Nachname"
|
||||
autoComplete="family-name"
|
||||
required
|
||||
error={state.errors?.lastName?.[0]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<FormField
|
||||
id="email"
|
||||
name="email"
|
||||
type="email"
|
||||
label="E-Mail"
|
||||
autoComplete="email"
|
||||
required
|
||||
error={state.errors?.email?.[0]}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
id="password"
|
||||
name="password"
|
||||
type="password"
|
||||
label="Passwort"
|
||||
autoComplete="new-password"
|
||||
required
|
||||
helperText="Mindestens 8 Zeichen."
|
||||
error={state.errors?.password?.[0]}
|
||||
/>
|
||||
|
||||
<div className="flex items-start gap-3 pt-2">
|
||||
<Checkbox id="acceptPrivacyPolicy" name="acceptPrivacyPolicy" required />
|
||||
<div className="grid gap-1 leading-none">
|
||||
<Label htmlFor="acceptPrivacyPolicy" className="text-sm font-normal">
|
||||
Ich habe die{" "}
|
||||
<a href="/datenschutz" className="underline" target="_blank" rel="noreferrer">
|
||||
Datenschutzerklärung
|
||||
</a>{" "}
|
||||
gelesen und akzeptiere sie.
|
||||
</Label>
|
||||
{state.errors?.acceptPrivacyPolicy?.[0] && (
|
||||
<p className="text-xs text-destructive">{state.errors.acceptPrivacyPolicy[0]}</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{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}>
|
||||
{pending ? "Wird erstellt…" : "Account erstellen"}
|
||||
</Button>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
|
||||
function FormField({
|
||||
id,
|
||||
name,
|
||||
label,
|
||||
type = "text",
|
||||
required,
|
||||
autoComplete,
|
||||
helperText,
|
||||
error,
|
||||
}: {
|
||||
id: string;
|
||||
name: string;
|
||||
label: string;
|
||||
type?: string;
|
||||
required?: boolean;
|
||||
autoComplete?: string;
|
||||
helperText?: string;
|
||||
error?: string;
|
||||
}) {
|
||||
return (
|
||||
<div className="space-y-1.5">
|
||||
<Label htmlFor={id}>{label}</Label>
|
||||
<Input
|
||||
id={id}
|
||||
name={name}
|
||||
type={type}
|
||||
required={required}
|
||||
autoComplete={autoComplete}
|
||||
aria-invalid={!!error}
|
||||
/>
|
||||
{error ? (
|
||||
<p className="text-xs text-destructive">{error}</p>
|
||||
) : helperText ? (
|
||||
<p className="text-xs text-muted-foreground">{helperText}</p>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user