"use client"; import { useEffect, useState } from "react"; import TextField from "@/components/ui/TextField"; import LoadingSpinner from "@/components/icons/LoadingSpinner"; import { ApiRequestError } from "@/lib/net"; import { Portal } from "@/components/utils/Portal"; import { Dialog, DialogButton, DialogButtonGroup, DialogHeadline, DialogSupportingText } from "@/components/ui/Dialog"; import { FilledButton } from "@/components/ui/Buttons/FilledButton"; import { string, object, ValidationError } from "yup"; import { setLocale } from "yup"; import { useTranslations } from "next-intl"; import type { ErrorResponse } from "@backend/src/schema"; import Link from "next/link"; import { useCaptcha } from "@/components/hooks/useCaptcha"; setLocale({ mixed: { default: "field_invalid", required: () => ({ key: "field_required" }) }, string: { min: ({ min }) => ({ key: "field_too_short", values: { min } }), max: ({ max }) => ({ key: "field_too_big", values: { max } }) } }); interface LocalizedMessage { key: string; values: { [key: string]: number | string; }; } const FormSchema = object().shape({ username: string().required().max(50), password: string().required().min(4).max(120), nickname: string().optional().max(30) }); interface RegistrationFormProps { backendURL: string; } interface ErrorDialogProps { children: React.ReactNode; closeDialog: () => void; } const ErrorDialog: React.FC = ({ children, closeDialog }) => { return ( <> 错误 {children} 关闭 ); }; const SignUpForm: React.FC = ({ backendURL }) => { const [usernameInput, setUsername] = useState(""); const [passwordInput, setPassword] = useState(""); const [nicknameInput, setNickname] = useState(""); const [loading, setLoading] = useState(false); const [showDialog, setShowDialog] = useState(false); const [dialogContent, setDialogContent] = useState(<>); const t = useTranslations(""); const { startCaptcha, captchaResult } = useCaptcha({ backendURL, route: "POST-/user" }); const translateErrorMessage = (item: LocalizedMessage | string, path?: string) => { if (typeof item === "string") { return item; } return t(`yup_errors.${item.key}`, { ...item.values, field: path ? t(path) : "" }); }; const register = async () => { let username: string | undefined; let password: string | undefined; let nickname: string | undefined; try { const formData = await FormSchema.validate( { username: usernameInput, password: passwordInput, nickname: nicknameInput }, { abortEarly: false } ); username = formData.username; password = formData.password; nickname = formData.nickname; } catch (e) { if (!(e instanceof ValidationError)) { return; } console.log(JSON.parse(JSON.stringify(e))); setShowDialog(true); setDialogContent( setShowDialog(false)}>

注册信息填写有误,请检查后重新提交。

错误信息:
    {e.errors.map((item, i) => { return
  1. {translateErrorMessage(item, e.inner[i].path)}
  2. ; })}
); return; } setLoading(true); try { if (!captchaResult || !captchaResult.token) { await startCaptcha(); } // Proceed with user registration using username, password, and nickname const registrationUrl = new URL(`${backendURL}/user`); const registrationResponse = await fetch(registrationUrl.toString(), { method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${captchaResult!.token}` }, body: JSON.stringify({ username: username, password: password, nickname: nickname }) }); if (registrationResponse.ok) { console.log("Registration successful!"); // Optionally redirect the user or show a success message //router.push("/login"); // Example redirection } else { const res: ErrorResponse = await registrationResponse.json(); setShowDialog(true); setDialogContent( setShowDialog(false)}>

无法为你注册账户。

错误码: {res.code}

错误信息:
{res.i18n ? t(res.i18n.key, { ...res.i18n.values }) : res.message}

); } } catch (error) { if (error instanceof ApiRequestError) { const res = error.response as ErrorResponse; setShowDialog(true); setDialogContent( setShowDialog(false)}>

无法为你注册账户。

错误码: {res.code}

错误信息:
{res.i18n ? t.rich(res.i18n.key, { ...res.i18n.values, support: (chunks) => {chunks} }) : res.message}

); } } finally { setLoading(false); } }; useEffect(() => { if (startCaptcha) { startCaptcha(); } }, [startCaptcha]); return (
{ e.preventDefault(); await register(); }} > {!loading ? 注册 : } {dialogContent} ); }; export default SignUpForm;