'use client'; import * as React from 'react'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { RefreshCw, Zap } from 'lucide-react'; import { atualizarFaturasAtrasadas, gerarFaturasMes, listFaturas, marcarFaturaPaga, type FaturaListItem, type FaturaStatus, } from '@/lib/api/faturas'; import { listTenants } from '@/lib/api/tenants'; import { ApiError } from '@/lib/api/client'; import { formatCurrency, formatDate } from '@/lib/format'; import { toast } from '@/lib/toast'; import { Button } from '@/components/ui/button'; import { Combobox } from '@/components/ui/combobox'; import { DataTable, type DataTableColumn } from '@/components/ui/data-table'; import { Input } from '@/components/ui/input'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { StatusPill } from '@/components/ui/status-pill'; import { ConfirmDialog } from '@/components/domain/confirm-dialog'; const STATUS_OPTIONS: { value: FaturaStatus | 'todos'; label: string }[] = [ { value: 'todos', label: 'Todos os status' }, { value: 'pendente', label: 'Pendente' }, { value: 'pago', label: 'Pago' }, { value: 'atrasado', label: 'Atrasado' }, { value: 'cancelado', label: 'Cancelado' }, ]; const LIMIT = 20; export default function FaturasPage() { const queryClient = useQueryClient(); const [status, setStatus] = React.useState('todos'); const [tenantId, setTenantId] = React.useState(''); const [referencia, setReferencia] = React.useState(''); const [page, setPage] = React.useState(1); const [gerarOpen, setGerarOpen] = React.useState(false); const [atualizarOpen, setAtualizarOpen] = React.useState(false); const { data: tenantsOptions } = useQuery({ queryKey: ['master', 'tenants', 'combobox'], queryFn: () => listTenants({ limit: 100 }), }); const { data, isLoading } = useQuery({ queryKey: ['master', 'faturas', { status, tenantId, referencia, page }], queryFn: () => listFaturas({ status: status === 'todos' ? undefined : status, tenant_id: tenantId || undefined, referencia: referencia || undefined, page, limit: LIMIT, }), placeholderData: (prev) => prev, }); const marcarPagoMutation = useMutation({ mutationFn: (id: string) => marcarFaturaPaga(id), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['master', 'faturas'] }); queryClient.invalidateQueries({ queryKey: ['master', 'dashboard'] }); toast.success('Fatura marcada como paga.'); }, onError: (err) => { toast.error(err instanceof ApiError ? err.message : 'Não foi possível marcar a fatura como paga.'); }, }); const gerarMutation = useMutation({ mutationFn: () => gerarFaturasMes(), onSuccess: (result) => { queryClient.invalidateQueries({ queryKey: ['master', 'faturas'] }); toast.success(`${result.criadas} fatura(s) geradas para ${result.referencia} (${result.ignoradas} já existiam).`); setGerarOpen(false); }, onError: (err) => { toast.error(err instanceof ApiError ? err.message : 'Não foi possível gerar as faturas do mês.'); }, }); const atualizarMutation = useMutation({ mutationFn: () => atualizarFaturasAtrasadas(), onSuccess: (result) => { queryClient.invalidateQueries({ queryKey: ['master', 'faturas'] }); queryClient.invalidateQueries({ queryKey: ['master', 'tenants'] }); toast.success(`${result.atualizadas} fatura(s) marcadas como atrasadas (${result.tenants_afetados} tenant(s) afetados).`); setAtualizarOpen(false); }, onError: (err) => { toast.error(err instanceof ApiError ? err.message : 'Não foi possível atualizar as faturas atrasadas.'); }, }); const columns: DataTableColumn[] = [ { id: 'tenant', header: 'Tenant', primary: true, cell: (row) => row.tenant.razao_social }, { id: 'referencia', header: 'Referência', cell: (row) => row.referencia }, { id: 'valor', header: 'Valor', cell: (row) => formatCurrency(row.valor) }, { id: 'vencimento', header: 'Vencimento', cell: (row) => formatDate(row.vencimento) }, { id: 'status', header: 'Status', primary: true, cell: (row) => }, ]; const tenantComboboxOptions = (tenantsOptions?.data ?? []).map((t) => ({ value: t.id, label: t.nome_fantasia || t.razao_social, })); return (

Faturas

Mensalidades cobradas dos tenants

{ setTenantId(value); setPage(1); }} placeholder="Todos os tenants" searchPlaceholder="Buscar tenant..." className="w-full sm:w-56" /> { setReferencia(e.target.value); setPage(1); }} className="w-full sm:w-40" />
row.id} loading={isLoading} emptyTitle="Nenhuma fatura encontrada" emptyDescription="Ajuste os filtros ou gere as faturas do mês." rowActions={(row) => row.status !== 'pago' && row.status !== 'cancelado' ? ( ) : null } pagination={ data ? { page: data.meta.page, limit: data.meta.limit, total: data.meta.total, onPageChange: setPage } : undefined } /> gerarMutation.mutate()} /> atualizarMutation.mutate()} />
); }