From 4e35698de53176f3b6b6dc77ee43ce38665b7f16 Mon Sep 17 00:00:00 2001 From: nzambello Date: Mon, 14 Feb 2022 11:49:32 +0100 Subject: [PATCH] feat: add transfer page placeholder --- app/routes/expenses/transfer.tsx | 165 +++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 app/routes/expenses/transfer.tsx diff --git a/app/routes/expenses/transfer.tsx b/app/routes/expenses/transfer.tsx new file mode 100644 index 0000000..5296b37 --- /dev/null +++ b/app/routes/expenses/transfer.tsx @@ -0,0 +1,165 @@ +import type { ActionFunction, LoaderFunction } from "remix"; +import { + useActionData, + redirect, + json, + useCatch, + Link, + Form, + useTransition, + useLoaderData, +} from "remix"; +import { db } from "~/utils/db.server"; +import { requireUserId, getUserId } from "~/utils/session.server"; + +function validateExpenseDescription(description: string) { + if (description.length < 2) { + return `That expense's description is too short`; + } +} + +type ActionData = { + formError?: string; + fieldErrors?: { + description: string | undefined; + }; + fields?: { + description: string; + amount: number; + }; +}; + +type LoaderData = { + userId: string | null; +}; + +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 data: LoaderData = { userId }; + return data; +}; + +export const action: ActionFunction = async ({ request }) => { + const userId = await requireUserId(request); + const form = await request.formData(); + const description = form.get("description"); + const amount = form.get("amount"); + if (typeof description !== "string" || typeof amount !== "number") { + return badRequest({ + formError: `Form not submitted correctly.`, + }); + } + + const fieldErrors = { + description: validateExpenseDescription(description), + }; + const fields = { description, amount }; + if (Object.values(fieldErrors).some(Boolean)) { + return badRequest({ fieldErrors, fields }); + } + + const expense = await db.expense.create({ + data: { ...fields, userId: userId }, + }); + return redirect(`/expenses/${expense.id}`); +}; + +export default function NewExpenseRoute() { + const data = useLoaderData(); + const actionData = useActionData(); + const transition = useTransition(); + + if (transition.submission) { + const description = transition.submission.formData.get("description"); + const amount = transition.submission.formData.get("content"); + if ( + typeof description === "string" && + typeof amount === "number" && + !validateExpenseDescription(description) + ) { + return ( +
+

Description: {description}

+

Amount: {amount}€

+

User: {data.userId}

+
+ ); + } + } + + return ( +
+

Add an expense

+
+
+ + {actionData?.fieldErrors?.description && ( + + )} +
+
+ +
+
+ +
+
+
+ ); +} + +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. +
+ ); +}