aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastien Castiel <sebastien@castiel.me>2023-12-14 12:34:15 -0500
committerSebastien Castiel <sebastien@castiel.me>2023-12-14 12:34:15 -0500
commit7e279a535d1722ce6e32a6b0c4a84b5639d8c859 (patch)
treef83e8f00f49f54d994760c493782bcd818fd83b5
parent80c4baa0e13af07c202deb7822a449e6e194ebaf (diff)
Improve loading states
-rw-r--r--src/app/groups/[groupId]/expenses/page.tsx46
-rw-r--r--src/app/groups/recent-group-list.tsx8
-rw-r--r--src/components/ui/skeleton.tsx15
-rw-r--r--src/lib/prisma.ts1
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()