import { useQuery } from '@tanstack/react-query' import { useNavigate } from '@tanstack/react-router' import { CalendarClock, Loader2, Plus, UserCheck, Users, Wallet, type LucideIcon } from 'lucide-react' import type { HomeSummaryDto, NextClassDto, PaymentDto, UpcomingPaymentDto } from '@gruperly/shared' import { Badge, Button } from '../components/ui' import { getHomeSummary } from '../lib/api' import { formatPrice, formatRelativeDateTime, formatSchedule, PAYMENT_STATUS_LABELS, } from '../lib/format' import { cn } from '../lib/utils' const PAYMENT_BADGE_VARIANT: Record< PaymentDto['status'], 'success' | 'warning' | 'danger' | 'neutral' > = { PENDING: 'warning', OVERDUE: 'danger', PAID: 'success', CANCELLED: 'neutral', } function NextClassHero({ nextClass }: { nextClass: NextClassDto }) { const navigate = useNavigate() const hasSchedule = (nextClass.days?.length ?? 0) > 0 return (

{nextClass.isNow ? 'Clase en curso' : 'Próxima clase'}

{nextClass.name}

{hasSchedule ? (
{formatSchedule(nextClass.days ?? [], nextClass.time)}
) : null}
{nextClass.isNow ? 'En curso ahora' : formatRelativeDateTime(nextClass.occurrenceAt)}
) } function UpcomingPaymentRow({ payment }: { payment: UpcomingPaymentDto }) { return (
  • {payment.attendeeName}

    {payment.groupName} · {formatRelativeDateTime(payment.dueDate)}

    {formatPrice(payment.amount)} {PAYMENT_STATUS_LABELS[payment.status]}
  • ) } function SummaryStats({ summary }: { summary: HomeSummaryDto }) { const navigate = useNavigate() const stats: { label: string value: string sub?: string icon: LucideIcon to: '/groups' | '/payments' }[] = [ { label: 'Grupos activos', value: String(summary.stats.groups), icon: Users, to: '/groups', }, { label: 'Cobros pendientes', value: summary.stats.pendingAmount > 0 ? formatPrice(summary.stats.pendingAmount) : '0', sub: `${summary.stats.pendingPayments} por cobrar`, icon: Wallet, to: '/payments', }, { label: 'Asistentes', value: String(summary.stats.attendees), icon: UserCheck, to: '/groups', }, ] return (
    {stats.map((stat) => { const Icon = stat.icon return ( ) })}
    ) } export function HomeView() { const navigate = useNavigate() const summaryQuery = useQuery({ queryKey: ['home-summary'], queryFn: getHomeSummary, }) return (

    Inicio

    Tu actividad de cobros de un vistazo.

    {summaryQuery.isPending ? (
    ) : null} {summaryQuery.isError ? (

    No pudimos cargar tu resumen.

    ) : null} {summaryQuery.isSuccess && summaryQuery.data.stats.groups === 0 ? (

    Todavía no tenés grupos

    Crea tu primer grupo para empezar a cobrar.

    ) : null} {summaryQuery.isSuccess && summaryQuery.data.stats.groups > 0 ? (
    {summaryQuery.data.nextClass ? ( ) : (

    Sin clases programadas

    Agregá días y horario a tus grupos para ver tu próxima clase acá.

    )}

    Próximos cobros

    {summaryQuery.data.upcomingPayments.length > 0 ? (
      {summaryQuery.data.upcomingPayments.map((payment) => ( ))}
    ) : (

    Sin cobros pendientes por ahora.

    )}
    ) : null}
    ) }