81 lines
2.7 KiB
TypeScript
81 lines
2.7 KiB
TypeScript
import { useQuery } from '@tanstack/react-query'
|
|
import { useNavigate } from '@tanstack/react-router'
|
|
import { Loader2, Plus } from 'lucide-react'
|
|
import { Button } from '../../components/ui'
|
|
import { getGroups, getGroupsRiskOverview } from '../../lib/api'
|
|
import { GroupCard } from './GroupCard'
|
|
|
|
export function GroupsView() {
|
|
const navigate = useNavigate()
|
|
const groupsQuery = useQuery({
|
|
queryKey: ['groups'],
|
|
queryFn: getGroups,
|
|
})
|
|
const riskQuery = useQuery({
|
|
queryKey: ['groups-risk-overview'],
|
|
queryFn: getGroupsRiskOverview,
|
|
})
|
|
|
|
const riskByGroup = new Map(
|
|
(riskQuery.data?.items ?? []).map((item) => [item.groupId, item.riskLevel]),
|
|
)
|
|
|
|
return (
|
|
<section>
|
|
<div className="flex items-center justify-between gap-3">
|
|
<div>
|
|
<h1 className="text-2xl font-bold text-primary">Grupos</h1>
|
|
<p className="mt-2 text-sm text-foreground/60">Tus grupos de cobranza.</p>
|
|
</div>
|
|
<Button variant="primary" onClick={() => void navigate({ to: '/groups/new' })}>
|
|
<Plus className="size-4" />
|
|
Crear
|
|
</Button>
|
|
</div>
|
|
|
|
{groupsQuery.isPending ? (
|
|
<div className="mt-8 flex items-center justify-center py-16">
|
|
<Loader2 className="size-6 animate-spin text-foreground/40" />
|
|
</div>
|
|
) : null}
|
|
|
|
{groupsQuery.isError ? (
|
|
<div className="mt-8 space-y-3 rounded-xl bg-danger-soft px-4 py-3 text-sm text-danger">
|
|
<p>No pudimos cargar tus grupos.</p>
|
|
<Button variant="outline" size="sm" onClick={() => void groupsQuery.refetch()}>
|
|
Reintentar
|
|
</Button>
|
|
</div>
|
|
) : null}
|
|
|
|
{groupsQuery.isSuccess && groupsQuery.data.data.length === 0 ? (
|
|
<div className="mt-8 rounded-xl border border-dashed border-border bg-surface px-4 py-12 text-center">
|
|
<p className="font-medium text-primary">Todavía no tenés grupos</p>
|
|
<p className="mt-1 text-sm text-foreground/60">
|
|
Crea tu primer grupo para empezar a cobrar.
|
|
</p>
|
|
<Button
|
|
variant="primary"
|
|
className="mt-5"
|
|
onClick={() => void navigate({ to: '/groups/new' })}
|
|
>
|
|
<Plus className="size-4" />
|
|
Crear tu primer grupo
|
|
</Button>
|
|
</div>
|
|
) : null}
|
|
|
|
{groupsQuery.isSuccess && groupsQuery.data.data.length > 0 ? (
|
|
<div className="mt-6 grid gap-4">
|
|
{groupsQuery.data.data.map((group) => (
|
|
<GroupCard
|
|
key={group.id}
|
|
group={group}
|
|
riskLevel={riskByGroup.get(group.id) ?? 'NONE'}
|
|
/>
|
|
))}
|
|
</div>
|
|
) : null}
|
|
</section>
|
|
)
|
|
} |