import React, { useState, useEffect } from 'react'; import { CreditCard, X, CheckCircle, AlertCircle, Loader2 } from 'lucide-react'; import { Button, Modal, Input } from '../../components/ui'; import { DialogModal } from '../../components/ui/DialogModal/DialogModal'; import { subscriptionService } from '../../api'; import { showToast } from '../../utils/toast'; import { useTranslation } from 'react-i18next'; interface PaymentMethodUpdateModalProps { isOpen: boolean; onClose: () => void; tenantId: string; currentPaymentMethod?: { brand?: string; last4?: string; exp_month?: number; exp_year?: number; }; onPaymentMethodUpdated: (paymentMethod: { brand: string; last4: string; exp_month?: number; exp_year?: number; }) => void; } export const PaymentMethodUpdateModal: React.FC = ({ isOpen, onClose, tenantId, currentPaymentMethod, onPaymentMethodUpdated }) => { const { t } = useTranslation('subscription'); const [loading, setLoading] = useState(false); const [paymentMethodId, setPaymentMethodId] = useState(''); const [stripe, setStripe] = useState(null); const [elements, setElements] = useState(null); const [cardElement, setCardElement] = useState(null); const [error, setError] = useState(null); const [success, setSuccess] = useState(false); // Load Stripe.js dynamically useEffect(() => { if (isOpen) { const loadStripe = async () => { try { // Load Stripe.js from CDN const stripeScript = document.createElement('script'); stripeScript.src = 'https://js.stripe.com/v3/'; stripeScript.async = true; stripeScript.onload = () => { const stripeInstance = (window as any).Stripe('pk_test_your_publishable_key'); // Replace with actual key setStripe(stripeInstance); const elementsInstance = stripeInstance.elements(); setElements(elementsInstance); }; document.body.appendChild(stripeScript); } catch (err) { console.error('Failed to load Stripe:', err); setError('Failed to load payment processor'); } }; loadStripe(); } }, [isOpen]); // Create card element when Stripe and elements are loaded useEffect(() => { if (elements && !cardElement) { const card = elements.create('card', { style: { base: { fontSize: '16px', color: '#32325d', '::placeholder': { color: '#aab7c4', }, }, invalid: { color: '#fa755a', iconColor: '#fa755a', }, }, }); // Mount the card element const cardElementContainer = document.getElementById('card-element'); if (cardElementContainer) { card.mount(cardElementContainer); setCardElement(card); } } }, [elements, cardElement]); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); if (!stripe || !cardElement) { setError('Payment processor not loaded'); return; } setLoading(true); setError(null); setSuccess(false); try { // Create payment method using Stripe Elements const { paymentMethod, error: stripeError } = await stripe.createPaymentMethod({ type: 'card', card: cardElement, }); if (stripeError) { setError(stripeError.message || 'Failed to create payment method'); setLoading(false); return; } if (!paymentMethod || !paymentMethod.id) { setError('No payment method created'); setLoading(false); return; } // Call backend to update payment method const result = await subscriptionService.updatePaymentMethod(tenantId, paymentMethod.id); if (result.success) { setSuccess(true); showToast.success(result.message); // Notify parent component about the update onPaymentMethodUpdated({ brand: result.brand, last4: result.last4, exp_month: result.exp_month, exp_year: result.exp_year, }); // Close modal after a brief delay to show success message setTimeout(() => { onClose(); }, 2000); } else { setError(result.message || 'Failed to update payment method'); } } catch (err) { console.error('Error updating payment method:', err); setError(err instanceof Error ? err.message : 'An unexpected error occurred'); } finally { setLoading(false); } }; const handleClose = () => { setError(null); setSuccess(false); setPaymentMethodId(''); onClose(); }; return (
{/* Current Payment Method Info */} {currentPaymentMethod && (

Método de Pago Actual

{currentPaymentMethod.brand} terminando en {currentPaymentMethod.last4}

{currentPaymentMethod.exp_month && currentPaymentMethod.exp_year && (

Expira: {currentPaymentMethod.exp_month}/{currentPaymentMethod.exp_year}

)}
)} {/* Payment Form */}
{/* Stripe card element will be mounted here */} {!cardElement && !error && (
Cargando procesador de pagos...
)}
{error && (
{error}
)} {success && (
Método de pago actualizado correctamente
)}
{/* Security Info */}

Tus datos de pago están protegidos y se procesan de forma segura.

); };