import type { ActionFunction, LoaderFunction, MetaFunction } from "remix"; import { Link, useLoaderData, useParams, useCatch, redirect, Form, } from "remix"; import type { Expense, User } from "@prisma/client"; import { db } from "~/utils/db.server"; import { requireUserId, getUserId } from "~/utils/session.server"; type LoaderData = { expense: Expense & { user: User }; isOwner: boolean }; export const meta: MetaFunction = ({ data, }: { data: LoaderData | undefined; }) => { if (!data) { return { title: "No expense", description: "No expense found", }; } return { title: `Expense: ${data.expense.description} | Explit`, description: `Details of expense: ${data.expense.description}`, }; }; export const loader: LoaderFunction = async ({ request, params }) => { const userId = await getUserId(request); if (!userId) { redirect("/login"); } const expense = await db.expense.findUnique({ where: { id: params.expenseId }, include: { user: true, }, }); if (!expense) { throw new Response("What an expense! Not found.", { status: 404, }); } const data: LoaderData = { expense, isOwner: userId === expense.userId, }; return data; }; export const action: ActionFunction = async ({ request, params }) => { const form = await request.formData(); if (form.get("_method") === "delete") { const userId = await requireUserId(request); const expense = await db.expense.findUnique({ where: { id: params.expenseId }, }); if (!expense) { throw new Response("Can't delete what does not exist", { status: 404 }); } if (expense.userId !== userId) { throw new Response("Pssh, nice try. That's not your expense", { status: 401, }); } await db.expense.delete({ where: { id: params.expenseId } }); return redirect("/expenses"); } }; export default function ExpenseRoute() { const data = useLoaderData(); return (
Back

Expense details

Description
{data.expense.description}
Amount
{data.expense.amount} €
User
{data.expense.user.icon ?? data.expense.user.username[0]}
{data.expense.user.username}
Date
{new Intl.DateTimeFormat("it", { dateStyle: "short", timeStyle: "short", }).format(new Date(data.expense.createdAt))}
{data.isOwner && ( <>

Do you really want to delete your expense? Its data will be permanently deleted.

)}
); } export function CatchBoundary() { const caught = useCatch(); const params = useParams(); switch (caught.status) { case 404: { return (
Huh? What the heck is {params.expenseId}?
); } case 401: { return (
Sorry, but {params.expenseId} is not your sheet.
); } default: { throw new Error(`Unhandled error: ${caught.status}`); } } } export function ErrorBoundary() { const { expenseId } = useParams(); return (
{`There was an error loading expense by the id ${expenseId}. Sorry.`}
); }