From 7f8b206e3e1e984bdaf4fa497084b78b314e6238 Mon Sep 17 00:00:00 2001 From: AdalbertoCV <34152734@uaz.edu.mx> Date: Wed, 2 Oct 2024 11:23:03 -0600 Subject: [PATCH 1/2] =?UTF-8?q?Configuraci=C3=B3n=20de=20alertas=20en=20Cr?= =?UTF-8?q?ear,Editar=20y=20Solicitar=20una=20modalidad?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/modalidades/CrearModalidad.jsx | 24 ++++- .../modalidades/EditarModalidad.jsx | 101 ++++++------------ 2 files changed, 54 insertions(+), 71 deletions(-) diff --git a/cosiap_frontend/src/components/modalidades/CrearModalidad.jsx b/cosiap_frontend/src/components/modalidades/CrearModalidad.jsx index b76498b..fb3ba54 100644 --- a/cosiap_frontend/src/components/modalidades/CrearModalidad.jsx +++ b/cosiap_frontend/src/components/modalidades/CrearModalidad.jsx @@ -17,6 +17,9 @@ const CreateModalidad = () => { const [sections, setSections] = useState([]); const [formatos, setFormatos] = useState([]); const navigate = useNavigate(); + // hooks para el manejo de las alertas + const [alertMessage, setAlertMessage] = useState(''); // Estado para el mensaje de alerta + const [isSuccess, setIsSuccess] = useState(false); // Obtener los formatos disponibles al cargar el componente useEffect(() => { @@ -110,6 +113,16 @@ const CreateModalidad = () => { setSections(newSections); }; + // metodo para mostrar una alerta + const showAlert = (message, isSuccess) => { + setAlertMessage(message); + setIsSuccess(isSuccess); + + setTimeout(() => { + setAlertMessage(''); + }, 3000); + }; + // manejar el orden de las peticiones creando un flujo correcto. const handleSubmit = async (e) => { @@ -180,14 +193,19 @@ const CreateModalidad = () => { }); navigate('/modalidades') } catch (error){ - console.error('Error al crear la modalidad.', error); - alert('Ocurrió un error al crear la modalidad.') + const errorMessage = 'Error al crear la modalidad, por favor complete o revise los datos.' + showAlert(`Error: ${errorMessage}`, false); } }; return(
- + {/* Alerta */} + {alertMessage && ( +
+ {alertMessage} +
+ )} {/* Card blanco para el formulario */}
diff --git a/cosiap_frontend/src/components/modalidades/EditarModalidad.jsx b/cosiap_frontend/src/components/modalidades/EditarModalidad.jsx index 6960bfa..3e4df4b 100644 --- a/cosiap_frontend/src/components/modalidades/EditarModalidad.jsx +++ b/cosiap_frontend/src/components/modalidades/EditarModalidad.jsx @@ -29,6 +29,9 @@ const EditModalidad = () => { const [newOptionName, setNewOptionName] = useState(''); const [selectedElementId, setSelectedElementId] = useState(null); const [isAddingOption, setIsAddingOption] = useState(false); + // hooks para el manejo de las alertas + const [alertMessage, setAlertMessage] = useState(''); // Estado para el mensaje de alerta + const [isSuccess, setIsSuccess] = useState(false); @@ -115,7 +118,7 @@ const EditModalidad = () => { const handleAddSection = async () => { try { if (!newSectionName) { - alert('Por favor, ingrese un nombre para la nueva sección.'); + showAlert('Por favor, ingrese un nombre para la nueva sección.', false); return; } @@ -143,7 +146,7 @@ const EditModalidad = () => { const handleAddElement = async (sectionId) => { try { if (!newElementName) { - alert('Por favor, ingrese un nombre para el nuevo elemento.'); + showAlert('Por favor, ingrese un nombre para el nuevo elemento.', false); return; } @@ -156,34 +159,6 @@ const EditModalidad = () => { await api.dynamicForms.secciones.postSectionElement(sectionId, response.data.data.id); - // Actualizar el estado para agregar el nuevo elemento a la sección - setSections(prevSections => { - const updatedSections = { ...prevSections }; - const section = updatedSections[sectionId]; - - if (!section) { - console.error('Sección no encontrada'); - return updatedSections; // No actualizamos si la sección no existe - } - - // Verificar que elementos sea un arreglo, inicializándolo si no lo es - if (!Array.isArray(section.elementos)) { - console.error('Elementos no es un arreglo, inicializando como un arreglo vacío.'); - section.elementos = []; // Asegurarse de que sea un arreglo - } - - // Agregar el nuevo elemento - const newElement = { - ...response.data.data, - opciones: [] // Asegurarnos que el nuevo elemento tenga un array vacío para opciones - }; - - // Asegurarse de que el nuevo elemento se agregue sin perder los existentes - section.elementos = [...section.elementos, newElement]; - - return updatedSections; - }); - // Limpiar el input y ocultar el campo setNewElementName(''); setSelectedSectionId(null); @@ -191,18 +166,17 @@ const EditModalidad = () => { await handleSubmit(); sessionStorage.setItem('scrollPosition', window.scrollY); window.location.reload(); - console.log(`Elemento "${newElementName}" agregado correctamente a la sección ${sectionId}.`); } catch (error) { console.error('Error al agregar el elemento', error); - alert('Ocurrió un error al agregar el elemento.'); + showAlert('Ocurrió un error al agregar el elemento.'); } }; // Agregamos una nueva opción a un elemento - const handleAddOption = async (sectionId, elementId) => { + const handleAddOption = async (elementId) => { try { if (!newOptionName) { - alert('Por favor, ingrese un nombre para la nueva opción.'); + showAlert('Por favor, ingrese un nombre para la nueva opción.', false); return; } @@ -213,34 +187,6 @@ const EditModalidad = () => { await api.dynamicForms.elementos.postElementOption(elementId, response.data.data.id); - // Actualizar el estado para agregar la nueva opción al elemento - setSections(prevSections => { - const updatedSections = { ...prevSections }; - const section = updatedSections[sectionId]; - - if (!section) { - console.error('Sección no encontrada'); - return updatedSections; // No actualizamos si la sección no existe - } - - const element = section.elementos[elementId] - if (!element) { - console.error('Elemento no encontrado'); - return updatedSections; // No actualizamos si el elemento no existe - } - - // Asegurarse de que opciones sea un arreglo, inicializándolo si no lo es - if (!Array.isArray(element.opciones)) { - console.error('Opciones no es un arreglo, inicializando como un arreglo vacío.'); - element.opciones = []; // Asegurarse de que sea un arreglo - } - - // Agregar la nueva opción manteniendo las existentes - element.opciones = [...element.opciones, response.data.data]; - - return updatedSections; // Devolver las secciones actualizadas - }); - // Limpiar el input y ocultar el campo setNewOptionName(''); setSelectedElementId(null); @@ -248,10 +194,9 @@ const EditModalidad = () => { await handleSubmit(); sessionStorage.setItem('scrollPosition', window.scrollY); window.location.reload(); - console.log(`Opción "${newOptionName}" agregada correctamente al elemento ${elementId}.`); } catch (error) { console.error('Error al agregar la opción', error); - alert('Ocurrió un error al agregar la opción.'); + showAlert('Ocurrió un error al agregar la opción.'); } }; @@ -395,6 +340,16 @@ const EditModalidad = () => { }); }; + // metodo para mostrar una alerta + const showAlert = (message, isSuccess) => { + setAlertMessage(message); + setIsSuccess(isSuccess); + + setTimeout(() => { + setAlertMessage(''); + }, 3000); + }; + const handleSubmit = async (e) => { if (e) { @@ -504,12 +459,16 @@ const EditModalidad = () => { formData.append('imagen', imagen); } await api.modalidades.update(id, formData); + showAlert('Modalidad actualizada correctamente', true) if (e) { - navigate('/modalidades'); + setTimeout(() => { + navigate('/modalidades'); + }, 1000); } + } catch (error) { - console.error('Error al actualizar la modalidad.', error); - alert('Ocurrió un error al actualizar la modalidad.'); + const errorMessage = 'Error al actualizar la modalidad, por favor complete o revise los datos.' + showAlert(`Error: ${errorMessage}`, false); } }; @@ -517,6 +476,12 @@ const EditModalidad = () => { return ( + {/* Alerta */} + {alertMessage && ( +
+ {alertMessage} +
+ )}
@@ -747,7 +712,7 @@ const EditModalidad = () => { /> -- GitLab From 21076e9bc9e6f6f2548e6e02f191829f25f34238 Mon Sep 17 00:00:00 2001 From: AdalbertoCV <34152734@uaz.edu.mx> Date: Wed, 2 Oct 2024 13:12:17 -0600 Subject: [PATCH 2/2] Descarga de formatos de un elemento de tipo documento --- cosiap_frontend/src/api.js | 3 +- .../common/utility/RenderElemento.jsx | 75 ++++++++++++++++--- .../modalidades/EditarModalidad.jsx | 17 +++-- .../src/components/modalidades/Modalidad.css | 27 +++++++ 4 files changed, 101 insertions(+), 21 deletions(-) diff --git a/cosiap_frontend/src/api.js b/cosiap_frontend/src/api.js index 603a0e0..63b9f2e 100644 --- a/cosiap_frontend/src/api.js +++ b/cosiap_frontend/src/api.js @@ -162,7 +162,8 @@ const api = { }, }, formatos: { - get: () => ax.get('api/plantillas') + get: () => ax.get('api/plantillas'), + getById: (id) => ax.get(`api/plantillas/download/${id}`,{ responseType: 'blob' }) } }; diff --git a/cosiap_frontend/src/components/common/utility/RenderElemento.jsx b/cosiap_frontend/src/components/common/utility/RenderElemento.jsx index 62ef2d1..e6b4abe 100644 --- a/cosiap_frontend/src/components/common/utility/RenderElemento.jsx +++ b/cosiap_frontend/src/components/common/utility/RenderElemento.jsx @@ -1,7 +1,8 @@ import '@/components/modalidades/Modalidad.css' +import api from "@/api"; export const renderElemento = (seccionId, elemento, handleInputChange, handleCheckboxChange) => { - const { tipo, opciones, id, nombre } = elemento; + const { tipo, opciones, id, nombre, formato } = elemento; const handleChange = (e) => { const valor = e.target.value; @@ -9,6 +10,48 @@ export const renderElemento = (seccionId, elemento, handleInputChange, handleChe handleInputChange(seccionId, id, valor); }; + const handleDownload = async (elemento, formato) => { + try { + // Realiza la petición al backend para obtener el archivo + const response = await api.formatos.getById(formato, { + responseType: 'blob', // Esto asegura que obtengas los datos como un archivo binario + }); + + // Verifica si el tipo de contenido es correcto + const contentType = response.headers['content-type']; + console.log('Content Type:', contentType); // Para depuración + + if (contentType !== 'application/vnd.openxmlformats-officedocument.wordprocessingml.document') { + throw new Error('Tipo de archivo inesperado'); + } + + // Crea un Blob a partir de los datos recibidos + const blob = new Blob([response.data], { type: contentType }); + + // Crea un URL para el archivo descargado + const url = window.URL.createObjectURL(blob); + + // Crea un enlace temporal + const link = document.createElement('a'); + link.href = url; + link.setAttribute('download', `${elemento.nombre}_formato.docx`); // Cambia a .docx + + // Añadir el enlace al cuerpo del documento para que sea visible en el navegador + document.body.appendChild(link); + + // En lugar de hacer clic en el enlace, solo configuramos el enlace + link.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true, view: window })); + + // Dejar el enlace en el DOM para que sea visible + // document.body.removeChild(link); // No eliminar el enlace si deseas que la descarga sea visible + + // Revoca el URL del blob para liberar memoria + window.URL.revokeObjectURL(url); + } catch (error) { + console.error('Error al descargar el formato:', error); + } + }; + switch (tipo) { case "texto_corto": @@ -74,18 +117,26 @@ export const renderElemento = (seccionId, elemento, handleInputChange, handleChe ))}
); - case "documento": + case "documento": return ( - handleInputChange(seccionId, id, e.target.files[0])} - /> +
+ handleInputChange(seccionId, id, e.target.files[0])} + /> + {formato && ( + + )} +
); case "fecha": return ( diff --git a/cosiap_frontend/src/components/modalidades/EditarModalidad.jsx b/cosiap_frontend/src/components/modalidades/EditarModalidad.jsx index 3e4df4b..2b36492 100644 --- a/cosiap_frontend/src/components/modalidades/EditarModalidad.jsx +++ b/cosiap_frontend/src/components/modalidades/EditarModalidad.jsx @@ -135,9 +135,11 @@ const EditModalidad = () => { // Limpiar el input y ocultar el campo setNewSectionName(''); setIsAddingSection(false); + await handleSubmit(); + window.location.reload(); } catch (error) { console.error('Error al agregar la sección', error); - alert('Ocurrió un error al agregar la sección.'); + showAlert('Ocurrió un error al agregar la sección.', false); } }; @@ -164,11 +166,10 @@ const EditModalidad = () => { setSelectedSectionId(null); setIsAddingElement(false); await handleSubmit(); - sessionStorage.setItem('scrollPosition', window.scrollY); - window.location.reload(); + window.location.reload(); } catch (error) { console.error('Error al agregar el elemento', error); - showAlert('Ocurrió un error al agregar el elemento.'); + showAlert('Ocurrió un error al agregar el elemento.', false); } }; @@ -192,11 +193,11 @@ const EditModalidad = () => { setSelectedElementId(null); setIsAddingOption(false); await handleSubmit(); - sessionStorage.setItem('scrollPosition', window.scrollY); - window.location.reload(); + window.location.reload(); + } catch (error) { console.error('Error al agregar la opción', error); - showAlert('Ocurrió un error al agregar la opción.'); + showAlert('Ocurrió un error al agregar la opción.', false); } }; @@ -459,8 +460,8 @@ const EditModalidad = () => { formData.append('imagen', imagen); } await api.modalidades.update(id, formData); - showAlert('Modalidad actualizada correctamente', true) if (e) { + showAlert('Modalidad actualizada correctamente', true) setTimeout(() => { navigate('/modalidades'); }, 1000); diff --git a/cosiap_frontend/src/components/modalidades/Modalidad.css b/cosiap_frontend/src/components/modalidades/Modalidad.css index 105c714..56eb7ca 100644 --- a/cosiap_frontend/src/components/modalidades/Modalidad.css +++ b/cosiap_frontend/src/components/modalidades/Modalidad.css @@ -262,4 +262,31 @@ .error { background-color: #f44336; /* Rojo para error */ +} + + +.download-button { + display: inline-block; + padding: 10px 20px; + margin-top: 10px; + background-color: #955e3d; /* Color de fondo */ + color: white; /* Color del texto */ + text-align: center; + text-decoration: none; + font-size: 12px; + font-weight: bold; + border-radius: 5px; + transition: background-color 0.3s ease; +} + +.download-button:hover { + background-color: #45a049; /* Color de fondo al pasar el mouse */ +} + +.download-button:active { + background-color: #3e8e41; /* Color de fondo al hacer clic */ +} + +.download-button:focus { + outline: none; /* Elimina el borde de enfoque */ } \ No newline at end of file -- GitLab