import { User } from "@prisma/client"; import type { ActionFunction, LoaderFunction } from "remix"; import { useActionData, redirect, json, useCatch, Link, Form, useLoaderData, } from "remix"; import { db } from "~/utils/db.server"; import { requireUserId, getUser, getUserId, getUsersByTeam, } from "~/utils/session.server"; type ActionData = { formError?: string; fieldErrors?: { description: string | undefined; amount?: string | undefined; user?: string | undefined; toUser?: string | undefined; }; fields?: { description: string; amount: number; toUser: string; }; }; type LoaderData = { userId: string | null; teamUsers: User[]; }; const badRequest = (data: ActionData) => json(data, { status: 400 }); export const loader: LoaderFunction = async ({ request }) => { const userId = await getUserId(request); if (!userId) { throw new Response("Unauthorized", { status: 401 }); } const teamUsers = await getUsersByTeam(request); const data: LoaderData = { userId, teamUsers: teamUsers?.filter((user) => user.id !== userId) ?? [], }; return data; }; export const action: ActionFunction = async ({ request }) => { const userId = await requireUserId(request); const user = await getUser(request); const form = await request.formData(); const toUser = form.get("toUser"); const description = form.get("description") ?? "TRASFER"; const amount = parseInt(form.get("amount")?.toString() || "0", 10); if ( typeof description !== "string" || typeof amount !== "number" || typeof toUser !== "string" || user === null ) { return badRequest({ formError: `Form not submitted correctly.`, }); } const expenseFrom = await db.expense.create({ data: { description, amount, userId: userId, teamId: user.teamId, }, }); const expenseTo = await db.expense.create({ data: { description, amount: -amount, userId: toUser, teamId: user.teamId, }, }); if (!expenseFrom || !expenseTo) return json("Internal Server Error", { status: 500 }); return redirect(`/expenses`); }; export default function NewExpenseRoute() { const data = useLoaderData(); const actionData = useActionData(); return ( <>

Transfer to user

{actionData?.formError && (
)}
); } export function CatchBoundary() { const caught = useCatch(); if (caught.status === 401) { return (

You must be logged in to submit an expense.

Login
); } } export function ErrorBoundary() { return (
Something unexpected went wrong. Sorry about that.
); }