mirror of
https://github.com/spliit-app/spliit.git
synced 2026-03-07 20:59:05 +01:00
Use tRPC in other group pages (#249)
* Use tRPC in group edition + group layout * Use tRPC in group modals * Use tRPC in group stats * Use tRPC in group activity
This commit is contained in:
committed by
GitHub
parent
66e15e419e
commit
210c12b7ef
27
src/app/groups/[groupId]/stats/page.client.tsx
Normal file
27
src/app/groups/[groupId]/stats/page.client.tsx
Normal file
@@ -0,0 +1,27 @@
|
||||
import { Totals } from '@/app/groups/[groupId]/stats/totals'
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from '@/components/ui/card'
|
||||
import { useTranslations } from 'next-intl'
|
||||
|
||||
export function TotalsPageClient({ groupId }: { groupId: string }) {
|
||||
const t = useTranslations('Stats')
|
||||
|
||||
return (
|
||||
<>
|
||||
<Card className="mb-4">
|
||||
<CardHeader>
|
||||
<CardTitle>{t('Totals.title')}</CardTitle>
|
||||
<CardDescription>{t('Totals.description')}</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="flex flex-col space-y-4">
|
||||
<Totals groupId={groupId} />
|
||||
</CardContent>
|
||||
</Card>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -1,17 +1,5 @@
|
||||
import { cached } from '@/app/cached-functions'
|
||||
import { Totals } from '@/app/groups/[groupId]/stats/totals'
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from '@/components/ui/card'
|
||||
import { getGroupExpenses } from '@/lib/api'
|
||||
import { getTotalGroupSpending } from '@/lib/totals'
|
||||
import { TotalsPageClient } from '@/app/groups/[groupId]/stats/page.client'
|
||||
import { Metadata } from 'next'
|
||||
import { getTranslations } from 'next-intl/server'
|
||||
import { notFound } from 'next/navigation'
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Totals',
|
||||
@@ -22,28 +10,5 @@ export default async function TotalsPage({
|
||||
}: {
|
||||
params: { groupId: string }
|
||||
}) {
|
||||
const t = await getTranslations('Stats')
|
||||
const group = await cached.getGroup(groupId)
|
||||
if (!group) notFound()
|
||||
|
||||
const expenses = await getGroupExpenses(groupId)
|
||||
const totalGroupSpendings = getTotalGroupSpending(expenses)
|
||||
|
||||
return (
|
||||
<>
|
||||
<Card className="mb-4">
|
||||
<CardHeader>
|
||||
<CardTitle>{t('Totals.title')}</CardTitle>
|
||||
<CardDescription>{t('Totals.description')}</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="flex flex-col space-y-4">
|
||||
<Totals
|
||||
group={group}
|
||||
expenses={expenses}
|
||||
totalGroupSpendings={totalGroupSpendings}
|
||||
/>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</>
|
||||
)
|
||||
return <TotalsPageClient groupId={groupId} />
|
||||
}
|
||||
|
||||
@@ -1,30 +1,16 @@
|
||||
'use client'
|
||||
import { getGroup, getGroupExpenses } from '@/lib/api'
|
||||
import { getTotalActiveUserShare } from '@/lib/totals'
|
||||
import { cn, formatCurrency } from '@/lib/utils'
|
||||
import { useLocale, useTranslations } from 'next-intl'
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
type Props = {
|
||||
group: NonNullable<Awaited<ReturnType<typeof getGroup>>>
|
||||
expenses: NonNullable<Awaited<ReturnType<typeof getGroupExpenses>>>
|
||||
}
|
||||
|
||||
export function TotalsYourShare({ group, expenses }: Props) {
|
||||
export function TotalsYourShare({
|
||||
totalParticipantShare = 0,
|
||||
currency,
|
||||
}: {
|
||||
totalParticipantShare?: number
|
||||
currency: string
|
||||
}) {
|
||||
const locale = useLocale()
|
||||
const t = useTranslations('Stats.Totals')
|
||||
const [activeUser, setActiveUser] = useState('')
|
||||
|
||||
useEffect(() => {
|
||||
const activeUser = localStorage.getItem(`${group.id}-activeUser`)
|
||||
if (activeUser) setActiveUser(activeUser)
|
||||
}, [group, expenses])
|
||||
|
||||
const totalActiveUserShare =
|
||||
activeUser === '' || activeUser === 'None'
|
||||
? 0
|
||||
: getTotalActiveUserShare(activeUser, expenses)
|
||||
const currency = group.currency
|
||||
|
||||
return (
|
||||
<div>
|
||||
@@ -32,10 +18,10 @@ export function TotalsYourShare({ group, expenses }: Props) {
|
||||
<div
|
||||
className={cn(
|
||||
'text-lg',
|
||||
totalActiveUserShare < 0 ? 'text-green-600' : 'text-red-600',
|
||||
totalParticipantShare < 0 ? 'text-green-600' : 'text-red-600',
|
||||
)}
|
||||
>
|
||||
{formatCurrency(currency, Math.abs(totalActiveUserShare), locale)}
|
||||
{formatCurrency(currency, Math.abs(totalParticipantShare), locale)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -1,26 +1,19 @@
|
||||
'use client'
|
||||
import { getGroup, getGroupExpenses } from '@/lib/api'
|
||||
import { useActiveUser } from '@/lib/hooks'
|
||||
import { getTotalActiveUserPaidFor } from '@/lib/totals'
|
||||
import { cn, formatCurrency } from '@/lib/utils'
|
||||
import { useLocale, useTranslations } from 'next-intl'
|
||||
|
||||
type Props = {
|
||||
group: NonNullable<Awaited<ReturnType<typeof getGroup>>>
|
||||
expenses: NonNullable<Awaited<ReturnType<typeof getGroupExpenses>>>
|
||||
}
|
||||
|
||||
export function TotalsYourSpendings({ group, expenses }: Props) {
|
||||
export function TotalsYourSpendings({
|
||||
totalParticipantSpendings = 0,
|
||||
currency,
|
||||
}: {
|
||||
totalParticipantSpendings?: number
|
||||
currency: string
|
||||
}) {
|
||||
const locale = useLocale()
|
||||
const t = useTranslations('Stats.Totals')
|
||||
const activeUser = useActiveUser(group.id)
|
||||
|
||||
const totalYourSpendings =
|
||||
activeUser === '' || activeUser === 'None'
|
||||
? 0
|
||||
: getTotalActiveUserPaidFor(activeUser, expenses)
|
||||
const currency = group.currency
|
||||
const balance = totalYourSpendings < 0 ? 'yourEarnings' : 'yourSpendings'
|
||||
const balance =
|
||||
totalParticipantSpendings < 0 ? 'yourEarnings' : 'yourSpendings'
|
||||
|
||||
return (
|
||||
<div>
|
||||
@@ -29,10 +22,10 @@ export function TotalsYourSpendings({ group, expenses }: Props) {
|
||||
<div
|
||||
className={cn(
|
||||
'text-lg',
|
||||
totalYourSpendings < 0 ? 'text-green-600' : 'text-red-600',
|
||||
totalParticipantSpendings < 0 ? 'text-green-600' : 'text-red-600',
|
||||
)}
|
||||
>
|
||||
{formatCurrency(currency, Math.abs(totalYourSpendings), locale)}
|
||||
{formatCurrency(currency, Math.abs(totalParticipantSpendings), locale)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -2,19 +2,36 @@
|
||||
import { TotalsGroupSpending } from '@/app/groups/[groupId]/stats/totals-group-spending'
|
||||
import { TotalsYourShare } from '@/app/groups/[groupId]/stats/totals-your-share'
|
||||
import { TotalsYourSpendings } from '@/app/groups/[groupId]/stats/totals-your-spending'
|
||||
import { getGroup, getGroupExpenses } from '@/lib/api'
|
||||
import { Skeleton } from '@/components/ui/skeleton'
|
||||
import { useActiveUser } from '@/lib/hooks'
|
||||
import { trpc } from '@/trpc/client'
|
||||
|
||||
export function Totals({
|
||||
group,
|
||||
expenses,
|
||||
totalGroupSpendings,
|
||||
}: {
|
||||
group: NonNullable<Awaited<ReturnType<typeof getGroup>>>
|
||||
expenses: NonNullable<Awaited<ReturnType<typeof getGroupExpenses>>>
|
||||
totalGroupSpendings: number
|
||||
}) {
|
||||
const activeUser = useActiveUser(group.id)
|
||||
export function Totals({ groupId }: { groupId: string }) {
|
||||
const activeUser = useActiveUser(groupId)
|
||||
|
||||
const participantId =
|
||||
activeUser && activeUser !== 'None' ? activeUser : undefined
|
||||
const { data } = trpc.groups.stats.get.useQuery({ groupId, participantId })
|
||||
const { data: groupData } = trpc.groups.get.useQuery({ groupId })
|
||||
|
||||
if (!data || !groupData)
|
||||
return (
|
||||
<div className="flex flex-col gap-7">
|
||||
{[0, 1, 2].map((index) => (
|
||||
<div key={index}>
|
||||
<Skeleton className="mt-1 h-3 w-48" />
|
||||
<Skeleton className="mt-3 h-4 w-20" />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
|
||||
const {
|
||||
totalGroupSpendings,
|
||||
totalParticipantShare,
|
||||
totalParticipantSpendings,
|
||||
} = data
|
||||
const { group } = groupData
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -22,10 +39,16 @@ export function Totals({
|
||||
totalGroupSpendings={totalGroupSpendings}
|
||||
currency={group.currency}
|
||||
/>
|
||||
{activeUser && activeUser !== 'None' && (
|
||||
{participantId && (
|
||||
<>
|
||||
<TotalsYourSpendings group={group} expenses={expenses} />
|
||||
<TotalsYourShare group={group} expenses={expenses} />
|
||||
<TotalsYourSpendings
|
||||
totalParticipantSpendings={totalParticipantSpendings}
|
||||
currency={group.currency}
|
||||
/>
|
||||
<TotalsYourShare
|
||||
totalParticipantShare={totalParticipantShare}
|
||||
currency={group.currency}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
|
||||
Reference in New Issue
Block a user