From a529862e5294ccbad8f551985cf09fce81912172 Mon Sep 17 00:00:00 2001 From: Elliot Axel Noriega Date: Wed, 16 Oct 2024 13:12:18 -0600 Subject: [PATCH] Correcion de estilosy primera parte de lista de solicitudes --- cosiap_frontend/package-lock.json | 157 +++++++++- cosiap_frontend/package.json | 3 +- .../components/SolicitudesAdmin/Button.jsx | 16 + .../SolicitudesAdmin/MenuColumnas.jsx | 68 +++++ .../SolicitudesAdmin/MenuFiltros.jsx | 18 ++ .../SolicitudesAdmin/Solicitudes.jsx | 284 +++++++++++++++++- .../LayoutsNavigation/Navbar/MobileMenu.jsx | 2 +- .../Navbar/Notifications.jsx | 2 +- .../layouts/LayoutsNavigation/Settings.jsx | 2 +- .../Sidebar/Notifications.jsx | 2 +- 10 files changed, 536 insertions(+), 18 deletions(-) create mode 100644 cosiap_frontend/src/components/SolicitudesAdmin/Button.jsx create mode 100644 cosiap_frontend/src/components/SolicitudesAdmin/MenuColumnas.jsx create mode 100644 cosiap_frontend/src/components/SolicitudesAdmin/MenuFiltros.jsx diff --git a/cosiap_frontend/package-lock.json b/cosiap_frontend/package-lock.json index 82530f0..4aad360 100644 --- a/cosiap_frontend/package-lock.json +++ b/cosiap_frontend/package-lock.json @@ -15,6 +15,7 @@ "@tailwindcss/typography": "^0.5.13", "axios": "^1.7.2", "react": "^18.2.0", + "react-beautiful-dnd": "^13.1.0", "react-dom": "^18.2.0", "react-helmet-async": "^2.0.5", "react-hook-form": "^7.52.1", @@ -45,6 +46,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@babel/runtime": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.7.tgz", + "integrity": "sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w==", + "license": "MIT", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", @@ -1136,17 +1149,25 @@ "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, + "node_modules/@types/hoist-non-react-statics": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz", + "integrity": "sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==", + "license": "MIT", + "dependencies": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, "node_modules/@types/prop-types": { "version": "15.7.12", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", - "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==", - "dev": true + "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==" }, "node_modules/@types/react": { "version": "18.3.3", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz", "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==", - "dev": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -1161,6 +1182,18 @@ "@types/react": "*" } }, + "node_modules/@types/react-redux": { + "version": "7.1.34", + "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.34.tgz", + "integrity": "sha512-GdFaVjEbYv4Fthm2ZLvj1VSCedV7TqE5y1kNwnjSdBOTXuRSgowux6J8TAct15T3CKBr63UMk+2CO7ilRhyrAQ==", + "license": "MIT", + "dependencies": { + "@types/hoist-non-react-statics": "^3.3.0", + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0", + "redux": "^4.0.0" + } + }, "node_modules/@ungap/structured-clone": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", @@ -1627,6 +1660,15 @@ "node": ">= 8" } }, + "node_modules/css-box-model": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/css-box-model/-/css-box-model-1.2.1.tgz", + "integrity": "sha512-a7Vr4Q/kd/aw96bnJG332W9V9LkJO69JRcaCYDUqjp6/z0w6VcZjgAcTbgFxEPfBgdnAwlh3iwu+hLopa+flJw==", + "license": "MIT", + "dependencies": { + "tiny-invariant": "^1.0.6" + } + }, "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", @@ -1642,8 +1684,7 @@ "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "dev": true + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, "node_modules/data-view-buffer": { "version": "1.0.1", @@ -2637,6 +2678,15 @@ "node": ">= 0.4" } }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "license": "BSD-3-Clause", + "dependencies": { + "react-is": "^16.7.0" + } + }, "node_modules/ignore": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", @@ -3263,6 +3313,12 @@ "node": "14 || >=16.14" } }, + "node_modules/memoize-one": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", + "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==", + "license": "MIT" + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -3846,7 +3902,6 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -3893,6 +3948,12 @@ } ] }, + "node_modules/raf-schd": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/raf-schd/-/raf-schd-4.0.3.tgz", + "integrity": "sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ==", + "license": "MIT" + }, "node_modules/react": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", @@ -3904,6 +3965,26 @@ "node": ">=0.10.0" } }, + "node_modules/react-beautiful-dnd": { + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/react-beautiful-dnd/-/react-beautiful-dnd-13.1.1.tgz", + "integrity": "sha512-0Lvs4tq2VcrEjEgDXHjT98r+63drkKEgqyxdA7qD3mvKwga6a5SscbdLPO2IExotU1jW8L0Ksdl0Cj2AF67nPQ==", + "deprecated": "react-beautiful-dnd is now deprecated. Context and options: https://github.com/atlassian/react-beautiful-dnd/issues/2672", + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.9.2", + "css-box-model": "^1.2.0", + "memoize-one": "^5.1.1", + "raf-schd": "^4.0.2", + "react-redux": "^7.2.0", + "redux": "^4.0.4", + "use-memo-one": "^1.1.1" + }, + "peerDependencies": { + "react": "^16.8.5 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.5 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-dom": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", @@ -3955,8 +4036,38 @@ "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/react-redux": { + "version": "7.2.9", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.9.tgz", + "integrity": "sha512-Gx4L3uM182jEEayZfRbI/G11ZpYdNAnBs70lFVMNdHJI76XYtR+7m0MN+eAs7UHBPhWXcnFPaS+9owSCJQHNpQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.15.4", + "@types/react-redux": "^7.1.20", + "hoist-non-react-statics": "^3.3.2", + "loose-envify": "^1.4.0", + "prop-types": "^15.7.2", + "react-is": "^17.0.2" + }, + "peerDependencies": { + "react": "^16.8.3 || ^17 || ^18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, + "node_modules/react-redux/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "license": "MIT" }, "node_modules/react-router": { "version": "6.23.1", @@ -4011,6 +4122,15 @@ "node": ">=8.10.0" } }, + "node_modules/redux": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", + "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.9.2" + } + }, "node_modules/reflect.getprototypeof": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz", @@ -4032,6 +4152,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "license": "MIT" + }, "node_modules/regexp.prototype.flags": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", @@ -4660,6 +4786,12 @@ "integrity": "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==", "license": "MIT" }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", + "license": "MIT" + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -4805,6 +4937,15 @@ "punycode": "^2.1.0" } }, + "node_modules/use-memo-one": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/use-memo-one/-/use-memo-one-1.1.3.tgz", + "integrity": "sha512-g66/K7ZQGYrI6dy8GLpVcMsBp4s17xNkYJVSMvTEevGy3nDxHOfE6z8BVE22+5G5x7t3+bhzrlTDB7ObrEE0cQ==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", diff --git a/cosiap_frontend/package.json b/cosiap_frontend/package.json index 0c1fb0d..6ed0a1e 100644 --- a/cosiap_frontend/package.json +++ b/cosiap_frontend/package.json @@ -22,7 +22,8 @@ "react-helmet-async": "^2.0.5", "react-hook-form": "^7.52.1", "react-router-dom": "^6.23.1", - "yup": "^1.4.0" + "yup": "^1.4.0", + "react-beautiful-dnd": "^13.1.0" }, "devDependencies": { "@types/react": "^18.2.66", diff --git a/cosiap_frontend/src/components/SolicitudesAdmin/Button.jsx b/cosiap_frontend/src/components/SolicitudesAdmin/Button.jsx new file mode 100644 index 0000000..336f07e --- /dev/null +++ b/cosiap_frontend/src/components/SolicitudesAdmin/Button.jsx @@ -0,0 +1,16 @@ +export default function Button( {nameIcon, text, onClick, buttonRef} ){ + return ( +
+ + {nameIcon} + + + {text} + +
+ ); +} \ No newline at end of file diff --git a/cosiap_frontend/src/components/SolicitudesAdmin/MenuColumnas.jsx b/cosiap_frontend/src/components/SolicitudesAdmin/MenuColumnas.jsx new file mode 100644 index 0000000..43d5dad --- /dev/null +++ b/cosiap_frontend/src/components/SolicitudesAdmin/MenuColumnas.jsx @@ -0,0 +1,68 @@ +export default function MenuColumnas( {columnas, columnasOcultas, setColumnasOcultas, menuRef} ){ + // Función para manejar la selección/deselección de columnas + const handleToggleColumn = (key) => { + if (columnasOcultas.includes(key)) { + // Si la columna está oculta, quitarla de la lista + setColumnasOcultas(columnasOcultas.filter(col => col !== key)); + } else { + // Si la columna no está oculta, agregarla a la lista + setColumnasOcultas([...columnasOcultas, key]); + } + }; + + // Función para ocultar todas las columnas + const handleHideAll = () => { + // Agrega todas las claves de columnas a columnasOcultas + setColumnasOcultas(Object.keys(columnas)); + }; + + // Función para mostrar todas las columnas + const handleShowAll = () => { + // Limpia la lista de columnas ocultas + setColumnasOcultas([]); + }; + + return ( + <> +
+
+
+ + + Ocultar todas + + + + + Mostrar todas + + +
+
+ {Object.entries(columnas).map(([key, value], index) => ( +
+ + + {key === 'modalidad__nombre' ? "Modalidad" : key === 'solicitante__nombre' ? "Solicitante" : value} + +
+ ))} +
+
+
+ + ); +} \ No newline at end of file diff --git a/cosiap_frontend/src/components/SolicitudesAdmin/MenuFiltros.jsx b/cosiap_frontend/src/components/SolicitudesAdmin/MenuFiltros.jsx new file mode 100644 index 0000000..66c832d --- /dev/null +++ b/cosiap_frontend/src/components/SolicitudesAdmin/MenuFiltros.jsx @@ -0,0 +1,18 @@ +export default function MenuFiltros( {filtros, setFiltros} ){ + return ( + <> +
+
+
+ + Eliminar filtros + +
+
+ +
+
+
+ + ); +} \ No newline at end of file diff --git a/cosiap_frontend/src/components/SolicitudesAdmin/Solicitudes.jsx b/cosiap_frontend/src/components/SolicitudesAdmin/Solicitudes.jsx index 065d4b6..166bf99 100644 --- a/cosiap_frontend/src/components/SolicitudesAdmin/Solicitudes.jsx +++ b/cosiap_frontend/src/components/SolicitudesAdmin/Solicitudes.jsx @@ -1,12 +1,286 @@ +import { useEffect, useRef, useState } from "react"; import SectionContainer from "../common/ui/SectionContainers/SectionContainer"; +import Button from "./Button"; +import api from "@/api"; +import MenuColumnas from "./MenuColumnas"; +import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd"; +import MenuFiltros from "./MenuFiltros"; + +export default function Solicitudes( {setViewPageLoader} ){ + const [solicitudes, setSolicitudes] = useState([]); + const [columnas, setColumnas] = useState({}); + const [columnasOcultas, setColumnasOcultas] = useState([]); + const [filtros, setFiltros] = useState([]); + const [solicitudesOriginales, setSolicitudesOriginales] = useState([]); + + //Vistas de columnas y filtros + const [viewMenuColumnas, setViewMenuColumnas] = useState(false) + const [viewMenuFiltros, setViewMenuFiltros] = useState(false) + + //Ref para ventanas y botones de los filtros y columnas + const menuColumnasRef = useRef(null); + const buttonMenuColumnasRef = useRef(null); + + const [sortConfig, setSortConfig] = useState({ key: null, direction: 'ascending' }); + + const obtenerSolicitudes = async () => { + try { + setViewPageLoader(true) + + //Obtenemos las solicitudes + const response = await api.solicitudes.get(); + console.log('Extraccion de solicitudes exitosa', response) + setSolicitudes(response.data.data); + setSolicitudesOriginales(response.data.data); + setColumnas(response.data.available_columns); + setFiltros(response.data.available_filters); + console.log('Columnas', response.data.available_columns) + console.log('Filtros', response.data.available_filters) + console.log('Solicitudes', response.data.data) + } catch (error) { + console.log('Extraccion de solicitudes fallida', error) + }finally{ + setViewPageLoader(false) + } + }; + + // Efecto para manejar los clics fuera de los menús y notificaciones + useEffect(() => { + function handleClickOutside(event) { + // Cierra el menú si se hace clic fuera de él y de su botón de toggle + if (menuColumnasRef.current && !menuColumnasRef.current.contains(event.target) && + buttonMenuColumnasRef.current && !buttonMenuColumnasRef.current.contains(event.target)){ + setViewMenuColumnas(false); + } + } + + // Añade el event listener para detectar clics fuera de los elementos + document.addEventListener("mousedown", handleClickOutside); + + // Remueve el event listener cuando el componente se desmonte + return () => { + document.removeEventListener("mousedown", handleClickOutside); + }; + }, []); + + useEffect(() => { + obtenerSolicitudes() + }, []) + + const sortSolicitudes = (key) => { + let direction = 'ascending'; + + // Cambiar a descendente si ya está en ascendente + if (sortConfig.key === key && sortConfig.direction === 'ascending') { + direction = 'descending'; + } + // Si ya está en descendente, quitamos el sort y restauramos el orden original + else if (sortConfig.key === key && sortConfig.direction === 'descending') { + setSortConfig({ key: null, direction: null }); + setSolicitudes([...solicitudesOriginales]); // Restaurar a la lista original + return; + } + + const sortedSolicitudes = [...solicitudes].sort((a, b) => { + const aValue = typeof a[key] === 'number' ? a[key] : a[key].toString().toLowerCase(); + const bValue = typeof b[key] === 'number' ? b[key] : b[key].toString().toLowerCase(); + + if (aValue < bValue) { + return direction === 'ascending' ? -1 : 1; + } + if (aValue > bValue) { + return direction === 'ascending' ? 1 : -1; + } + return 0; + }); + + setSolicitudes(sortedSolicitudes); + setSortConfig({ key, direction }); + }; + + const handleDragEnd = (result) => { + const { source, destination } = result; + if (!destination) return; + + const updatedColumnOrder = Array.from(Object.keys(columnas)); + const [movedColumn] = updatedColumnOrder.splice(source.index, 1); + updatedColumnOrder.splice(destination.index, 0, movedColumn); + + const reorderedColumns = {}; + updatedColumnOrder.forEach((columnKey) => { + reorderedColumns[columnKey] = columnas[columnKey]; + }); + + // Reordenar las solicitudes según el nuevo orden de las columnas + const reorderedSolicitudes = solicitudes.map((solicitud) => { + const reorderedSolicitud = {}; + updatedColumnOrder.forEach((columnKey) => { + reorderedSolicitud[columnKey] = solicitud[columnKey]; + }); + return reorderedSolicitud; + }); + + setColumnas(reorderedColumns); + setSolicitudes(reorderedSolicitudes); + }; + + // Función que retorna los estilos según el campo y el valor + const getEstiloCampo = (key, value) => { + switch (key) { + case 'status': + return ( + + {value} + + ); + case 'solicitante__sexo': + return ( + value === 'M' ? 'Masculino' : value === 'O' ? 'Otro' : "Femenino" + ); + + case 'modalidad__nombre': + return ( + + {value} + + ); + + case 'monto_solicitado': + return ( + + ${value.toLocaleString('es-MX', { + minimumFractionDigits: 2, // Número mínimo de decimales + maximumFractionDigits: 2, // Número máximo de decimales + })} + + ); + case 'monto_aprobado': + return ( + + ${value.toLocaleString('es-MX', { + minimumFractionDigits: 2, // Número mínimo de decimales + maximumFractionDigits: 2, // Número máximo de decimales + })} + + ); + case 'modalidad__monto_maximo': + return ( + + ${value.toLocaleString('es-MX', { + minimumFractionDigits: 2, // Número mínimo de decimales + maximumFractionDigits: 2, // Número máximo de decimales + })} + + ); + + + default: + return value; + } + } -export default function Solicitudes( {} ){ return ( <> - - - - + {viewMenuColumnas && ( + + )} + {viewMenuFiltros && ( + + )} +
+
+ +
+
+
+ + search + + +
+
+
+
+ + + + + {(provided) => ( + + {Object.entries(columnas).map(([key, value], index) => ( + !columnasOcultas.includes(key) && ( + + {(provided, snapshot) => ( + + )} + + ) + ))} + {provided.placeholder} + + )} + + + + + {solicitudes.map((solicitud, index) => ( + + {Object.entries(solicitud).map(([key, value], i) => ( + !columnasOcultas.includes(key) && ( + + ) + ))} + + ))} + +
+
+ + {key === 'modalidad__nombre' ? "Modalidad" : key === 'solicitante__nombre' ? "Solicitante" : value} + + + sortSolicitudes(key)} // Ordenar al hacer clic + > + {sortConfig.key === key ? ( + sortConfig.direction === 'ascending' ? 'keyboard_arrow_up' : 'keyboard_arrow_down' + ) : ( + 'unfold_more' + )} + +
+
+ {getEstiloCampo(key, value)} +
+
+
+
+
+
+
); } \ No newline at end of file diff --git a/cosiap_frontend/src/components/common/layouts/LayoutsNavigation/Navbar/MobileMenu.jsx b/cosiap_frontend/src/components/common/layouts/LayoutsNavigation/Navbar/MobileMenu.jsx index 3fe95cf..f3e9a30 100644 --- a/cosiap_frontend/src/components/common/layouts/LayoutsNavigation/Navbar/MobileMenu.jsx +++ b/cosiap_frontend/src/components/common/layouts/LayoutsNavigation/Navbar/MobileMenu.jsx @@ -12,7 +12,7 @@ export default function MobileMenu({ menuRef, linksItems }) { return ( <> {/* Contenedor principal del menú móvil */} -
+
{ // Si existe linksItems, mapea cada uno para generar enlaces diff --git a/cosiap_frontend/src/components/common/layouts/LayoutsNavigation/Navbar/Notifications.jsx b/cosiap_frontend/src/components/common/layouts/LayoutsNavigation/Navbar/Notifications.jsx index ec64502..5464c7c 100644 --- a/cosiap_frontend/src/components/common/layouts/LayoutsNavigation/Navbar/Notifications.jsx +++ b/cosiap_frontend/src/components/common/layouts/LayoutsNavigation/Navbar/Notifications.jsx @@ -4,7 +4,7 @@ export default function Notifications( {notificationsRef} ){ return ( <> -
+
diff --git a/cosiap_frontend/src/components/common/layouts/LayoutsNavigation/Settings.jsx b/cosiap_frontend/src/components/common/layouts/LayoutsNavigation/Settings.jsx index 3425804..2047f00 100644 --- a/cosiap_frontend/src/components/common/layouts/LayoutsNavigation/Settings.jsx +++ b/cosiap_frontend/src/components/common/layouts/LayoutsNavigation/Settings.jsx @@ -1,6 +1,6 @@ export default function Settings( {settingsRef, selectedNav, setSelectedNav} ){ return ( -
+
diff --git a/cosiap_frontend/src/components/common/layouts/LayoutsNavigation/Sidebar/Notifications.jsx b/cosiap_frontend/src/components/common/layouts/LayoutsNavigation/Sidebar/Notifications.jsx index fbde007..3275a4e 100644 --- a/cosiap_frontend/src/components/common/layouts/LayoutsNavigation/Sidebar/Notifications.jsx +++ b/cosiap_frontend/src/components/common/layouts/LayoutsNavigation/Sidebar/Notifications.jsx @@ -4,7 +4,7 @@ export default function Notifications( {notificationsRef} ){ return ( <> -
+
-- GitLab