Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e838a5b78d |
+45
-43
@@ -1,59 +1,61 @@
|
|||||||
import axios from 'axios';
|
import axios from "axios";
|
||||||
|
|
||||||
// Crea una instancia base de Axios
|
// Crea una instancia base de Axios
|
||||||
export const axiosInstance = axios.create({
|
export const axiosInstance = axios.create({
|
||||||
baseURL: process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3000/api', // poner la url
|
baseURL: process.env.NEXT_PUBLIC_API_URL || "http://localhost:3411", // poner la url
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
"Content-Type": "application/json",
|
||||||
},
|
},
|
||||||
timeout: 10000, // tiempo máximo de espera (10 segundos)
|
timeout: 10000, // tiempo máximo de espera (10 segundos)
|
||||||
});
|
});
|
||||||
|
|
||||||
// Interceptor para agregar el token automáticamente
|
// Interceptor para agregar el token automáticamente
|
||||||
axiosInstance.interceptors.request.use(
|
axiosInstance.interceptors.request.use(
|
||||||
(config) => {
|
(config) => {
|
||||||
if (typeof window !== 'undefined') {
|
if (typeof window !== "undefined") {
|
||||||
const token = localStorage.getItem('token');
|
const token = localStorage.getItem("token");
|
||||||
if (token) {
|
if (token) {
|
||||||
// Múltiples formatos según lo que espere el backend
|
// Múltiples formatos según lo que espere el backend
|
||||||
config.headers.Authorization = `Bearer ${token}`;
|
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
|
||||||
return config;
|
config.headers["token"] = token;
|
||||||
},
|
config.headers["x-access-token"] = token;
|
||||||
(error) => Promise.reject(error)
|
config.headers["token-v2"] = token;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return config;
|
||||||
|
},
|
||||||
|
(error) => Promise.reject(error)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Interceptor para manejar respuestas y errores globales
|
// Interceptor para manejar respuestas y errores globales
|
||||||
axiosInstance.interceptors.response.use(
|
axiosInstance.interceptors.response.use(
|
||||||
(response) => response,
|
(response) => response,
|
||||||
(error) => {
|
(error) => {
|
||||||
if (error.response) {
|
if (error.response) {
|
||||||
// Token inválido o sesión expirada
|
// Token inválido o sesión expirada
|
||||||
if (error.response.status === 401) {
|
if (error.response.status === 401) {
|
||||||
console.warn('Sesión expirada o token inválido.');
|
console.warn("Sesión expirada o token inválido.");
|
||||||
if (typeof window !== 'undefined') {
|
if (typeof window !== "undefined") {
|
||||||
localStorage.clear();
|
localStorage.clear();
|
||||||
window.location.href = '/'; // redirige automáticamente
|
window.location.href = "/"; // redirige automáticamente
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Errores del servidor
|
// Errores del servidor
|
||||||
console.error('Error en la respuesta del servidor:', error.response.data);
|
console.error("Error en la respuesta del servidor:", error.response.data);
|
||||||
} else if (error.request) {
|
} else if (error.request) {
|
||||||
// No hubo respuesta del servidor
|
// No hubo respuesta del servidor
|
||||||
console.error('No se recibió respuesta del servidor.');
|
console.error("No se recibió respuesta del servidor.");
|
||||||
} else {
|
} else {
|
||||||
// Error en la configuración de la petición
|
// Error en la configuración de la petición
|
||||||
console.error('Error en la configuración de la solicitud:', error.message);
|
console.error(
|
||||||
}
|
"Error en la configuración de la solicitud:",
|
||||||
|
error.message
|
||||||
return Promise.reject(error);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Promise.reject(error);
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
+93
-69
@@ -1,85 +1,109 @@
|
|||||||
'use client'
|
"use client";
|
||||||
import { axiosInstance } from "@/api/config";
|
import { axiosInstance } from "@/api/config";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const handleOnSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
|
const handleOnSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const formData = new FormData(e.currentTarget);
|
const formData = new FormData(e.currentTarget);
|
||||||
const object = Object.fromEntries(formData);
|
const object = Object.fromEntries(formData);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await axiosInstance.post('/usuario/login', object);
|
const res = await axiosInstance.post("/auth/login", object);
|
||||||
|
|
||||||
// Extraer datos del backend
|
// Extraer datos del backend
|
||||||
const token = res?.data?.token ?? '';
|
const token = res?.data?.token ?? "";
|
||||||
const usuarioObj = res?.data?.Usuario ?? res?.data ?? {};
|
const usuarioObj = res?.data?.Usuario ?? res?.data ?? {};
|
||||||
const idUsuario = usuarioObj.idUsuario ?? '';
|
const idUsuario = usuarioObj.idUsuario ?? "";
|
||||||
const usuario = usuarioObj.usuario ?? '';
|
const usuario = usuarioObj.usuario ?? "";
|
||||||
const nombre = usuarioObj.nombre ?? '';
|
const nombre = usuarioObj.nombre ?? "";
|
||||||
const idTipoUsuario = Number(usuarioObj.TipoUsuario?.idTipoUsuario ?? 0);
|
const idTipoUsuario = Number(usuarioObj.TipoUsuario?.idTipoUsuario ?? 0);
|
||||||
//const idTipoUsuario = Number((usuarioObj as any).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));
|
||||||
|
|
||||||
// Guardar en localStorage
|
// Validar y redirigir según el idTipoUsuario
|
||||||
localStorage.setItem('token', String(token));
|
if (token && idUsuario && idTipoUsuario) {
|
||||||
localStorage.setItem('idUsuario', String(idUsuario));
|
switch (idTipoUsuario) {
|
||||||
localStorage.setItem('usuario', String(usuario));
|
case 1:
|
||||||
localStorage.setItem('nombre', String(nombre));
|
router.push("/administrador");
|
||||||
localStorage.setItem('idTipoUsuario', String(idTipoUsuario));
|
break;
|
||||||
|
case 2:
|
||||||
// Validar y redirigir según el idTipoUsuario
|
router.push("/responsable");
|
||||||
if (token && idUsuario && idTipoUsuario) {
|
break;
|
||||||
switch (idTipoUsuario) {
|
case 3:
|
||||||
case 1:
|
router.push("/alumno");
|
||||||
router.push('/administrador');
|
break;
|
||||||
break;
|
case 4:
|
||||||
case 2:
|
router.push("/casoEspecial");
|
||||||
router.push('/responsable');
|
break;
|
||||||
break;
|
default:
|
||||||
case 3:
|
console.warn(`Tipo de usuario desconocido: ${idTipoUsuario}`);
|
||||||
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();
|
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 (
|
return (
|
||||||
<div className="d-flex justify-content-center align-items-center bg-light" style={{ minHeight: 'calc(100vh - 200px)' }}>
|
<div
|
||||||
<form className="p-4 shadow rounded bg-white w-100" style={{ maxWidth: '400px' }} onSubmit={handleOnSubmit}>
|
className="d-flex justify-content-center align-items-center bg-light"
|
||||||
<h2 className="text-center mb-4 fw-bold">IRIS</h2>
|
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">
|
<div className="mb-3">
|
||||||
<label htmlFor="usuario" className="form-label">Usuario</label>
|
<label htmlFor="usuario" className="form-label">
|
||||||
<input type="text" name="usuario" id="usuario" className="form-control" required />
|
Usuario
|
||||||
</div>
|
</label>
|
||||||
|
<input
|
||||||
<div className="mb-4">
|
type="text"
|
||||||
<label htmlFor="password" className="form-label">Contraseña</label>
|
name="usuario"
|
||||||
<input type="password" name="password" id="password" className="form-control" required />
|
id="usuario"
|
||||||
</div>
|
className="form-control"
|
||||||
|
required
|
||||||
<div className="d-grid">
|
/>
|
||||||
<button type="submit" className="btn btn-primary btn-lg">Iniciar Sesión</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
</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>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,18 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import React, { useEffect, useRef, useState } from "react";
|
import React, { useEffect, useRef, useState } from "react";
|
||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from "next/navigation";
|
||||||
import { Form, FormGroup, FormLabel, FormControl, FormSelect, Button, InputGroup, Row, Col } from "react-bootstrap";
|
import {
|
||||||
|
Form,
|
||||||
|
FormGroup,
|
||||||
|
FormLabel,
|
||||||
|
FormControl,
|
||||||
|
FormSelect,
|
||||||
|
Button,
|
||||||
|
InputGroup,
|
||||||
|
Row,
|
||||||
|
Col,
|
||||||
|
} from "react-bootstrap";
|
||||||
import { FaUser, FaSchool, FaInfoCircle } from "react-icons/fa";
|
import { FaUser, FaSchool, FaInfoCircle } from "react-icons/fa";
|
||||||
import ServicioSocialTabla from "../servicio-social-tabla";
|
import ServicioSocialTabla from "../servicio-social-tabla";
|
||||||
import { axiosInstance } from "@/api/config";
|
import { axiosInstance } from "@/api/config";
|
||||||
@@ -11,197 +21,240 @@ import { Prev } from "react-bootstrap/esm/PageItem";
|
|||||||
import { AxiosError } from "axios";
|
import { AxiosError } from "axios";
|
||||||
|
|
||||||
interface Admin {
|
interface Admin {
|
||||||
idTipoUsuario: number;
|
idTipoUsuario: number;
|
||||||
token?: string;
|
token?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
admin: Admin;
|
admin: Admin;
|
||||||
imprimirError: (mensaje: string) => void;
|
imprimirError: (mensaje: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
type StatusItem = { idStatus: number; status: string };
|
type StatusItem = { idStatus: number; status: string };
|
||||||
|
|
||||||
|
|
||||||
export default function TablaServicioSocial({ admin, imprimirError }: Props) {
|
export default function TablaServicioSocial({ admin, imprimirError }: Props) {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
const [page, setPage] = useState(1);
|
const [page, setPage] = useState(1);
|
||||||
const [total, setTotal] = useState(0);
|
const [total, setTotal] = useState(0);
|
||||||
const [data, setData] = useState<ServicioSocialResponse[]>([]);
|
const [data, setData] = useState<ServicioSocialResponse[]>([]);
|
||||||
const [status, setStatus] = useState<StatusItem[]>([]);
|
const [status, setStatus] = useState<StatusItem[]>([]);
|
||||||
|
|
||||||
const [search, setSearch] = useState({ numeroCuenta: '', nombre: '', idStatus: '' });
|
const [search, setSearch] = useState({
|
||||||
const searchAnterior = useRef({ numeroCuenta: '', nombre: '', idStatus: '' });
|
numeroCuenta: "",
|
||||||
|
nombre: "",
|
||||||
|
idStatus: "",
|
||||||
|
});
|
||||||
|
const searchAnterior = useRef({ numeroCuenta: "", nombre: "", idStatus: "" });
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (admin?.idTipoUsuario === 1) {
|
if (admin?.idTipoUsuario === 1) {
|
||||||
obtenerCatalogoStatus();
|
obtenerCatalogoStatus();
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [admin?.idTipoUsuario]);
|
}, [admin?.idTipoUsuario]);
|
||||||
|
|
||||||
function onPageChange(newPage: number) {
|
function onPageChange(newPage: number) {
|
||||||
setPage(newPage);
|
setPage(newPage);
|
||||||
obtenerServicios(newPage);
|
obtenerServicios(newPage);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 };
|
||||||
}
|
}
|
||||||
|
|
||||||
async function obtenerServicios(pagina?: number) {
|
if (search.idStatus)
|
||||||
const paginaActual = pagina ?? page;
|
query += `&idStatus=${encodeURIComponent(search.idStatus)}`;
|
||||||
let query = '';
|
if (search.nombre) query += `&nombre=${encodeURIComponent(search.nombre)}`;
|
||||||
|
if (search.numeroCuenta)
|
||||||
|
query += `&numeroCuenta=${encodeURIComponent(search.numeroCuenta)}`;
|
||||||
|
|
||||||
setIsLoading(true);
|
try {
|
||||||
|
// asegurar que enviamos Authorization si existe en admin, y loggear token para debug
|
||||||
if (
|
const config = admin?.token
|
||||||
search.numeroCuenta !== searchAnterior.current.numeroCuenta ||
|
? { headers: { Authorization: `Bearer ${admin.token}` } }
|
||||||
search.nombre !== searchAnterior.current.nombre ||
|
: undefined;
|
||||||
search.idStatus !== searchAnterior.current.idStatus
|
console.debug(
|
||||||
) {
|
"Obtener servicios - localStorage token:",
|
||||||
// resetear a primera página si cambió la búsqueda
|
typeof window !== "undefined"
|
||||||
setPage(1);
|
? localStorage.getItem("token")
|
||||||
searchAnterior.current = { ...search };
|
: undefined,
|
||||||
}
|
"admin.token:",
|
||||||
|
admin?.token
|
||||||
if (search.idStatus) query += `&idStatus=${encodeURIComponent(search.idStatus)}`;
|
);
|
||||||
if (search.nombre) query += `&nombre=${encodeURIComponent(search.nombre)}`;
|
const res = await axiosInstance.get(
|
||||||
if (search.numeroCuenta) query += `&numeroCuenta=${encodeURIComponent(search.numeroCuenta)}`;
|
`/servicio/admin?pagina=${paginaActual}${query}`,
|
||||||
|
config
|
||||||
try {
|
);
|
||||||
// asegurar que enviamos Authorization si existe en admin, y loggear token para debug
|
console.debug("Respuesta servicios_admin:", res.data);
|
||||||
const config = admin?.token ? { headers: { Authorization: `Bearer ${admin.token}` } } : undefined;
|
setData(res.data.serviciosAdmin || []);
|
||||||
console.debug('Obtener servicios - localStorage token:', typeof window !== 'undefined' ? localStorage.getItem('token') : undefined, 'admin.token:', admin?.token);
|
setTotal(res.data.count ?? 0);
|
||||||
const res = await axiosInstance.get(`/servicio/servicios_admin?pagina=${paginaActual}${query}`, config);
|
} catch (err: unknown) {
|
||||||
console.debug('Respuesta servicios_admin:', res.data);
|
// manejar error
|
||||||
setData(res.data.serviciosAdmin || []);
|
console.error("Error obtenerServicios", err);
|
||||||
setTotal(res.data.count ?? 0);
|
//const mensaje = (err as any)?.response?.data ?? String(err); Falta imprimir error
|
||||||
} catch (err: unknown) {
|
//imprimirError(mensaje);
|
||||||
// manejar error
|
} finally {
|
||||||
console.error('Error obtenerServicios', err);
|
setIsLoading(false);
|
||||||
//const mensaje = (err as any)?.response?.data ?? String(err); Falta imprimir error
|
|
||||||
//imprimirError(mensaje);
|
|
||||||
} finally {
|
|
||||||
setIsLoading(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const obtenerCatalogoStatus = async () => {
|
const obtenerCatalogoStatus = async () => {
|
||||||
try {
|
try {
|
||||||
//const headers = responsable?.token ? { Authorization: `Bearer ${responsable.token}` } : undefined;
|
//const headers = responsable?.token ? { Authorization: `Bearer ${responsable.token}` } : undefined;
|
||||||
const res = await axiosInstance.get<StatusItem[]>('/status');
|
const res = await axiosInstance.get<StatusItem[]>("/status");
|
||||||
setStatus(res.data);
|
setStatus(res.data);
|
||||||
console.log(res.data);
|
console.log(res.data);
|
||||||
//console.log('Status obtenidos', status);
|
//console.log('Status obtenidos', status);
|
||||||
obtenerServicios();
|
obtenerServicios();
|
||||||
} catch (err: unknown) {
|
} catch (err: unknown) {
|
||||||
const axiosErr = err as AxiosError;
|
const axiosErr = err as AxiosError;
|
||||||
console.log('Error al obtener catálogo de status:', err);
|
console.log("Error al obtener catálogo de status:", err);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section>
|
||||||
|
<div className="columns">
|
||||||
|
<h2 className="title">Servicios Sociales</h2>
|
||||||
|
|
||||||
return (
|
<section className="container-fluid my-4">
|
||||||
<section>
|
<Form
|
||||||
<div className="columns">
|
onSubmit={(e) => {
|
||||||
<h2 className="title">Servicios Sociales</h2>
|
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">
|
<Col md={3}>
|
||||||
<Form onSubmit={(e) => { e.preventDefault(); obtenerServicios(1); }}>
|
<FormGroup>
|
||||||
<Row className="g-3">
|
<FormLabel>Nombre</FormLabel>
|
||||||
<Col md={3}>
|
<InputGroup>
|
||||||
<FormGroup>
|
<InputGroup.Text className="rounded-4">
|
||||||
<FormLabel>Número de Cuenta</FormLabel>
|
<FaUser />
|
||||||
<InputGroup>
|
</InputGroup.Text>
|
||||||
<InputGroup.Text className="rounded-4">
|
<FormControl
|
||||||
<FaSchool />
|
type="text"
|
||||||
</InputGroup.Text>
|
placeholder="Nombre"
|
||||||
<FormControl
|
value={search.nombre}
|
||||||
type="text"
|
onChange={(e) =>
|
||||||
placeholder="No.Cuenta"
|
setSearch((prev) => ({
|
||||||
maxLength={9}
|
...prev,
|
||||||
value={search.numeroCuenta}
|
nombre: e.target.value,
|
||||||
onChange={(e) => setSearch(prev => ({ ...prev, numeroCuenta: e.target.value }))}
|
}))
|
||||||
onKeyDown={(e) => { if (e.key === 'Enter') obtenerServicios(1); }}
|
}
|
||||||
className="rounded-4"
|
onKeyDown={(e) => {
|
||||||
/>
|
if (e.key === "Enter") obtenerServicios(1);
|
||||||
</InputGroup>
|
}}
|
||||||
</FormGroup>
|
className="rounded-4"
|
||||||
</Col>
|
/>
|
||||||
|
</InputGroup>
|
||||||
|
</FormGroup>
|
||||||
|
</Col>
|
||||||
|
|
||||||
<Col md={3}>
|
<Col md={3}>
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<FormLabel>Nombre</FormLabel>
|
<FormLabel>Status</FormLabel>
|
||||||
<InputGroup>
|
<InputGroup>
|
||||||
<InputGroup.Text className="rounded-4">
|
<InputGroup.Text className="rounded-4">
|
||||||
<FaUser />
|
<FaInfoCircle />
|
||||||
</InputGroup.Text>
|
</InputGroup.Text>
|
||||||
<FormControl
|
<FormSelect
|
||||||
type="text"
|
value={search.idStatus}
|
||||||
placeholder="Nombre"
|
onChange={(e) =>
|
||||||
value={search.nombre}
|
setSearch((Prev) => ({
|
||||||
onChange={(e) => setSearch(prev => ({ ...prev, nombre: e.target.value }))}
|
...Prev,
|
||||||
onKeyDown={(e) => { if (e.key === 'Enter') obtenerServicios(1); }}
|
idStatus: e.target.value,
|
||||||
className="rounded-4"
|
}))
|
||||||
/>
|
}
|
||||||
</InputGroup>
|
className="rounded-4"
|
||||||
</FormGroup>
|
>
|
||||||
</Col>
|
<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}>
|
<Col md={3} className="d-flex align-items-end">
|
||||||
<FormGroup>
|
<Button
|
||||||
<FormLabel>Status</FormLabel>
|
type="submit"
|
||||||
<InputGroup>
|
className="w-100 rounded-5"
|
||||||
<InputGroup.Text className="rounded-4">
|
disabled={isLoading}
|
||||||
<FaInfoCircle />
|
>
|
||||||
</InputGroup.Text>
|
{isLoading ? "Buscando..." : "Buscar"}
|
||||||
<FormSelect
|
</Button>
|
||||||
value={search.idStatus}
|
</Col>
|
||||||
onChange={(e) => setSearch(Prev => ({ ...Prev, idStatus: e.target.value }))}
|
</Row>
|
||||||
className="rounded-4"
|
</Form>
|
||||||
>
|
|
||||||
<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>
|
|
||||||
</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>
|
</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>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,104 +2,107 @@
|
|||||||
|
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { axiosInstance } from "@/api/config";
|
import { axiosInstance } from "@/api/config";
|
||||||
import { ServicioSocialConCasoEspecial, ServicioSocialResponse } from "@/types/responses";
|
import {
|
||||||
|
ServicioSocialConCasoEspecial,
|
||||||
|
ServicioSocialResponse,
|
||||||
|
} from "@/types/responses";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
data?: ServicioSocialResponse[];
|
data?: ServicioSocialResponse[];
|
||||||
total?: number;
|
total?: number;
|
||||||
onPageChange?: (newPage: number) => void;
|
onPageChange?: (newPage: number) => void;
|
||||||
columnaFechaInicio?: boolean;
|
columnaFechaInicio?: boolean;
|
||||||
columnaFechaFin?: boolean;
|
columnaFechaFin?: boolean;
|
||||||
idTipoUsuario?: number; // 1=admin, 2=responsable, 3=alumno, 4=caso especial
|
idTipoUsuario?: number; // 1=admin, 2=responsable, 3=alumno, 4=caso especial
|
||||||
columnasResponsable?: boolean;
|
columnasResponsable?: boolean;
|
||||||
onRowAction?: (row: ServicioSocialResponse, path: string) => void;
|
onRowAction?: (row: ServicioSocialResponse, path: string) => void;
|
||||||
columnaCuestionario?: boolean;
|
columnaCuestionario?: boolean;
|
||||||
columnaCartaTermino?: boolean;
|
columnaCartaTermino?: boolean;
|
||||||
columnaCuestionarioCompleto?: boolean;
|
columnaCuestionarioCompleto?: boolean;
|
||||||
columnaFechaRegistro?: boolean;
|
columnaFechaRegistro?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function ServicioSocialTabla({
|
export default function ServicioSocialTabla({
|
||||||
data,
|
data,
|
||||||
total = 0,
|
total = 0,
|
||||||
onPageChange,
|
onPageChange,
|
||||||
idTipoUsuario,
|
idTipoUsuario,
|
||||||
columnasResponsable = false,
|
columnasResponsable = false,
|
||||||
columnaFechaInicio = false,
|
columnaFechaInicio = false,
|
||||||
columnaFechaFin = false,
|
columnaFechaFin = false,
|
||||||
columnaCuestionario = false,
|
columnaCuestionario = false,
|
||||||
columnaCartaTermino = false,
|
columnaCartaTermino = false,
|
||||||
columnaCuestionarioCompleto = false,
|
columnaCuestionarioCompleto = false,
|
||||||
columnaFechaRegistro = false,
|
columnaFechaRegistro = false,
|
||||||
onRowAction,
|
onRowAction,
|
||||||
}: Props) {
|
}: Props) {
|
||||||
const [info, setInfo] = useState<ServicioSocialResponse[]>(data || []);
|
const [info, setInfo] = useState<ServicioSocialResponse[]>(data || []);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
//const columnaFechaInicio = true;
|
//const columnaFechaInicio = true;
|
||||||
//const columnaFechaFin = true;
|
//const columnaFechaFin = true;
|
||||||
|
|
||||||
// 🔹 Cargar datos del padre si existen
|
// 🔹 Cargar datos del padre si existen
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (data && data.length > 0) {
|
if (data && data.length > 0) {
|
||||||
setInfo(data);
|
setInfo(data);
|
||||||
}
|
|
||||||
}, [data]);
|
|
||||||
|
|
||||||
// 🔹 Paginación simple
|
|
||||||
function handlePrev() {
|
|
||||||
if (currentPage > 1) {
|
|
||||||
const np = currentPage - 1;
|
|
||||||
setCurrentPage(np);
|
|
||||||
onPageChange?.(np);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}, [data]);
|
||||||
|
|
||||||
function handleNext() {
|
// 🔹 Paginación simple
|
||||||
const lastPage = Math.max(1, Math.ceil(total / 10));
|
function handlePrev() {
|
||||||
if (currentPage < lastPage) {
|
if (currentPage > 1) {
|
||||||
const np = currentPage + 1;
|
const np = currentPage - 1;
|
||||||
setCurrentPage(np);
|
setCurrentPage(np);
|
||||||
onPageChange?.(np);
|
onPageChange?.(np);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const servicioSelected = (row: ServicioSocialResponse | ServicioSocialConCasoEspecial) => {
|
function handleNext() {
|
||||||
if (!row) return;
|
const lastPage = Math.max(1, Math.ceil(total / 10));
|
||||||
|
if (currentPage < lastPage) {
|
||||||
if (idTipoUsuario === 1) {
|
const np = currentPage + 1;
|
||||||
|
setCurrentPage(np);
|
||||||
if (row.idServicio) {
|
onPageChange?.(np);
|
||||||
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) => {
|
const servicioSelected = (row: ServicioSocialResponse | ServicioSocialConCasoEspecial) => {
|
||||||
if (!row) return;
|
if (!row) return;
|
||||||
|
|
||||||
@@ -146,177 +149,179 @@ const servicioSelected = (row: ServicioSocialResponse | ServicioSocialConCasoEsp
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section>
|
<section>
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<div>Cargando...</div>
|
<div>Cargando...</div>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<div className="table-responsive">
|
<div className="table-responsive">
|
||||||
<table className="table table-striped">
|
<table className="table table-striped">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
{columnaFechaRegistro && <th>Fecha Registro</th>}
|
{columnaFechaRegistro && <th>Fecha Registro</th>}
|
||||||
<th>Número de Cuenta</th>
|
<th>Número de Cuenta</th>
|
||||||
<th>Nombre</th>
|
<th>Nombre</th>
|
||||||
<th>Carrera</th>
|
<th>Carrera</th>
|
||||||
{columnaFechaInicio && <th>Fecha Inicio</th>}
|
{columnaFechaInicio && <th>Fecha Inicio</th>}
|
||||||
{columnaFechaFin && <th>Fecha Fin</th>}
|
{columnaFechaFin && <th>Fecha Fin</th>}
|
||||||
<th>Status</th>
|
<th>Status</th>
|
||||||
{columnaCuestionarioCompleto && <th>Cuestionario Completo</th>}
|
{columnaCuestionarioCompleto && (
|
||||||
{columnaCartaTermino && <th>Carta Termino</th>}
|
<th>Cuestionario Completo</th>
|
||||||
{columnaCuestionario && <th>Cuestionario</th>}
|
)}
|
||||||
</tr>
|
{columnaCartaTermino && <th>Carta Termino</th>}
|
||||||
</thead>
|
{columnaCuestionario && <th>Cuestionario</th>}
|
||||||
<tbody>
|
</tr>
|
||||||
{info.map((item, index) => (
|
</thead>
|
||||||
<tr
|
<tbody>
|
||||||
key={index}
|
{info.map((item, index) => (
|
||||||
style={{
|
<tr
|
||||||
cursor: idTipoUsuario === 1 ? "pointer" : "default",
|
key={index}
|
||||||
}}
|
style={{
|
||||||
onClick={() => (
|
cursor: idTipoUsuario === 1 ? "pointer" : "default",
|
||||||
idTipoUsuario === 1 ? servicioSelected(item) : undefined
|
}}
|
||||||
)}
|
onClick={() =>
|
||||||
//onClick={() => Falta corregir
|
idTipoUsuario === 1 ? servicioSelected(item) : undefined
|
||||||
//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>
|
|
||||||
)}</td>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{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 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))
|
|
||||||
}
|
}
|
||||||
>
|
//onClick={() => Falta corregir
|
||||||
Siguiente
|
//idTipoUsuario === 1 ? servicioSelected(item) : undefined
|
||||||
</button>
|
//}
|
||||||
</div>
|
>
|
||||||
|
{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>
|
||||||
|
)}
|
||||||
|
</td>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{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 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>
|
||||||
</>
|
</div>
|
||||||
)}
|
</>
|
||||||
</section>
|
)}
|
||||||
);
|
</section>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatDate(value?: string | null): string {
|
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
|
// 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`);
|
const d = new Date(value.includes("T") ? value : `${value}T00:00:00`);
|
||||||
|
|
||||||
if (isNaN(d.getTime())) {
|
if (isNaN(d.getTime())) {
|
||||||
console.warn("⚠️ Fecha inválida:", value);
|
console.warn("⚠️ Fecha inválida:", value);
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
const day = String(d.getDate()).padStart(2, "0");
|
const day = String(d.getDate()).padStart(2, "0");
|
||||||
const month = String(d.getMonth() + 1).padStart(2, "0");
|
const month = String(d.getMonth() + 1).padStart(2, "0");
|
||||||
const year = d.getFullYear();
|
const year = d.getFullYear();
|
||||||
|
|
||||||
return `${day}/${month}/${year}`;
|
return `${day}/${month}/${year}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function statusClass(id?: number) {
|
function statusClass(id?: number) {
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case 1:
|
case 1:
|
||||||
return "dark";
|
return "dark";
|
||||||
case 2:
|
case 2:
|
||||||
return "info";
|
return "info";
|
||||||
case 3:
|
case 3:
|
||||||
return "warning";
|
return "warning";
|
||||||
case 4:
|
case 4:
|
||||||
return "primary";
|
return "primary";
|
||||||
case 5:
|
case 5:
|
||||||
case 6:
|
case 6:
|
||||||
return "success";
|
return "success";
|
||||||
case 7:
|
case 7:
|
||||||
case 8:
|
case 8:
|
||||||
case 9:
|
case 9:
|
||||||
case 10:
|
case 10:
|
||||||
return "danger";
|
return "danger";
|
||||||
default:
|
default:
|
||||||
return "secondary";
|
return "secondary";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+36
-36
@@ -1,60 +1,60 @@
|
|||||||
import { AxiosRequestConfig } from "axios";
|
import { AxiosRequestConfig } from "axios";
|
||||||
|
|
||||||
export interface ServicioSocialResponse {
|
export interface ServicioSocialResponse {
|
||||||
idServicio?: number;
|
idServicio?: number;
|
||||||
id?: number;
|
id?: number;
|
||||||
createdAt?: string;
|
createdAt?: string;
|
||||||
fecha_creacion?: string | null;
|
fecha_creacion?: string | null;
|
||||||
fechaFin?: string | null;
|
fechaFin?: string | null;
|
||||||
fechaInicio?: string | null;
|
fechaInicio?: string | null;
|
||||||
fecha_registro?: string | null;
|
fecha_registro?: string | null;
|
||||||
Usuario?: Usuario;
|
usuario?: Usuario;
|
||||||
Carrera?: Carrera;
|
carrera?: Carrera;
|
||||||
Status?: Status;
|
status?: Status;
|
||||||
cartaTermino?: boolean;
|
cartaTermino?: boolean;
|
||||||
idCuestionarioPrograma?: number | null;
|
idCuestionarioPrograma?: number | null;
|
||||||
idCuestionarioPrograma2?: number | null;
|
idCuestionarioPrograma2?: number | null;
|
||||||
cuestionarioCompletado?: boolean;
|
cuestionarioCompletado?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Usuario {
|
export interface Usuario {
|
||||||
idUsuario?: number;
|
idUsuario?: number;
|
||||||
usuario: string | number;
|
usuario: string | number;
|
||||||
nombre: string;
|
nombre: string;
|
||||||
idservicio?: number;
|
idservicio?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OtraTabla {
|
export interface OtraTabla {
|
||||||
title: string;
|
title: string;
|
||||||
admin: Record<string, unknown>;
|
admin: Record<string, unknown>;
|
||||||
alumno: Record<string, unknown>;
|
alumno: Record<string, unknown>;
|
||||||
imprimirError?: (...args: unknown[]) => void;
|
imprimirError?: (...args: unknown[]) => void;
|
||||||
imprimirMensaje?: (...args: unknown[]) => void;
|
imprimirMensaje?: (...args: unknown[]) => void;
|
||||||
imprimirWairning?: (...args: unknown[]) => void;
|
imprimirWairning?: (...args: unknown[]) => void;
|
||||||
updateIsLoading?: (...args: unknown[]) => void;
|
updateIsLoading?: (...args: unknown[]) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Carrera {
|
export interface Carrera {
|
||||||
idCarrera?: number;
|
idCarrera?: number;
|
||||||
carrera: string;
|
carrera: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Status {
|
export interface Status {
|
||||||
idStatus: number;
|
idStatus: number;
|
||||||
status: string;
|
status: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CargaMasivaProps {
|
export interface CargaMasivaProps {
|
||||||
admin: { tokenArchivo: string };
|
admin: { tokenArchivo: string };
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Responsables {
|
export interface Responsables {
|
||||||
idUsuario: number;
|
idUsuario: number;
|
||||||
usuario: string;
|
usuario: string;
|
||||||
nombre: string;
|
nombre: string;
|
||||||
activo: boolean;
|
activo: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ServicioSocialConCasoEspecial extends ServicioSocialResponse {
|
interface ServicioSocialConCasoEspecial extends ServicioSocialResponse {
|
||||||
idCasoEspecial?: number;
|
idCasoEspecial?: number;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user