diff --git a/cosiap_api/users/serializers.py b/cosiap_api/users/serializers.py index abdbb1de0ca71928d0054ed9e29823d85fa05921..f7825c94373fa2eba6fb9417667ee594ce887f86 100644 --- a/cosiap_api/users/serializers.py +++ b/cosiap_api/users/serializers.py @@ -123,7 +123,7 @@ class SolicitanteSerializer(serializers.ModelSerializer): # indicamos el modelo a utilziar model = Solicitante # indicamos los campos que debe ingresar el usuario - fields = ['ap_paterno', 'ap_materno', 'telefono', 'RFC','sexo', 'direccion', 'codigo_postal', 'municipio', 'poblacion', 'INE'] + fields = ['nombre','ap_paterno', 'ap_materno', 'telefono', 'RFC','sexo', 'direccion', 'codigo_postal', 'municipio', 'poblacion', 'INE'] # Agregamos validadores para asegurar que los campos puedan estar vacíos extra_kwargs = {'ap_paterno': {'required': False}, 'ap_materno': {'required': False},'telefono': {'required': False},'RFC': {'required': False}, 'sexo':{'required':False}, 'direccion': {'required': False},'codigo_postal': {'required': False},'municipio': {'required': False},'poblacion': {'required': False}, diff --git a/cosiap_api/users/views.py b/cosiap_api/users/views.py index ff1dfea64a099527450ca129896296b4ea735656..07d7fe26821b7405dc49fb5c57884f8f50dcf9e6 100644 --- a/cosiap_api/users/views.py +++ b/cosiap_api/users/views.py @@ -340,6 +340,29 @@ class SolicitanteAPIView(DynamicTableAPIView): return Response(response_data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + def put(self, request, *args, **kwargs): + ''' Sobreescribimos metodo para especialziar el comportamineto''' + data = {} + try: + solicitante = Solicitante.objects.get(id=kwargs['pk']) + serializer = SolicitanteSerializer(solicitante, data=request.data, partial=True) + if serializer.is_valid(): + serializer.save() + data['message'] = 'Solicitante actualizado exitosamente' + data['solicitante'] = serializer.data + return Response(data, status=status.HTTP_200_OK) + else: + # Si la validación falla, devolvemos el error con el estado 400 + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + + + except Solicitante.DoesNotExist: + data['error'] = 'Solicitante no encontrado' + return Response(data, status=status.HTTP_404_NOT_FOUND) + except Exception as e: + Mensaje.error(data, str(e)) + return Response(data, status = status.HTTP_400_BAD_REQUEST) + class ResetPassword(APIView): diff --git a/cosiap_frontend/src/api.js b/cosiap_frontend/src/api.js index 990e5f5df2064e1f55f13d1f06c0a700f2bd33aa..f819e5d6e132759f3db82f63b71ea0c66280708b 100644 --- a/cosiap_frontend/src/api.js +++ b/cosiap_frontend/src/api.js @@ -128,14 +128,14 @@ const api = { get: () => ax.get('api/formularios/opciones/'), post: (data) => ax.post('api/formularios/opciones/', data), getById: (id) => ax.get(`api/formularios/opciones/${id}`), - update: (id, data) => ax.put(`api/formularios/opciones/${id}`, data), + update: (id, data) => ax.put(`api/formularios/opciones/${id}/`, data), delete: (id) => ax.delete(`api/formularios/opciones/${id}`) }, elementos: { get: () => ax.get('api/formularios/elementos'), post: (data) => ax.post('api/formularios/elementos/', data), getById: (id) => ax.get(`api/formularios/elementos/${id}`), - update: (id, data) => ax.put(`api/formularios/elementos/${id}`, data), + update: (id, data) => ax.put(`api/formularios/elementos/${id}/`, data), delete: (id) => ax.delete(`api/formularios/elementos/${id}`), postElementOption: (elementId, optionId) => ax.post(`/api/formularios/elementos/${elementId}/opcion/${optionId}/`), }, @@ -143,7 +143,7 @@ const api = { get: () => ax.get('api/formularios/secciones'), post: (data) => ax.post('api/formularios/secciones/', data), getById: (id) => ax.get(`api/formularios/secciones/${id}`), - update: (id, data) => ax.put(`api/formularios/secciones/${id}`, data), + update: (id, data) => ax.put(`api/formularios/secciones/${id}/`, data), delete: (id) => ax.delete(`api/formularios/secciones/${id}`), postSectionElement: (sectionId, elementId) => ax.post(`/api/formularios/secciones/${sectionId}/elementos/${elementId}`), }, diff --git a/cosiap_frontend/src/components/modalidades/CrearModalidad.css b/cosiap_frontend/src/components/modalidades/CrearModalidad.css index bb5b4fc4e3328414de29195baf9a308447273934..9112abd3f22ba27787a5a0cd2af2a66a34b17d0f 100644 --- a/cosiap_frontend/src/components/modalidades/CrearModalidad.css +++ b/cosiap_frontend/src/components/modalidades/CrearModalidad.css @@ -172,7 +172,7 @@ input[type="checkbox"] { border-radius: 5px; margin: 15px 0; padding: 10px; - background-color: #f9f9f9; + background-color: #f5f5f5; } .card-header { diff --git a/cosiap_frontend/src/components/modalidades/EditarModalidad.jsx b/cosiap_frontend/src/components/modalidades/EditarModalidad.jsx index 735ce963f353d98f9e919a48b37ede767839e601..e60c4742dc8a55e52793f849061ff8030854ef0c 100644 --- a/cosiap_frontend/src/components/modalidades/EditarModalidad.jsx +++ b/cosiap_frontend/src/components/modalidades/EditarModalidad.jsx @@ -15,7 +15,11 @@ const EditModalidad = () => { const [imagen, setImagen] = useState(null); const [sections, setSections] = useState([]); const navigate = useNavigate(); - // const [formID, setFormID] = useState(''); + const [formId, setFormId] = useState(null) + const [formName, setFormName] = useState(''); + const [formatos, setFormatos] = useState([]); + + useEffect(() => { const fetchModalidad = async () => { @@ -28,9 +32,11 @@ const EditModalidad = () => { setMostrar(modalidadData.data.mostrar); setImagenAnterior(modalidadData.data.imagen); setArchivado(modalidadData.data.archivado); - + setFormId(modalidadData.data.dynamic_form) // Cargamos las secciones del formulario dinámico const formResponse = await api.dynamicForms.dynamicForms.getById(modalidadData.data.dynamic_form); + + setFormName(formResponse.data.data.nombre) // Transformamos los datos const seccionesArray = formResponse.data.data.secciones; @@ -75,6 +81,21 @@ const EditModalidad = () => { fetchModalidad(); }, [id]); + // Obtener los formatos disponibles al cargar el componente + useEffect(() => { + const fetchFormatos = async () => { + try { + const response = await api.formatos.get(); + console.log(response.data); // Verifica la estructura de la respuesta + setFormatos(response.data || []); // Asegúrate de que `data` sea un array + } catch (error) { + console.error("Error al obtener los formatos", error); + setFormatos([]); + } + }; + fetchFormatos(); + }, []); + const handleImageChange = (e) => { setImagen(e.target.files[0]); }; @@ -119,15 +140,26 @@ const EditModalidad = () => { }); }; - // actualizamos el nombre de una opcion. const handleUpdateOptionName = (sectionId, elementId, optionId, newName) => { setSections(prevSections => { const updatedSections = { ...prevSections }; + // Verificamos si la sección y el elemento existen if (updatedSections[sectionId] && updatedSections[sectionId].elementos[elementId]) { - const optionToUpdate = updatedSections[sectionId].elementos[elementId].opciones.find(opt => opt.id === optionId); + // Verificamos si 'opciones' es un array; si no, lo convertimos en uno + let opciones = updatedSections[sectionId].elementos[elementId].opciones; + + // Si 'opciones' no es un array, lo convertimos en uno usando Object.values o creamos uno vacío + if (!Array.isArray(opciones)) { + opciones = Object.values(opciones || {}); + updatedSections[sectionId].elementos[elementId].opciones = opciones; // Actualizamos el objeto + } + + // Encontramos la opción a actualizar + const optionToUpdate = opciones.find(opt => opt.id === optionId); + if (optionToUpdate) { - optionToUpdate.nombre = newName; + optionToUpdate.nombre = newName; // Actualizamos el nombre } } @@ -138,11 +170,100 @@ const EditModalidad = () => { const handleSubmit = async (e) => { e.preventDefault(); - + try { + console.log('Nombre del formulario:', formName); + + // Asegurarse de que formId no sea undefined + if (!formId) { + console.error('El ID del formulario es undefined o nulo'); + return; + } + + // Convertir el objeto sections en un array si no lo es + const sectionsArray = Array.isArray(sections) ? sections : Object.values(sections); - - // actualizamos los datos de la modalidad + console.log('Secciones del formulario: ', sectionsArray) + // Asegurarse de que las secciones existan + if (!sectionsArray || !Array.isArray(sectionsArray)) { + console.error('Secciones no están definidas o no son un array'); + return; + } + + // Editamos el formulario dinámico + await api.dynamicForms.dynamicForms.update(formId, { nombre: formName }); + + // Asegurarse de que cada sección tenga un ID antes de hacer la actualización + const sectionPromises = sectionsArray.map(section => { + console.log(`Seccion ${section.nombre}:`, section.nombre) + if (!section.id) { + console.error(`La sección con nombre ${section.nombre} no tiene un ID`); + return; + } + + return api.dynamicForms.secciones.update(section.id, { nombre: section.nombre }); + }); + + // Esperamos a que todas las secciones se actualicen + await Promise.all(sectionPromises); + + // Editamos los elementos y sus opciones + for (const section of sectionsArray) { + // Convertir elementos en array si no lo son + const elementsArray = Array.isArray(section.elementos) ? section.elementos : Object.values(section.elementos); + console.log('Elementos de la seccion: ', elementsArray) + + // Asegurarse de que section.elements no sea undefined o no sea un array + if (!elementsArray || !Array.isArray(elementsArray)) { + console.error(`Los elementos de la sección ${section.nombre} no están definidos o no son un array`); + continue; // Saltar esta sección si no tiene elementos + } + + const elementPromises = elementsArray.map(element => { + if (!element.id) { + console.error(`El elemento con nombre ${element.nombre} no tiene un ID`); + return; + } + + return api.dynamicForms.elementos.update(element.id, { + nombre: element.nombre, + tipo: element.tipo, + formato: element.formato + }); + }); + + // Esperamos a que se actualicen los elementos de la sección actual + await Promise.all(elementPromises); + + // Editamos las opciones de cada elemento + for (const element of elementsArray) { + // Convertir opciones en array si no lo son + const optionsArray = Array.isArray(element.opciones) ? element.opciones : Object.values(element.opciones); + console.log('Opciones del elemento: ', optionsArray) + + // Asegurarse de que element.options no sea undefined o no sea un array + if (!optionsArray || !Array.isArray(optionsArray)) { + console.error(`Las opciones del elemento ${element.nombre} no están definidas o no son un array`); + continue; // Saltar este elemento si no tiene opciones + } + + const optionPromises = optionsArray.map(option => { + if (!option.id) { + console.error(`La opción con nombre ${option.nombre} no tiene un ID`); + return; + } + + return api.dynamicForms.opciones.update(option.id, { + nombre: option.nombre + }); + }); + + // Esperamos a que todas las opciones del elemento actual se actualicen + await Promise.all(optionPromises); + } + } + + // Actualizamos los datos de la modalidad const formData = new FormData(); formData.append('nombre', nombre); formData.append('descripcion', descripcion); @@ -153,12 +274,13 @@ const EditModalidad = () => { formData.append('imagen', imagen); } await api.modalidades.update(id, formData); - navigate('/modalidades') + navigate('/modalidades'); } catch (error) { console.error('Error al actualizar la modalidad.', error); alert('Ocurrió un error al actualizar la modalidad.'); } }; + return ( @@ -225,11 +347,20 @@ const EditModalidad = () => { /> + +
+ + setFormName(e.target.value)} + /> +
{/* Secciones del formulario */} {Object.values(sections).map(section => (
-
+

Sección {section.id}

{ - + @@ -267,6 +398,23 @@ const EditModalidad = () => { + + {element.tipo === 'documento' && ( +
+ + +
+ )} {/* Opciones del elemento (si existen) */} {element.opciones && Object.values(element.opciones).map(option => ( diff --git a/cosiap_frontend/src/components/modalidades/ListaModalidades.jsx b/cosiap_frontend/src/components/modalidades/ListaModalidades.jsx index 55d54b667ac548fef99ef254a05095dec1377a79..fec23e5e0e5338f7d8806aa4f501c2179f1c2fd5 100644 --- a/cosiap_frontend/src/components/modalidades/ListaModalidades.jsx +++ b/cosiap_frontend/src/components/modalidades/ListaModalidades.jsx @@ -77,7 +77,7 @@ export default function ListaModalidades({ { isAdmin && }