'use client'; import React, {ChangeEvent, SubmitEvent, useState} from 'react'; import Link from 'next/link'; import {useRouter} from 'next/navigation'; import { Box, Button, InputAdornment, Paper, Stack, TextField, Typography, Alert, } from '@mui/material'; import {authClient} from '@/lib/api/auth'; import {ApiError, ApiValidationErrors} from '@/lib/api/client'; import {GuestGuard} from "@/src/auth/GuestGuard"; type FormValues = { username: string; firstName: string; lastName: string; email: string; phone: string; password: string; confirmPassword: string; }; type FormErrors = Partial>; const initialValues: FormValues = { username: '', firstName: '', lastName: '', email: '', phone: '', password: '', confirmPassword: '', }; const validationFieldMap: Partial> = { username: 'username', first_name: 'firstName', last_name: 'lastName', email: 'email', phone: 'phone', password: 'password', password_confirmation: 'confirmPassword', }; const mapValidationErrors = (errors?: ApiValidationErrors): FormErrors => { if (!errors) { return {}; } return Object.entries(errors).reduce((accumulator, [key, messages]) => { const field = validationFieldMap[key]; if (field && messages.length > 0) { accumulator[field] = messages[0]; } return accumulator; }, {}); }; const Page: React.FC = () => { const router = useRouter(); const [values, setValues] = useState(initialValues); const [errors, setErrors] = useState({}); const [isSubmitting, setIsSubmitting] = useState(false); const [serverError, setServerError] = useState(''); const handleChange = (field: keyof FormValues) => (event: ChangeEvent) => { const nextValue = field === 'phone' ? event.target.value.replace(/\D/g, '').slice(0, 10) : event.target.value; setValues((current) => ({ ...current, [field]: nextValue, })); setErrors((current) => { if (!current[field]) { return current; } const nextErrors = {...current}; delete nextErrors[field]; return nextErrors; }); }; const validateForm = () => { const nextErrors: FormErrors = {}; if (!values.username.trim()) { nextErrors.username = 'El nombre de usuario es obligatorio.'; } if (!values.firstName.trim()) { nextErrors.firstName = 'El nombre es obligatorio.'; } if (!values.lastName.trim()) { nextErrors.lastName = 'El apellido es obligatorio.'; } if (!values.email.trim()) { nextErrors.email = 'El correo electrónico es obligatorio.'; } else if (!/\S+@\S+\.\S+/.test(values.email)) { nextErrors.email = 'Ingresa un correo electrónico válido.'; } if (!values.phone.trim()) { nextErrors.phone = 'El número celular es obligatorio.'; } else if (!/^\d{10}$/.test(values.phone)) { nextErrors.phone = 'Ingresa 10 dígitos numéricos.'; } if (!values.password) { nextErrors.password = 'La contraseña es obligatoria.'; } else if (values.password.length < 8) { nextErrors.password = 'La contraseña debe tener al menos 8 caracteres.'; } if (!values.confirmPassword) { nextErrors.confirmPassword = 'Confirma tu contraseña.'; } else if (values.password !== values.confirmPassword) { nextErrors.confirmPassword = 'Las contraseñas no coinciden.'; } setErrors(nextErrors); return Object.keys(nextErrors).length === 0; }; const handleSubmit = (event: SubmitEvent) => { event.preventDefault(); setServerError(''); if (!validateForm()) { return; } setIsSubmitting(true); authClient .register({ username: values.username.trim(), first_name: values.firstName.trim(), last_name: values.lastName.trim(), email: values.email.trim(), phone: values.phone.trim(), password: values.password, password_confirmation: values.confirmPassword, }) .then(() => router.push('/')) .catch((error: unknown) => { if (error instanceof ApiError) { setErrors((current) => ({ ...current, ...mapValidationErrors(error.errors), })); setServerError(error.message); return; } setServerError('No fue posible crear la cuenta.'); }) .finally(() => { setIsSubmitting(false); }); }; return ( Crea tu cuenta Llena todos los campos para crear tu cuenta {serverError ? {serverError} : null} +52 ), }, }} /> ¿Ya tienes cuenta?{' '} Inicia sesión ); }; export default Page;