"use client"; import { useState } from "react"; import TextField from "@/components/ui/TextField"; import LoadingSpinner from "@/components/icons/LoadingSpinner"; import { computeVdfInWorker } from "@/lib/vdf"; import useSWR from "swr"; 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"; 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 CaptchaSessionResponse { g: string; n: string; t: string; id: string; } interface CaptchaResultResponse { token: string; } async function fetcher(input: RequestInfo, init?: RequestInit): Promise { const res = await fetch(input, init); if (!res.ok) { const error = new ApiRequestError("An error occurred while fetching the data."); error.response = await res.json(); error.code = res.status; throw error; } return res.json(); } interface RegistrationFormProps { backendURL: string; } 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 { data: captchaSession, error: captchaSessionError, mutate: createCaptchaSession } = useSWR( `${backendURL}/captcha/session`, (url) => fetcher(url, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ route: "POST-/user" }) }), { revalidateOnFocus: false, revalidateOnReconnect: false } ); const getCaptchaResult = async (id: string, ans: string): Promise => { const url = new URL(`${backendURL}/captcha/${id}/result`); url.searchParams.set("ans", ans); return fetcher(url.toString()); }; 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( <> 错误

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

错误信息:
    {e.errors.map((item, i) => { return
  1. {translateErrorMessage(item, e.inner[i].path)}
  2. ; })}
setShowDialog(false)}>关闭 ); return; } setLoading(true); try { if (!captchaSession?.g || !captchaSession?.n || !captchaSession?.t || !captchaSession?.id) { console.error("Captcha session data is missing."); return; } const ans = await computeVdfInWorker( BigInt(captchaSession.g), BigInt(captchaSession.n), BigInt(captchaSession.t) ); const captchaResult = await getCaptchaResult(captchaSession.id, ans.result.toString()); if (!captchaResult.token) { } // 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 { console.error("Registration failed:", await registrationResponse.json()); // Handle registration error } } catch (error) { console.error("Registration process error:", error); // Handle general error } finally { setLoading(false); } }; return (
{ e.preventDefault(); await register(); }} > {!loading ? 注册 : } {dialogContent} ); }; export default SignUpForm;