Skip to content

Commit

Permalink
Use tRPC in group information + better loading states
Browse files Browse the repository at this point in the history
  • Loading branch information
scastiel committed Oct 19, 2024
1 parent a91df3f commit bc3adf1
Show file tree
Hide file tree
Showing 7 changed files with 151 additions and 48 deletions.
69 changes: 66 additions & 3 deletions src/app/groups/[groupId]/balances/balances-and-reimbursements.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ import {
CardHeader,
CardTitle,
} from '@/components/ui/card'
import { Skeleton } from '@/components/ui/skeleton'
import { getGroup } from '@/lib/api'
import { trpc } from '@/trpc/client'
import { useTranslations } from 'next-intl'
import { useEffect } from 'react'
import { Fragment, useEffect } from 'react'

export default function BalancesAndReimbursements({
group,
Expand Down Expand Up @@ -42,7 +43,7 @@ export default function BalancesAndReimbursements({
</CardHeader>
<CardContent>
{isLoading || !data ? (
<p className="text-muted-foreground text-sm">Loading…</p>
<BalancesLoading participantCount={group.participants.length} />
) : (
<BalancesList
balances={data.balances}
Expand All @@ -59,7 +60,9 @@ export default function BalancesAndReimbursements({
</CardHeader>
<CardContent>
{isLoading || !data ? (
<p className="text-muted-foreground text-sm">Loading…</p>
<ReimbursementsLoading
participantCount={group.participants.length}
/>
) : (
<ReimbursementList
reimbursements={data.reimbursements}
Expand All @@ -73,3 +76,63 @@ export default function BalancesAndReimbursements({
</>
)
}

const ReimbursementsLoading = ({
participantCount,
}: {
participantCount: number
}) => {
return (
<div className="flex flex-col">
{Array(participantCount - 1)
.fill(undefined)
.map((_, index) => (
<div key={index} className="flex justify-between py-5">
<div className="flex flex-col sm:flex-row gap-3 sm:gap-4">
<Skeleton className="h-3 w-32" />
<Skeleton className="h-3 w-24" />
</div>
<Skeleton className="h-3 w-16" />
</div>
))}
</div>
)
}

const BalancesLoading = ({
participantCount,
}: {
participantCount: number
}) => {
return (
<div className="grid grid-cols-2 py-1 gap-y-2">
{Array(participantCount)
.fill(undefined)
.map((_, index) =>
index % 2 === 0 ? (
<Fragment key={index}>
<div className="flex items-center justify-end pr-2">
<Skeleton className="h-3 w-16" />
</div>
<div className="self-start">
<Skeleton
className={`h-7 w-${(index % 3) + 1}/3 rounded-l-none`}
/>
</div>
</Fragment>
) : (
<Fragment key={index}>
<div className="flex items-center justify-end">
<Skeleton
className={`h-7 w-${(index % 3) + 1}/3 rounded-r-none`}
/>
</div>
<div className="flex items-center pl-2">
<Skeleton className="h-3 w-16" />
</div>
</Fragment>
),
)}
</div>
)
}
52 changes: 52 additions & 0 deletions src/app/groups/[groupId]/information/group-information.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
'use client'

import { Button } from '@/components/ui/button'
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from '@/components/ui/card'
import { Skeleton } from '@/components/ui/skeleton'
import { trpc } from '@/trpc/client'
import { Pencil } from 'lucide-react'
import { useTranslations } from 'next-intl'
import Link from 'next/link'

export default function GroupInformation({ groupId }: { groupId: string }) {
const t = useTranslations('Information')
const { data, isLoading } = trpc.groups.information.get.useQuery({ groupId })

return (
<>
<Card className="mb-4">
<CardHeader>
<CardTitle className="flex justify-between">
<span>{t('title')}</span>
<Button size="icon" asChild className="-mb-12">
<Link href={`/groups/${groupId}/edit`}>
<Pencil className="w-4 h-4" />
</Link>
</Button>
</CardTitle>
<CardDescription className="mr-12">
{t('description')}
</CardDescription>
</CardHeader>
<CardContent className="prose prose-sm sm:prose-base max-w-full whitespace-break-spaces">
{isLoading || !data ? (
<div className="py-1 flex flex-col gap-2">
<Skeleton className="h-3 w-3/4" />
<Skeleton className="h-3 w-1/2" />
</div>
) : (
data.information || (
<p className="text-muted-foreground text-sm">{t('empty')}</p>
)
)}
</CardContent>
</Card>
</>
)
}
48 changes: 4 additions & 44 deletions src/app/groups/[groupId]/information/page.tsx
Original file line number Diff line number Diff line change
@@ -1,54 +1,14 @@
import { cached } from '@/app/cached-functions'
import { Button } from '@/components/ui/button'
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from '@/components/ui/card'
import { Pencil } from 'lucide-react'
import GroupInformation from '@/app/groups/[groupId]/information/group-information'
import { Metadata } from 'next'
import { getTranslations } from 'next-intl/server'
import Link from 'next/link'
import { notFound } from 'next/navigation'

export const metadata: Metadata = {
title: 'Totals',
title: 'Group Information',
}

export default async function InformationPage({
export default function InformationPage({
params: { groupId },
}: {
params: { groupId: string }
}) {
const group = await cached.getGroup(groupId)
if (!group) notFound()

const t = await getTranslations('Information')

return (
<>
<Card className="mb-4">
<CardHeader>
<CardTitle className="flex justify-between">
<span>{t('title')}</span>
<Button size="icon" asChild className="-mb-12">
<Link href={`/groups/${groupId}/edit`}>
<Pencil className="w-4 h-4" />
</Link>
</Button>
</CardTitle>
<CardDescription className="mr-12">
{t('description')}
</CardDescription>
</CardHeader>
<CardContent className="prose prose-sm sm:prose-base max-w-full whitespace-break-spaces">
{group.information || (
<p className="text-muted-foreground italic">{t('empty')}</p>
)}
</CardContent>
</Card>
</>
)
return <GroupInformation groupId={groupId} />
}
1 change: 0 additions & 1 deletion src/app/groups/[groupId]/stats/totals.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ export function Totals({
totalGroupSpendings: number
}) {
const activeUser = useActiveUser(group.id)
console.log('activeUser', activeUser)

return (
<>
Expand Down
2 changes: 2 additions & 0 deletions src/trpc/routers/groups/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { createTRPCRouter } from '@/trpc/init'
import { groupBalancesRouter } from '@/trpc/routers/groups/balances'
import { groupExpensesRouter } from '@/trpc/routers/groups/expenses'
import { groupInformationRouter } from '@/trpc/routers/groups/information'

export const groupsRouter = createTRPCRouter({
expenses: groupExpensesRouter,
balances: groupBalancesRouter,
information: groupInformationRouter,
})
21 changes: 21 additions & 0 deletions src/trpc/routers/groups/information/get.procedure.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { getGroup } from '@/lib/api'
import { baseProcedure } from '@/trpc/init'
import { TRPCError } from '@trpc/server'
import { z } from 'zod'

export const getGroupInformationProcedure = baseProcedure
.input(
z.object({
groupId: z.string().min(1),
}),
)
.query(async ({ input: { groupId } }) => {
const group = await getGroup(groupId)
if (!group) {
throw new TRPCError({
code: 'NOT_FOUND',
message: 'Group not found.',
})
}
return { information: group.information ?? '' }
})
6 changes: 6 additions & 0 deletions src/trpc/routers/groups/information/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { createTRPCRouter } from '@/trpc/init'
import { getGroupInformationProcedure } from '@/trpc/routers/groups/information/get.procedure'

export const groupInformationRouter = createTRPCRouter({
get: getGroupInformationProcedure,
})

0 comments on commit bc3adf1

Please sign in to comment.