diff --git a/web-app/app/ui/HomePage.tsx b/web-app/app/ui/HomePage.tsx index 2e46fcb..581608d 100644 --- a/web-app/app/ui/HomePage.tsx +++ b/web-app/app/ui/HomePage.tsx @@ -1,9 +1,8 @@ import { fetchAllLocations } from '@/app/lib/actions/locationActions'; import { fetchAvailableYears } from '@/app/lib/actions/monthActions'; import { getUserSettings } from '@/app/lib/actions/userSettingsActions'; -import { BillingLocation, YearMonth } from '@/app/lib/db-types'; import { FC } from 'react'; -import { MonthLocationList } from '@/app/ui/MonthLocationList'; +import { MonthArray, MonthLocationList } from '@/app/ui/MonthLocationList'; import { ParamsYearInvalidMessage } from './ParamsYearInvalidMessage'; export interface HomePageProps { @@ -46,51 +45,59 @@ export const HomePage:FC = async ({ searchParams }) => { } selectedYear = paramsYear; + } else { const currYear = new Date().getFullYear(); - // IF current year is available in DB THEN use it - // ELSE use the latest year found in the DB - selectedYear = availableYears.includes(currYear) ? currYear : availableYears[0]; + if(availableYears.length === 0) { + // Database is in it's initial state + // so just set selected year to current year + selectedYear = currYear; + } else { + // IF current year is available in DB THEN use it + // ELSE use the latest year found in the DB + selectedYear = availableYears.includes(currYear) ? currYear : availableYears[0]; + } } const locations = await fetchAllLocations(selectedYear); const userSettings = await getUserSettings(); - // group locations by month - const months = locations.reduce((acc, location) => { + // Create months object by grouping locations by yearMonth + const { months } = locations.reduce((acc, location) => { const {year, month} = location.yearMonth; const key = `${year}-${month}`; - const locationsInMonth = acc[key]; + const monthIx = acc.index[key]; - if(locationsInMonth) { - return({ - ...acc, - [key]: { - yearMonth: location.yearMonth, - locations: [...locationsInMonth.locations, location], - unpaidTotal: locationsInMonth.unpaidTotal + location.bills.reduce((acc, bill) => !bill.paid ? acc + (bill.payedAmount ?? 0) : acc, 0), - payedTotal: locationsInMonth.payedTotal + location.bills.reduce((acc, bill) => bill.paid ? acc + (bill.payedAmount ?? 0) : acc, 0) - } - }) + if(monthIx) { + + const existingMonth = acc.months[monthIx]; + + existingMonth.locations.push(location); + existingMonth.unpaidTotal += location.bills.reduce((acc, bill) => !bill.paid ? acc + (bill.payedAmount ?? 0) : acc, 0); + existingMonth.payedTotal += location.bills.reduce((acc, bill) => bill.paid ? acc + (bill.payedAmount ?? 0) : acc, 0); + + return acc; } - return({ - ...acc, - [key]: { - yearMonth: location.yearMonth, - locations: [location], - unpaidTotal: location.bills.reduce((acc, bill) => !bill.paid ? acc + (bill.payedAmount ?? 0) : acc, 0), - payedTotal: location.bills.reduce((acc, bill) => bill.paid ? acc + (bill.payedAmount ?? 0) : acc, 0) - } + acc.months.push({ + yearMonth: location.yearMonth, + locations: [location], + unpaidTotal: location.bills.reduce((acc, bill) => !bill.paid ? acc + (bill.payedAmount ?? 0) : acc, 0), + payedTotal: location.bills.reduce((acc, bill) => bill.paid ? acc + (bill.payedAmount ?? 0) : acc, 0) }); - }, {} as {[key:string]:{ - yearMonth: YearMonth, - locations: BillingLocation[], - unpaidTotal: number, - payedTotal: number - } }); + + acc.index[key] = acc.months.length - 1; + + return acc; + }, { + index: {}, + months: [] + } as { + index: Record, + months: MonthArray + }); return ( diff --git a/web-app/app/ui/MonthLocationList.tsx b/web-app/app/ui/MonthLocationList.tsx index 86bce23..ce94482 100644 --- a/web-app/app/ui/MonthLocationList.tsx +++ b/web-app/app/ui/MonthLocationList.tsx @@ -22,22 +22,22 @@ const getNextYearMonth = (yearMonth:YearMonth) => { } as YearMonth); } +export type MonthArray = Array<{ + yearMonth: YearMonth; + locations: BillingLocation[]; + payedTotal: number; + unpaidTotal: number; +}>; + export interface MonthLocationListProps { - availableYears?: number[]; - months?: { - [key: string]: { - yearMonth: YearMonth; - locations: BillingLocation[]; - payedTotal: number; - unpaidTotal: number; - }; - }; + availableYears: number[]; + months: MonthArray; userSettings?: UserSettings | null; } export const MonthLocationList:React.FC = ({ availableYears, - months, + months: activeYearMonths, userSettings, }) => { @@ -93,7 +93,7 @@ export const MonthLocationList:React.FC = ({ } }, [search, router, t]); - if(!availableYears || !months) { + if(availableYears.length === 0 || activeYearMonths.length === 0) { const currentYearMonth:YearMonth = { year: new Date().getFullYear(), month: new Date().getMonth() + 1 @@ -107,8 +107,6 @@ export const MonthLocationList:React.FC = ({ ) }; - const monthsArray = Object.entries(months); - // when the month is toggled, update the URL // and set the the new expandedMonth const handleMonthToggle = (yearMonth:YearMonth) => { @@ -123,10 +121,10 @@ export const MonthLocationList:React.FC = ({ } return(<> - + { - monthsArray.map(([monthKey, { yearMonth, locations, unpaidTotal, payedTotal }], monthIx) => - + activeYearMonths.map(({ yearMonth, locations, unpaidTotal, payedTotal }, monthIx) => + { yearMonth.month === expandedMonth ? locations.map((location, ix) => )