// ============================================================ // AuthPage — 登录 / 注册页面 // 职责:用户认证表单,支持登录和注册模式切换 // ============================================================ import { useCallback, useState } from "react"; import { useAuth } from "../../lib/auth"; import { useI18n } from "../../lib/i18n"; type AuthMode = "login" | "register"; export function AuthPage() { const { login, register } = useAuth(); const { t } = useI18n(); const [mode, setMode] = useState("login"); const [username, setUsername] = useState(""); const [password, setPassword] = useState(""); const [error, setError] = useState(""); const [isSubmitting, setIsSubmitting] = useState(false); const handleSubmit = useCallback( async (e: React.FormEvent) => { e.preventDefault(); setError(""); // 前端校验 if (username.length < 3 || username.length > 64) { setError(t("auth.error.usernameLength")); return; } if (password.length < 8 || password.length > 72) { setError(t("auth.error.passwordLength")); return; } setIsSubmitting(true); const fn = mode === "login" ? login : register; const result = await fn(username, password); setIsSubmitting(false); if (result.error) { setError(result.error); } }, [username, password, mode, login, register, t] ); const toggleMode = useCallback(() => { setMode((m) => (m === "login" ? "register" : "login")); setError(""); }, []); return (

CamTalk

{t("auth.subtitle")}

{error &&
{error}
}

{mode === "login" ? t("auth.noAccount") : t("auth.hasAccount")}

); }