55 lines
1.7 KiB
TypeScript
55 lines
1.7 KiB
TypeScript
"use client";
|
|
|
|
import { useActionState } from "react";
|
|
import { anmeldenMitPasswort, type AnmeldeZustand } from "@/actions/auth";
|
|
import { Button } from "@/components/ui/Button";
|
|
import { CONTROL_CLASS, Field } from "@/components/ui/Field";
|
|
|
|
// Anmeldung mit Passwort — der zweite Weg neben dem Firmenkonto, auf Zeit
|
|
// (siehe actions/auth.ts).
|
|
//
|
|
// Die Meldung kommt aus der Server Action und ist für jeden Fehlschlag
|
|
// dieselbe. Kein `autoFocus`: die Seite bietet zwei Wege an, und der obere ist
|
|
// der gemeinte — den Cursor unten hineinzusetzen kehrte das um.
|
|
|
|
const START: AnmeldeZustand = { fehler: null };
|
|
|
|
export function PasswortFormular() {
|
|
const [zustand, aktion, laeuft] = useActionState(anmeldenMitPasswort, START);
|
|
|
|
return (
|
|
<form action={aktion} className="flex flex-col gap-3">
|
|
{zustand.fehler && (
|
|
<p role="alert" className="rounded-md border border-danger-text/20 bg-danger-bg px-3 py-2 text-sm text-danger-text">
|
|
{zustand.fehler}
|
|
</p>
|
|
)}
|
|
|
|
<Field label="E-Mail-Adresse">
|
|
{(p) => (
|
|
<input
|
|
{...p}
|
|
name="email"
|
|
type="email"
|
|
required
|
|
// `username`, nicht `email`: nur so bietet der Passwortspeicher des
|
|
// Browsers das Paar aus Adresse und Passwort gemeinsam an.
|
|
autoComplete="username"
|
|
className={CONTROL_CLASS}
|
|
/>
|
|
)}
|
|
</Field>
|
|
|
|
<Field label="Passwort">
|
|
{(p) => (
|
|
<input {...p} name="passwort" type="password" required autoComplete="current-password" className={CONTROL_CLASS} />
|
|
)}
|
|
</Field>
|
|
|
|
<Button type="submit" fullWidth pending={laeuft} pendingLabel="Anmelden…">
|
|
Anmelden
|
|
</Button>
|
|
</form>
|
|
);
|
|
}
|