diff --git a/app/page.tsx b/app/page.tsx index 73b9cb1..d321cd7 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,12 +1,7 @@ -import { AddLocationButton } from './ui/AddLocationButton'; -import { PageFooter } from './ui/PageFooter'; -import { fetchAllLocations } from './lib/actions/locationActions'; -import { fetchAvailableYears } from './lib/actions/monthActions'; -import { BillingLocation, YearMonth } from './lib/db-types'; -import { FC } from 'react'; +import { FC, Suspense } from 'react'; import { Main } from './ui/Main'; -import { MonthCard } from './ui/MonthCard'; -import { MonthLocationList } from './ui/MonthLocationList'; +import HomePage from './ui/HomePage'; +import { HomePageSkeleton } from './ui/MonthCardSceleton'; export interface PageProps { searchParams?: { @@ -17,74 +12,11 @@ export interface PageProps { const Page:FC = async ({ searchParams }) => { - let availableYears: number[]; - - try { - availableYears = await fetchAvailableYears(); - } catch (error:any) { - return ( -
-

{error.message}

-
); - } - - // if the database is in it's initial state, show the add location button for the current month - if(availableYears.length === 0) { - - const currentYearMonth:YearMonth = { - year: new Date().getFullYear(), - month: new Date().getMonth() + 1 - }; - - return ( -
- - - - -
- ); - } - - const currentYear = Number(searchParams?.year) || availableYears[0]; - - const locations = await fetchAllLocations(currentYear); - - // group locations by month - const months = locations.reduce((acc, location) => { - const {year, month} = location.yearMonth; - const key = `${year}-${month}`; - - const locationsInMonth = acc[key]; - - if(locationsInMonth) { - return({ - ...acc, - [key]: { - yearMonth: location.yearMonth, - locations: [...locationsInMonth.locations, location], - monthlyExpense: locationsInMonth.monthlyExpense + location.bills.reduce((acc, bill) => bill.paid ? acc + (bill.payedAmount ?? 0) : acc, 0) - } - }) - } - - return({ - ...acc, - [key]: { - yearMonth: location.yearMonth, - locations: [location], - monthlyExpense: location.bills.reduce((acc, bill) => bill.paid ? acc + (bill.payedAmount ?? 0) : acc, 0) - } - }); - }, {} as {[key:string]:{ - yearMonth: YearMonth, - locations: BillingLocation[], - monthlyExpense: number - } }); - return (
- + }> + +
); } diff --git a/app/ui/HomePage.tsx b/app/ui/HomePage.tsx new file mode 100644 index 0000000..e2c2118 --- /dev/null +++ b/app/ui/HomePage.tsx @@ -0,0 +1,77 @@ +import { fetchAllLocations } from '@/app/lib/actions/locationActions'; +import { fetchAvailableYears } from '@/app/lib/actions/monthActions'; +import { BillingLocation, YearMonth } from '@/app/lib/db-types'; +import { FC } from 'react'; +import { MonthLocationList } from '@/app/ui/MonthLocationList'; + +export interface HomePageProps { + searchParams?: { + year?: string; + month?: string; + }; +} + +export const HomePage:FC = async ({ searchParams }) => { + + let availableYears: number[]; + + const asyncTimout = (ms:number) => new Promise(resolve => setTimeout(resolve, ms)); + + await asyncTimout(5000); + + try { + availableYears = await fetchAvailableYears(); + } catch (error:any) { + return ( +
+

{error.message}

+
); + } + + // if the database is in it's initial state, show the add location button for the current month + if(availableYears.length === 0) { + return (); + } + + const currentYear = Number(searchParams?.year) || availableYears[0]; + + const locations = await fetchAllLocations(currentYear); + + // group locations by month + const months = locations.reduce((acc, location) => { + const {year, month} = location.yearMonth; + const key = `${year}-${month}`; + + const locationsInMonth = acc[key]; + + if(locationsInMonth) { + return({ + ...acc, + [key]: { + yearMonth: location.yearMonth, + locations: [...locationsInMonth.locations, location], + monthlyExpense: locationsInMonth.monthlyExpense + location.bills.reduce((acc, bill) => bill.paid ? acc + (bill.payedAmount ?? 0) : acc, 0) + } + }) + } + + return({ + ...acc, + [key]: { + yearMonth: location.yearMonth, + locations: [location], + monthlyExpense: location.bills.reduce((acc, bill) => bill.paid ? acc + (bill.payedAmount ?? 0) : acc, 0) + } + }); + }, {} as {[key:string]:{ + yearMonth: YearMonth, + locations: BillingLocation[], + monthlyExpense: number + } }); + + return ( + + ); +} + +export default HomePage; \ No newline at end of file diff --git a/app/ui/MonthCardSceleton.tsx b/app/ui/MonthCardSceleton.tsx new file mode 100644 index 0000000..bc88b4b --- /dev/null +++ b/app/ui/MonthCardSceleton.tsx @@ -0,0 +1,32 @@ +import { Cog8ToothIcon, PlusCircleIcon } from "@heroicons/react/24/outline"; +import React from "react" + +const LocationCardSkeleton: React.FC = () => +
+
+

+
+
; + +export interface MonthCardSkeletonProps { + checked?: boolean; +} + +export const MonthCardSkeleton: React.FC = ({checked=false}) => +
+ +
+
+
+ + +
+
; + + +export const HomePageSkeleton: React.FC = () => +<> + + + +; \ No newline at end of file diff --git a/app/ui/MonthLocationList.tsx b/app/ui/MonthLocationList.tsx index 8afee17..72c5ac3 100644 --- a/app/ui/MonthLocationList.tsx +++ b/app/ui/MonthLocationList.tsx @@ -18,8 +18,8 @@ const getNextYearMonth = (yearMonth:YearMonth) => { } export interface MonthLocationListProps { - availableYears: number[]; - months: { + availableYears?: number[]; + months?: { [key: string]: { yearMonth: YearMonth; locations: BillingLocation[]; @@ -36,6 +36,20 @@ export const MonthLocationList:React.FC = ({ const router = useRouter(); const params = useParams(); + if(!availableYears || !months) { + const currentYearMonth:YearMonth = { + year: new Date().getFullYear(), + month: new Date().getMonth() + 1 + }; + + return( + <> + {}}> + + + ) + }; + const { month: initialMonth } = params; const [expandedMonth, setExpandedMonth] = React.useState(