Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 801e1b4205 | |||
| 3de2f08ed2 | |||
| bbb0b0f795 | |||
| 6ff9641761 | |||
| 99adfdebb5 | |||
| ac1fd05638 | |||
| 8b27cbd425 | |||
| 82b5b1fc50 | |||
| e27b1fb643 | |||
| da73df3e7d | |||
| 5a0fe4edde | |||
| b1bafec1be |
@@ -0,0 +1 @@
|
||||
correo,nombre,institucion,dependencia,programa,clave
|
||||
|
+43
-45
@@ -1,61 +1,59 @@
|
||||
import axios from "axios";
|
||||
import axios from 'axios';
|
||||
|
||||
// Crea una instancia base de Axios
|
||||
export const axiosInstance = axios.create({
|
||||
baseURL: process.env.NEXT_PUBLIC_API_URL || "http://localhost:3411", // poner la url
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
timeout: 10000, // tiempo máximo de espera (10 segundos)
|
||||
baseURL: process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3000/api', // poner la url
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
timeout: 10000, // tiempo máximo de espera (10 segundos)
|
||||
});
|
||||
|
||||
// Interceptor para agregar el token automáticamente
|
||||
axiosInstance.interceptors.request.use(
|
||||
(config) => {
|
||||
if (typeof window !== "undefined") {
|
||||
const token = localStorage.getItem("token");
|
||||
if (token) {
|
||||
// Múltiples formatos según lo que espere el backend
|
||||
config.headers.Authorization = `Bearer ${token}`;
|
||||
(config) => {
|
||||
if (typeof window !== 'undefined') {
|
||||
const token = localStorage.getItem('token');
|
||||
if (token) {
|
||||
// Múltiples formatos según lo que espere el backend
|
||||
config.headers.Authorization = `Bearer ${token}`;
|
||||
|
||||
//Quitar estas lienas
|
||||
config.headers['token'] = token;
|
||||
config.headers['x-access-token'] = token;
|
||||
config.headers['token-v2'] = token;
|
||||
}
|
||||
|
||||
//Quitar estas lienas
|
||||
config.headers["token"] = token;
|
||||
config.headers["x-access-token"] = token;
|
||||
config.headers["token-v2"] = token;
|
||||
}
|
||||
}
|
||||
return config;
|
||||
},
|
||||
(error) => Promise.reject(error)
|
||||
}
|
||||
return config;
|
||||
},
|
||||
(error) => Promise.reject(error)
|
||||
);
|
||||
|
||||
// Interceptor para manejar respuestas y errores globales
|
||||
axiosInstance.interceptors.response.use(
|
||||
(response) => response,
|
||||
(error) => {
|
||||
if (error.response) {
|
||||
// Token inválido o sesión expirada
|
||||
if (error.response.status === 401) {
|
||||
console.warn("Sesión expirada o token inválido.");
|
||||
if (typeof window !== "undefined") {
|
||||
localStorage.clear();
|
||||
window.location.href = "/"; // redirige automáticamente
|
||||
(response) => response,
|
||||
(error) => {
|
||||
if (error.response) {
|
||||
// Token inválido o sesión expirada
|
||||
if (error.response.status === 401) {
|
||||
console.warn('Sesión expirada o token inválido.');
|
||||
if (typeof window !== 'undefined') {
|
||||
//localStorage.clear();
|
||||
//window.location.href = '/'; // redirige automáticamente
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Errores del servidor
|
||||
console.error("Error en la respuesta del servidor:", error.response.data);
|
||||
} else if (error.request) {
|
||||
// No hubo respuesta del servidor
|
||||
console.error("No se recibió respuesta del servidor.");
|
||||
} else {
|
||||
// Error en la configuración de la petición
|
||||
console.error(
|
||||
"Error en la configuración de la solicitud:",
|
||||
error.message
|
||||
);
|
||||
// Errores del servidor
|
||||
console.error('Error en la respuesta del servidor:', error.response.data);
|
||||
} else if (error.request) {
|
||||
// No hubo respuesta del servidor
|
||||
console.error('No se recibió respuesta del servidor.');
|
||||
} else {
|
||||
// Error en la configuración de la petición
|
||||
console.error('Error en la configuración de la solicitud:', error.message);
|
||||
}
|
||||
|
||||
return Promise.reject(error);
|
||||
}
|
||||
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
@@ -27,9 +27,9 @@ interface Status {
|
||||
}
|
||||
|
||||
interface Alumno {
|
||||
Usuario?: object;
|
||||
Carrera?: object;
|
||||
Status?: Status;
|
||||
usuario?: object;
|
||||
carrera?: object;
|
||||
status?: Status;
|
||||
}
|
||||
|
||||
export default function CasoEspecialPage() {
|
||||
@@ -38,7 +38,7 @@ export default function CasoEspecialPage() {
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [idCasoEspecial, setIdCasoEspecial] = useState<number | null>(null);
|
||||
const [admin, setAdmin] = useState<Admin>({});
|
||||
const [alumno, setAlumno] = useState<Alumno>({ Usuario: {}, Carrera: {}, Status: {} });
|
||||
const [alumno, setAlumno] = useState<Alumno>({ usuario: {}, carrera: {}, status: {} });
|
||||
|
||||
// Funciones de dialogo
|
||||
const imprimirError = (err: unknown = {}, title = '¡Hubo un error!', onConfirm = () => {}) => {
|
||||
@@ -111,8 +111,11 @@ export default function CasoEspecialPage() {
|
||||
updateIsLoading(true);
|
||||
|
||||
try {
|
||||
const res = await axiosInstance.get(`/caso_especial?idCasoEspecial=${idCasoEspecial}`, { headers: { token: admin.token } });
|
||||
setAlumno(res.data);
|
||||
const res = await axiosInstance.get(`/caso-especial/caso_especial/${idCasoEspecial}`);
|
||||
setAlumno(res.data.data);
|
||||
|
||||
console.log("Respuesta del servidor", res.data)
|
||||
|
||||
} catch (err: unknown) {
|
||||
if (isAxiosError(err)) imprimirError(err.response?.data || err.message);
|
||||
else if (err instanceof Error) imprimirError(err.message);
|
||||
@@ -148,7 +151,7 @@ export default function CasoEspecialPage() {
|
||||
|
||||
<InformacionCasoEspecial alumno={alumno} />
|
||||
|
||||
{(alumno.Status?.idStatus === 11 || alumno.Status?.idStatus === 12) && (
|
||||
{(alumno.status?.idStatus === 11 || alumno.status?.idStatus === 12) && (
|
||||
<LiberarCasoEspecial
|
||||
idCasoEspecial={idCasoEspecial!}
|
||||
admin={{ token: admin.token! }}
|
||||
|
||||
@@ -49,7 +49,7 @@ export default function Editar() {
|
||||
|
||||
try {
|
||||
updateIsLoading(true)
|
||||
const res = await axiosInstance.get(`usuario/responsable?idUsuario=${idUsuario}`)
|
||||
const res = await axiosInstance.get(`usuario/responsable/${idUsuario}`)
|
||||
//imprimirMensaje(res.data.message)
|
||||
setData(res.data)
|
||||
} catch (error) {
|
||||
|
||||
@@ -78,10 +78,10 @@ Programa: { Usuario: {} },
|
||||
|
||||
//Interface
|
||||
interface Datos {
|
||||
Programa?: Programa;
|
||||
Carrera?: Carrera;
|
||||
Usuario?: Usuario;
|
||||
Status?: Status;
|
||||
programa?: Programa;
|
||||
carrera?: Carrera;
|
||||
usuario?: Usuario;
|
||||
status?: Status;
|
||||
creditos?: string;
|
||||
correo?: string;
|
||||
fechaRegistro?: string;
|
||||
@@ -190,10 +190,10 @@ export default function Servicio() {
|
||||
const obtenerRegistro = async (adminInfo: AdminInfo, idServicioVal: number) => {
|
||||
try {
|
||||
updateIsLoading(true);
|
||||
const res = await axiosInstance.get(`/servicio/admin?idServicio=${idServicioVal}`); //, adminInfo.token
|
||||
const res = await axiosInstance.get(`/servicio/admin/${idServicioVal}`); //, adminInfo.token
|
||||
console.log('Respuesta del servicio:', res.data);
|
||||
setDatos(res.data);
|
||||
console.log('Programa obtenido:', datos.Status);
|
||||
console.log('Programa obtenido:', datos.status);
|
||||
} catch (error) {
|
||||
//imprimirError(error.response?.data || { message: 'Error al obtener el registro' });
|
||||
console.log('Error al obtener el registro:', error);
|
||||
@@ -239,7 +239,7 @@ export default function Servicio() {
|
||||
<section className="container px-2 pb-6">
|
||||
<BotonRegresar />
|
||||
|
||||
<h3 className="container fw-bold title">{datos.Status?.status}</h3>
|
||||
<h3 className="container fw-bold title">{datos.status?.status}</h3>
|
||||
|
||||
<InformacionServicio
|
||||
datos={datos}
|
||||
@@ -248,7 +248,7 @@ export default function Servicio() {
|
||||
updateIsLoading={updateIsLoading}
|
||||
/>
|
||||
|
||||
<TituloStatus status={datos.Status}/>
|
||||
<TituloStatus status={datos.status}/>
|
||||
|
||||
{/* Para mostrar si tiene la carta y poder ver los diferentes archivos */}
|
||||
{datos.cartaAceptacion && (
|
||||
|
||||
+89
-97
@@ -1,109 +1,101 @@
|
||||
"use client";
|
||||
'use client'
|
||||
import { axiosInstance } from "@/api/config";
|
||||
import { useRouter } from "next/navigation";
|
||||
import React from "react";
|
||||
|
||||
export default function Home() {
|
||||
const router = useRouter();
|
||||
const router = useRouter();
|
||||
|
||||
const handleOnSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
|
||||
e.preventDefault();
|
||||
const formData = new FormData(e.currentTarget);
|
||||
const object = Object.fromEntries(formData);
|
||||
const [error, setError] = React.useState('');
|
||||
const [loadingData, setLoadingData] = React.useState({
|
||||
usuario: '',
|
||||
password: '',
|
||||
});
|
||||
|
||||
try {
|
||||
const res = await axiosInstance.post("/auth/login", object);
|
||||
|
||||
// Extraer datos del backend
|
||||
const token = res?.data?.token ?? "";
|
||||
const usuarioObj = res?.data?.Usuario ?? res?.data ?? {};
|
||||
const idUsuario = usuarioObj.idUsuario ?? "";
|
||||
const usuario = usuarioObj.usuario ?? "";
|
||||
const nombre = usuarioObj.nombre ?? "";
|
||||
const idTipoUsuario = Number(usuarioObj.TipoUsuario?.idTipoUsuario ?? 0);
|
||||
//const idTipoUsuario = Number((usuarioObj as any).TipoUsuario?.idTipoUsuario ?? 0);
|
||||
|
||||
// Guardar en localStorage
|
||||
localStorage.setItem("token", String(token));
|
||||
localStorage.setItem("idUsuario", String(idUsuario));
|
||||
localStorage.setItem("usuario", String(usuario));
|
||||
localStorage.setItem("nombre", String(nombre));
|
||||
localStorage.setItem("idTipoUsuario", String(idTipoUsuario));
|
||||
|
||||
// Validar y redirigir según el idTipoUsuario
|
||||
if (token && idUsuario && idTipoUsuario) {
|
||||
switch (idTipoUsuario) {
|
||||
case 1:
|
||||
router.push("/administrador");
|
||||
break;
|
||||
case 2:
|
||||
router.push("/responsable");
|
||||
break;
|
||||
case 3:
|
||||
router.push("/alumno");
|
||||
break;
|
||||
case 4:
|
||||
router.push("/casoEspecial");
|
||||
break;
|
||||
default:
|
||||
console.warn(`Tipo de usuario desconocido: ${idTipoUsuario}`);
|
||||
localStorage.clear();
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
localStorage.clear();
|
||||
console.error("Error: datos de usuario incompletos");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error en el inicio de sesión:", error);
|
||||
localStorage.clear();
|
||||
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const { name, value } = e.target;
|
||||
setLoadingData((prevData) => ({ ...prevData, [name]: value}));
|
||||
if (error) setError('');
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className="d-flex justify-content-center align-items-center bg-light"
|
||||
style={{ minHeight: "calc(100vh - 200px)" }}
|
||||
>
|
||||
<form
|
||||
className="p-4 shadow rounded bg-white w-100"
|
||||
style={{ maxWidth: "400px" }}
|
||||
onSubmit={handleOnSubmit}
|
||||
>
|
||||
<h2 className="text-center mb-4 fw-bold">IRIS</h2>
|
||||
const handleOnSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
|
||||
e.preventDefault();
|
||||
const formData = new FormData(e.currentTarget);
|
||||
const object = Object.fromEntries(formData);
|
||||
|
||||
<div className="mb-3">
|
||||
<label htmlFor="usuario" className="form-label">
|
||||
Usuario
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
name="usuario"
|
||||
id="usuario"
|
||||
className="form-control"
|
||||
required
|
||||
/>
|
||||
try {
|
||||
const res = await axiosInstance.post('/auth/login', {
|
||||
usuario: loadingData.usuario,
|
||||
password: loadingData.password,
|
||||
});
|
||||
|
||||
// Extraer datos del backend
|
||||
const token = res?.data?.token ?? '';
|
||||
const usuarioObj = res?.data?.Usuario ?? res?.data ?? {};
|
||||
const idUsuario = usuarioObj.idUsuario ?? '';
|
||||
const usuario = usuarioObj.usuario ?? '';
|
||||
const nombre = usuarioObj.nombre ?? '';
|
||||
const idTipoUsuario = Number(usuarioObj.TipoUsuario?.idTipoUsuario ?? 0);
|
||||
//const idTipoUsuario = Number((usuarioObj as any).TipoUsuario?.idTipoUsuario ?? 0);
|
||||
|
||||
|
||||
// Guardar en localStorage
|
||||
localStorage.setItem('token', String(token));
|
||||
localStorage.setItem('idUsuario', String(idUsuario));
|
||||
localStorage.setItem('usuario', String(usuario));
|
||||
localStorage.setItem('nombre', String(nombre));
|
||||
localStorage.setItem('idTipoUsuario', String(idTipoUsuario));
|
||||
|
||||
|
||||
// Validar y redirigir según el idTipoUsuario
|
||||
if (token && idUsuario && idTipoUsuario) {
|
||||
switch (idTipoUsuario) {
|
||||
case 1:
|
||||
router.push('/administrador');
|
||||
break;
|
||||
case 2:
|
||||
router.push('/responsable');
|
||||
break;
|
||||
case 3:
|
||||
router.push('/alumno');
|
||||
break;
|
||||
case 4:
|
||||
router.push('/casoEspecial');
|
||||
break;
|
||||
default:
|
||||
console.warn(`Tipo de usuario desconocido: ${idTipoUsuario}`);
|
||||
//localStorage.clear();
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
//localStorage.clear();
|
||||
console.error('Error: datos de usuario incompletos');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error en el inicio de sesión:', error);
|
||||
//localStorage.clear();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="d-flex justify-content-center align-items-center bg-light" style={{ minHeight: 'calc(100vh - 200px)' }}>
|
||||
<form className="p-4 shadow rounded bg-white w-100" style={{ maxWidth: '400px' }} onSubmit={handleOnSubmit}>
|
||||
<h2 className="text-center mb-4 fw-bold">IRIS</h2>
|
||||
|
||||
<div className="mb-3">
|
||||
<label htmlFor="usuario" className="form-label">Usuario</label>
|
||||
<input type="text" name="usuario" id="usuario" className="form-control" onChange={handleChange} required />
|
||||
</div>
|
||||
|
||||
<div className="mb-4">
|
||||
<label htmlFor="password" className="form-label">Contraseña</label>
|
||||
<input type="password" name="password" id="password" className="form-control" onChange={handleChange} required />
|
||||
</div>
|
||||
|
||||
<div className="d-grid">
|
||||
<button type="submit" className="btn btn-primary btn-lg">Iniciar Sesión</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div className="mb-4">
|
||||
<label htmlFor="password" className="form-label">
|
||||
Contraseña
|
||||
</label>
|
||||
<input
|
||||
type="password"
|
||||
name="password"
|
||||
id="password"
|
||||
className="form-control"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="d-grid">
|
||||
<button type="submit" className="btn btn-primary btn-lg">
|
||||
Iniciar Sesión
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
@@ -53,17 +53,20 @@ export default function Page() {
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const r: Responsable = {
|
||||
idUsuario: Number(localStorage.getItem('idUsuario')) || undefined,
|
||||
idTipoUsuario: Number(localStorage.getItem('idTipoUsuario')) || undefined,
|
||||
//tipoUsuario: localStorage.getItem('tipoUsuario') || undefined,
|
||||
token: localStorage.getItem('token') || undefined,
|
||||
};
|
||||
const r: Responsable = {
|
||||
idUsuario: Number(localStorage.getItem('idUsuario')) || undefined,
|
||||
idTipoUsuario: Number(localStorage.getItem('idTipoUsuario')) || undefined,
|
||||
//tipoUsuario: localStorage.getItem('tipoUsuario') || undefined,
|
||||
token: localStorage.getItem('token') || undefined,
|
||||
};
|
||||
|
||||
setResponsable(r);
|
||||
console.log('Responsable:', r);
|
||||
console.log('id Usuario en componente padrre', r.idUsuario);
|
||||
//ontenerCatalogoStatus();
|
||||
|
||||
console.log("Esta es la infromacino del useState en responsable", responsable)
|
||||
|
||||
if (r.idTipoUsuario === 1) router.push('/administrador');
|
||||
if (r.idTipoUsuario === 3) router.push('/alumno');
|
||||
if (r.idTipoUsuario === 4) router.push('/casoEspecial');
|
||||
|
||||
@@ -81,7 +81,7 @@ export default function CancelarServicio({
|
||||
const res = await axiosInstance.put(`/servicio/cancelar`, data);
|
||||
localStorage.removeItem("idServicio");
|
||||
imprimirMensaje(res.data.message);
|
||||
router.push("/admin");
|
||||
router.push("/administrador");
|
||||
} catch (err: unknown) {
|
||||
if (isAxiosError(err)) imprimirError(err.response?.data || err.message);
|
||||
else if (err instanceof Error) imprimirError(err.message);
|
||||
|
||||
@@ -5,15 +5,25 @@ import { useRouter } from "next/navigation";
|
||||
import React, { useState } from "react";
|
||||
import { Button, Form } from "react-bootstrap";
|
||||
import { FaUpload } from "react-icons/fa";
|
||||
import { ImDownload } from "react-icons/im";
|
||||
|
||||
export default function CargaMasiva({datos}: {datos: CargaMasivaProps}) {
|
||||
const router = useRouter();
|
||||
const [csv, setCsv] = useState<File | null>(null)
|
||||
|
||||
const url = process.env.NEXT_PUBLIC_API_URL
|
||||
const link = `${url}/plantilla.csv`
|
||||
//const link = `${url}/plantilla.csv`
|
||||
const handleDowload = () => {
|
||||
console.log("Esta entrando a la funcion");
|
||||
const link = document.createElement("a");
|
||||
link.href = "/plantilla/plantilla.csv";
|
||||
link.download = "plantilla.csv";
|
||||
link.click();
|
||||
}
|
||||
//const [link] = useState(`${url}/plantilla.csv`)
|
||||
|
||||
//console.log("Esta es la url para descargar la plantilla", link);
|
||||
|
||||
const validarExt = (file: File | null) => {
|
||||
if (!file) return
|
||||
const extPermitidas = /(.csv)$/i
|
||||
@@ -38,9 +48,13 @@ export default function CargaMasiva({datos}: {datos: CargaMasivaProps}) {
|
||||
//updateIsLoading(true)
|
||||
|
||||
try {
|
||||
|
||||
console.log("Este es el archivo csv", formData)
|
||||
|
||||
const res = await axiosInstance.post("/programa/carga_masiva", formData,{
|
||||
headers: {
|
||||
Authorization: `Bearer ${datos.admin.tokenArchivo}`,
|
||||
'Content-Type': 'multipart/form-data',
|
||||
},
|
||||
})
|
||||
console.log('Respuesta de carga masiva:', res.data)
|
||||
@@ -86,16 +100,16 @@ export default function CargaMasiva({datos}: {datos: CargaMasivaProps}) {
|
||||
disabled={!csv}
|
||||
onClick={enviarCargaMasiva}>
|
||||
Enviar archivo
|
||||
</Button>
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
href={link}
|
||||
<Button
|
||||
onClick={handleDowload}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="bg-morado border-morado"
|
||||
>
|
||||
Descargar plantilla
|
||||
</Button>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -19,8 +19,8 @@ export default function Cuestionario({ years, admin, updateIsLoading }: Props) {
|
||||
try {
|
||||
//updateIsLoading(true);
|
||||
//const res = await axiosInstance.get(`/cuestionario_alumno?year=${selectedCuestionario}&version=${version}`, {
|
||||
const res = await axiosInstance.get(`/cuestionario_alumno`, {
|
||||
params: { year: selectedYear, version },
|
||||
const res = await axiosInstance.get(`/cuestionario-alumno2`, {
|
||||
params: { anio: selectedYear, version },
|
||||
responseType: "blob",
|
||||
});
|
||||
|
||||
|
||||
@@ -26,6 +26,11 @@ interface Props {
|
||||
updateIsLoading: (value: boolean) => void;
|
||||
}
|
||||
|
||||
function convertirFecha(fecha: string | Date) {
|
||||
return new Date(fecha).toISOString().split("T")[0];
|
||||
}
|
||||
|
||||
|
||||
export default function EditarResponsable({
|
||||
//admin,
|
||||
responsable,
|
||||
@@ -54,19 +59,29 @@ export default function EditarResponsable({
|
||||
|
||||
// Actualizar información del responsable
|
||||
const actualizar = async () => {
|
||||
const data: Record<string, unknown> = { idUsuario: responsable.idUsuario };
|
||||
|
||||
const idResponsable = localStorage.getItem("idResponsable");
|
||||
|
||||
if (!idResponsable) return
|
||||
|
||||
const data: Record<string, unknown> = { idUsuario: responsable.idUsuario };
|
||||
if (nuevo.correo) data.correo = nuevo.correo;
|
||||
if (nuevo.nombre) data.nombre = nuevo.nombre;
|
||||
|
||||
// Hacemos el parseo de la fecha
|
||||
//data.fechaNacimiento = convertirFecha(data.fechaNacimiento);
|
||||
|
||||
|
||||
try {
|
||||
updateIsLoading(true);
|
||||
const res = await axiosInstance.put(`/usuario/responsable/update`, data);
|
||||
const res = await axiosInstance.patch(`/usuario/responsable/${idResponsable}`, data);
|
||||
imprimirMensaje(res.data.message);
|
||||
router.push("/administrador/responsables/responsable");
|
||||
} catch (err: unknown) {
|
||||
let msg: unknown = err;
|
||||
if (isAxiosError(err) && err.response?.data) {
|
||||
msg = err.response.data;
|
||||
console.error("ERROR DEL SERVER:", err.response.data);
|
||||
msg = JSON.stringify(err.response.data, null, 2);
|
||||
} else if (err instanceof Error) {
|
||||
msg = err.message;
|
||||
}
|
||||
@@ -80,9 +95,13 @@ export default function EditarResponsable({
|
||||
const password = async () => {
|
||||
const data = { idUsuario: responsable.idUsuario };
|
||||
|
||||
const idResponsable = localStorage.getItem("idResponsable");
|
||||
|
||||
if (!idResponsable) return
|
||||
|
||||
try {
|
||||
updateIsLoading(true);
|
||||
const res = await axiosInstance.put(`/usuario/new_password_responsable`, data);
|
||||
const res = await axiosInstance.post(`/usuario/new-password-responsable/${idResponsable}`);
|
||||
imprimirMensaje(res.data.message);
|
||||
router.push("/administrador/responsables/responsable");
|
||||
} catch (err: unknown) {
|
||||
|
||||
@@ -10,9 +10,10 @@ import "react-datepicker/dist/react-datepicker.css";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { Col, FormGroup, FormLabel, InputGroup } from "react-bootstrap";
|
||||
import { FaRegCalendarAlt, FaUpload } from "react-icons/fa";
|
||||
import { TbFlagSearch } from "react-icons/tb";
|
||||
|
||||
interface Servicio {
|
||||
Status: { idStatus?: number };
|
||||
status: { idStatus?: number };
|
||||
correo?: string;
|
||||
direccion?: string;
|
||||
telefono?: string;
|
||||
@@ -44,8 +45,11 @@ export default function EditarServicio({
|
||||
imprimirWarning,
|
||||
updateIsLoading,
|
||||
}: Props) {
|
||||
const [selectedInicio, setSelectedInicio] = useState<Date | null>(null);
|
||||
const [selectFechaFin, setSelectedFechaFin] = useState<Date | null>(null);
|
||||
|
||||
const [servicioid, setServicioid] = useState<number>();
|
||||
const [servicio, setServicio] = useState<Servicio>({ Status: {} });
|
||||
const [servicio, setServicio] = useState<Servicio>({ status: {} });
|
||||
const [correo, setCorreo] = useState("");
|
||||
const [telefono, setTelefono] = useState("");
|
||||
const [direccion, setDireccion] = useState("");
|
||||
@@ -62,6 +66,14 @@ export default function EditarServicio({
|
||||
const fecha = (date?: Date) =>
|
||||
date ? moment(date).format("DD/MM/YYYY") : "";
|
||||
|
||||
const validarFechas = () => {
|
||||
const fechaInicio = moment(selectedInicio);
|
||||
const fechaFin = moment(selectFechaFin);
|
||||
|
||||
if (!fechaInicio.isValid() || !fechaFin.isValid()) return true;
|
||||
return false
|
||||
}
|
||||
|
||||
// Validación de archivos
|
||||
const sizeFileValido = (file: File) => {
|
||||
if (file.size >= 20000000) {
|
||||
@@ -82,13 +94,16 @@ export default function EditarServicio({
|
||||
try {
|
||||
updateIsLoading(true);
|
||||
console.log("Obteniendo registro para servicioid al hacer el get:", servicioid);
|
||||
const res = await axiosInstance.get(`/servicio/admin?idServicio=${servicioid}`);
|
||||
const res = await axiosInstance.get(`/servicio/admin/${servicioid}`);
|
||||
console.log("Respuesta del servicio obtenido:", res.data);
|
||||
const data = res.data;
|
||||
setServicio(data);
|
||||
|
||||
console.log("Esta es la info de la respuesta", res.data)
|
||||
console.log("Esta es la info de la respuesta con doble data", res.data.data)
|
||||
|
||||
// Redirección si el estado no es válido
|
||||
if (data.Status.idStatus === 6 || data.Status.idStatus === 10) {
|
||||
if (data.status.idStatus === 6 || data.status.idStatus === 10) {
|
||||
router.push("/administrador/servicio");
|
||||
}
|
||||
|
||||
@@ -122,9 +137,11 @@ export default function EditarServicio({
|
||||
if (direccion) data.direccion = direccion;
|
||||
if (correo) data.correo = correo;
|
||||
if (telefono) data.telefono = telefono;
|
||||
if (fechaInicio) data.fechaInicio = fechaInicio;
|
||||
if (fechaFin) data.fechaFin = fechaFin;
|
||||
if (fechaNacimiento) data.fechaNacimiento = fechaNacimiento;
|
||||
|
||||
// Transformamos las fechas para que no muestre error en el back
|
||||
if (selectedInicio && moment(selectedInicio).isValid()) data.fechaInicio = moment(selectedInicio).format("YYYY-MM-DD");
|
||||
if (selectFechaFin && moment(selectFechaFin).isValid()) data.fechaFin = moment(selectFechaFin).format("YYYY-MM-DD");
|
||||
if (fechaNacimiento && moment(fechaNacimiento).isValid()) data.fechaNacimiento = moment(fechaNacimiento).format("YYYY-MM-DD");
|
||||
|
||||
formData.append("data", JSON.stringify(data));
|
||||
|
||||
@@ -151,10 +168,12 @@ export default function EditarServicio({
|
||||
console.log("Id del servicio para nueva password", data);
|
||||
console.log("Id servicio entrando a la info", data.servicioid)
|
||||
|
||||
//const idServicio ={ idServicio: servicioid }
|
||||
|
||||
try {
|
||||
console.log("Si entro par mandar la solicitud")
|
||||
updateIsLoading(true);
|
||||
const res = await axiosInstance.put(`/usuario/new_password_alumno`, { idServicio: servicioid });
|
||||
const res = await axiosInstance.post(`/usuario/new-password-alumno/${data.servicioid}`);
|
||||
imprimirMensaje(res.data.message);
|
||||
updateIsLoading(false);
|
||||
router.push("/administrador");
|
||||
@@ -197,6 +216,9 @@ export default function EditarServicio({
|
||||
} else {
|
||||
setActualizarFechaFin(true);
|
||||
}
|
||||
|
||||
|
||||
console.log("Esta es la info de servicio", servicio);
|
||||
}, [fechaInicio]);
|
||||
|
||||
// Validar tamaños de archivos
|
||||
@@ -257,8 +279,9 @@ export default function EditarServicio({
|
||||
<FaRegCalendarAlt />
|
||||
</InputGroup.Text>
|
||||
<DatePicker
|
||||
selected={selectedInicio}
|
||||
onChange={(date: Date | null ) => {
|
||||
if (date) setFechaInicio(date);
|
||||
if (date) setSelectedInicio(date);
|
||||
}}
|
||||
placeholderText="Selecciona una fecha de inicio"
|
||||
minDate={fechaInicio}
|
||||
@@ -279,8 +302,9 @@ export default function EditarServicio({
|
||||
<FaRegCalendarAlt />
|
||||
</InputGroup.Text>
|
||||
<DatePicker
|
||||
selected={selectFechaFin}
|
||||
onChange={(date: Date | null) => {
|
||||
if (date) setFechaFin(date);
|
||||
if (date) setSelectedFechaFin(date);
|
||||
}}
|
||||
placeholderText="Selecciona una fecha de fin"
|
||||
dateFormat={'dd-MM-yyyy'}
|
||||
@@ -291,7 +315,8 @@ export default function EditarServicio({
|
||||
</InputGroup>
|
||||
</FormGroup>
|
||||
</Col>
|
||||
|
||||
{/*
|
||||
Fecha inicio
|
||||
<div className="mb-3">
|
||||
<label className="form-label fw-semibold block font-medium mb-1">Fecha de inicio</label>
|
||||
<DatePicker
|
||||
@@ -304,7 +329,7 @@ export default function EditarServicio({
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Fecha fin */}
|
||||
fecha fin
|
||||
<div className="mb-3">
|
||||
<label className="form-labeñ fw-semibold block font-medium mb-1">Fecha de fin</label>
|
||||
<DatePicker
|
||||
@@ -316,6 +341,7 @@ export default function EditarServicio({
|
||||
className="border rounded p-2 w-full"
|
||||
/>
|
||||
</div>
|
||||
*/}
|
||||
|
||||
{/* Dirección */}
|
||||
{servicio.direccion && (
|
||||
@@ -346,7 +372,8 @@ export default function EditarServicio({
|
||||
</div>
|
||||
)}
|
||||
|
||||
{servicio.fechaNacimiento && (
|
||||
{/*
|
||||
{servicio.fechaNacimiento && (
|
||||
<Col>
|
||||
<FormGroup>
|
||||
<FormLabel>Fecha de nacimiento</FormLabel>
|
||||
@@ -359,7 +386,7 @@ export default function EditarServicio({
|
||||
</Col>
|
||||
)}
|
||||
|
||||
{/* Fecha nacimiento */}
|
||||
|
||||
{servicio.fechaNacimiento && (
|
||||
<div className="mb-3">
|
||||
<label className="form-label fw-semibold block font-medium mb-1">
|
||||
@@ -368,13 +395,14 @@ export default function EditarServicio({
|
||||
<DatePicker
|
||||
selected={fechaFin}
|
||||
onChange={(date: Date | null) => {
|
||||
if (date) setFechaFin(date);
|
||||
if (date) setFechaNacimiento(date);
|
||||
}}
|
||||
minDate={fechaInicio}
|
||||
className="border rounded p-2 w-full"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
*/}
|
||||
|
||||
<FormGroup className="mb-4">
|
||||
<FormLabel>Carta de aceptaciòn</FormLabel>
|
||||
@@ -382,7 +410,7 @@ export default function EditarServicio({
|
||||
<div
|
||||
className="border p-4 text-center rounded"
|
||||
style={{ cursor: "pointer" }}
|
||||
onClick={() => document.getElementById("application/pdf")?.click()}
|
||||
onClick={() => document.getElementById("pdfInput")?.click()}
|
||||
>
|
||||
<FaUpload size={40} className="mb-2"/>
|
||||
<p className="mb-1">
|
||||
@@ -440,7 +468,7 @@ export default function EditarServicio({
|
||||
|
||||
<button
|
||||
disabled={
|
||||
servicio.Status.idStatus === 1 || servicio.Status.idStatus === 7
|
||||
servicio.status.idStatus === 1 || servicio.status.idStatus === 7
|
||||
}
|
||||
onClick={() =>
|
||||
imprimirWarning(
|
||||
|
||||
@@ -43,10 +43,17 @@ export default function InformacionResponsable({ admin, imprimirError, updateIsL
|
||||
const obtenerResponsable = async () => {
|
||||
try {
|
||||
updateIsLoading(true);
|
||||
const res = await axiosInstance.get(`/usuario/responsable?idUsuario=${idResponsable}`, {
|
||||
|
||||
console.log("Este es el id del responsable", idResponsable)
|
||||
|
||||
const res = await axiosInstance.get(`/usuario/responsable/${idResponsable}`, {
|
||||
headers: { Authorization: admin.token },
|
||||
});
|
||||
setResponsable(res.data);
|
||||
|
||||
console.log("Esta es la info de la res", res.data)
|
||||
console.log("Esta es la info con doble data", res.data.data)
|
||||
|
||||
obtenerProgramas();
|
||||
} catch (err: unknown) {
|
||||
if (isAxiosError(err)) imprimirError(String(err.response?.data) || err.message || 'Error al obtener responsable');
|
||||
@@ -60,21 +67,26 @@ export default function InformacionResponsable({ admin, imprimirError, updateIsL
|
||||
// Funcion para obtener programas
|
||||
const obtenerProgramas = async () => {
|
||||
try {
|
||||
const res = await axiosInstance.get(`/programa/programas_admin?idUsuario=${idResponsable}`, {
|
||||
headers: { Authorization: admin.token },
|
||||
});
|
||||
setProgramas(res.data);
|
||||
const res = await axiosInstance.get(`/programa/programas_admin/${idResponsable}`,);
|
||||
|
||||
console.log("Esta es la info de la res de programas", res.data)
|
||||
console.log("Esta es la info con doble data de programas", res.data.data)
|
||||
|
||||
setProgramas(res.data.data);
|
||||
} catch (err: unknown) {
|
||||
if (isAxiosError(err)) imprimirError(String(err.response?.data) || err.message || 'Error al obtener programas');
|
||||
else if (err instanceof Error) imprimirError(err.message);
|
||||
else imprimirError('Error al obtener programas');
|
||||
if (isAxiosError(err)) {
|
||||
console.error("ERROR COMPLETO:", err.response?.data);
|
||||
imprimirError(JSON.stringify(err.response?.data, null, 2));
|
||||
} else if (err instanceof Error) {
|
||||
imprimirError(err.message);
|
||||
} else imprimirError('Error al obtener programas');
|
||||
}
|
||||
};
|
||||
|
||||
// Cargar al montar
|
||||
useEffect(() => {
|
||||
const id = Number(localStorage.getItem('idResponsable'));
|
||||
|
||||
|
||||
if (!id) {
|
||||
router.push('/administrador/responsables');
|
||||
} else {
|
||||
|
||||
@@ -21,9 +21,9 @@ interface Status {
|
||||
}
|
||||
|
||||
interface Alumno {
|
||||
Usuario?: Usuario;
|
||||
Carrera?: Carrera;
|
||||
Status?: Status;
|
||||
usuario?: Usuario;
|
||||
carrera?: Carrera;
|
||||
status?: Status;
|
||||
creditos?: number;
|
||||
correo?: string;
|
||||
fechaNacimiento?: string;
|
||||
@@ -56,23 +56,23 @@ export default function InformacionCasoEspecial({ alumno }: Props) {
|
||||
return (
|
||||
<div className="mt-4">
|
||||
{/* Título */}
|
||||
<h2 className="fw-bold mb-3">{alumno.Status?.status}</h2>
|
||||
<h2 className="fw-bold mb-3">{alumno.status?.status}</h2>
|
||||
|
||||
<h4 className="mb-4">Datos personales</h4>
|
||||
|
||||
<div className="mb-3">
|
||||
<label className="form-label fw-semibold">Número de Cuenta: </label>
|
||||
<p className="form-control">{alumno.Usuario?.usuario || ''}</p>
|
||||
<p className="form-control">{alumno.usuario?.usuario || ''}</p>
|
||||
</div>
|
||||
|
||||
<div className="fw-semibold mb-3">
|
||||
<label className="form-label">Nombre:</label>
|
||||
<p className="form-control">{alumno.Usuario?.nombre || ''}</p>
|
||||
<p className="form-control">{alumno.usuario?.nombre || ''}</p>
|
||||
</div>
|
||||
|
||||
<div className="fw-semibold mb-3">
|
||||
<label className="form-label">Carrera:</label>
|
||||
<p className="form-control">{alumno.Carrera?.carrera || ''}</p>
|
||||
<p className="form-control">{alumno.carrera?.carrera || ''}</p>
|
||||
</div>
|
||||
|
||||
<div className="fw-semibold mb-3">
|
||||
@@ -265,7 +265,7 @@ export default function InformacionCasoEspecial({ alumno }: Props) {
|
||||
</Form.Group>
|
||||
*/}
|
||||
|
||||
{(alumno.Status?.idStatus === 11 || alumno.Status?.idStatus === 12) && (
|
||||
{(alumno.status?.idStatus === 11 || alumno.status?.idStatus === 12) && (
|
||||
<div className="text-end mt-4">
|
||||
<Button
|
||||
variant="info"
|
||||
|
||||
@@ -29,15 +29,15 @@ interface Programa {
|
||||
programa?: string;
|
||||
clavePrograma?: string;
|
||||
acatlan?: boolean;
|
||||
Usuario?: Usuario;
|
||||
usuario?: Usuario;
|
||||
}
|
||||
|
||||
interface Datos {
|
||||
idServicio?: number;
|
||||
Programa?: Programa;
|
||||
Carrera?: Carrera;
|
||||
Usuario?: Usuario;
|
||||
Status?: Status;
|
||||
programa?: Programa;
|
||||
carrera?: Carrera;
|
||||
usuario?: Usuario;
|
||||
status?: Status;
|
||||
creditos?: string;
|
||||
correo?: string;
|
||||
createdAt?: string;
|
||||
@@ -136,32 +136,32 @@ export default function InformacionServicio({ admin, imprimirError, updateIsLoad
|
||||
|
||||
<div className="mb-3">
|
||||
<label className="form-label fw-semibold">Institucion:</label>
|
||||
<p className="form-control">{datos.Programa?.institucion || '-'}</p>
|
||||
<p className="form-control">{datos.programa?.institucion || '-'}</p>
|
||||
</div>
|
||||
|
||||
<div className="mb-3">
|
||||
<label className="form-label fw-semibold">Dependencias:</label>
|
||||
<p className="form-control">{datos.Programa?.dependencia || '-'}</p>
|
||||
<p className="form-control">{datos.programa?.dependencia || '-'}</p>
|
||||
</div>
|
||||
|
||||
<div className="mb-3">
|
||||
<label className="form-label fw-semibold">Programa:</label>
|
||||
<p className="form-control">{datos.Programa?.programa}</p>
|
||||
<p className="form-control">{datos.programa?.programa}</p>
|
||||
</div>
|
||||
|
||||
<div className="mb-3">
|
||||
<label className="form-label fw-semibold">Clave de programa:</label>
|
||||
<p className="form-control">{datos.Programa?.clavePrograma}</p>
|
||||
<p className="form-control">{datos.programa?.clavePrograma}</p>
|
||||
</div>
|
||||
|
||||
<div className="mb-3">
|
||||
<label className="form-label fw-semibold">Responsable:</label>
|
||||
<p className="form-control">{datos.Programa?.Usuario?.nombre}</p>
|
||||
<p className="form-control">{datos.programa?.usuario?.nombre}</p>
|
||||
</div>
|
||||
|
||||
<div className="mb-3">
|
||||
<label className="form-label fw-semibold">Correo:</label>
|
||||
<p className="form-control">{datos.Programa?.Usuario?.usuario}</p>
|
||||
<p className="form-control">{datos.programa?.usuario?.usuario}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -170,30 +170,29 @@ export default function InformacionServicio({ admin, imprimirError, updateIsLoad
|
||||
|
||||
<div className="mb-3">
|
||||
<label className="form-label fw-semibold">Numero de cuenta:</label>
|
||||
<p className="form-control">{datos.Usuario?.usuario || '-'}</p>
|
||||
<p className="form-control">{datos.usuario?.usuario || '-'}</p>
|
||||
</div>
|
||||
|
||||
<div className="mb-3">
|
||||
<label className="form-label fw-semibold">Nombre:</label>
|
||||
<p className="form-control">{datos.Usuario?.nombre || '-'}</p>
|
||||
<p className="form-control">{datos.usuario?.nombre || '-'}</p>
|
||||
</div>
|
||||
|
||||
{datos.fechaNacimiento && (
|
||||
<div className="mb-3">
|
||||
<label className="form-label fw-semibold">Fecha de nacimiento:
|
||||
<label className="form-label fw-semibold">Fecha de nacimiento:</label>
|
||||
<p className="form-control">{formatDate(datos.fechaNacimiento)}</p>
|
||||
</label>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="mb-3">
|
||||
<label className="form-label fw-semibold">Carrera:</label>
|
||||
<p className="form-control">{datos.Carrera?.carrera || '-'}</p>
|
||||
<p className="form-control">{datos.carrera?.carrera || '-'}</p>
|
||||
</div>
|
||||
|
||||
<div className="mb-3">
|
||||
<label className="form-label fw-semibold">Creditos:</label>
|
||||
<p className="form-control">{datos.creditos || '-'}</p>
|
||||
<p className="form-control">{datos.creditos?.replace(/^0+/, '') + '%' || '-'}</p>
|
||||
</div>
|
||||
|
||||
{datos.telefono && (
|
||||
|
||||
@@ -38,17 +38,21 @@ export default function ReasignacionProgramas({
|
||||
// Función principal: reasignar programas
|
||||
const reasignarProgramas = async () => {
|
||||
const data = {
|
||||
idUsuario: responsable.idUsuario,
|
||||
correoOtroResponsable,
|
||||
//idUsuario: responsable.idUsuario,
|
||||
correo: correoOtroResponsable,
|
||||
};
|
||||
|
||||
console.log("Esta es la data que se pasa en el update de responsable", data)
|
||||
console.log("Esta es la info del correo entrando en el data", data.correo)
|
||||
|
||||
try {
|
||||
updateIsLoading(true);
|
||||
const res = await axiosInstance.put(`/programa/reasignar_programas`, data);
|
||||
const res = await axiosInstance.put(`/programa/reasignar_programas/${responsable.idUsuario}`, data);
|
||||
updateIsLoading(false);
|
||||
imprimirMensaje(res.data.message);
|
||||
router.push("/admin/responsables/responsable");
|
||||
router.push("/administrador/responsables");
|
||||
} catch (err: unknown) {
|
||||
console.log("Esta entrando al catch no sale la peticion")
|
||||
updateIsLoading(false);
|
||||
if (isAxiosError(err)) imprimirError(err.response?.data || err.message);
|
||||
else if (err instanceof Error) imprimirError(err.message);
|
||||
|
||||
@@ -32,10 +32,15 @@ export default function Reporte({ admin }: Props) {
|
||||
try {
|
||||
//updateIsLoading(true);
|
||||
|
||||
console.log("Fecha inicio seleccionada:", selectedInicio);
|
||||
console.log("Fecha fin seleccionada:", selectedFin);
|
||||
|
||||
//console.log("Fechas parseadas", selectedInicio ? moment(selectedInicio).format("YYYY") : null, selectedFin ? moment(selectedFin).format("YYYY") : null);
|
||||
|
||||
const res = await axiosInstance.get("/servicio/reporte", {
|
||||
params: {
|
||||
inicio: moment(selectedInicio).format("YYYY-MM-DD"),
|
||||
fin: moment(selectedFin).format("YYYY-MM-DD"),
|
||||
inicio: moment(selectedInicio).format("YYYY-MM-DD"), // Mandamos solo el año, quitamos el mes y día
|
||||
fin: moment(selectedFin).format("YYYY-MM-DD"), // Mandamos solo el año, quitamos el mes y día
|
||||
},
|
||||
responseType: "blob",
|
||||
});
|
||||
@@ -66,6 +71,7 @@ export default function Reporte({ admin }: Props) {
|
||||
setSelectedFin(null);
|
||||
//updateIsLoading(false);
|
||||
} catch (err: unknown) {
|
||||
console.log("Error al descargar el reporte", err)
|
||||
//updateIsLoading(false);
|
||||
// optional: handle error
|
||||
}
|
||||
|
||||
@@ -92,11 +92,12 @@ export default function TablaCasosEspeciales({ admin, imprimirError }: Props) {
|
||||
try {
|
||||
const config = admin?.token ? { headers: { Authorization: `Bearer ${admin.token}` } } : undefined;
|
||||
console.debug('Obtener servicios - localStorage token:', typeof window !== 'undefined' ? localStorage.getItem('token') : undefined, 'admin.token:', admin?.token);
|
||||
const res = await axiosInstance.get(`/caso_especial/servicios_especiales?pagina=${pagina}${query}`, config);
|
||||
const res = await axiosInstance.get(`/caso-especial/servicios_especiales?pagina=${pagina}${query}`);
|
||||
console.debug('Respuesta casos especiales:', res.data);
|
||||
setData(res.data.serviciosEspeciales || []);
|
||||
setData(res.data.data.serviciosEspeciales ?? []);
|
||||
setTotal(res.data.count);
|
||||
console.log('Respuesta casos especiales:', res.data);
|
||||
console.log("Respuesta Caso especial con doble data", res.data.data)
|
||||
} catch (err: unknown) {
|
||||
if (imprimirError) {
|
||||
if (isAxiosError(err)) {
|
||||
|
||||
@@ -68,6 +68,7 @@ export default function TablaResponsables() {
|
||||
className="form-control border-0 rounded-4"
|
||||
value={correo}
|
||||
onChange={(e) => setCorreo(e.target.value)}
|
||||
onKeyDown={(e) => {if (e.key === 'Enter') fetchData(correo)}}
|
||||
/>
|
||||
</div>
|
||||
</Col>
|
||||
@@ -80,6 +81,7 @@ export default function TablaResponsables() {
|
||||
className="form-control border-0 rounded-4"
|
||||
value={nombre}
|
||||
onChange={(e) => setNombre(e.target.value)}
|
||||
onKeyDown={(e) => { if (e.key === 'Enter') fetchData(nombre)}}
|
||||
/>
|
||||
</div>
|
||||
</Col>
|
||||
|
||||
@@ -1,18 +1,8 @@
|
||||
"use client";
|
||||
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import {
|
||||
Form,
|
||||
FormGroup,
|
||||
FormLabel,
|
||||
FormControl,
|
||||
FormSelect,
|
||||
Button,
|
||||
InputGroup,
|
||||
Row,
|
||||
Col,
|
||||
} from "react-bootstrap";
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { Form, FormGroup, FormLabel, FormControl, FormSelect, Button, InputGroup, Row, Col } from "react-bootstrap";
|
||||
import { FaUser, FaSchool, FaInfoCircle } from "react-icons/fa";
|
||||
import ServicioSocialTabla from "../servicio-social-tabla";
|
||||
import { axiosInstance } from "@/api/config";
|
||||
@@ -21,240 +11,203 @@ import { Prev } from "react-bootstrap/esm/PageItem";
|
||||
import { AxiosError } from "axios";
|
||||
|
||||
interface Admin {
|
||||
idTipoUsuario: number;
|
||||
token?: string;
|
||||
idTipoUsuario: number;
|
||||
token?: string;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
admin: Admin;
|
||||
imprimirError: (mensaje: string) => void;
|
||||
admin: Admin;
|
||||
imprimirError: (mensaje: string) => void;
|
||||
}
|
||||
|
||||
type StatusItem = { idStatus: number; status: string };
|
||||
|
||||
|
||||
export default function TablaServicioSocial({ admin, imprimirError }: Props) {
|
||||
const router = useRouter();
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [page, setPage] = useState(1);
|
||||
const [total, setTotal] = useState(0);
|
||||
const [data, setData] = useState<ServicioSocialResponse[]>([]);
|
||||
const [status, setStatus] = useState<StatusItem[]>([]);
|
||||
const router = useRouter();
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [page, setPage] = useState(1);
|
||||
const [total, setTotal] = useState(0);
|
||||
const [data, setData] = useState<ServicioSocialResponse[]>([]);
|
||||
const [status, setStatus] = useState<StatusItem[]>([]);
|
||||
|
||||
const [search, setSearch] = useState({
|
||||
numeroCuenta: "",
|
||||
nombre: "",
|
||||
idStatus: "",
|
||||
});
|
||||
const searchAnterior = useRef({ numeroCuenta: "", nombre: "", idStatus: "" });
|
||||
const [search, setSearch] = useState({ numeroCuenta: '', nombre: '', idStatus: '' });
|
||||
const searchAnterior = useRef({ numeroCuenta: '', nombre: '', idStatus: '' });
|
||||
|
||||
useEffect(() => {
|
||||
if (admin?.idTipoUsuario === 1) {
|
||||
obtenerCatalogoStatus();
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [admin?.idTipoUsuario]);
|
||||
useEffect(() => {
|
||||
if (admin?.idTipoUsuario === 1) {
|
||||
obtenerCatalogoStatus();
|
||||
}
|
||||
|
||||
function onPageChange(newPage: number) {
|
||||
setPage(newPage);
|
||||
obtenerServicios(newPage);
|
||||
}
|
||||
console.log("Esta es la info que tiene al guardar en la state", data)
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [admin?.idTipoUsuario]);
|
||||
|
||||
async function obtenerServicios(pagina?: number) {
|
||||
const paginaActual = pagina ?? page;
|
||||
let query = "";
|
||||
|
||||
setIsLoading(true);
|
||||
|
||||
if (
|
||||
search.numeroCuenta !== searchAnterior.current.numeroCuenta ||
|
||||
search.nombre !== searchAnterior.current.nombre ||
|
||||
search.idStatus !== searchAnterior.current.idStatus
|
||||
) {
|
||||
// resetear a primera página si cambió la búsqueda
|
||||
setPage(1);
|
||||
searchAnterior.current = { ...search };
|
||||
function onPageChange(newPage: number) {
|
||||
setPage(newPage);
|
||||
obtenerServicios(newPage);
|
||||
}
|
||||
|
||||
if (search.idStatus)
|
||||
query += `&idStatus=${encodeURIComponent(search.idStatus)}`;
|
||||
if (search.nombre) query += `&nombre=${encodeURIComponent(search.nombre)}`;
|
||||
if (search.numeroCuenta)
|
||||
query += `&numeroCuenta=${encodeURIComponent(search.numeroCuenta)}`;
|
||||
async function obtenerServicios(pagina?: number) {
|
||||
const paginaActual = pagina ?? page;
|
||||
let query = '';
|
||||
|
||||
try {
|
||||
// asegurar que enviamos Authorization si existe en admin, y loggear token para debug
|
||||
const config = admin?.token
|
||||
? { headers: { Authorization: `Bearer ${admin.token}` } }
|
||||
: undefined;
|
||||
console.debug(
|
||||
"Obtener servicios - localStorage token:",
|
||||
typeof window !== "undefined"
|
||||
? localStorage.getItem("token")
|
||||
: undefined,
|
||||
"admin.token:",
|
||||
admin?.token
|
||||
);
|
||||
const res = await axiosInstance.get(
|
||||
`/servicio/admin?pagina=${paginaActual}${query}`,
|
||||
config
|
||||
);
|
||||
console.debug("Respuesta servicios_admin:", res.data);
|
||||
setData(res.data.serviciosAdmin || []);
|
||||
setTotal(res.data.count ?? 0);
|
||||
} catch (err: unknown) {
|
||||
// manejar error
|
||||
console.error("Error obtenerServicios", err);
|
||||
//const mensaje = (err as any)?.response?.data ?? String(err); Falta imprimir error
|
||||
//imprimirError(mensaje);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
setIsLoading(true);
|
||||
|
||||
if (
|
||||
search.numeroCuenta !== searchAnterior.current.numeroCuenta ||
|
||||
search.nombre !== searchAnterior.current.nombre ||
|
||||
search.idStatus !== searchAnterior.current.idStatus
|
||||
) {
|
||||
// resetear a primera página si cambió la búsqueda
|
||||
setPage(1);
|
||||
searchAnterior.current = { ...search };
|
||||
}
|
||||
|
||||
if (search.idStatus) query += `&idStatus=${encodeURIComponent(search.idStatus)}`;
|
||||
if (search.nombre) query += `&nombre=${encodeURIComponent(search.nombre)}`;
|
||||
if (search.numeroCuenta) query += `&numeroCuenta=${encodeURIComponent(search.numeroCuenta)}`;
|
||||
|
||||
try {
|
||||
// asegurar que enviamos Authorization si existe en admin, y loggear token para debug
|
||||
const config = admin?.token ? { headers: { Authorization: `Bearer ${admin.token}` } } : undefined;
|
||||
console.debug('Obtener servicios - localStorage token:', typeof window !== 'undefined' ? localStorage.getItem('token') : undefined, 'admin.token:', admin?.token);
|
||||
const res = await axiosInstance.get(`/servicio/admin?pagina=${paginaActual}${query}`);
|
||||
console.debug('Respuesta servicios_admin:', res.data);
|
||||
setData(res.data.serviciosAdmin || []);
|
||||
//setData(res.data)
|
||||
//setData(res.data.serviciosAdmin);
|
||||
setTotal(res.data.count ?? 0);
|
||||
|
||||
console.log("Esta es la info", res.data)
|
||||
} catch (err: unknown) {
|
||||
// manejar error
|
||||
console.error('Error obtenerServicios', err);
|
||||
//const mensaje = (err as any)?.response?.data ?? String(err); Falta imprimir error
|
||||
//imprimirError(mensaje);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const obtenerCatalogoStatus = async () => {
|
||||
try {
|
||||
//const headers = responsable?.token ? { Authorization: `Bearer ${responsable.token}` } : undefined;
|
||||
const res = await axiosInstance.get<StatusItem[]>("/status");
|
||||
setStatus(res.data);
|
||||
console.log(res.data);
|
||||
//console.log('Status obtenidos', status);
|
||||
obtenerServicios();
|
||||
} catch (err: unknown) {
|
||||
const axiosErr = err as AxiosError;
|
||||
console.log("Error al obtener catálogo de status:", err);
|
||||
}
|
||||
};
|
||||
const obtenerCatalogoStatus = async () => {
|
||||
try {
|
||||
//const headers = responsable?.token ? { Authorization: `Bearer ${responsable.token}` } : undefined;
|
||||
const res = await axiosInstance.get<StatusItem[]>('/status');
|
||||
setStatus(res.data);
|
||||
console.log(res.data);
|
||||
//console.log('Status obtenidos', status);
|
||||
obtenerServicios();
|
||||
} catch (err: unknown) {
|
||||
const axiosErr = err as AxiosError;
|
||||
console.log('Error al obtener catálogo de status:', err);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<section>
|
||||
<div className="columns">
|
||||
<h2 className="title">Servicios Sociales</h2>
|
||||
return (
|
||||
<section>
|
||||
<div className="columns">
|
||||
<h2 className="title">Servicios Sociales</h2>
|
||||
|
||||
<section className="container-fluid my-4">
|
||||
<Form
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault();
|
||||
obtenerServicios(1);
|
||||
}}
|
||||
>
|
||||
<Row className="g-3">
|
||||
<Col md={3}>
|
||||
<FormGroup>
|
||||
<FormLabel>Número de Cuenta</FormLabel>
|
||||
<InputGroup>
|
||||
<InputGroup.Text className="rounded-4">
|
||||
<FaSchool />
|
||||
</InputGroup.Text>
|
||||
<FormControl
|
||||
type="text"
|
||||
placeholder="No.Cuenta"
|
||||
maxLength={9}
|
||||
value={search.numeroCuenta}
|
||||
onChange={(e) =>
|
||||
setSearch((prev) => ({
|
||||
...prev,
|
||||
numeroCuenta: e.target.value,
|
||||
}))
|
||||
}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === "Enter") obtenerServicios(1);
|
||||
}}
|
||||
className="rounded-4"
|
||||
/>
|
||||
</InputGroup>
|
||||
</FormGroup>
|
||||
</Col>
|
||||
<section className="container-fluid my-4">
|
||||
<Form onSubmit={(e) => { e.preventDefault(); obtenerServicios(1); }}>
|
||||
<Row className="g-3">
|
||||
<Col md={3}>
|
||||
<FormGroup>
|
||||
<FormLabel>Número de Cuenta</FormLabel>
|
||||
<InputGroup>
|
||||
<InputGroup.Text className="rounded-4">
|
||||
<FaSchool />
|
||||
</InputGroup.Text>
|
||||
<FormControl
|
||||
type="text"
|
||||
placeholder="No.Cuenta"
|
||||
maxLength={9}
|
||||
value={search.numeroCuenta}
|
||||
onChange={(e) => setSearch(prev => ({ ...prev, numeroCuenta: e.target.value }))}
|
||||
onKeyDown={(e) => { if (e.key === 'Enter') obtenerServicios(1); }}
|
||||
className="rounded-4"
|
||||
/>
|
||||
</InputGroup>
|
||||
</FormGroup>
|
||||
</Col>
|
||||
|
||||
<Col md={3}>
|
||||
<FormGroup>
|
||||
<FormLabel>Nombre</FormLabel>
|
||||
<InputGroup>
|
||||
<InputGroup.Text className="rounded-4">
|
||||
<FaUser />
|
||||
</InputGroup.Text>
|
||||
<FormControl
|
||||
type="text"
|
||||
placeholder="Nombre"
|
||||
value={search.nombre}
|
||||
onChange={(e) =>
|
||||
setSearch((prev) => ({
|
||||
...prev,
|
||||
nombre: e.target.value,
|
||||
}))
|
||||
}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === "Enter") obtenerServicios(1);
|
||||
}}
|
||||
className="rounded-4"
|
||||
/>
|
||||
</InputGroup>
|
||||
</FormGroup>
|
||||
</Col>
|
||||
<Col md={3}>
|
||||
<FormGroup>
|
||||
<FormLabel>Nombre</FormLabel>
|
||||
<InputGroup>
|
||||
<InputGroup.Text className="rounded-4">
|
||||
<FaUser />
|
||||
</InputGroup.Text>
|
||||
<FormControl
|
||||
type="text"
|
||||
placeholder="Nombre"
|
||||
value={search.nombre}
|
||||
onChange={(e) => setSearch(prev => ({ ...prev, nombre: e.target.value }))}
|
||||
onKeyDown={(e) => { if (e.key === 'Enter') obtenerServicios(1); }}
|
||||
className="rounded-4"
|
||||
/>
|
||||
</InputGroup>
|
||||
</FormGroup>
|
||||
</Col>
|
||||
|
||||
<Col md={3}>
|
||||
<FormGroup>
|
||||
<FormLabel>Status</FormLabel>
|
||||
<InputGroup>
|
||||
<InputGroup.Text className="rounded-4">
|
||||
<FaInfoCircle />
|
||||
</InputGroup.Text>
|
||||
<FormSelect
|
||||
value={search.idStatus}
|
||||
onChange={(e) =>
|
||||
setSearch((Prev) => ({
|
||||
...Prev,
|
||||
idStatus: e.target.value,
|
||||
}))
|
||||
}
|
||||
className="rounded-4"
|
||||
>
|
||||
<option value="">Status</option>
|
||||
{status.slice(0, 10).map((s) => (
|
||||
<option key={s.idStatus} value={s.idStatus}>
|
||||
{s.status}
|
||||
</option>
|
||||
))}
|
||||
</FormSelect>
|
||||
</InputGroup>
|
||||
</FormGroup>
|
||||
</Col>
|
||||
<Col md={3}>
|
||||
<FormGroup>
|
||||
<FormLabel>Status</FormLabel>
|
||||
<InputGroup>
|
||||
<InputGroup.Text className="rounded-4">
|
||||
<FaInfoCircle />
|
||||
</InputGroup.Text>
|
||||
<FormSelect
|
||||
value={search.idStatus}
|
||||
onChange={(e) => setSearch(Prev => ({ ...Prev, idStatus: e.target.value }))}
|
||||
className="rounded-4"
|
||||
onKeyDown={(e) => { if (e.key === 'Enter') obtenerServicios()}}
|
||||
>
|
||||
<option value="">Status</option>
|
||||
{status.slice(0, 10).map((s) => (
|
||||
<option key={s.idStatus} value={s.idStatus}>{s.status}</option>
|
||||
))}
|
||||
</FormSelect>
|
||||
</InputGroup>
|
||||
</FormGroup>
|
||||
</Col>
|
||||
|
||||
<Col md={3} className="d-flex align-items-end">
|
||||
<Button
|
||||
type="submit"
|
||||
className="w-100 rounded-5"
|
||||
disabled={isLoading}
|
||||
>
|
||||
{isLoading ? "Buscando..." : "Buscar"}
|
||||
</Button>
|
||||
</Col>
|
||||
</Row>
|
||||
</Form>
|
||||
<Col md={3} className="d-flex align-items-end">
|
||||
<Button type="submit" className="w-100 rounded-5" disabled={isLoading}>
|
||||
{isLoading ? 'Buscando...' : 'Buscar'}
|
||||
</Button>
|
||||
</Col>
|
||||
</Row>
|
||||
</Form>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
|
||||
<ServicioSocialTabla
|
||||
data={data}
|
||||
total={total}
|
||||
columnaFechaFin={true}
|
||||
columnaFechaInicio={true}
|
||||
onPageChange={onPageChange}
|
||||
idTipoUsuario={admin?.idTipoUsuario}
|
||||
columnasResponsable={admin?.idTipoUsuario === 1}
|
||||
columnaFechaRegistro={true}
|
||||
columnaCuestionario={false}
|
||||
columnaCartaTermino={false}
|
||||
columnaCuestionarioCompleto={false}
|
||||
onRowAction={(row, path) => {
|
||||
try {
|
||||
// Falta corregir este parte de codigo para poder subirlo
|
||||
//if ((row as any)?.idServicio) localStorage.setItem('idServicio', String((row as any).idServicio));
|
||||
router.push(`/responsable/${path}`);
|
||||
} catch (e) {
|
||||
console.error('Error al manejar acción de fila', e);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
||||
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<ServicioSocialTabla
|
||||
data={data}
|
||||
total={total}
|
||||
columnaFechaFin={true}
|
||||
columnaFechaInicio={true}
|
||||
onPageChange={onPageChange}
|
||||
idTipoUsuario={admin?.idTipoUsuario}
|
||||
columnasResponsable={admin?.idTipoUsuario === 1}
|
||||
columnaFechaRegistro={true}
|
||||
columnaCuestionario={false}
|
||||
columnaCartaTermino={false}
|
||||
columnaCuestionarioCompleto={false}
|
||||
onRowAction={(row, path) => {
|
||||
try {
|
||||
// Falta corregir este parte de codigo para poder subirlo
|
||||
//if ((row as any)?.idServicio) localStorage.setItem('idServicio', String((row as any).idServicio));
|
||||
router.push(`/responsable/${path}`);
|
||||
} catch (e) {
|
||||
console.error("Error al manejar acción de fila", e);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</section>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ interface ServicioEspecial {
|
||||
idServicio: number;
|
||||
nombre: string;
|
||||
numeroCuenta: string;
|
||||
status: string;
|
||||
Status: string;
|
||||
// agrega más campos según lo que devuelva tu API
|
||||
}
|
||||
|
||||
@@ -71,13 +71,9 @@ export default function LiberarCasoEspecial({ responsable, imprimirError }: Prop
|
||||
if (search.nombre) query += `&nombre=${search.nombre}`;
|
||||
if (search.numeroCuenta) query += `&numeroCuenta=${search.numeroCuenta}`;
|
||||
|
||||
const res = await axiosInstance.get(`/caso_especial/servicios_especiales?pagina=${page}${query}`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${responsable.token}`,
|
||||
},
|
||||
});
|
||||
const res = await axiosInstance.get(`/caso-especial/servicios_especiales?pagina=${page}${query}`);
|
||||
|
||||
setData(res.data.serviciosEspeciales);
|
||||
setData(res.data.data.serviciosEspeciales);
|
||||
setTotal(res.data.count);
|
||||
} catch (err: unknown) {
|
||||
let msg = 'Error al obtener los casos especiales';
|
||||
|
||||
@@ -94,9 +94,10 @@ export default function NuevoServicio({
|
||||
updateIsLoading(true);
|
||||
try {
|
||||
const headers = responsable?.token ? { Authorization: `Bearer ${responsable.token}` } : undefined;
|
||||
const res = await axiosInstance.get<Alumno>(`/usuario/escolares?numeroCuenta=${encodeURIComponent(numeroCuenta)}`, { headers });
|
||||
const res = await axiosInstance.post<Alumno>(`/usuario/escolares/${numeroCuenta}`, { headers });
|
||||
resetar();
|
||||
setAlumno(res.data);
|
||||
obtenerProgramas();
|
||||
updateIsLoading(false);
|
||||
} catch (err: unknown) {
|
||||
setNumeroCuenta("");
|
||||
@@ -149,7 +150,7 @@ export default function NuevoServicio({
|
||||
const obtenerProgramas = async () => {
|
||||
try {
|
||||
const headers = responsable?.token ? { Authorization: `Bearer ${responsable.token}` } : undefined;
|
||||
const res = await axiosInstance.get<Programa[]>(`/programa/programas_responsable?idUsuario=${responsable.idUsuario}`, { headers });
|
||||
const res = await axiosInstance.get<Programa[]>(`/programa/programas_responsable/${responsable.idUsuario}`, { headers });
|
||||
setProgramas(res.data);
|
||||
} catch (err: unknown) {
|
||||
const axiosErr = err as AxiosError;
|
||||
@@ -182,7 +183,7 @@ export default function NuevoServicio({
|
||||
md.setDate(md.getDate() - 16);
|
||||
setMinDate(md);
|
||||
updateFechas();
|
||||
obtenerProgramas();
|
||||
//obtenerProgramas();
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
@@ -49,14 +49,21 @@ export default function TablaServiciosResponsable({ responsable, imprimirError }
|
||||
if (search.nombre) query += `&nombre=${encodeURIComponent(search.nombre)}`;
|
||||
if (search.numeroCuenta) query += `&numeroCuenta=${encodeURIComponent(search.numeroCuenta)}`;
|
||||
|
||||
const idUsuario = localStorage.getItem("idUsuario")
|
||||
|
||||
try {
|
||||
|
||||
console.log('Informacion en el componente hijo del responsable:', responsable);
|
||||
console.log('Id del usuario responsable:', responsable.idUsuario);
|
||||
const idUsuario = localStorage.getItem('idUsuario') ?? '';
|
||||
const idUsuario1 = localStorage.getItem('idUsuario') ?? '';
|
||||
console.log('idUsuario usado en la consulta componente hijo:', idUsuario);
|
||||
|
||||
console.log("Este es la optencion del id del usuario desde el local", idUsuario1)
|
||||
//const headers = responsable?.token ? { Authorization: `Bearer ${responsable.token}` } : undefined;
|
||||
const res = await axiosInstance.get<{ serviciosResponsable: ServicioSocialResponse[]; count: number }>(`/servicio/servicios_responsable?idUsuario=${idUsuario}&pagina=${pagina}${query}`);
|
||||
//const res = await axiosInstance.get<{ serviciosResponsable: ServicioSocialResponse[]; count: number }>(`/servicio/servicios_responsable?idUsuario=${idUsuario}&pagina=${pagina}${query}`);
|
||||
const res = await axiosInstance.get(`/servicio/servicios_responsable?idUsuario=${idUsuario1}&pagina=${pagina}${query}`);
|
||||
//const res = await axiosInstance.get(`/servicio/servicios_responsable?idUsuario=${idUsuario1}&pagina=${pagina}${query}`);
|
||||
|
||||
setData(res.data.serviciosResponsable);
|
||||
setTotal(res.data.count);
|
||||
setIsLoading(false);
|
||||
|
||||
@@ -2,107 +2,104 @@
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import { axiosInstance } from "@/api/config";
|
||||
import {
|
||||
ServicioSocialConCasoEspecial,
|
||||
ServicioSocialResponse,
|
||||
} from "@/types/responses";
|
||||
import { ServicioSocialConCasoEspecial, ServicioSocialResponse } from "@/types/responses";
|
||||
import { useRouter } from "next/navigation";
|
||||
|
||||
interface Props {
|
||||
data?: ServicioSocialResponse[];
|
||||
total?: number;
|
||||
onPageChange?: (newPage: number) => void;
|
||||
columnaFechaInicio?: boolean;
|
||||
columnaFechaFin?: boolean;
|
||||
idTipoUsuario?: number; // 1=admin, 2=responsable, 3=alumno, 4=caso especial
|
||||
columnasResponsable?: boolean;
|
||||
onRowAction?: (row: ServicioSocialResponse, path: string) => void;
|
||||
columnaCuestionario?: boolean;
|
||||
columnaCartaTermino?: boolean;
|
||||
columnaCuestionarioCompleto?: boolean;
|
||||
columnaFechaRegistro?: boolean;
|
||||
data?: ServicioSocialResponse[];
|
||||
total?: number;
|
||||
onPageChange?: (newPage: number) => void;
|
||||
columnaFechaInicio?: boolean;
|
||||
columnaFechaFin?: boolean;
|
||||
idTipoUsuario?: number; // 1=admin, 2=responsable, 3=alumno, 4=caso especial
|
||||
columnasResponsable?: boolean;
|
||||
onRowAction?: (row: ServicioSocialResponse, path: string) => void;
|
||||
columnaCuestionario?: boolean;
|
||||
columnaCartaTermino?: boolean;
|
||||
columnaCuestionarioCompleto?: boolean;
|
||||
columnaFechaRegistro?: boolean;
|
||||
}
|
||||
|
||||
export default function ServicioSocialTabla({
|
||||
data,
|
||||
total = 0,
|
||||
onPageChange,
|
||||
idTipoUsuario,
|
||||
columnasResponsable = false,
|
||||
columnaFechaInicio = false,
|
||||
columnaFechaFin = false,
|
||||
columnaCuestionario = false,
|
||||
columnaCartaTermino = false,
|
||||
columnaCuestionarioCompleto = false,
|
||||
columnaFechaRegistro = false,
|
||||
onRowAction,
|
||||
data,
|
||||
total = 0,
|
||||
onPageChange,
|
||||
idTipoUsuario,
|
||||
columnasResponsable = false,
|
||||
columnaFechaInicio = false,
|
||||
columnaFechaFin = false,
|
||||
columnaCuestionario = false,
|
||||
columnaCartaTermino = false,
|
||||
columnaCuestionarioCompleto = false,
|
||||
columnaFechaRegistro = false,
|
||||
onRowAction,
|
||||
}: Props) {
|
||||
const [info, setInfo] = useState<ServicioSocialResponse[]>(data || []);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const [info, setInfo] = useState<ServicioSocialResponse[]>(data || []);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
|
||||
const router = useRouter();
|
||||
const router = useRouter();
|
||||
|
||||
//const columnaFechaInicio = true;
|
||||
//const columnaFechaFin = true;
|
||||
//const columnaFechaInicio = true;
|
||||
//const columnaFechaFin = true;
|
||||
|
||||
// 🔹 Cargar datos del padre si existen
|
||||
useEffect(() => {
|
||||
if (data && data.length > 0) {
|
||||
setInfo(data);
|
||||
// 🔹 Cargar datos del padre si existen
|
||||
useEffect(() => {
|
||||
if (data && data.length > 0) {
|
||||
setInfo(data);
|
||||
}
|
||||
}, [data]);
|
||||
|
||||
// 🔹 Paginación simple
|
||||
function handlePrev() {
|
||||
if (currentPage > 1) {
|
||||
const np = currentPage - 1;
|
||||
setCurrentPage(np);
|
||||
onPageChange?.(np);
|
||||
}
|
||||
}
|
||||
}, [data]);
|
||||
|
||||
// 🔹 Paginación simple
|
||||
function handlePrev() {
|
||||
if (currentPage > 1) {
|
||||
const np = currentPage - 1;
|
||||
setCurrentPage(np);
|
||||
onPageChange?.(np);
|
||||
function handleNext() {
|
||||
const lastPage = Math.max(1, Math.ceil(total / 10));
|
||||
if (currentPage < lastPage) {
|
||||
const np = currentPage + 1;
|
||||
setCurrentPage(np);
|
||||
onPageChange?.(np);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function handleNext() {
|
||||
const lastPage = Math.max(1, Math.ceil(total / 10));
|
||||
if (currentPage < lastPage) {
|
||||
const np = currentPage + 1;
|
||||
setCurrentPage(np);
|
||||
onPageChange?.(np);
|
||||
const servicioSelected = (row: ServicioSocialResponse | ServicioSocialConCasoEspecial) => {
|
||||
if (!row) return;
|
||||
|
||||
if (idTipoUsuario === 1) {
|
||||
|
||||
if (row.idServicio) {
|
||||
localStorage.setItem("idServicio", String(row.idServicio));
|
||||
}
|
||||
|
||||
// esta mal esta logica
|
||||
if ("idCasoEspecial" in row && row.idCasoEspecial) {
|
||||
localStorage.setItem("idCasoEspecial", String(row.idCasoEspecial));
|
||||
}
|
||||
|
||||
if ( row.idServicio ) {
|
||||
router.push("/administrador/servicio");
|
||||
} else if ("idCasoEspecial" in row && row.idCasoEspecial) {
|
||||
router.push('/administrador/casos_especiales/caso_especial')
|
||||
}
|
||||
// Hacer validacion para saber que id fue y redireccionar
|
||||
//router.push("/administrador/servicio");
|
||||
//router.push('/administrador/casos_especiales/caso_especial')
|
||||
|
||||
} else if (
|
||||
row.idServicio ||
|
||||
("idCasoEspecial" in row && row.idCasoEspecial)
|
||||
) {
|
||||
console.log("Limpiando selección (no admin)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const servicioSelected = (
|
||||
row: ServicioSocialResponse | ServicioSocialConCasoEspecial
|
||||
) => {
|
||||
if (!row) return;
|
||||
|
||||
if (idTipoUsuario === 1) {
|
||||
if (row.idServicio) {
|
||||
localStorage.setItem("idServicio", String(row.idServicio));
|
||||
}
|
||||
|
||||
// esta mal esta logica
|
||||
if ("idCasoEspecial" in row && row.idCasoEspecial) {
|
||||
localStorage.setItem("idCasoEspecial", String(row.idCasoEspecial));
|
||||
}
|
||||
|
||||
if (row.idServicio) {
|
||||
router.push("/administrador/servicio");
|
||||
} else if ("idCasoEspecial" in row && row.idCasoEspecial) {
|
||||
router.push("/administrador/casos_especiales/caso_especial");
|
||||
}
|
||||
// Hacer validacion para saber que id fue y redireccionar
|
||||
//router.push("/administrador/servicio");
|
||||
//router.push('/administrador/casos_especiales/caso_especial')
|
||||
} else if (
|
||||
row.idServicio ||
|
||||
("idCasoEspecial" in row && row.idCasoEspecial)
|
||||
) {
|
||||
console.log("Limpiando selección (no admin)");
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
/*
|
||||
const servicioSelected = (row: ServicioSocialResponse | ServicioSocialConCasoEspecial) => {
|
||||
if (!row) return;
|
||||
|
||||
@@ -149,179 +146,180 @@ const servicioSelected = (row: ServicioSocialResponse | ServicioSocialConCasoEsp
|
||||
|
||||
*/
|
||||
|
||||
return (
|
||||
<section>
|
||||
{loading ? (
|
||||
<div>Cargando...</div>
|
||||
) : (
|
||||
<>
|
||||
<div className="table-responsive">
|
||||
<table className="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
{columnaFechaRegistro && <th>Fecha Registro</th>}
|
||||
<th>Número de Cuenta</th>
|
||||
<th>Nombre</th>
|
||||
<th>Carrera</th>
|
||||
{columnaFechaInicio && <th>Fecha Inicio</th>}
|
||||
{columnaFechaFin && <th>Fecha Fin</th>}
|
||||
<th>Status</th>
|
||||
{columnaCuestionarioCompleto && (
|
||||
<th>Cuestionario Completo</th>
|
||||
)}
|
||||
{columnaCartaTermino && <th>Carta Termino</th>}
|
||||
{columnaCuestionario && <th>Cuestionario</th>}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{info.map((item, index) => (
|
||||
<tr
|
||||
key={index}
|
||||
style={{
|
||||
cursor: idTipoUsuario === 1 ? "pointer" : "default",
|
||||
}}
|
||||
onClick={() =>
|
||||
idTipoUsuario === 1 ? servicioSelected(item) : undefined
|
||||
}
|
||||
//onClick={() => Falta corregir
|
||||
//idTipoUsuario === 1 ? servicioSelected(item) : undefined
|
||||
//}
|
||||
>
|
||||
{columnaFechaRegistro && (
|
||||
<td>{formatDate(item.createdAt)}</td>
|
||||
)}
|
||||
<td>{item.usuario?.usuario}</td>
|
||||
<td>{item.usuario?.nombre}</td>
|
||||
<td>{item.carrera?.carrera}</td>
|
||||
{columnaFechaInicio && (
|
||||
<td>{formatDate(item.fechaInicio)}</td>
|
||||
)}
|
||||
{columnaFechaFin && <td>{formatDate(item.fechaFin)}</td>}
|
||||
<td>
|
||||
{columnasResponsable && item.status?.idStatus === 7 ? (
|
||||
<button
|
||||
className="btn btn-sm btn-danger"
|
||||
onClick={() =>
|
||||
onRowAction?.(item, "carta_aceptacion")
|
||||
}
|
||||
>
|
||||
Carta Aceptación Rechazada
|
||||
</button>
|
||||
) : (
|
||||
<span
|
||||
className={`badge bg-${statusClass(
|
||||
item.status?.idStatus
|
||||
)}`}
|
||||
>
|
||||
{item.status?.status}
|
||||
</span>
|
||||
)}
|
||||
</td>
|
||||
{columnaCartaTermino && (
|
||||
<td>
|
||||
{item.cartaTermino ? (
|
||||
<span className="badge bg-success">Completado</span>
|
||||
) : (
|
||||
<span className="badge bg-danger">No Completado</span>
|
||||
return (
|
||||
<section>
|
||||
{loading ? (
|
||||
<div>Cargando...</div>
|
||||
) : (
|
||||
<>
|
||||
<div className="table-responsive">
|
||||
<table className="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
{columnaFechaRegistro && <th>Fecha Registro</th>}
|
||||
<th>Número de Cuenta</th>
|
||||
<th>Nombre</th>
|
||||
<th>Carrera</th>
|
||||
{columnaFechaInicio && <th>Fecha Inicio</th>}
|
||||
{columnaFechaFin && <th>Fecha Fin</th>}
|
||||
<th>Status</th>
|
||||
{columnaCuestionarioCompleto && <th>Cuestionario Completo</th>}
|
||||
{columnaCartaTermino && <th>Carta Termino</th>}
|
||||
{columnaCuestionario && <th>Cuestionario</th>}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{info.map((item, index) => (
|
||||
<tr
|
||||
key={index}
|
||||
style={{
|
||||
cursor: idTipoUsuario === 1 ? "pointer" : "default",
|
||||
}}
|
||||
onClick={() => (
|
||||
idTipoUsuario === 1 ? servicioSelected(item) : undefined
|
||||
)}
|
||||
</td>
|
||||
)}
|
||||
|
||||
{columnaCuestionarioCompleto && (
|
||||
<td>
|
||||
{item.cuestionarioCompletado ? (
|
||||
<span className="badge bg-success">Completado</span>
|
||||
) : (
|
||||
<span className="badge bg-danger">No Completado</span>
|
||||
//onClick={() => Falta corregir
|
||||
//idTipoUsuario === 1 ? servicioSelected(item) : undefined
|
||||
//}
|
||||
>
|
||||
{columnaFechaRegistro && <td>{formatDate(item.createdAt)}</td>}
|
||||
<td>{item.usuario?.usuario}</td>
|
||||
<td>{item.usuario?.nombre}</td>
|
||||
<td>{item.carrera?.carrera}</td>
|
||||
|
||||
{columnaFechaInicio && (
|
||||
<td>{formatDate(item.fechaInicio)}</td>
|
||||
)}
|
||||
</td>
|
||||
)}
|
||||
|
||||
{columnaCuestionario && (
|
||||
<td>
|
||||
{item.cuestionarioCompletado ? (
|
||||
<span className="badge bg-success">Completado</span>
|
||||
{columnaFechaFin && <td>{formatDate(item.fechaFin)}</td>}
|
||||
|
||||
<td>
|
||||
{columnasResponsable && item.status?.idStatus === 7 ? (
|
||||
<button
|
||||
className="btn btn-sm btn-danger"
|
||||
onClick={() =>
|
||||
onRowAction?.(item, "carta_aceptacion")
|
||||
}
|
||||
>
|
||||
Carta Aceptación Rechazada
|
||||
</button>
|
||||
) : (
|
||||
<span className="badge bg-danger">No Completado</span>
|
||||
<span
|
||||
className={`badge bg-${statusClass(
|
||||
item.status?.idStatus
|
||||
)}`}
|
||||
>
|
||||
{item.status?.status}
|
||||
</span>
|
||||
)}
|
||||
</td>
|
||||
{columnaCartaTermino && (
|
||||
<td>{item.cartaTermino ? (
|
||||
<span className="badge bg-success">Completado</span>
|
||||
) : (
|
||||
<span className="badge bg-danger">No Completado</span>
|
||||
)}</td>
|
||||
)}
|
||||
</td>
|
||||
)}
|
||||
</tr>
|
||||
))}
|
||||
{info.length === 0 && (
|
||||
<tr>
|
||||
<td colSpan={7} className="text-center">
|
||||
No hay registros
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div className="d-flex justify-content-between align-items-center mt-2">
|
||||
<div>Total: {total}</div>
|
||||
<div>
|
||||
<button
|
||||
className="btn btn-sm btn-outline-primary me-2"
|
||||
onClick={handlePrev}
|
||||
disabled={currentPage <= 1}
|
||||
>
|
||||
Anterior
|
||||
</button>
|
||||
<span>Página {currentPage}</span>
|
||||
<button
|
||||
className="btn btn-sm btn-outline-primary ms-2"
|
||||
onClick={handleNext}
|
||||
disabled={currentPage >= Math.max(1, Math.ceil(total / 10))}
|
||||
>
|
||||
Siguiente
|
||||
</button>
|
||||
{columnaCuestionarioCompleto && (
|
||||
<td>{item.cuestionarioCompletado ? (
|
||||
<span className="badge bg-success">Completado</span>
|
||||
) : (
|
||||
<span className="badge bg-danger">No Completado</span>
|
||||
)}</td>
|
||||
)}
|
||||
|
||||
|
||||
{columnaCuestionario && (
|
||||
<td>
|
||||
{item.cuestionarioCompletado ? (
|
||||
<span className="badge bg-success">Completado</span>
|
||||
) : (
|
||||
<span className="badge bg-danger">No Completado</span>
|
||||
)}
|
||||
</td>
|
||||
)}
|
||||
</tr>
|
||||
))}
|
||||
{info.length === 0 && (
|
||||
<tr>
|
||||
<td colSpan={7} className="text-center">
|
||||
No hay registros
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</section>
|
||||
);
|
||||
|
||||
<div className="d-flex justify-content-between align-items-center mt-2">
|
||||
<div>Total: {total}</div>
|
||||
<div>
|
||||
<button
|
||||
className="btn btn-sm btn-outline-primary me-2"
|
||||
onClick={handlePrev}
|
||||
disabled={currentPage <= 1}
|
||||
>
|
||||
Anterior
|
||||
</button>
|
||||
<span>Página {currentPage}</span>
|
||||
<button
|
||||
className="btn btn-sm btn-outline-primary ms-2"
|
||||
onClick={handleNext}
|
||||
disabled={
|
||||
currentPage >= Math.max(1, Math.ceil(total / 10))
|
||||
}
|
||||
>
|
||||
Siguiente
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
function formatDate(value?: string | null): string {
|
||||
if (!value) return "";
|
||||
if (!value) return "";
|
||||
|
||||
// Si ya viene como fecha ISO, forzamos a hora local sin modificar el día
|
||||
const d = new Date(value.includes("T") ? value : `${value}T00:00:00`);
|
||||
// Si ya viene como fecha ISO, forzamos a hora local sin modificar el día
|
||||
const d = new Date(value.includes("T") ? value : `${value}T00:00:00`);
|
||||
|
||||
if (isNaN(d.getTime())) {
|
||||
console.warn("⚠️ Fecha inválida:", value);
|
||||
return "";
|
||||
}
|
||||
if (isNaN(d.getTime())) {
|
||||
console.warn("⚠️ Fecha inválida:", value);
|
||||
return "";
|
||||
}
|
||||
|
||||
const day = String(d.getDate()).padStart(2, "0");
|
||||
const month = String(d.getMonth() + 1).padStart(2, "0");
|
||||
const year = d.getFullYear();
|
||||
const day = String(d.getDate()).padStart(2, "0");
|
||||
const month = String(d.getMonth() + 1).padStart(2, "0");
|
||||
const year = d.getFullYear();
|
||||
|
||||
return `${day}/${month}/${year}`;
|
||||
return `${day}/${month}/${year}`;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function statusClass(id?: number) {
|
||||
switch (id) {
|
||||
case 1:
|
||||
return "dark";
|
||||
case 2:
|
||||
return "info";
|
||||
case 3:
|
||||
return "warning";
|
||||
case 4:
|
||||
return "primary";
|
||||
case 5:
|
||||
case 6:
|
||||
return "success";
|
||||
case 7:
|
||||
case 8:
|
||||
case 9:
|
||||
case 10:
|
||||
return "danger";
|
||||
default:
|
||||
return "secondary";
|
||||
}
|
||||
switch (id) {
|
||||
case 1:
|
||||
return "dark";
|
||||
case 2:
|
||||
return "info";
|
||||
case 3:
|
||||
return "warning";
|
||||
case 4:
|
||||
return "primary";
|
||||
case 5:
|
||||
case 6:
|
||||
return "success";
|
||||
case 7:
|
||||
case 8:
|
||||
case 9:
|
||||
case 10:
|
||||
return "danger";
|
||||
default:
|
||||
return "secondary";
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+36
-36
@@ -1,60 +1,60 @@
|
||||
import { AxiosRequestConfig } from "axios";
|
||||
|
||||
export interface ServicioSocialResponse {
|
||||
idServicio?: number;
|
||||
id?: number;
|
||||
createdAt?: string;
|
||||
fecha_creacion?: string | null;
|
||||
fechaFin?: string | null;
|
||||
fechaInicio?: string | null;
|
||||
fecha_registro?: string | null;
|
||||
usuario?: Usuario;
|
||||
carrera?: Carrera;
|
||||
status?: Status;
|
||||
cartaTermino?: boolean;
|
||||
idCuestionarioPrograma?: number | null;
|
||||
idCuestionarioPrograma2?: number | null;
|
||||
cuestionarioCompletado?: boolean;
|
||||
idServicio?: number;
|
||||
id?: number;
|
||||
createdAt?: string;
|
||||
fecha_creacion?: string | null;
|
||||
fechaFin?: string | null;
|
||||
fechaInicio?: string | null;
|
||||
fecha_registro?: string | null;
|
||||
usuario?: Usuario;
|
||||
carrera?: Carrera;
|
||||
status?: Status;
|
||||
cartaTermino?: boolean;
|
||||
idCuestionarioPrograma?: number | null;
|
||||
idCuestionarioPrograma2?: number | null;
|
||||
cuestionarioCompletado?: boolean;
|
||||
}
|
||||
|
||||
export interface Usuario {
|
||||
idUsuario?: number;
|
||||
usuario: string | number;
|
||||
nombre: string;
|
||||
idservicio?: number;
|
||||
idUsuario?: number;
|
||||
usuario: string | number;
|
||||
nombre: string;
|
||||
idservicio?: number;
|
||||
}
|
||||
|
||||
export interface OtraTabla {
|
||||
title: string;
|
||||
admin: Record<string, unknown>;
|
||||
alumno: Record<string, unknown>;
|
||||
imprimirError?: (...args: unknown[]) => void;
|
||||
imprimirMensaje?: (...args: unknown[]) => void;
|
||||
imprimirWairning?: (...args: unknown[]) => void;
|
||||
updateIsLoading?: (...args: unknown[]) => void;
|
||||
title: string;
|
||||
admin: Record<string, unknown>;
|
||||
alumno: Record<string, unknown>;
|
||||
imprimirError?: (...args: unknown[]) => void;
|
||||
imprimirMensaje?: (...args: unknown[]) => void;
|
||||
imprimirWairning?: (...args: unknown[]) => void;
|
||||
updateIsLoading?: (...args: unknown[]) => void;
|
||||
}
|
||||
|
||||
export interface Carrera {
|
||||
idCarrera?: number;
|
||||
carrera: string;
|
||||
idCarrera?: number;
|
||||
carrera: string;
|
||||
}
|
||||
|
||||
export interface Status {
|
||||
idStatus: number;
|
||||
status: string;
|
||||
idStatus: number;
|
||||
status: string;
|
||||
}
|
||||
|
||||
export interface CargaMasivaProps {
|
||||
admin: { tokenArchivo: string };
|
||||
admin: { tokenArchivo: string };
|
||||
}
|
||||
|
||||
export interface Responsables {
|
||||
idUsuario: number;
|
||||
usuario: string;
|
||||
nombre: string;
|
||||
activo: boolean;
|
||||
idUsuario: number;
|
||||
usuario: string;
|
||||
nombre: string;
|
||||
activo: boolean;
|
||||
}
|
||||
|
||||
interface ServicioSocialConCasoEspecial extends ServicioSocialResponse {
|
||||
idCasoEspecial?: number;
|
||||
}
|
||||
idCasoEspecial?: number;
|
||||
}
|
||||
Reference in New Issue
Block a user