import * as React from "react"; import Link from "next/link"; 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 { CaptchaField } from "@/components/auth/captcha-field"; export function LoginForm(props: { clientId: string; tenantId: string; callback: string; initialEmail: string; prefillPassword?: string; disabled?: boolean; externalError?: string | null; onClearExternalError?: () => void; captcha: string; onCaptchaChange: (next: string) => void; captchaKey: string; onRefreshCaptcha: () => void; }) { const [email, setEmail] = React.useState(props.initialEmail); const [password, setPassword] = React.useState(""); const [rememberMe, setRememberMe] = React.useState( Boolean(props.initialEmail), ); const [submitting, setSubmitting] = React.useState(false); const [error, setError] = React.useState(null); React.useEffect(() => { setEmail(props.initialEmail); setRememberMe(Boolean(props.initialEmail)); }, [props.initialEmail]); React.useEffect(() => { if (props.prefillPassword) { setPassword(props.prefillPassword); } }, [props.prefillPassword]); const missingParams = !props.clientId || !props.tenantId || !props.callback; async function onSubmit(e: React.FormEvent) { e.preventDefault(); setError(null); props.onClearExternalError?.(); setSubmitting(true); try { const res = await fetch("/api/auth/login", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ clientId: props.clientId, tenantId: props.tenantId, callback: props.callback, email, password, captcha: props.captcha, rememberMe, }), }); const json = (await res.json()) as { redirectTo?: string; message?: string; }; if (!res.ok || !json.redirectTo) { throw new Error(json.message || "登录失败"); } window.location.href = json.redirectTo; } catch (err) { setError(err instanceof Error ? err.message : "登录失败"); props.onCaptchaChange(""); props.onRefreshCaptcha(); } finally { setSubmitting(false); } } const disabled = Boolean(props.disabled) || submitting; return (
{missingParams ? (
缺少 clientId、tenantId 或 callback 参数,无法继续登录
) : null} {props.externalError ? (
{props.externalError}
) : null} {error ?
{error}
: null}
setEmail(e.target.value)} placeholder="user@example.com" disabled={disabled} required />
setPassword(e.target.value)} disabled={disabled} required />
忘记密码
); }