diff options
| author | Sebastien Castiel <sebastien@castiel.me> | 2023-12-14 12:34:15 -0500 |
|---|---|---|
| committer | Sebastien Castiel <sebastien@castiel.me> | 2023-12-14 12:34:15 -0500 |
| commit | 7e279a535d1722ce6e32a6b0c4a84b5639d8c859 (patch) | |
| tree | f83e8f00f49f54d994760c493782bcd818fd83b5 | |
| parent | 80c4baa0e13af07c202deb7822a449e6e194ebaf (diff) | |
Improve loading states
| -rw-r--r-- | src/app/groups/[groupId]/expenses/page.tsx | 46 | ||||
| -rw-r--r-- | src/app/groups/recent-group-list.tsx | 8 | ||||
| -rw-r--r-- | src/components/ui/skeleton.tsx | 15 | ||||
| -rw-r--r-- | src/lib/prisma.ts | 1 |
4 files changed, 56 insertions, 14 deletions
diff --git a/src/app/groups/[groupId]/expenses/page.tsx b/src/app/groups/[groupId]/expenses/page.tsx index 0ec5086..5285cb8 100644 --- a/src/app/groups/[groupId]/expenses/page.tsx +++ b/src/app/groups/[groupId]/expenses/page.tsx @@ -7,11 +7,13 @@ import { CardHeader, CardTitle, } from '@/components/ui/card' +import { Skeleton } from '@/components/ui/skeleton' import { getGroup, getGroupExpenses } from '@/lib/api' import { Plus } from 'lucide-react' import { Metadata } from 'next' import Link from 'next/link' import { notFound } from 'next/navigation' +import { Suspense } from 'react' export const metadata: Metadata = { title: 'Expenses', @@ -22,11 +24,6 @@ export default async function GroupExpensesPage({ }: { params: { groupId: string } }) { - const group = await getGroup(groupId) - if (!group) notFound() - - const expenses = await getGroupExpenses(groupId) - return ( <Card className="mb-4"> <div className="flex flex-1"> @@ -46,13 +43,40 @@ export default async function GroupExpensesPage({ </div> <CardContent className="p-0"> - <ExpenseList - expenses={expenses} - groupId={groupId} - currency={group.currency} - participants={group.participants} - /> + <Suspense + fallback={[0, 1, 2].map((i) => ( + <div + key={i} + className="border-t flex justify-between items-center px-6 py-4 text-sm" + > + <div className="flex flex-col gap-2"> + <Skeleton className="h-4 w-16 rounded-full" /> + <Skeleton className="h-4 w-32 rounded-full" /> + </div> + <div> + <Skeleton className="h-4 w-16 rounded-full" /> + </div> + </div> + ))} + > + <Expenses groupId={groupId} /> + </Suspense> </CardContent> </Card> ) } + +async function Expenses({ groupId }: { groupId: string }) { + const group = await getGroup(groupId) + if (!group) notFound() + const expenses = await getGroupExpenses(group.id) + + return ( + <ExpenseList + expenses={expenses} + groupId={group.id} + currency={group.currency} + participants={group.participants} + /> + ) +} diff --git a/src/app/groups/recent-group-list.tsx b/src/app/groups/recent-group-list.tsx index 60e3922..77feaf4 100644 --- a/src/app/groups/recent-group-list.tsx +++ b/src/app/groups/recent-group-list.tsx @@ -2,6 +2,7 @@ import { getGroupsAction } from '@/app/groups/actions' import { getRecentGroups } from '@/app/groups/recent-groups-helpers' import { Button } from '@/components/ui/button' +import { Skeleton } from '@/components/ui/skeleton' import { getGroups } from '@/lib/api' import { Calendar, Loader2, Users } from 'lucide-react' import Link from 'next/link' @@ -96,9 +97,10 @@ export function RecentGroupList() { </div> </div> ) : ( - <> - <Loader2 className="w-3 h-3 mr-1 inline animate-spin" /> - </> + <div className="flex justify-between"> + <Skeleton className="h-4 w-6 rounded-full" /> + <Skeleton className="h-4 w-24 rounded-full" /> + </div> )} </div> </div> diff --git a/src/components/ui/skeleton.tsx b/src/components/ui/skeleton.tsx new file mode 100644 index 0000000..01b8b6d --- /dev/null +++ b/src/components/ui/skeleton.tsx @@ -0,0 +1,15 @@ +import { cn } from "@/lib/utils" + +function Skeleton({ + className, + ...props +}: React.HTMLAttributes<HTMLDivElement>) { + return ( + <div + className={cn("animate-pulse rounded-md bg-muted", className)} + {...props} + /> + ) +} + +export { Skeleton } diff --git a/src/lib/prisma.ts b/src/lib/prisma.ts index 210e691..2886a89 100644 --- a/src/lib/prisma.ts +++ b/src/lib/prisma.ts @@ -3,6 +3,7 @@ import { PrismaClient } from '@prisma/client' let prisma: PrismaClient export async function getPrisma() { + // await delay(1000) if (!prisma) { if (process.env.NODE_ENV === 'production') { prisma = new PrismaClient() |
