From 6cf892f06432926e5258415bfe960debca7d2753 Mon Sep 17 00:00:00 2001 From: Stefan Hynst Date: Sat, 17 Feb 2024 00:32:30 +0100 Subject: [PATCH] Implement simple pagination of expenses (see #30) - display only this year's entries by default - a "Show more" button reveals all expenses --- .../[groupId]/expenses/expense-list.tsx | 48 ++++++++++++------- src/app/groups/[groupId]/expenses/page.tsx | 10 ++-- 2 files changed, 38 insertions(+), 20 deletions(-) diff --git a/src/app/groups/[groupId]/expenses/expense-list.tsx b/src/app/groups/[groupId]/expenses/expense-list.tsx index d3201ac3..13e06294 100644 --- a/src/app/groups/[groupId]/expenses/expense-list.tsx +++ b/src/app/groups/[groupId]/expenses/expense-list.tsx @@ -1,15 +1,17 @@ 'use client' +import { ExpenseCard } from '@/app/groups/[groupId]/expenses/expense-card' import { Button } from '@/components/ui/button' import { SearchBar } from '@/components/ui/search-bar' import { getGroupExpenses } from '@/lib/api' import { Participant } from '@prisma/client' import dayjs, { type Dayjs } from 'dayjs' import Link from 'next/link' -import { useEffect, useState } from 'react' -import { ExpenseCard } from '@/app/groups/[groupId]/expenses/expense-card' +import { useEffect, useMemo, useState } from 'react' + +type ExpensesType = Awaited> type Props = { - expenses: Awaited> + expenses: ExpensesType participants: Participant[] currency: string groupId: string @@ -40,19 +42,14 @@ function getExpenseGroup(date: Dayjs, today: Dayjs) { } } -function getGroupedExpensesByDate( - expenses: Awaited>, -) { +function getGroupedExpensesByDate(expenses: ExpensesType) { const today = dayjs() - return expenses.reduce( - (result: { [key: string]: Awaited> }, expense) => { - const expenseGroup = getExpenseGroup(dayjs(expense.expenseDate), today) - result[expenseGroup] = result[expenseGroup] ?? [] - result[expenseGroup].push(expense) - return result - }, - {}, - ) + return expenses.reduce((result: { [key: string]: ExpensesType }, expense) => { + const expenseGroup = getExpenseGroup(dayjs(expense.expenseDate), today) + result[expenseGroup] = result[expenseGroup] ?? [] + result[expenseGroup].push(expense) + return result + }, {}) } export function ExpenseList({ @@ -81,11 +78,25 @@ export function ExpenseList({ } }, [groupId, participants]) - const groupedExpensesByDate = getGroupedExpensesByDate(expenses) + const groupedExpensesByDate = useMemo( + () => getGroupedExpensesByDate(expenses), + [expenses], + ) + const [showAll, setShowAll] = useState( + !groupedExpensesByDate[EXPENSE_GROUPS.LAST_YEAR], + ) + return expenses.length > 0 ? ( <> setSearchText(e.target.value)} /> {Object.values(EXPENSE_GROUPS).map((expenseGroup: string) => { + if ( + !showAll && + (expenseGroup === EXPENSE_GROUPS.LAST_YEAR || + expenseGroup === EXPENSE_GROUPS.OLDER) + ) + return null + let groupExpenses = groupedExpensesByDate[expenseGroup] if (!groupExpenses) return null @@ -116,6 +127,11 @@ export function ExpenseList({ ) })} + {!showAll && ( + + )} ) : (

diff --git a/src/app/groups/[groupId]/expenses/page.tsx b/src/app/groups/[groupId]/expenses/page.tsx index 9dc3ab5e..2c32744f 100644 --- a/src/app/groups/[groupId]/expenses/page.tsx +++ b/src/app/groups/[groupId]/expenses/page.tsx @@ -87,7 +87,7 @@ export default async function GroupExpensesPage({ ))} > - + @@ -97,9 +97,11 @@ export default async function GroupExpensesPage({ ) } -async function Expenses({ groupId }: { groupId: string }) { - const group = await cached.getGroup(groupId) - if (!group) notFound() +type Props = { + group: NonNullable>> +} + +async function Expenses({ group }: Props) { const expenses = await getGroupExpenses(group.id) return (