83 lines
2.2 KiB
TypeScript
83 lines
2.2 KiB
TypeScript
import { Button } from "@xtablo/ui/components/button";
|
|
import { FieldError } from "@xtablo/ui/components/field";
|
|
import { Input } from "@xtablo/ui/components/input";
|
|
import { Label } from "@xtablo/ui/components/label";
|
|
import type { ReactNode } from "react";
|
|
|
|
type AuthEmailPasswordFormProps = {
|
|
email: string;
|
|
password: string;
|
|
onEmailChange: (value: string) => void;
|
|
onPasswordChange: (value: string) => void;
|
|
onSubmit: (event: React.FormEvent<HTMLFormElement>) => void;
|
|
submitLabel: string;
|
|
emailLabel: string;
|
|
passwordLabel: string;
|
|
emailPlaceholder: string;
|
|
passwordPlaceholder: string;
|
|
emailError?: string;
|
|
passwordError?: string;
|
|
isPending?: boolean;
|
|
footer?: ReactNode;
|
|
extraContent?: ReactNode;
|
|
};
|
|
|
|
export function AuthEmailPasswordForm({
|
|
email,
|
|
password,
|
|
onEmailChange,
|
|
onPasswordChange,
|
|
onSubmit,
|
|
submitLabel,
|
|
emailLabel,
|
|
passwordLabel,
|
|
emailPlaceholder,
|
|
passwordPlaceholder,
|
|
emailError,
|
|
passwordError,
|
|
isPending = false,
|
|
footer,
|
|
extraContent,
|
|
}: AuthEmailPasswordFormProps) {
|
|
return (
|
|
<form className="space-y-4 w-full max-w-md mx-auto" onSubmit={onSubmit}>
|
|
<div className="space-y-2">
|
|
<Label htmlFor="email">{emailLabel}</Label>
|
|
<Input
|
|
id="email"
|
|
name="email"
|
|
type="email"
|
|
value={email}
|
|
onChange={(event) => onEmailChange(event.target.value)}
|
|
required
|
|
placeholder={emailPlaceholder}
|
|
disabled={isPending}
|
|
/>
|
|
{emailError ? <FieldError errors={[{ message: emailError }]} /> : null}
|
|
</div>
|
|
|
|
<div className="space-y-2">
|
|
<Label htmlFor="password">{passwordLabel}</Label>
|
|
<Input
|
|
id="password"
|
|
name="password"
|
|
type="password"
|
|
value={password}
|
|
onChange={(event) => onPasswordChange(event.target.value)}
|
|
required
|
|
placeholder={passwordPlaceholder}
|
|
disabled={isPending}
|
|
/>
|
|
{passwordError ? <FieldError errors={[{ message: passwordError }]} /> : null}
|
|
</div>
|
|
|
|
{extraContent}
|
|
|
|
<Button className="w-full" type="submit" disabled={isPending}>
|
|
{submitLabel}
|
|
</Button>
|
|
|
|
{footer}
|
|
</form>
|
|
);
|
|
}
|