import React, { useState } from 'react'; import { DollarSign, Users, TrendingUp, Calculator, Plus, Search, X, Check, CreditCard, History, FileText } from 'lucide-react'; export default function LoanApp() { const [activeTab, setActiveTab] = useState('dashboard'); const [loans, setLoans] = useState([ { id: 1, client: 'Juan Pérez', amount: 5000, rate: 12, term: 12, date: '2024-01-15', status: 'active', payments: Array.from({length: 12}, (_, i) => ({ number: i + 1, amount: 444.24, dueDate: new Date(2024, i + 1, 15).toISOString().split('T')[0], paid: i < 3, paidDate: i < 3 ? new Date(2024, i + 1, 14).toISOString().split('T')[0] : null })) }, { id: 2, client: 'María García', amount: 10000, rate: 10, term: 24, date: '2024-02-20', status: 'active', payments: Array.from({length: 24}, (_, i) => ({ number: i + 1, amount: 461.45, dueDate: new Date(2024, 2 + i, 20).toISOString().split('T')[0], paid: i < 5, paidDate: i < 5 ? new Date(2024, 2 + i, 19).toISOString().split('T')[0] : null })) }, { id: 3, client: 'Carlos López', amount: 3000, rate: 15, term: 6, date: '2024-03-10', status: 'paid', payments: Array.from({length: 6}, (_, i) => ({ number: i + 1, amount: 521.27, dueDate: new Date(2024, 3 + i, 10).toISOString().split('T')[0], paid: true, paidDate: new Date(2024, 3 + i, 9).toISOString().split('T')[0] })) }, ]); const [showNewLoan, setShowNewLoan] = useState(false); const [showDetail, setShowDetail] = useState(false); const [selected, setSelected] = useState(null); const [newLoan, setNewLoan] = useState({client: '', amount: '', rate: '', term: ''}); const [calc, setCalc] = useState({amount: 10000, rate: 12, term: 12}); const [search, setSearch] = useState(''); const [filter, setFilter] = useState('all'); const calcPayment = (p, r, m) => { const mr = r / 100 / 12; return (p * (mr * Math.pow(1 + mr, m)) / (Math.pow(1 + mr, m) - 1)).toFixed(2); }; const addLoan = () => { if (!newLoan.client || !newLoan.amount || !newLoan.rate || !newLoan.term) return; const mp = parseFloat(calcPayment(parseFloat(newLoan.amount), parseFloat(newLoan.rate), parseInt(newLoan.term))); const loan = { id: loans.length + 1, client: newLoan.client, amount: parseFloat(newLoan.amount), rate: parseFloat(newLoan.rate), term: parseInt(newLoan.term), date: new Date().toISOString().split('T')[0], status: 'active', payments: Array.from({length: parseInt(newLoan.term)}, (_, i) => ({ number: i + 1, amount: mp, dueDate: new Date(Date.now() + (i + 1) * 30 * 24 * 60 * 60 * 1000).toISOString().split('T')[0], paid: false, paidDate: null })) }; setLoans([...loans, loan]); setNewLoan({client: '', amount: '', rate: '', term: ''}); setShowNewLoan(false); }; const pay = (lid, pnum) => { const updatedLoans = loans.map(l => { if (l.id === lid) { const up = l.payments.map(p => p.number === pnum ? {...p, paid: true, paidDate: new Date().toISOString().split('T')[0]} : p); const updatedLoan = {...l, payments: up, status: up.every(p => p.paid) ? 'paid' : 'active'}; setSelected(updatedLoan); return updatedLoan; } return l; }); setLoans(updatedLoans); }; const openDetail = (l) => { setSelected(l); setShowDetail(true); }; const total = loans.reduce((s, l) => s + l.amount, 0); const active = loans.filter(l => l.status === 'active').length; const avgR = loans.length > 0 ? (loans.reduce((s, l) => s + l.rate, 0) / loans.length).toFixed(1) : 0; const history = loans.flatMap(l => l.payments.filter(p => p.paid).map(p => ({...p, client: l.client}))).sort((a, b) => new Date(b.paidDate) - new Date(a.paidDate)); const filtered = loans.filter(l => l.client.toLowerCase().includes(search.toLowerCase()) && (filter === 'all' || l.status === filter)); return (

Sistema de Préstamos

{[ {id: 'dashboard', label: 'Panel', icon: TrendingUp}, {id: 'loans', label: 'Préstamos', icon: FileText}, {id: 'history', label: 'Historial', icon: History}, {id: 'calculator', label: 'Calculadora', icon: Calculator} ].map(t => ( ))}
{activeTab === 'dashboard' && (

Total Prestado

${total.toLocaleString()}

Activos

{active}

Tasa Promedio

{avgR}%

Préstamos Recientes

{loans.slice(-3).reverse().map(l => ( ))}
Cliente Monto Estado Acción
{l.client} ${l.amount.toLocaleString()} {l.status === 'active' ? 'Activo' : 'Pagado'}
)} {activeTab === 'loans' && (

Todos los Préstamos

setSearch(e.target.value)} className="pl-10 pr-4 py-2 border rounded-lg w-full focus:ring-2 focus:ring-indigo-500" />
{filtered.map(l => { const paid = l.payments.filter(p => p.paid).length; return ( ); })}
Cliente Monto Progreso Estado Acción
{l.client} ${l.amount.toLocaleString()} {paid}/{l.payments.length} {l.status === 'active' ? 'Activo' : 'Pagado'}
)} {activeTab === 'history' && (

Historial de Pagos

{history.length === 0 ? ( ) : ( history.map((p, i) => ( )) )}
Fecha Cliente Cuota Monto
No hay pagos
{p.paidDate} {p.client} #{p.number} ${p.amount.toFixed(2)}
)} {activeTab === 'calculator' && (

Calculadora

setCalc({...calc, amount: parseFloat(e.target.value)})} className="w-full" />
setCalc({...calc, rate: parseFloat(e.target.value)})} className="w-full" />
setCalc({...calc, term: parseInt(e.target.value)})} className="w-full" />

Resumen

Monto: ${calc.amount.toLocaleString()}
Cuota: ${calcPayment(calc.amount, calc.rate, calc.term)}
Total: ${(calcPayment(calc.amount, calc.rate, calc.term) * calc.term).toFixed(2)}
Interés: ${((calcPayment(calc.amount, calc.rate, calc.term) * calc.term) - calc.amount).toFixed(2)}
)}
{showNewLoan && (

Nuevo Préstamo

setNewLoan({...newLoan, client: e.target.value})} className="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-indigo-500" /> setNewLoan({...newLoan, amount: e.target.value})} className="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-indigo-500" /> setNewLoan({...newLoan, rate: e.target.value})} className="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-indigo-500" /> setNewLoan({...newLoan, term: e.target.value})} className="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-indigo-500" />
)} {showDetail && selected && (

{selected.client}

Préstamo #{selected.id}

Monto

${selected.amount.toLocaleString()}

Tasa

{selected.rate}%

Plazo

{selected.term} meses

Cuota

${calcPayment(selected.amount, selected.rate, selected.term)}

Tabla de Pagos

{selected.payments.map(p => ( ))}
Cuota Vencimiento Monto Estado Acción
#{p.number} {p.dueDate} ${p.amount.toFixed(2)} {p.paid ? ( Pagado ) : ( Pendiente )} {!p.paid && ( )}
)}
); }