import * as React from "react"; import type { ActionFunction, LoaderFunction, MetaFunction } from "remix"; import { Form, Link, redirect, useSearchParams, json, useActionData, } from "remix"; import { getUserId, createUserSession } from "~/session.server"; import { createUser, getUserByEmail } from "~/models/user.server"; import { validateEmail } from "~/utils"; export const loader: LoaderFunction = async ({ request }) => { const userId = await getUserId(request); if (userId) return redirect("/"); return json({}); }; interface ActionData { errors: { email?: string; password?: string; }; } export const action: ActionFunction = async ({ request }) => { const formData = await request.formData(); const email = formData.get("email"); const password = formData.get("password"); const redirectTo = formData.get("redirectTo"); if (!validateEmail(email)) { return json( { errors: { email: "Email is invalid" } }, { status: 400 } ); } if (typeof password !== "string") { return json( { errors: { password: "Password is required" } }, { status: 400 } ); } if (password.length < 8) { return json( { errors: { password: "Password is too short" } }, { status: 400 } ); } const existingUser = await getUserByEmail(email); if (existingUser) { return json( { errors: { email: "A user already exists with this email" } }, { status: 400 } ); } const user = await createUser(email, password); return createUserSession({ request, userId: user.id, remember: false, redirectTo: typeof redirectTo === "string" ? redirectTo : "/", }); }; export const meta: MetaFunction = () => { return { title: "Sign Up", }; }; export default function Join() { const [searchParams] = useSearchParams(); const redirectTo = searchParams.get("redirectTo") ?? undefined; const actionData = useActionData() as ActionData; const emailRef = React.useRef(null); const passwordRef = React.useRef(null); React.useEffect(() => { if (actionData?.errors?.email) { emailRef.current?.focus(); } else if (actionData?.errors?.password) { passwordRef.current?.focus(); } }, [actionData]); return (
{actionData?.errors?.email && (
{actionData.errors.email}
)}
{actionData?.errors?.password && (
{actionData.errors.password}
)}
Already have an account?{" "} Log in
); }