Imporve UI and token

This commit is contained in:
Urtzi Alfaro
2026-01-11 07:50:34 +01:00
parent bf1db7cb9e
commit 5533198cab
14 changed files with 1370 additions and 670 deletions

View File

@@ -1,11 +1,11 @@
import React, { useState, useEffect, useRef } from 'react';
import { useTranslation } from 'react-i18next';
import { Card, Input, Button } from '../../ui';
import { CardElement, useStripe, useElements } from '@stripe/react-stripe-js';
import { PaymentElement, useStripe, useElements } from '@stripe/react-stripe-js';
import { AlertCircle, CheckCircle, CreditCard, Lock } from 'lucide-react';
interface PaymentFormProps {
onPaymentSuccess: () => void;
onPaymentSuccess: (paymentMethodId?: string) => void;
onPaymentError: (error: string) => void;
className?: string;
bypassPayment?: boolean;
@@ -50,7 +50,7 @@ const PaymentForm: React.FC<PaymentFormProps> = ({
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (!stripe || !elements) {
// Stripe.js has not loaded yet
onPaymentError('Stripe.js no ha cargado correctamente');
@@ -67,29 +67,41 @@ const PaymentForm: React.FC<PaymentFormProps> = ({
setError(null);
try {
// Create payment method
const { error, paymentMethod } = await stripe.createPaymentMethod({
type: 'card',
card: elements.getElement('card')!,
billing_details: {
name: billingDetails.name,
email: billingDetails.email,
address: billingDetails.address,
},
});
// Submit the payment element to validate all inputs
const { error: submitError } = await elements.submit();
if (error) {
setError(error.message || 'Error al procesar el pago');
onPaymentError(error.message || 'Error al procesar el pago');
if (submitError) {
setError(submitError.message || 'Error al validar el formulario');
onPaymentError(submitError.message || 'Error al validar el formulario');
setLoading(false);
return;
}
// In a real application, you would send the paymentMethod.id to your server
// to create a subscription. For now, we'll simulate success.
// Create payment method using the PaymentElement
// This is the correct way to create a payment method with PaymentElement
const { error: paymentError, paymentMethod } = await stripe.createPaymentMethod({
elements,
params: {
billing_details: {
name: billingDetails.name,
email: billingDetails.email,
address: billingDetails.address,
},
},
});
if (paymentError) {
setError(paymentError.message || 'Error al procesar el pago');
onPaymentError(paymentError.message || 'Error al procesar el pago');
setLoading(false);
return;
}
// Send the paymentMethod.id to your server to create a subscription
console.log('Payment method created:', paymentMethod);
onPaymentSuccess();
// Pass the payment method ID to the parent component for server-side processing
onPaymentSuccess(paymentMethod?.id);
} catch (err) {
const errorMessage = err instanceof Error ? err.message : 'Error desconocido al procesar el pago';
setError(errorMessage);
@@ -99,7 +111,7 @@ const PaymentForm: React.FC<PaymentFormProps> = ({
}
};
const handleCardChange = (event: any) => {
const handlePaymentElementChange = (event: any) => {
setError(event.error?.message || null);
setCardComplete(event.complete);
};
@@ -208,33 +220,29 @@ const PaymentForm: React.FC<PaymentFormProps> = ({
</div>
</div>
{/* Card Element */}
{/* Payment Element */}
<div className="mb-6">
<label className="block text-sm font-medium text-text-primary mb-2">
{t('auth:payment.card_details', 'Detalles de la tarjeta')}
{t('auth:payment.payment_details', 'Detalles de Pago')}
</label>
<div className="border border-border-primary rounded-lg p-3 bg-bg-primary">
<CardElement
<PaymentElement
options={{
style: {
base: {
fontSize: '16px',
color: '#424770',
'::placeholder': {
color: '#aab7c4',
},
},
invalid: {
color: '#9e2146',
},
layout: 'tabs',
fields: {
billingDetails: 'auto',
},
wallets: {
applePay: 'auto',
googlePay: 'auto',
},
}}
onChange={handleCardChange}
onChange={handlePaymentElementChange}
/>
</div>
<p className="text-xs text-text-tertiary mt-2 flex items-center gap-1">
<Lock className="w-3 h-3" />
{t('auth:payment.card_info_secure', 'Tu información de tarjeta está segura')}
{t('auth:payment.payment_info_secure', 'Tu información de pago está segura')}
</p>
</div>
@@ -275,7 +283,7 @@ const PaymentForm: React.FC<PaymentFormProps> = ({
<Button
variant="primary"
size="lg"
onClick={onPaymentSuccess}
onClick={() => onPaymentSuccess()}
className="w-full"
>
{t('auth:payment.continue_registration', 'Continuar con el Registro')}