// src/pages/SaldoPendiente.jsx import { useState, useEffect, useMemo } from "react"; import { api } from "../lib/api"; import { Loader, ErrorBox, Filters, Select } from "../components/UI"; const CUOTAS = ["1° Cuota","2° Cuota","3° Cuota","4° Cuota","5° Cuota"]; function toNum(v){ const n=parseFloat(String(v).replace("S/","").replace(/,/g,"").trim()); return isNaN(n)?0:n; } function fmt(v){ const n=toNum(v); return "S/ " + n.toLocaleString("es-PE",{maximumFractionDigits:0}); } export default function SaldoPendiente() { const [tipoCuota, setTipoCuota] = useState("1° Cuota"); const [datos, setDatos] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [vendedor, setVendedor] = useState("TODOS"); useEffect(() => { let activo = true; setLoading(true); setError(null); api.saldoPendiente(tipoCuota) .then((res)=>{ if(activo){setDatos(res.datos||[]);setLoading(false);} }) .catch((e)=>{ if(activo){setError(e.message);setLoading(false);} }); return ()=>{activo=false;}; }, [tipoCuota]); const colSaldo = `SALDO ${tipoCuota.toUpperCase()}`; const vendedores = useMemo(() => { const set = new Set(datos.map((d)=>String(d.VENDEDOR||"").trim()).filter(Boolean)); return ["TODOS", ...Array.from(set).sort()]; }, [datos]); const filtrados = useMemo(() => { let arr = datos.filter((d)=>toNum(d[colSaldo])>0.01); if (vendedor!=="TODOS") arr = arr.filter((d)=>String(d.VENDEDOR||"").trim().toUpperCase()===vendedor.toUpperCase()); return arr; }, [datos, vendedor, colSaldo]); const totalSaldo = useMemo(()=>filtrados.reduce((s,d)=>s+toNum(d[colSaldo]),0),[filtrados,colSaldo]); const totalMat = useMemo(()=>filtrados.reduce((s,d)=>s+toNum(d["SALDO MAT."]),0),[filtrados]); const COLS = ["MATRÍCULA","VENDEDOR","ALUMNO","PROGRAMA","F. INICIO","F. MATR.","SALDO MAT.",colSaldo,"VENCIMIENTO","INV. NETA"]; const KEYS = ["MATRICULA","VENDEDOR","ALUMNO","PROGRAMA","FECHA INICIO","FECHA MATR.","SALDO MAT.",colSaldo,"VENCIMIENTO","INV. NETA"]; return (

⏳ Saldo Pendiente

{loading ? : error ? : <>
👥
Alumnos con Saldo
{filtrados.length}
⏳
Saldo {tipoCuota}
{fmt(totalSaldo)}
📋
Saldo Matrícula
{fmt(totalMat)}
{COLS.map((c)=>)} {filtrados.map((d,i)=>( {KEYS.map((k,j)=>{ const isMonto = k.includes("SALDO")||k.includes("INV"); return ( ); })} ))} {filtrados.length>0 && ( )}
{c}
{isMonto ? fmt(d[k]) : (d[k] ?? "")}
TOTAL GENERAL ({filtrados.length}) {fmt(totalMat)} {fmt(totalSaldo)} ——
}
); }