import type { ActionFunction, LinksFunction, MetaFunction } from "remix"; import { useActionData, json, Link, useSearchParams, Form } from "remix"; import { login, createUserSession, register } from "~/utils/session.server"; import Header from "../components/Header"; export const links: LinksFunction = () => { return []; }; export const meta: MetaFunction = () => { return { title: "Explit | Login", description: "Login to track and split your expenses!", }; }; function validateUsername(username: unknown) { if (typeof username !== "string" || username.length < 3) { return `Usernames must be at least 3 characters long`; } } function validatePassword(password: unknown) { if (typeof password !== "string" || password.length < 6) { return `Passwords must be at least 6 characters long`; } } type ActionData = { formError?: string; fieldErrors?: { username: string | undefined; password: string | undefined; }; fields?: { username: string; password: string; }; }; const badRequest = (data: ActionData) => json(data, { status: 400 }); export const action: ActionFunction = async ({ request }) => { const form = await request.formData(); const username = form.get("username"); const password = form.get("password"); const redirectTo = form.get("redirectTo") || "/expenses"; if ( typeof username !== "string" || typeof password !== "string" || typeof redirectTo !== "string" ) { return badRequest({ formError: `Form not submitted correctly.`, }); } const fields = { username, password }; const fieldErrors = { username: validateUsername(username), password: validatePassword(password), }; if (Object.values(fieldErrors).some(Boolean)) return badRequest({ fieldErrors, fields }); const user = await login({ username, password }); if (!user) { return badRequest({ fields, formError: `Username/Password combination is incorrect`, }); } return createUserSession(user.id, redirectTo); }; export default function Login() { const actionData = useActionData(); const [searchParams] = useSearchParams(); return ( <>

Login

{actionData?.fieldErrors?.username && (
)}
{actionData?.fieldErrors?.password && (
)}
{actionData?.formError && (
)}
); }