import { useState } from 'react';
import { Layers } from 'lucide-react';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import {
getInstallmentPlans,
type InstallmentPlan,
} from '@/lib/api';
import { formatAmount } from '@/lib/format';
import { cn } from '@/lib/utils';
import { Badge } from '@/components/ui/badge';
import { Progress } from '@/components/ui/progress';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from '@/components/ui/table';
import ErrorState from '@/components/ErrorState';
import { PageHeader } from '@/components/page-header';
import ConvertToInstallmentsDialog from '@/components/transactions/ConvertToInstallmentsDialog';
function formatDate(iso: string) {
return new Date(iso).toLocaleDateString('es-CR', {
day: 'numeric',
month: 'short',
year: 'numeric',
});
}
function CuotasProgress({ plan }: { plan: InstallmentPlan }) {
const pct = (plan.cuotas_billed / plan.num_installments) * 100;
return (
{plan.cuotas_billed}/{plan.num_installments}
);
}
export default function Financiamientos() {
const queryClient = useQueryClient();
const [editing, setEditing] = useState(null);
const plansQ = useQuery({
queryKey: ['installment-plans'],
queryFn: () => getInstallmentPlans().then((r) => r.data),
});
const plans = plansQ.data?.plans ?? [];
const active = plans.filter((p) => !p.is_completed);
const completed = plans.filter((p) => p.is_completed);
const totalRemaining = plansQ.data?.total_remaining ?? 0;
const totalCuotaMes = active.reduce((sum, p) => sum + p.installment_amount, 0);
const handleSaved = () => {
queryClient.invalidateQueries({ queryKey: ['installment-plans'] });
queryClient.invalidateQueries({ queryKey: ['transactions'] });
queryClient.invalidateQueries({ queryKey: ['budget'] });
};
const renderRows = (rows: InstallmentPlan[]) =>
rows.map((plan) => (
setEditing(plan)}
onKeyDown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
setEditing(plan);
}
}}
>
{plan.merchant}
{plan.is_completed && (
Completado
)}
{formatDate(plan.purchase_date)}
{formatAmount(plan.installment_amount, plan.currency)}
{formatAmount(plan.total_amount, plan.currency)}
{formatAmount(plan.remaining_amount, plan.currency)}
{plan.next_cuota_date ? formatDate(plan.next_cuota_date) : '—'}
));
return (
{/* Summary */}
Saldo faltante total
{formatAmount(totalRemaining, 'CRC')}
Cuotas por mes (activos)
{formatAmount(totalCuotaMes, 'CRC')}
Planes activos
{active.length}
{completed.length > 0 && (
(+{completed.length} completado{completed.length === 1 ? '' : 's'})
)}
{/* Plans table */}
{plansQ.isError ? (
plansQ.refetch()}
/>
) : (
{plans.length === 0 && !plansQ.isPending ? (
Sin financiamientos. Convertí una compra de tarjeta a Tasa
Cero desde la lista de transacciones.
) : (
Comercio
Fecha compra
Cuotas
Monto cuota
Saldo inicial
Saldo faltante
Próxima cuota
{renderRows(active)}
{renderRows(completed)}
)}
)}
!open && setEditing(null)}
onSaved={handleSaved}
plan={editing}
/>
);
}