+ );
+}
+
+const MultiRangeSliderSelection = ({ filtro, updateFilterValue, solicitudes, handleDeleteFilter }) => {
+ // Obtenemos el valor máximo del campo específico en las solicitudes
+ const maxValue = Math.max(...solicitudes.map((solicitud) => solicitud[filtro.campo]));
+ // Obtenemos el valor mínimo del campo específico en las solicitudes
+ const minValue = Math.min(...solicitudes.map((solicitud) => solicitud[filtro.campo]));
+
+ // Estado para almacenar los valores del rango
+ const [values, setValues] = useState([(minValue !== maxValue ? minValue : 0), maxValue]);
+
+ // Efecto para actualizar el estado cuando el filtro cambie
+ useEffect(() => {
+ setValues([filtro.lookups.gte || (minValue !== maxValue ? minValue : 0 ), filtro.lookups.lte || maxValue]);
+ }, [filtro, minValue, maxValue]);
+
+ // Función para manejar el cambio de valores en el rango
+ const handleRangeChange = (newValues) => {
+ setValues(newValues); // Actualizamos el estado local del slider
+ // Actualizamos los valores en el filtro
+ //Si los dos valores son el valor minimo y maximo
+ if ((minValue === maxValue ? (newValues[0] === 0) : (newValues[0] === minValue)) && newValues[1] === maxValue) {
+ //Estableceremos valores nulos, ya que se tomara que no se hiso ningun filtro
+ updateFilterValue(filtro.campo, { gte: null, lte: null });
+ } else {
+ // Actualizamos los valores en el filtro
+ updateFilterValue(filtro.campo, { gte: newValues[0], lte: newValues[1]});
+ }
+ };
+
+ // Función para eliminar los filtros y restablecer los valores del rango
+ const handleDeleteFilterAndValues = (filtro) => {
+ handleDeleteFilter(filtro); // Elimina el filtro y sus valores
+ // Restablece los valores del rango a sus valores mínimos y máximos
+ setValues([(minValue !== maxValue ? minValue : 0), maxValue]);
+ };
+
+ return (
+ <>
+
+ >
+ );
+};
+
+const DateSelection = ({ filtro, updateFilterValue, handleDeleteFilter }) => {
+ const [startDate, setStartDate] = useState(filtro.lookups.gte); // Fecha de inicio
+ const [endDate, setEndDate] = useState(filtro.lookups.lte); // Fecha de fin
+
+ // Actualizamos los filtros cada vez que cambien las fechas de inicio o fin.
+ useEffect(() => {
+ if (startDate !== "" && endDate !== "") {
+ updateFilterValue(filtro.campo, { gte: startDate, lte: endDate});
+ }
+ }, [startDate, endDate]);
+
+ // Maneja el cambio de la fecha de inicio
+ const handleStartDateChange = (e) => {
+ const selectedDate = e.target.value;
+ // Solo actualiza si la fecha de inicio es menor o igual que la fecha de fin
+ if (!endDate || selectedDate <= endDate) {
+ setStartDate(selectedDate);
+ }
+ if(selectedDate === ""){ //Si limpia el campo, se borra el estado
+ setEndDate("");
+ }
+ };
+
+ const handleDeleteFilterAndValues = (filtro) => {
+ handleDeleteFilter(filtro); // Elimina el filtro y sus valores
+ //Eliminamos los valores actuales
+ setStartDate("");
+ setEndDate("");
+ }
+
+ // Maneja el cambio de la fecha de fin
+ const handleEndDateChange = (e) => {
+ const selectedDate = e.target.value;
+ // Solo actualiza si la fecha de fin es mayor o igual que la fecha de inicio
+ if (!startDate || selectedDate >= startDate) {
+ setEndDate(selectedDate);
+ }
+ if(selectedDate === ""){ //Si limpia el campo, se borra el estado
+ setEndDate("");
+ }
+ };
+
+ return (
+ <>
+
+ >
+ );
+};
diff --git a/cosiap_frontend/src/components/SolicitudesAdmin/Solicitudes.jsx b/cosiap_frontend/src/components/SolicitudesAdmin/Solicitudes.jsx
index 166bf99d2e65260a806fae15f139e724138574fd..d0ec8f815c31889c272c5189549d0d9fc4d5a430 100644
--- a/cosiap_frontend/src/components/SolicitudesAdmin/Solicitudes.jsx
+++ b/cosiap_frontend/src/components/SolicitudesAdmin/Solicitudes.jsx
@@ -12,6 +12,8 @@ export default function Solicitudes( {setViewPageLoader} ){
const [columnasOcultas, setColumnasOcultas] = useState([]);
const [filtros, setFiltros] = useState([]);
const [solicitudesOriginales, setSolicitudesOriginales] = useState([]);
+ const [filtrosAplicados, setFiltrosAplicados] = useState([]);
+ const [searchTerm, setSearchTerm] = useState('');
//Vistas de columnas y filtros
const [viewMenuColumnas, setViewMenuColumnas] = useState(false)
@@ -20,9 +22,59 @@ export default function Solicitudes( {setViewPageLoader} ){
//Ref para ventanas y botones de los filtros y columnas
const menuColumnasRef = useRef(null);
const buttonMenuColumnasRef = useRef(null);
+ const menuFiltrosRef = useRef(null);
+ const buttonMenuFiltrosRef = useRef(null);
const [sortConfig, setSortConfig] = useState({ key: null, direction: 'ascending' });
+ function Regimen (value) {
+ switch (value) {
+ case "1":
+ return "Régimen Simplificado de Confianza"
+ case "2":
+ return "Sueldos y salarios e ingresos asimilados a salarios"
+ case "3":
+ return "Régimen de Actividades Empresariales y Profesionales"
+ case "4":
+ return "Régimen de Incorporación Fiscal"
+ case "5":
+ return "Enajenación de bienes"
+ case "6":
+ return "Régimen de Actividades Empresariales con ingresos a través de Plataformas Tecnológicas"
+ case "7":
+ return "Régimen de Arrendamiento"
+ case "8":
+ return "Intereses"
+ case "9":
+ return "Obtención de premios"
+ case "10":
+ return "Dividendos"
+ case "11":
+ return "Demás Ingresos"
+ case "12":
+ return "Sin obligaciones fiscales"
+ default:
+ return value;
+ }
+ }
+
+ // Función para manejar la búsqueda
+ const handleSearch = (event) => {
+ const searchTerm = event.target.value.toLowerCase(); // Convertimos a minúsculas para hacer la búsqueda insensible a mayúsculas
+ setSearchTerm(searchTerm);
+
+ // Filtramos las solicitudes originales según el término de búsqueda
+ const filteredSolicitudes = solicitudesOriginales.filter(solicitud => {
+ // Buscamos en todas las columnas.
+ return Object.values(solicitud).some(value =>
+ value?.toString().toLowerCase().includes(searchTerm)
+ );
+ });
+
+ setSolicitudes(filteredSolicitudes);
+ };
+
+
const obtenerSolicitudes = async () => {
try {
setViewPageLoader(true)
@@ -47,11 +99,16 @@ export default function Solicitudes( {setViewPageLoader} ){
// 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
+ // Cierra el menú de las columnas 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);
}
+ // Cierra el menú de los filtros si se hace clic fuera de él y de su botón de toggle
+ if (menuFiltrosRef.current && !menuFiltrosRef.current.contains(event.target) &&
+ buttonMenuFiltrosRef.current && !buttonMenuFiltrosRef.current.contains(event.target)){
+ setViewMenuFiltros(false);
+ }
}
// Añade el event listener para detectar clics fuera de los elementos
@@ -63,6 +120,7 @@ export default function Solicitudes( {setViewPageLoader} ){
};
}, []);
+ //Cada renderizacion del componente, se obtendran las solicitudes
useEffect(() => {
obtenerSolicitudes()
}, [])
@@ -180,12 +238,115 @@ export default function Solicitudes( {setViewPageLoader} ){
})}
);
+ case 'timestamp':
+ const fecha = new Date(value);
+ return (
+
+ {fecha.toLocaleDateString('es-ES', {
+ day: '2-digit',
+ month: '2-digit',
+ year: 'numeric',
+ })}
+
+ );
+ case 'solicitante__datos_bancarios__regimen':
+ return Regimen(value)
-
default:
return value;
}
}
+
+ //Cada que el arreglo de filtros cambie, se aplicaran los filtros
+ useEffect(() => {
+ filtrarSolicitudes()
+ }, [filtros])
+
+ //Funcion para filtrar las solicitudes en base a los filtros
+ const filtrarSolicitudes = () => {
+ // Clonamos las solicitudes originales para no mutarlas
+ let solicitudesFiltradas = [...solicitudesOriginales];
+ let nuevosFiltrosAplicados = [];
+
+
+ // Iteramos sobre cada filtro disponible
+ filtros.forEach(filtro => {
+ const { campo, lookups, html_type } = filtro;
+ // console.log(campo, lookups, html_type)
+ // Filtramos solo si el campo tiene valores en lookups
+ if (html_type === "numberInput") {
+ if (lookups.gte !== null && lookups.lte !== null) {
+ solicitudesFiltradas = solicitudesFiltradas.filter(solicitud => {
+ // console.log(solicitud,(solicitud[campo] >= lookups.gte), (solicitud[campo] <= lookups.lte))
+ return (solicitud[campo] >= lookups.gte) && (solicitud[campo] <= lookups.lte);
+ });
+ // Agregar a la lista de filtros aplicados
+ nuevosFiltrosAplicados.push({ filtro });
+ }
+ } else if (html_type === "dateInput") {
+ if (lookups.gte !== null && lookups.lte !== null) {
+ solicitudesFiltradas = solicitudesFiltradas.filter(solicitud => {
+ // Convertimos los valores de la solicitud y los filtros a Date
+ const fechaSolicitud = new Date(solicitud[campo]);
+ const fechaGte = new Date(lookups.gte);
+ const fechaLte = new Date(lookups.lte);
+
+ // Truncamos la parte de la hora para gte (solo fecha) y ajustamos lte al final del día
+ const fechaSolicitudSinHora = new Date(fechaSolicitud.getFullYear(), fechaSolicitud.getMonth(), fechaSolicitud.getDate());
+ const fechaGteSinHora = new Date(fechaGte.getFullYear(), fechaGte.getMonth(), fechaGte.getDate());
+
+ // Límite superior se ajusta para incluir todo el día (hasta las 23:59:59)
+ const fechaLteFinDia = new Date(fechaLte.getFullYear(), fechaLte.getMonth(), fechaLte.getDate(), 23, 59, 59);
+
+ // Comparación de fechas con gte y lte
+ return (fechaSolicitudSinHora >= fechaGteSinHora) && (fechaSolicitudSinHora <= fechaLteFinDia);
+ });
+ // Agregar a la lista de filtros aplicados
+ nuevosFiltrosAplicados.push({ filtro });
+ }
+ } else if (html_type === "textInput") {
+ if (lookups.icontains) {
+ solicitudesFiltradas = solicitudesFiltradas.filter(solicitud =>
+ solicitud[campo].toLowerCase().includes(lookups.icontains.toLowerCase())
+ );
+ // Agregar a la lista de filtros aplicados
+ nuevosFiltrosAplicados.push({ filtro });
+ }
+ if (lookups.iexact) {
+ solicitudesFiltradas = solicitudesFiltradas.filter(solicitud =>
+ lookups.iexact.includes(solicitud[campo])
+ );
+ // Agregar a la lista de filtros aplicados
+ nuevosFiltrosAplicados.push({ filtro });
+ }
+ }
+ });
+
+ setSolicitudes(solicitudesFiltradas); // Actualizamos las solicitudes filtradas
+ setFiltrosAplicados(nuevosFiltrosAplicados); // Actualizamos los filtros aplicados
+ };
+
+ const deleteFilter = (campo) => {
+ const updatedFiltros = filtros.map((filter) => {
+ if (filter.campo === campo) {
+ if ((filter.html_type === "numberInput") || (filter.html_type === "dateInput")) {
+ //Declaramos gte del filter como nulo igual que lte
+ filter.lookups.gte = null;
+ filter.lookups.lte = null;
+
+ } else if (filter.html_type === "textInput") {
+ if (filter.lookups.icontains){
+ filter.lookups.icontains = null;
+ }
+ if (filter.lookups.iexact){
+ filter.lookups.iexact = null;
+ }
+ }
+ }
+ return filter;
+ });
+ setFiltros(updatedFiltros);
+ };
return (
<>
@@ -193,7 +354,7 @@ export default function Solicitudes( {setViewPageLoader} ){
)}
{viewMenuFiltros && (
-
+
)}
diff --git a/cosiap_frontend/src/components/users/Perfil/Direccion.jsx b/cosiap_frontend/src/components/users/Perfil/Direccion.jsx
index 35fa7e1938210d5f3c11ac3c102f3606e5c1729d..21ccef7552f220e0e615e1ad44d6c59b35ba6942 100644
--- a/cosiap_frontend/src/components/users/Perfil/Direccion.jsx
+++ b/cosiap_frontend/src/components/users/Perfil/Direccion.jsx
@@ -9,7 +9,7 @@ import { DirectionInformationValidationSchema } from "@/components/FormsValidati
import api from "@/api";
-export default function Direccion({ datosSolicitante, setViewPageLoader, setShowAlertSuccesful }){
+export default function Direccion({ datosSolicitante, obtenerInformacionSolicitante, setViewPageLoader, setShowAlertSuccesful }){
// Estados
const [isEditing, setIsEditing] = useState(false); // Estado para controlar si está en modo edición
const [modifiedFields, setModifiedFields] = useState({}); // Campos que han sido modificados
@@ -38,8 +38,8 @@ export default function Direccion({ datosSolicitante, setViewPageLoader, setShow
// Función para resetear los datos del formulario con los valores actuales del solicitante
const resetData = () => reset({
direccion: datosSolicitante.direccion || "",
- estado: estadoSeleccionado || "",
- municipio: municipioSeleccionado || "",
+ estado: (datosSolicitante.municipio ? (datosSolicitante.municipio.estado.id) : ""),
+ municipio: (datosSolicitante.municipio ? (datosSolicitante.municipio.id) : ""),
codigo_postal: datosSolicitante.codigo_postal || "",
poblacion: datosSolicitante.poblacion || ""
});
@@ -98,6 +98,9 @@ export default function Direccion({ datosSolicitante, setViewPageLoader, setShow
try {
// Actualizar los datos del solicitante
const response = await api.usuarios.solicitantes.update(datosSolicitante.id, data);
+
+ //Obtenemos de nuevo los datos del solicitante
+ obtenerInformacionSolicitante();
// Cerrar modal de confirmación y deshabilitar la edición
setShowModalConfirmation(false);
setIsEditing(false);
@@ -133,6 +136,10 @@ export default function Direccion({ datosSolicitante, setViewPageLoader, setShow
setIsEditing(false); // Deshabilitar el modo edición
resetData(); // Restablecer los datos originales
setModifiedFields({}); // Limpiar los campos modificados
+ if (datosSolicitante.municipio){
+ setEstadoSeleccionado(datosSolicitante.municipio.estado.id);
+ setMunicipioSeleccionado(datosSolicitante.municipio.id);
+ }
};
// Función para manejar el clic de "Guardar" con validación
diff --git a/cosiap_frontend/src/components/users/Perfil/InformacionIdentificacion.jsx b/cosiap_frontend/src/components/users/Perfil/InformacionIdentificacion.jsx
index 194a4021f55a22d3d3ef3c67e5335705fe9c9968..2c7965de63c57ce3bd4f2a50b9e1224fe0ecea6c 100644
--- a/cosiap_frontend/src/components/users/Perfil/InformacionIdentificacion.jsx
+++ b/cosiap_frontend/src/components/users/Perfil/InformacionIdentificacion.jsx
@@ -8,7 +8,7 @@ import { IdentificationValidationSchema } from "@/components/FormsValidations";
import api, { apiUrl } from "@/api";
import Label_InputFile from "./Label_InputFile";
-export default function InformacionIdentificacion( {datosSolicitante, setViewPageLoader, setShowAlertSuccesful} ){
+export default function InformacionIdentificacion( {datosSolicitante, setDatosSolicitante, setViewPageLoader, setShowAlertSuccesful} ){
// Estados
const [isEditing, setIsEditing] = useState(false); // Estado para controlar si está en modo edición
const [modifiedFields, setModifiedFields] = useState({}); // Campos que han sido modificados
@@ -21,11 +21,6 @@ export default function InformacionIdentificacion( {datosSolicitante, setViewPag
formState: { errors, isSubmitting } // Estado del formulario: errores y si se está enviando
} = useForm({
resolver: yupResolver(IdentificationValidationSchema), // Resolver para la validación con Yup
- defaultValues: {
- RFC: "",
- curp: "",
- INE: "",
- }
});
// Función para resetear los datos del formulario con los valores actuales del solicitante
@@ -67,14 +62,14 @@ export default function InformacionIdentificacion( {datosSolicitante, setViewPag
'Content-Type': 'multipart/form-data',
},
});
- console.log(response)
+
+ //Obtenemos de nuevo los datos del solicitante
+ obtenerInformacionSolicitante();
+
// Cerrar modal de confirmación y deshabilitar la edición
setShowModalConfirmation(false);
setIsEditing(false);
setModifiedFields({}); // Vaciar los campos modificados
- if(datosSolicitante.INE){
- setUrlFileIne(apiUrl + response.data.solicitante.INE);//Declaramos la ruta con el archivo subido
- }
setShowAlertSuccesful(true);
} catch (error) {
console.error(error); // Manejar errores
diff --git a/cosiap_frontend/src/components/users/Perfil/InformacionPersonal.jsx b/cosiap_frontend/src/components/users/Perfil/InformacionPersonal.jsx
index 52778407992dc1048290c54f7ef4e31f7f807f65..836400b9de528712ff5c952b70539db376ac1455 100644
--- a/cosiap_frontend/src/components/users/Perfil/InformacionPersonal.jsx
+++ b/cosiap_frontend/src/components/users/Perfil/InformacionPersonal.jsx
@@ -8,7 +8,7 @@ import { useEffect, useState } from "react";
import { PersonalInformationValidationSchema } from "@/components/FormsValidations";
import api from "@/api";
-export default function InformacionPersonal({ datosSolicitante, setViewPageLoader, setShowAlertSuccesful }) {
+export default function InformacionPersonal({ datosSolicitante, obtenerInformacionSolicitante, setViewPageLoader, setShowAlertSuccesful }) {
// Estados
const [isEditing, setIsEditing] = useState(false); // Estado para controlar si está en modo edición
const [modifiedFields, setModifiedFields] = useState({}); // Campos que han sido modificados
@@ -57,6 +57,9 @@ export default function InformacionPersonal({ datosSolicitante, setViewPageLoade
// Actualizar los datos del solicitante
const response = await api.usuarios.solicitantes.update(datosSolicitante.id, data);
console.log(response);
+
+ //Obtenemos de nuevo los datos del solicitante
+ obtenerInformacionSolicitante();
// Cerrar modal de confirmación y deshabilitar la edición
setShowModalConfirmation(false);
diff --git a/cosiap_frontend/src/components/users/Perfil/Label_InputFile.jsx b/cosiap_frontend/src/components/users/Perfil/Label_InputFile.jsx
index 585b0b5c623e112e95f41e4a7cda1f74360828c9..7ed66cf2c4100e10e753f637547439d3d5dd2557 100644
--- a/cosiap_frontend/src/components/users/Perfil/Label_InputFile.jsx
+++ b/cosiap_frontend/src/components/users/Perfil/Label_InputFile.jsx
@@ -42,7 +42,6 @@ export default function Label_InputFile({urlFile, label, id, name, type, placeho
isDisabled={isDisabled}
errors={errors}
/>
-
{message}
{/* Aquí mostramos el área de vista previa si hay un archivo seleccionado */}
{selectedFile && !isDisabled && ( //Cuando hay un archivo seleccionado y esta habilitado el campo
diff --git a/cosiap_frontend/src/components/users/Perfil/Perfil.jsx b/cosiap_frontend/src/components/users/Perfil/Perfil.jsx
index 4b804605fc7cd7006331872d101180db305da6cf..a9956e422db90941ccbf6482a63241da33930125 100644
--- a/cosiap_frontend/src/components/users/Perfil/Perfil.jsx
+++ b/cosiap_frontend/src/components/users/Perfil/Perfil.jsx
@@ -5,6 +5,7 @@ import Alert from "@/components/common/ui/Alert";
import api from "@/api";
import { useAutenticacion } from "@/components/common/utility/Autenticador";
import { useEffect, useState } from "react";
+import DatosBancarios from "./DatosBancarios";
export default function Perfil( {setViewPageLoader} ){
const { uid } = useAutenticacion();
@@ -26,11 +27,12 @@ export default function Perfil( {setViewPageLoader} ){
const obtenerInformacionSolicitante = async () =>{
if (uid){
- setViewPageLoader(true);
try {
+ setViewPageLoader(true);
//Tratamos de obtener el solicitante con el id
const responseObtain = await api.usuarios.solicitantes.getById(uid);
//Declaramos los datos del solicitante
+ console.log(responseObtain.data)
setDatosSolicitante(responseObtain.data);
console.log(responseObtain.data)
} catch (error) { // Si da error significa que es su primera vez ingresando
@@ -55,19 +57,28 @@ export default function Perfil( {setViewPageLoader} ){
/>