From 9c7b4a38de651b176d4605977c37989e46a7c36a Mon Sep 17 00:00:00 2001 From: Pinx0 Date: Sat, 9 Nov 2024 18:00:42 +0100 Subject: [PATCH] refactor: unify help request edit and create forms --- src/app/ofertas/editar/[id]/page.tsx | 2 +- .../_components/Form/FormContainer.tsx | 217 ----------------- .../_components/Form/FormRenderer.tsx | 215 ----------------- .../solicitar-ayuda/_components/Form/index.ts | 3 - .../_components/TipoDeAyudaInputRenderer.tsx | 27 --- .../TownSelector/TownSelectorDataWrapper.tsx | 33 --- .../TownSelector/TownSelectorRenderer.tsx | 35 --- .../_components/TownSelector/index.ts | 3 - .../solicitar-ayuda/_components/constants.ts | 58 ----- src/app/solicitar-ayuda/_components/types.ts | 46 ---- src/app/solicitar-ayuda/page.tsx | 4 +- src/app/solicitudes/editar/[id]/page.tsx | 13 +- .../HelpRequests/CreateHelpRequest.tsx | 63 +++++ .../HelpRequests/EditHelpRequest.tsx | 66 +++++ .../HelpRequestForm.tsx} | 225 ++++++------------ ...PhoneInputContainer.tsx => PhoneInput.tsx} | 2 +- src/components/PhoneInput/index.ts | 2 +- 17 files changed, 214 insertions(+), 800 deletions(-) delete mode 100644 src/app/solicitar-ayuda/_components/Form/FormContainer.tsx delete mode 100644 src/app/solicitar-ayuda/_components/Form/FormRenderer.tsx delete mode 100644 src/app/solicitar-ayuda/_components/Form/index.ts delete mode 100644 src/app/solicitar-ayuda/_components/TipoDeAyudaInputRenderer.tsx delete mode 100644 src/app/solicitar-ayuda/_components/TownSelector/TownSelectorDataWrapper.tsx delete mode 100644 src/app/solicitar-ayuda/_components/TownSelector/TownSelectorRenderer.tsx delete mode 100644 src/app/solicitar-ayuda/_components/TownSelector/index.ts delete mode 100644 src/app/solicitar-ayuda/_components/constants.ts delete mode 100644 src/app/solicitar-ayuda/_components/types.ts create mode 100644 src/components/HelpRequests/CreateHelpRequest.tsx create mode 100644 src/components/HelpRequests/EditHelpRequest.tsx rename src/components/{RequestHelp.js => HelpRequests/HelpRequestForm.tsx} (61%) rename src/components/PhoneInput/{PhoneInputContainer.tsx => PhoneInput.tsx} (88%) diff --git a/src/app/ofertas/editar/[id]/page.tsx b/src/app/ofertas/editar/[id]/page.tsx index 6707924d..92b783a8 100644 --- a/src/app/ofertas/editar/[id]/page.tsx +++ b/src/app/ofertas/editar/[id]/page.tsx @@ -12,5 +12,5 @@ export default async function EditarSolicitud({ params }: { params: Promise<{ id } const numberId = Number(id); const request = await helpRequestService.getOne(numberId); - return ; + return ; } diff --git a/src/app/solicitar-ayuda/_components/Form/FormContainer.tsx b/src/app/solicitar-ayuda/_components/Form/FormContainer.tsx deleted file mode 100644 index 43971f3c..00000000 --- a/src/app/solicitar-ayuda/_components/Form/FormContainer.tsx +++ /dev/null @@ -1,217 +0,0 @@ -'use client'; - -import React, { FormEvent, useCallback, useMemo, useState } from 'react'; - -import { FormRenderer } from './FormRenderer'; -import { FormData, Status } from '../types'; -import { formatPhoneNumber, isValidPhone } from '@/helpers/utils'; -import { helpRequestService } from '@/lib/service'; -import { Database } from '@/types/database'; -import { Enums } from '@/types/common'; -import { useRouter } from 'next/navigation'; - -import { TIPOS_DE_AYUDA, TIPOS_DE_AYUDA_MAP } from '../constants'; -import { useSession } from '@/context/SessionProvider'; - -const mapHelpToEnum = (helpTypeMap: FormData['tiposDeAyuda']): Enums['help_type_enum'][] => - Array.from(helpTypeMap).reduce( - (acc, [id, isSelected]) => { - if (isSelected) { - const value = TIPOS_DE_AYUDA_MAP.get(id); - if (!value) { - return acc; - } - return acc.concat(value.enum); - } - return acc; - }, - [] as Enums['help_type_enum'][], - ); - -export function FormContainer() { - const router = useRouter(); - const session = useSession(); - - const userId = session.user?.id; - - const [formData, setFormData] = useState({ - nombre: session?.user?.user_metadata?.full_name || session?.user?.user_metadata?.nombre || ''.split(' ')[0], - ubicacion: '', - coordinates: null, - tiposDeAyuda: new Map(TIPOS_DE_AYUDA.map(({ id }) => [id, false])), - numeroDePersonas: undefined, - descripcion: '', - urgencia: 'alta', - situacionEspecial: '', - contacto: session?.user?.user_metadata?.telefono || '', - consentimiento: false, - pueblo: '', - email: session?.user?.user_metadata?.email || '', - }); - - const [status, setStatus] = useState({ - isSubmitting: false, - error: null, - success: false, - }); - - const handleSubmit = useCallback( - async (e: FormEvent) => { - e.preventDefault(); - - /* Form validation */ - if (!formData.ubicacion) { - alert('La ubicación es un campo obligatorio'); - return; - } - - if (!formData.consentimiento) { - alert('Debe aceptar el consentimiento para enviar la solicitud'); - return; - } - - if (!isValidPhone(formData.contacto)) { - alert('El teléfono de contacto no es válido.'); - return; - } - - if (!isValidPhone(formData.contacto)) { - alert('El teléfono de contacto no es válido.'); - return; - } - - setStatus({ isSubmitting: true, error: null, success: false }); - - try { - const helpRequestData: Database['public']['Tables']['help_requests']['Insert'] = { - type: 'necesita', - name: formData.nombre.split(' ')[0], - location: formData.ubicacion, - latitude: formData.coordinates ? parseFloat(formData.coordinates.lat) : null, - longitude: formData.coordinates ? parseFloat(formData.coordinates.lng) : null, - help_type: mapHelpToEnum(formData.tiposDeAyuda), - description: formData.descripcion, - urgency: formData.urgencia, - number_of_people: formData.numeroDePersonas || 1, - contact_info: formatPhoneNumber(formData.contacto), - additional_info: { - special_situations: formData.situacionEspecial || null, - consent: true, - email: formData.email, - }, - town_id: parseInt(formData.pueblo), - status: 'active', - user_id: userId, - }; - - await helpRequestService.createRequest(helpRequestData); - - // Limpiar formulario - setFormData({ - nombre: '', - ubicacion: '', - coordinates: null, - tiposDeAyuda: new Map(), - numeroDePersonas: undefined, - descripcion: '', - urgencia: 'alta', - situacionEspecial: '', - contacto: '', - pueblo: '', - consentimiento: false, - email: '', - }); - - setStatus({ isSubmitting: false, error: null, success: true }); - setStatus((prev) => ({ ...prev, success: false })); - router.push('/casos-activos/solicitudes'); - } catch (error: any) { - console.log('Error al enviar solicitud:', error.message); - setStatus({ - isSubmitting: false, - error: `Error al enviar la solicitud: ${error.message}`, - success: false, - }); - } - }, - [userId, formData, router], - ); - - const handleInputElementChange: React.ChangeEventHandler = useCallback((e) => { - const { name, value, type, checked } = e.target; - setFormData((prev) => ({ - ...prev, - [name]: type === 'checkbox' ? checked : value, - })); - }, []); - - const handleTextAreaElementChange: React.ChangeEventHandler = useCallback((e) => { - const { name, value } = e.target; - setFormData((formData) => ({ - ...formData, - [name]: value, - })); - }, []); - - const handleSelectElementChange: React.ChangeEventHandler = useCallback((e) => { - const { name, value } = e.target; - setFormData((prev) => ({ - ...prev, - [name]: value, - })); - }, []); - - const handleAddressSelection = useCallback((address: any) => { - setFormData((formData) => ({ - ...formData, - ubicacion: address.fullAddress, - coordinates: address.coordinates - ? { - lat: address.coordinates.lat, - lng: address.coordinates.lon, - } - : null, - })); - }, []); - - const handlePhoneChange = useCallback((phoneNumber: string) => { - setFormData((formData) => ({ - ...formData, - contacto: phoneNumber, - })); - }, []); - - const handleHelpTypeChange: React.ChangeEventHandler = useCallback((event) => { - const { id, checked } = event.target; - - setFormData((formData) => { - const prevHelp = formData.tiposDeAyuda; - const newHelp = new Map([...prevHelp]); - newHelp.set(parseInt(id), checked); - return { ...formData, tiposDeAyuda: newHelp }; - }); - }, []); - - const selectedHelp = useMemo(() => formData.tiposDeAyuda, [formData]); - - return ( - - ); -} diff --git a/src/app/solicitar-ayuda/_components/Form/FormRenderer.tsx b/src/app/solicitar-ayuda/_components/Form/FormRenderer.tsx deleted file mode 100644 index b0968a8e..00000000 --- a/src/app/solicitar-ayuda/_components/Form/FormRenderer.tsx +++ /dev/null @@ -1,215 +0,0 @@ -'use client'; -import React from 'react'; -import { Check } from 'lucide-react'; - -import { PhoneInput } from '@/components/PhoneInput'; -import AddressAutocomplete from '@/components/AddressAutocomplete.js'; -import { TIPOS_DE_AYUDA } from '../constants'; -import { TipoDeAyudaInputRenderer } from '../TipoDeAyudaInputRenderer'; -import { FormData, HelpCategory, Status } from '../types'; -import { TownSelector } from '../TownSelector'; - -type FormRendererProps = { - status: Status; - formData: FormData; - isUserLoggedIn: boolean; - selectedHelp: Map; - handleSubmit: React.FormEventHandler; - handlePhoneChange: (phoneNumber: string) => void; - handleAddressSelection: (address: string) => void; - handleSituacionEspecialChange: React.ChangeEventHandler; - handleUrgencyChange: React.ChangeEventHandler; - handleDescriptionChange: React.ChangeEventHandler; - handleTownChange: React.ChangeEventHandler; - handleTipoAyudaChange: React.ChangeEventHandler; - handleNameChange: React.ChangeEventHandler; - handleEmailChange: React.ChangeEventHandler; - handleNumberPeopleChange: React.ChangeEventHandler; - handleConsentChange: React.ChangeEventHandler; -}; - -export function FormRenderer({ - handleSubmit, - status, - formData, - isUserLoggedIn, - handlePhoneChange, - handleAddressSelection, - handleSituacionEspecialChange, - handleUrgencyChange, - handleDescriptionChange, - handleTownChange, - handleTipoAyudaChange, - handleNameChange, - handleEmailChange, - handleNumberPeopleChange, - handleConsentChange, - selectedHelp, -}: FormRendererProps) { - return ( - <> - {status.error && ( -
-

{status.error}

-
- )} - - {/* Formulario principal */} -
-

Solicitar Ayuda

- -
-
-
- - -
- -
-
- - -

- {isUserLoggedIn - ? 'Se utilizará para que puedas eliminar o editar la información de tu solicitud' - : 'Se utilizará para que puedas actualizar tu solicitud y marcarla como completada. Para realizar cambios, deberás registrarte con el mismo email'} -

-
-
- - -

- Incluya todos los detalles posibles para poder localizarle (campo obligatorio) -

-
- -
- -
- {TIPOS_DE_AYUDA.map(({ id, label }) => ( - - ))} -
-
- -
- - -
- -
- -