import type { User, Team, Expense } from "@prisma/client"; import type { LoaderFunction } from "remix"; import { redirect, useLoaderData, useCatch, Link } from "remix"; import { db } from "~/utils/db.server"; import { getUser, requireUserId } from "~/utils/session.server"; import Header from "../components/Header"; type LoaderData = { user: (User & { team: Team & { members: User[] } }) | null; thisMonth: { count: number; amount: number; }; count: number; avg: number; statsByMonth: { [month: string]: { count: number; amount: number; }; }; }; export const loader: LoaderFunction = async ({ request }) => { const userId = requireUserId(request); const user = await getUser(request); if (!user?.id || !userId) { return redirect("/login"); } const expenses = await db.expense.aggregate({ _avg: { amount: true, }, _count: { _all: true, }, where: { userId: user.id }, orderBy: { createdAt: "asc", }, }); let thisMonth = new Date(); thisMonth.setDate(0); const thisMonthExp = await db.expense.aggregate({ _avg: { amount: true, }, _count: { _all: true, }, where: { userId: user.id, createdAt: { gt: thisMonth } }, orderBy: { createdAt: "asc", }, }); const allExpenses = await db.expense.findMany({ where: { userId: user.id }, }); const statsByMonth = allExpenses.reduce( ( acc: { [key: string]: { count: number; amount: number } }, exp: Expense ) => { const month = new Intl.DateTimeFormat("it", { month: "2-digit", year: "numeric", }).format(new Date(exp.createdAt)); if (!acc[month]) { acc[month] = { count: 0, amount: 0, }; } acc[month].count += 1; acc[month].amount += exp.amount; return acc; }, {} ); console.log(statsByMonth); const data: LoaderData = { user, thisMonth: { count: thisMonthExp?._count?._all ?? 0, amount: thisMonthExp?._avg?.amount ?? 0, }, count: expenses._count._all ?? 0, avg: expenses._avg?.amount ?? 0, statsByMonth, }; return data; }; export default function ListExpensesRoute() { const data = useLoaderData(); return ( <>

Statistics

Expenses count
{data.count}
Average per month
{data.avg} €
This month
{data.thisMonth.amount} €
{data.thisMonth.count} expenses

Expenses by month

{Object.keys(data.statsByMonth)?.map((month) => ( ))}
Month Total Count
{month} {data.statsByMonth[month].amount} € {data.statsByMonth[month].count}
); } export function CatchBoundary() { const caught = useCatch(); if (caught.status === 401) { return redirect("/login"); } if (caught.status === 404) { return
There is no data to display.
; } throw new Error(`Unexpected caught response with status: ${caught.status}`); } export function ErrorBoundary() { return
I did a whoopsies.
; }