Added routes
This commit is contained in:
81
apps/web/src/features/groups/GroupsView.tsx
Normal file
81
apps/web/src/features/groups/GroupsView.tsx
Normal file
@@ -0,0 +1,81 @@
|
||||
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>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user