import { useEffect, useState } from "react"; import type { SubmitEvent } from "react"; import { Link, useNavigate, useSearchParams } from "react-router"; import { t } from "@lingui/core/macro" import { Trans } from "@lingui/react/macro"; import { API_URL, VALIDATION } from "../config/api.ts"; import { deserializeAuthResponse, parseAPIResponse, type RawAuthResponse, type RegisterRequest, } from "../model.ts"; import { useAuth } from "../hooks/useAuth.ts"; import { PageShell } from "../components/PageShell.tsx"; import { ErrorCard } from "../components/ErrorCard.tsx"; import { friendlyFetchError } from "../utils/apiError.ts"; type TokenState = | { status: "checking" } | { status: "invalid" } | { status: "valid" }; type FormState = | { status: "idle" } | { status: "submitting" } | { status: "error"; error: string }; export function UserRegister() { const navigate = useNavigate(); const { login } = useAuth(); const [searchParams] = useSearchParams(); const token = searchParams.get("token") ?? ""; const [tokenState, setTokenState] = useState(() => token ? { status: "checking" } : { status: "invalid" } ); const [formState, setFormState] = useState({ status: "idle" }); const [prevToken, setPrevToken] = useState(token); if (prevToken !== token) { setPrevToken(token); setTokenState(token ? { status: "checking" } : { status: "invalid" }); } useEffect(() => { if (!token) return; fetch(`${API_URL}/api/invites/${encodeURIComponent(token)}`) .then((r) => { setTokenState(r.ok ? { status: "valid" } : { status: "invalid" }); }) .catch(() => setTokenState({ status: "invalid" })); }, [token]); const handleSubmit = async (e: SubmitEvent) => { e.preventDefault(); setFormState({ status: "submitting" }); const formData = new FormData(e.currentTarget); const username = formData.get("username") as string; const password = formData.get("password") as string; const email = formData.get("email") as string; try { const res = await fetch(`${API_URL}/api/users/register`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify( { username, password, inviteToken: token, email, } satisfies RegisterRequest, ), }); const apiResponse = parseAPIResponse(await res.json()); if (apiResponse.success) { login(deserializeAuthResponse(apiResponse.data)); navigate("/"); } else { setFormState({ status: "error", error: apiResponse.error.message }); } } catch (err) { setFormState({ status: "error", error: friendlyFetchError(err) }); } }; if (tokenState.status === "checking") { return (

Checking invite…

); } if (tokenState.status === "invalid") { return (
); } return (

Register

{formState.status === "error" && ( )}

Already have an account? Log in

); }