Add payment modal for reloading credits with simulated payment flow
Some checks failed
continuous-integration/drone/push Build was killed

Integrated a modal to handle credit reloading with a simulated payment process. Updated logic to manage payment amount, successful payment handling, and credit updates. Improved UI with validations and placeholders for future payment gateway integration.
This commit is contained in:
2025-11-22 22:46:35 -04:00
parent 1458c143bc
commit f038fe4c69

View File

@@ -41,17 +41,24 @@ function App() {
setIsMobileMenuOpen(false); setIsMobileMenuOpen(false);
}; };
const [showPayment, setShowPayment] = useState(false);
const handleReloadCredits = () => { const handleReloadCredits = () => {
const input = window.prompt('¿Cuántos créditos desea recargar?'); // Abrir modal de pasarela de pago
if (input == null) return; setShowPayment(true);
const add = parseInt(input, 10); };
if (Number.isNaN(add) || add <= 0) {
alert('Ingrese un número válido mayor a 0.'); const handlePaymentClose = () => setShowPayment(false);
return;
const handlePaymentSuccess = (amount) => {
// Actualizar créditos después de un pago exitoso
const add = parseInt(amount, 10);
if (!Number.isNaN(add) && add > 0) {
const next = credits + add;
setCredits(next);
try { localStorage.setItem('credits', String(next)); } catch {}
} }
const next = credits + add; setShowPayment(false);
setCredits(next);
try { localStorage.setItem('credits', String(next)); } catch {}
}; };
const headerTitle = activeView === 'scheduled' const headerTitle = activeView === 'scheduled'
@@ -68,6 +75,25 @@ function App() {
? 'Perfil' ? 'Perfil'
: 'Dashboard'; : 'Dashboard';
const [paymentAmount, setPaymentAmount] = useState('');
const [isPaying, setIsPaying] = useState(false);
const proceedPayment = async () => {
const val = parseInt(paymentAmount, 10);
if (Number.isNaN(val) || val <= 0) {
alert('Ingrese un monto válido mayor a 0.');
return;
}
// Simulación de pasarela de pago
try {
setIsPaying(true);
await new Promise((res) => setTimeout(res, 1200));
handlePaymentSuccess(val);
} finally {
setIsPaying(false);
}
};
return ( return (
<div className="container"> <div className="container">
<Sidebar <Sidebar
@@ -99,6 +125,70 @@ function App() {
</div> </div>
</section> </section>
)} )}
{showPayment && (
<div className="modal-overlay" onClick={handlePaymentClose}>
<div className="modal" onClick={(e) => e.stopPropagation()}>
<div className="modal-header">
<h3>
<i className="fas fa-credit-card"></i>
Recargar créditos
</h3>
<button className="btn btn-outline btn-sm" onClick={handlePaymentClose} disabled={isPaying}>
<i className="fas fa-times"></i> Cerrar
</button>
</div>
<div className="modal-body">
<div className="form-container">
<div className="form-row">
<div className="form-group" style={{ flex: 1 }}>
<label>
<i className="fas fa-coins" aria-hidden="true"></i> Monto a recargar (créditos)
</label>
<input
className="input"
type="number"
min={1}
step={1}
value={paymentAmount}
onChange={(e) => setPaymentAmount(e.target.value)}
placeholder="Ej: 10"
disabled={isPaying}
autoFocus
/>
</div>
</div>
{/* Placeholder de pasarela de pago: reemplace con su integración real (Mercado Pago, Stripe, etc.) */}
<div className="card" style={{ marginTop: 12 }}>
<div className="form-header">
<h3>
<i className="fas fa-shield-alt" style={{ marginRight: 8 }}></i>
Pasarela de pago
</h3>
</div>
<div style={{ padding: 12 }}>
<p style={{ marginTop: 0, color: 'var(--gray)' }}>
Esta es una simulación. Conecte aquí su pasarela (iframe, checkout, etc.).
</p>
<button className="btn btn-primary" onClick={proceedPayment} disabled={isPaying}>
{isPaying ? (
<>
<i className="fas fa-spinner fa-spin"></i> Procesando...
</>
) : (
<>
<i className="fas fa-lock"></i> Pagar y recargar
</>
)}
</button>
</div>
</div>
</div>
</div>
</div>
</div>
)}
</main> </main>
</div> </div>
); );