aboutsummaryrefslogtreecommitdiffstats
path: root/src/app/groups
diff options
context:
space:
mode:
authorSebastien Castiel <sebastien@castiel.me>2023-12-06 17:02:37 -0500
committerSebastien Castiel <sebastien@castiel.me>2023-12-06 17:02:59 -0500
commit12b1cdb52a9d2723c319083b45a4e9a21896b3b4 (patch)
tree0521ab02b3a3fbab7c8955acf20da20f919b48e6 /src/app/groups
parent72fe19987957e78cbd1d97ccfd8b87d85fea5c88 (diff)
Balances
Diffstat (limited to 'src/app/groups')
-rw-r--r--src/app/groups/[groupId]/balances-list.tsx63
-rw-r--r--src/app/groups/[groupId]/page.tsx20
2 files changed, 76 insertions, 7 deletions
diff --git a/src/app/groups/[groupId]/balances-list.tsx b/src/app/groups/[groupId]/balances-list.tsx
new file mode 100644
index 0000000..c0cffa9
--- /dev/null
+++ b/src/app/groups/[groupId]/balances-list.tsx
@@ -0,0 +1,63 @@
+import { Balances } from '@/lib/balances'
+import { cn } from '@/lib/utils'
+import { Participant } from '@prisma/client'
+
+type Props = {
+ balances: Balances
+ participants: Participant[]
+ currency: string
+}
+
+export function BalancesList({ balances, participants, currency }: Props) {
+ const maxBalance = Math.max(
+ ...Object.values(balances).map((b) => Math.abs(b.total)),
+ )
+
+ return (
+ <div className="text-sm">
+ {participants.map((participant) => (
+ <div
+ key={participant.id}
+ className={cn(
+ 'flex',
+ balances[participant.id]?.total > 0 || 'flex-row-reverse',
+ )}
+ >
+ <div
+ className={cn(
+ 'w-1/2 p-2',
+ balances[participant.id]?.total > 0 && 'text-right',
+ )}
+ >
+ {participant.name}
+ </div>
+ <div
+ className={cn(
+ 'w-1/2 relative',
+ balances[participant.id]?.total > 0 || 'text-right',
+ )}
+ >
+ <div className="absolute inset-0 p-2 z-20">
+ {currency} {(balances[participant.id]?.total ?? 0).toFixed(2)}
+ </div>
+ <div
+ className={cn(
+ 'absolute top-1 h-7 z-10',
+ balances[participant.id]?.total > 0
+ ? 'bg-green-200 left-0 rounded-r-lg border border-green-300'
+ : 'bg-red-200 right-0 rounded-l-lg border border-red-300',
+ )}
+ style={{
+ width:
+ (Math.abs(balances[participant.id]?.total ?? 0) /
+ maxBalance) *
+ 100 +
+ '%',
+ }}
+ ></div>
+ </div>
+ </div>
+ ))}
+ </div>
+ )
+}
diff --git a/src/app/groups/[groupId]/page.tsx b/src/app/groups/[groupId]/page.tsx
index 83fc3ef..7fffcb3 100644
--- a/src/app/groups/[groupId]/page.tsx
+++ b/src/app/groups/[groupId]/page.tsx
@@ -1,3 +1,4 @@
+import { BalancesList } from '@/app/groups/[groupId]/balances-list'
import { SaveGroupLocally } from '@/app/groups/[groupId]/save-recent-group'
import { Badge } from '@/components/ui/badge'
import { Button } from '@/components/ui/button'
@@ -17,6 +18,7 @@ import {
TableRow,
} from '@/components/ui/table'
import { getGroup, getGroupExpenses } from '@/lib/api'
+import { getBalances } from '@/lib/balances'
import { ChevronRight, Plus } from 'lucide-react'
import Link from 'next/link'
import { notFound } from 'next/navigation'
@@ -30,6 +32,7 @@ export default async function GroupPage({
if (!group) notFound()
const expenses = await getGroupExpenses(groupId)
+ const balances = getBalances(expenses)
return (
<>
@@ -52,7 +55,7 @@ export default async function GroupPage({
<CardContent className="p-0">
{expenses.length > 0 ? (
- <Table className="">
+ <Table>
<TableHeader>
<TableRow>
<TableHead>Title</TableHead>
@@ -115,14 +118,17 @@ export default async function GroupPage({
<Card className="mb-4">
<CardHeader>
- <CardTitle>Participants</CardTitle>
+ <CardTitle>Balances</CardTitle>
+ <CardDescription>
+ This is the amount that each participant paid or was paid for.
+ </CardDescription>
</CardHeader>
<CardContent>
- <ul>
- {group.participants.map((participant) => (
- <li key={participant.id}>{participant.name}</li>
- ))}
- </ul>
+ <BalancesList
+ balances={balances}
+ participants={group.participants}
+ currency={group.currency}
+ />
</CardContent>
</Card>
<SaveGroupLocally group={{ id: group.id, name: group.name }} />