{/* Register Form */}
{/* Full Name Field */}
{errors.fullName && (

{errors.fullName}

)}
{/* Email Field */}
{errors.email && (

{errors.email}

)}
{/* Password Field */}
{/* Password Strength Indicator */} {formData.password && (
{[...Array(5)].map((_, i) => (
))}

Seguridad: {strengthLabels[passwordStrength - 1] || 'Muy débil'}

)} {errors.password && (

{errors.password}

)}
{/* Confirm Password Field */}
{formData.confirmPassword && formData.password === formData.confirmPassword && (
)}
{errors.confirmPassword && (

{errors.confirmPassword}

)}
{/* Terms and Conditions */}
{errors.acceptTerms && (

{errors.acceptTerms}

)}
{/* Submit Button */}
{/* Login Link */}

¿Ya tienes una cuenta?{' '}

import React, { useState } from 'react'; import { Eye, EyeOff, Loader2, Check } from 'lucide-react'; import toast from 'react-hot-toast'; interface RegisterPageProps { onLogin: (user: any, token: string) => void; onNavigateToLogin: () => void; } interface RegisterForm { fullName: string; email: string; password: string; confirmPassword: string; acceptTerms: boolean; } const RegisterPage: React.FC = ({ onLogin, onNavigateToLogin }) => { const [formData, setFormData] = useState({ fullName: '', email: '', password: '', confirmPassword: '', acceptTerms: false }); const [showPassword, setShowPassword] = useState(false); const [showConfirmPassword, setShowConfirmPassword] = useState(false); const [isLoading, setIsLoading] = useState(false); const [errors, setErrors] = useState>({}); const validateForm = (): boolean => { const newErrors: Partial = {}; if (!formData.fullName.trim()) { newErrors.fullName = 'El nombre completo es obligatorio'; } else if (formData.fullName.trim().length < 2) { newErrors.fullName = 'El nombre debe tener al menos 2 caracteres'; } if (!formData.email) { newErrors.email = 'El email es obligatorio'; } else if (!/\S+@\S+\.\S+/.test(formData.email)) { newErrors.email = 'El email no es válido'; } if (!formData.password) { newErrors.password = 'La contraseña es obligatoria'; } else if (formData.password.length < 8) { newErrors.password = 'La contraseña debe tener al menos 8 caracteres'; } else if (!/(?=.*[a-z])(?=.*[A-Z])(?=.*\d)/.test(formData.password)) { newErrors.password = 'La contraseña debe incluir mayúsculas, minúsculas y números'; } if (!formData.confirmPassword) { newErrors.confirmPassword = 'Confirma tu contraseña'; } else if (formData.password !== formData.confirmPassword) { newErrors.confirmPassword = 'Las contraseñas no coinciden'; } if (!formData.acceptTerms) { newErrors.acceptTerms = 'Debes aceptar los términos y condiciones'; } setErrors(newErrors); return Object.keys(newErrors).length === 0; }; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); if (!validateForm()) return; setIsLoading(true); try { const response = await fetch('/api/v1/auth/register', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ full_name: formData.fullName, email: formData.email, password: formData.password, role: 'admin' // Default role for bakery owners }), }); const data = await response.json(); if (!response.ok) { throw new Error(data.message || 'Error al crear la cuenta'); } // Auto-login after successful registration const loginResponse = await fetch('/api/v1/auth/login', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ email: formData.email, password: formData.password, }), }); const loginData = await loginResponse.json(); if (!loginResponse.ok) { throw new Error('Cuenta creada, pero error al iniciar sesión'); } toast.success('¡Cuenta creada exitosamente! Bienvenido a PanIA'); onLogin(loginData.user, loginData.access_token); } catch (error: any) { console.error('Registration error:', error); toast.error(error.message || 'Error al crear la cuenta'); } finally { setIsLoading(false); } }; const handleInputChange = (e: React.ChangeEvent) => { const { name, value, type, checked } = e.target; setFormData(prev => ({ ...prev, [name]: type === 'checkbox' ? checked : value })); // Clear error when user starts typing if (errors[name as keyof RegisterForm]) { setErrors(prev => ({ ...prev, [name]: undefined })); } }; const getPasswordStrength = (password: string) => { let strength = 0; if (password.length >= 8) strength++; if (/[a-z]/.test(password)) strength++; if (/[A-Z]/.test(password)) strength++; if (/\d/.test(password)) strength++; if (/[^A-Za-z0-9]/.test(password)) strength++; return strength; }; const passwordStrength = getPasswordStrength(formData.password); const strengthLabels = ['Muy débil', 'Débil', 'Regular', 'Buena', 'Excelente']; const strengthColors = ['bg-red-500', 'bg-orange-500', 'bg-yellow-500', 'bg-blue-500', 'bg-green-500']; return (
{/* Logo and Header */}
🥖

Únete a PanIA

Crea tu cuenta y transforma tu panadería

Únete a más de 500 panaderías en Madrid

{/* Register Form */}
{/* Full Name Field */}
{errors.fullName && (

{errors.fullName}

)}
{/* Email Field */}
{errors.email && (

{errors.email}

)}
{/* Password Field */}
{/* Password Strength Indicator */} {formData.password && (
{[...Array(5)].map((_, i) => (
))}

Seguridad: {strengthLabels[passwordStrength - 1] || 'Muy débil'}

)} {errors.password && (

{errors.password}

)}
{/* Confirm Password Field */}
{formData.confirmPassword && formData.password === formData.confirmPassword && (
)}
{errors.confirmPassword && (

{errors.confirmPassword}

)}
{/* Terms and Conditions */}
{errors.acceptTerms && (

{errors.acceptTerms}

)}
{/* Submit Button */}
{/* Login Link */}

¿Ya tienes una cuenta?{' '}

{/* Benefits */}

Al registrarte obtienes acceso completo durante 30 días gratis

Predicciones IA
Soporte 24/7
Sin compromiso
); }; export default RegisterPage;