aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/app/groups/[groupId]/balances-list.tsx6
-rw-r--r--src/app/groups/[groupId]/expenses/expense-list.tsx76
-rw-r--r--src/app/groups/[groupId]/expenses/page.tsx124
-rw-r--r--src/app/groups/[groupId]/reimbursement-list.tsx12
4 files changed, 94 insertions, 124 deletions
diff --git a/src/app/groups/[groupId]/balances-list.tsx b/src/app/groups/[groupId]/balances-list.tsx
index c0d48b9..26092ec 100644
--- a/src/app/groups/[groupId]/balances-list.tsx
+++ b/src/app/groups/[groupId]/balances-list.tsx
@@ -20,13 +20,13 @@ export function BalancesList({ balances, participants, currency }: Props) {
key={participant.id}
className={cn(
'flex',
- balances[participant.id]?.total > 0 || 'flex-row-reverse',
+ balances[participant.id]?.total >= 0 || 'flex-row-reverse',
)}
>
<div
className={cn(
'w-1/2 p-2',
- balances[participant.id]?.total > 0 && 'text-right',
+ balances[participant.id]?.total >= 0 && 'text-right',
)}
>
{participant.name}
@@ -34,7 +34,7 @@ export function BalancesList({ balances, participants, currency }: Props) {
<div
className={cn(
'w-1/2 relative',
- balances[participant.id]?.total > 0 || 'text-right',
+ balances[participant.id]?.total >= 0 || 'text-right',
)}
>
<div className="absolute inset-0 p-2 z-20">
diff --git a/src/app/groups/[groupId]/expenses/expense-list.tsx b/src/app/groups/[groupId]/expenses/expense-list.tsx
new file mode 100644
index 0000000..0c03756
--- /dev/null
+++ b/src/app/groups/[groupId]/expenses/expense-list.tsx
@@ -0,0 +1,76 @@
+'use client'
+import { Badge } from '@/components/ui/badge'
+import { Button } from '@/components/ui/button'
+import { getGroupExpenses } from '@/lib/api'
+import { cn } from '@/lib/utils'
+import { Participant } from '@prisma/client'
+import { ChevronRight } from 'lucide-react'
+import Link from 'next/link'
+import { useRouter } from 'next/navigation'
+
+type Props = {
+ expenses: Awaited<ReturnType<typeof getGroupExpenses>>
+ participants: Participant[]
+ currency: string
+ groupId: string
+}
+
+export function ExpenseList({
+ expenses,
+ currency,
+ participants,
+ groupId,
+}: Props) {
+ const getParticipant = (id: string) => participants.find((p) => p.id === id)
+ const router = useRouter()
+
+ return expenses.length > 0 ? (
+ expenses.map((expense) => (
+ <div
+ key={expense.id}
+ className={cn(
+ 'border-t flex justify-between pl-6 pr-2 py-4 text-sm cursor-pointer hover:bg-slate-50',
+ expense.isReimbursement && 'italic',
+ )}
+ onClick={() => {
+ router.push(`/groups/${groupId}/expenses/${expense.id}/edit`)
+ }}
+ >
+ <div>
+ <div className="mb-1">{expense.title}</div>
+ <div className="text-xs text-muted-foreground">
+ Paid by{' '}
+ <Badge variant="secondary">
+ {getParticipant(expense.paidById)?.name}
+ </Badge>{' '}
+ for{' '}
+ {expense.paidFor.map((paidFor, index) => (
+ <Badge variant="secondary" key={index} className="mr-1 mb-1">
+ {participants.find((p) => p.id === paidFor.participantId)?.name}
+ </Badge>
+ ))}
+ </div>
+ </div>
+ <div className="flex items-center">
+ <div className="tabular-nums whitespace-nowrap font-bold">
+ {currency} {expense.amount.toFixed(2)}
+ </div>
+ <Button size="icon" variant="link" className="-my-2" asChild>
+ <Link href={`/groups/${groupId}/expenses/${expense.id}/edit`}>
+ <ChevronRight className="w-4 h-4" />
+ </Link>
+ </Button>
+ </div>
+ </div>
+ ))
+ ) : (
+ <p className="px-6 text-sm py-6">
+ Your group doesn’t contain any expense yet.{' '}
+ <Button variant="link" asChild className="-m-3">
+ <Link href={`/groups/${groupId}/expenses/create`}>
+ Create the first one
+ </Link>
+ </Button>
+ </p>
+ )
+}
diff --git a/src/app/groups/[groupId]/expenses/page.tsx b/src/app/groups/[groupId]/expenses/page.tsx
index 0047b1e..48f355b 100644
--- a/src/app/groups/[groupId]/expenses/page.tsx
+++ b/src/app/groups/[groupId]/expenses/page.tsx
@@ -1,4 +1,4 @@
-import { Badge } from '@/components/ui/badge'
+import { ExpenseList } from '@/app/groups/[groupId]/expenses/expense-list'
import { Button } from '@/components/ui/button'
import {
Card,
@@ -8,8 +8,7 @@ import {
CardTitle,
} from '@/components/ui/card'
import { getGroup, getGroupExpenses } from '@/lib/api'
-import { cn } from '@/lib/utils'
-import { ChevronRight, Plus } from 'lucide-react'
+import { Plus } from 'lucide-react'
import Link from 'next/link'
import { notFound } from 'next/navigation'
@@ -42,119 +41,12 @@ export default async function GroupExpensesPage({
</div>
<CardContent className="p-0">
- {expenses.length > 0 ? (
- expenses.map((expense) => (
- <div
- className={cn(
- 'border-t flex justify-between pl-6 pr-2 py-4 text-sm',
- expense.isReimbursement && 'italic',
- )}
- >
- <div>
- <div>{expense.title}</div>
- <div className="text-xs text-muted-foreground">
- Paid by{' '}
- <Badge variant="secondary">
- {
- group.participants.find((p) => p.id === expense.paidById)
- ?.name
- }
- </Badge>{' '}
- for{' '}
- {expense.paidFor.map((paidFor, index) => (
- <Badge variant="secondary" key={index} className="mr-1">
- {
- group.participants.find(
- (p) => p.id === paidFor.participantId,
- )?.name
- }
- </Badge>
- ))}
- </div>
- </div>
- <div className="flex items-center">
- <div className="tabular-nums whitespace-nowrap font-bold">
- {group.currency} {expense.amount.toFixed(2)}
- </div>
- <Button size="icon" variant="link" className="-my-2" asChild>
- <Link href={`/groups/${groupId}/expenses/${expense.id}/edit`}>
- <ChevronRight className="w-4 h-4" />
- </Link>
- </Button>
- </div>
- </div>
- ))
- ) : (
- <p className="px-6 text-sm py-6">
- Your group doesn’t contain any expense yet.{' '}
- <Button variant="link" asChild className="-m-3">
- <Link href={`/groups/${groupId}/expenses/create`}>
- Create the first one
- </Link>
- </Button>
- </p>
- )}
- {/* <Table>
- <TableHeader>
- <TableRow>
- <TableHead>Title</TableHead>
- <TableHead>Paid by</TableHead>
- <TableHead>Paid for</TableHead>
- <TableHead className="text-right">Amount</TableHead>
- <TableHead className="w-0"></TableHead>
- </TableRow>
- </TableHeader>
- <TableBody>
- {expenses.map((expense) => (
- <TableRow
- key={expense.id}
- className={cn(expense.isReimbursement && 'italic')}
- >
- <TableCell>{expense.title}</TableCell>
- <TableCell>
- <Badge variant="secondary">
- {
- group.participants.find(
- (p) => p.id === expense.paidById,
- )?.name
- }
- </Badge>
- </TableCell>
- <TableCell className="flex flex-wrap gap-1">
- {expense.paidFor.map((paidFor, index) => (
- <Badge variant="secondary" key={index}>
- {
- group.participants.find(
- (p) => p.id === paidFor.participantId,
- )?.name
- }
- </Badge>
- ))}
- </TableCell>
- <TableCell className="text-right tabular-nums whitespace-nowrap">
- {group.currency} {expense.amount.toFixed(2)}
- </TableCell>
- <TableCell>
- <Button
- size="icon"
- variant="link"
- className="-my-2"
- asChild
- >
- <Link
- href={`/groups/${groupId}/expenses/${expense.id}/edit`}
- >
- <ChevronRight className="w-4 h-4" />
- </Link>
- </Button>
- </TableCell>
- </TableRow>
- ))}
- </TableBody>
- </Table>
- ) : (
- <div className="p-6">Your group doesn’t have any expense yet.</div>
- )} */}
+ <ExpenseList
+ expenses={expenses}
+ groupId={groupId}
+ currency={group.currency}
+ participants={group.participants}
+ />
</CardContent>
</Card>
)
diff --git a/src/app/groups/[groupId]/reimbursement-list.tsx b/src/app/groups/[groupId]/reimbursement-list.tsx
index 3fc94bc..e8400ca 100644
--- a/src/app/groups/[groupId]/reimbursement-list.tsx
+++ b/src/app/groups/[groupId]/reimbursement-list.tsx
@@ -20,11 +20,13 @@ export function ReimbursementList({
return (
<div className="text-sm">
{reimbursements.map((reimbursement, index) => (
- <div className="border-t p-4 flex justify-between" key={index}>
- <div>
- <strong>{getParticipant(reimbursement.from)?.name}</strong> owes{' '}
- <strong>{getParticipant(reimbursement.to)?.name}</strong>
- <Button variant="link" asChild className="-my-3">
+ <div className="border-t px-6 py-4 flex justify-between" key={index}>
+ <div className="flex flex-col gap-1 items-start sm:flex-row sm:items-baseline sm:gap-4">
+ <div>
+ <strong>{getParticipant(reimbursement.from)?.name}</strong> owes{' '}
+ <strong>{getParticipant(reimbursement.to)?.name}</strong>
+ </div>
+ <Button variant="link" asChild className="-mx-4 -my-3">
<Link
href={`/groups/${groupId}/expenses/create?reimbursement=yes&from=${reimbursement.from}&to=${reimbursement.to}&amount=${reimbursement.amount}`}
>