From a91df3fda048c53f1728aadf7454f4756152ab63 Mon Sep 17 00:00:00 2001 From: Sebastien Castiel Date: Sat, 19 Oct 2024 16:57:47 -0400 Subject: [PATCH] Use tRPC for balances --- .../balances/balances-and-reimbursements.tsx | 75 +++++++++++++++++++ src/app/groups/[groupId]/balances/page.tsx | 55 +------------- .../groups/[groupId]/reimbursement-list.tsx | 2 +- src/trpc/routers/groups/balances/index.ts | 6 ++ .../routers/groups/balances/list.procedure.ts | 19 +++++ src/trpc/routers/groups/index.ts | 2 + 6 files changed, 105 insertions(+), 54 deletions(-) create mode 100644 src/app/groups/[groupId]/balances/balances-and-reimbursements.tsx create mode 100644 src/trpc/routers/groups/balances/index.ts create mode 100644 src/trpc/routers/groups/balances/list.procedure.ts diff --git a/src/app/groups/[groupId]/balances/balances-and-reimbursements.tsx b/src/app/groups/[groupId]/balances/balances-and-reimbursements.tsx new file mode 100644 index 00000000..691c4781 --- /dev/null +++ b/src/app/groups/[groupId]/balances/balances-and-reimbursements.tsx @@ -0,0 +1,75 @@ +'use client' + +import { BalancesList } from '@/app/groups/[groupId]/balances-list' +import { ReimbursementList } from '@/app/groups/[groupId]/reimbursement-list' +import { + Card, + CardContent, + CardDescription, + CardHeader, + CardTitle, +} from '@/components/ui/card' +import { getGroup } from '@/lib/api' +import { trpc } from '@/trpc/client' +import { useTranslations } from 'next-intl' +import { useEffect } from 'react' + +export default function BalancesAndReimbursements({ + group, +}: { + group: NonNullable>> +}) { + const utils = trpc.useUtils() + + useEffect(() => { + // Until we use tRPC more widely and can invalidate the cache on expense + // update, it's easier and safer to invalidate the cache on page load. + utils.groups.balances.invalidate() + }, [utils]) + + const t = useTranslations('Balances') + + const { data, isLoading } = trpc.groups.balances.list.useQuery({ + groupId: group.id, + }) + + return ( + <> + + + {t('title')} + {t('description')} + + + {isLoading || !data ? ( +

Loading…

+ ) : ( + + )} +
+
+ + + {t('Reimbursements.title')} + {t('Reimbursements.description')} + + + {isLoading || !data ? ( +

Loading…

+ ) : ( + + )} +
+
+ + ) +} diff --git a/src/app/groups/[groupId]/balances/page.tsx b/src/app/groups/[groupId]/balances/page.tsx index 615f033c..0a403aa4 100644 --- a/src/app/groups/[groupId]/balances/page.tsx +++ b/src/app/groups/[groupId]/balances/page.tsx @@ -1,21 +1,6 @@ import { cached } from '@/app/cached-functions' -import { BalancesList } from '@/app/groups/[groupId]/balances-list' -import { ReimbursementList } from '@/app/groups/[groupId]/reimbursement-list' -import { - Card, - CardContent, - CardDescription, - CardHeader, - CardTitle, -} from '@/components/ui/card' -import { getGroupExpenses } from '@/lib/api' -import { - getBalances, - getPublicBalances, - getSuggestedReimbursements, -} from '@/lib/balances' +import BalancesAndReimbursements from '@/app/groups/[groupId]/balances/balances-and-reimbursements' import { Metadata } from 'next' -import { getTranslations } from 'next-intl/server' import { notFound } from 'next/navigation' export const metadata: Metadata = { @@ -27,44 +12,8 @@ export default async function GroupPage({ }: { params: { groupId: string } }) { - const t = await getTranslations('Balances') const group = await cached.getGroup(groupId) if (!group) notFound() - const expenses = await getGroupExpenses(groupId) - const balances = getBalances(expenses) - const reimbursements = getSuggestedReimbursements(balances) - const publicBalances = getPublicBalances(reimbursements) - - return ( - <> - - - {t('title')} - {t('description')} - - - - - - - - {t('Reimbursements.title')} - {t('Reimbursements.description')} - - - - - - - ) + return } diff --git a/src/app/groups/[groupId]/reimbursement-list.tsx b/src/app/groups/[groupId]/reimbursement-list.tsx index 43bf4f61..6a7ca529 100644 --- a/src/app/groups/[groupId]/reimbursement-list.tsx +++ b/src/app/groups/[groupId]/reimbursement-list.tsx @@ -28,7 +28,7 @@ export function ReimbursementList({ return (
{reimbursements.map((reimbursement, index) => ( -
+
{t.rich('owes', { diff --git a/src/trpc/routers/groups/balances/index.ts b/src/trpc/routers/groups/balances/index.ts new file mode 100644 index 00000000..626ed64e --- /dev/null +++ b/src/trpc/routers/groups/balances/index.ts @@ -0,0 +1,6 @@ +import { createTRPCRouter } from '@/trpc/init' +import { listGroupBalancesProcedure } from '@/trpc/routers/groups/balances/list.procedure' + +export const groupBalancesRouter = createTRPCRouter({ + list: listGroupBalancesProcedure, +}) diff --git a/src/trpc/routers/groups/balances/list.procedure.ts b/src/trpc/routers/groups/balances/list.procedure.ts new file mode 100644 index 00000000..b851a1af --- /dev/null +++ b/src/trpc/routers/groups/balances/list.procedure.ts @@ -0,0 +1,19 @@ +import { getGroupExpenses } from '@/lib/api' +import { + getBalances, + getPublicBalances, + getSuggestedReimbursements, +} from '@/lib/balances' +import { baseProcedure } from '@/trpc/init' +import { z } from 'zod' + +export const listGroupBalancesProcedure = baseProcedure + .input(z.object({ groupId: z.string().min(1) })) + .query(async ({ input: { groupId } }) => { + const expenses = await getGroupExpenses(groupId) + const balances = getBalances(expenses) + const reimbursements = getSuggestedReimbursements(balances) + const publicBalances = getPublicBalances(reimbursements) + + return { balances: publicBalances, reimbursements } + }) diff --git a/src/trpc/routers/groups/index.ts b/src/trpc/routers/groups/index.ts index 29024178..9f2ec1e5 100644 --- a/src/trpc/routers/groups/index.ts +++ b/src/trpc/routers/groups/index.ts @@ -1,6 +1,8 @@ import { createTRPCRouter } from '@/trpc/init' +import { groupBalancesRouter } from '@/trpc/routers/groups/balances' import { groupExpensesRouter } from '@/trpc/routers/groups/expenses' export const groupsRouter = createTRPCRouter({ expenses: groupExpensesRouter, + balances: groupBalancesRouter, })