diff options
| author | Sebastien Castiel <sebastien@castiel.me> | 2023-12-06 21:07:51 -0500 |
|---|---|---|
| committer | Sebastien Castiel <sebastien@castiel.me> | 2023-12-06 21:07:51 -0500 |
| commit | ec981fd237a50dfc547d8c162b22f4e1a691c9fc (patch) | |
| tree | 397d50c89122d2044d3343a099dd94b1056170d9 /src | |
| parent | 59bb784b1c50ad57e7a0ce75cd0dc6fcd85a5594 (diff) | |
Improve responsiveness
Diffstat (limited to 'src')
| -rw-r--r-- | src/app/groups/[groupId]/balances-list.tsx | 6 | ||||
| -rw-r--r-- | src/app/groups/[groupId]/expenses/expense-list.tsx | 76 | ||||
| -rw-r--r-- | src/app/groups/[groupId]/expenses/page.tsx | 124 | ||||
| -rw-r--r-- | src/app/groups/[groupId]/reimbursement-list.tsx | 12 |
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}`} > |
