Add payment modal for reloading credits with simulated payment flow
Some checks failed
continuous-integration/drone/push Build was killed
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:
108
src/App.js
108
src/App.js
@@ -41,17 +41,24 @@ function App() {
|
||||
setIsMobileMenuOpen(false);
|
||||
};
|
||||
|
||||
const [showPayment, setShowPayment] = useState(false);
|
||||
|
||||
const handleReloadCredits = () => {
|
||||
const input = window.prompt('¿Cuántos créditos desea recargar?');
|
||||
if (input == null) return;
|
||||
const add = parseInt(input, 10);
|
||||
if (Number.isNaN(add) || add <= 0) {
|
||||
alert('Ingrese un número válido mayor a 0.');
|
||||
return;
|
||||
// Abrir modal de pasarela de pago
|
||||
setShowPayment(true);
|
||||
};
|
||||
|
||||
const handlePaymentClose = () => setShowPayment(false);
|
||||
|
||||
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;
|
||||
setCredits(next);
|
||||
try { localStorage.setItem('credits', String(next)); } catch {}
|
||||
setShowPayment(false);
|
||||
};
|
||||
|
||||
const headerTitle = activeView === 'scheduled'
|
||||
@@ -68,6 +75,25 @@ function App() {
|
||||
? 'Perfil'
|
||||
: '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 (
|
||||
<div className="container">
|
||||
<Sidebar
|
||||
@@ -99,6 +125,70 @@ function App() {
|
||||
</div>
|
||||
</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>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user