This commit is contained in:
2026-03-04 17:35:58 -06:00
89 changed files with 1610 additions and 2482 deletions
@@ -76,7 +76,7 @@
.checkbox-grid label {
display: inline-flex;
align-items: center;
font-size: 13px;
font-size: 1.4rem;
cursor: pointer;
}
+5 -3
View File
@@ -2,17 +2,19 @@ import Areas from "@/app/Components/ActivosMantenimiento/Areas";
import MesasDisponibles from "@/app/Components/ActivosMantenimiento/MesasDisponibles";
import TableEquipos from "@/app/Components/Equipos/tableequipos";
import Toggle from "@/app/Components/Global/Toggle/Toggle";
import { Metadata } from "next";
export const metadata: Metadata = {
title: "ActivosMantenimiento",
};
export default async function Page(props: {
searchParams?: Promise<{
key?: string;
numAcount?: string;
machine?: string;
}>;
}) {
const params = await props.searchParams;
const key = params?.key && params.key;
const numAcount = params?.numAcount ? params.numAcount : null;
return (
<section className="containerSection">
+9 -3
View File
@@ -2,12 +2,13 @@
import { useState } from "react";
import { useRouter } from "next/navigation";
import { envConfig } from "@/app/lib/config";
import SelectionCo from "@/app/Components/Selection/SelectionCo";
import axios from "axios";
import { envConfig } from "@/app/lib/config";
import Cookies from "js-cookie";
import Swal from "sweetalert2";
import "./addTime.css";
const PLATAFORMA_MAP: Record<string, number> = {
@@ -42,11 +43,16 @@ export default function AddTime({
const month = day.getMonth();
const today = day.getDate();
const minFecha = new Date(year, month, 1).toISOString().split("T")[0];
let minMount = month
if (!lock) {
minMount = month - 1
}
const minFecha = new Date(year, minMount, 1).toISOString().split("T")[0];
const maxFecha = new Date(year, month, today).toISOString().split("T")[0];
const handleSaveReceipt = async () => {
if (!numAcount) {
if (numAcount == null) {
Swal.fire({
title: "Busca de nuevo al estudiante!",
+23 -5
View File
@@ -23,21 +23,21 @@
width: 100%;
}
.buttonLock{
.buttonLock {
padding: 0.8rem;
position: absolute;
right: 0;
right: 100px;
background-color: #d32f2f;
}
.buttonOpenLock{
.buttonOpenLock {
padding: 0.8rem;
position: absolute;
right: 0;
right: 100px;
background-color: #8cd32f;
}
.buttonOpenLock:hover{
.buttonOpenLock:hover {
background-color: #78b32c;
}
@@ -63,6 +63,24 @@
background-repeat: no-repeat;
}
@media(max-height:800px) {
.addTime {
margin-top: 0.5rem;
padding: 0.5rem;
max-width: 320px;
}
.firstPartInformationTime {
max-width: 320px;
}
}
@media(max-height:800px) {
.buttonLock {
padding: 0.5rem;
}
}
@media (max-width: 800px) {
.containeInformationTime {
flex-direction: column;
+5
View File
@@ -8,9 +8,14 @@ import AddTime from "./Addtime";
import Table from "@/app/Components/Global/table";
import "./addTime.css";
import { Metadata } from "next";
const headers = ["Inscrito", "Tiempo", "Confirmó"];
export const metadata: Metadata = {
title: "AgregarTiempo",
};
export default async function Page(props: {
searchParams?: Promise<{ numAcount: string }>;
}) {
+5
View File
@@ -1,6 +1,11 @@
import RegisterAlta from "@/app/Components/Alta/registerAlta";
import "./style.css";
import { Metadata } from "next";
export const metadata: Metadata = {
title: "Alta",
};
export default async function Page(props: {
searchParams?: Promise<{
+24 -7
View File
@@ -6,9 +6,11 @@ import { envConfig } from "@/app/lib/config";
import { getEquipoByCount } from "@/app/lib/getEquipoByCount";
import { getMesaByCount } from "@/app/lib/getMesaByCount";
import "./asignacion.css";
import Swal from "sweetalert2";
import axios from "axios";
import Cookies from "js-cookie";
import "./asignacion.css";
type Props = {
inscripcion: any[];
@@ -23,7 +25,10 @@ export default function PlaticaGate({ inscripcion, numAcount }: Props) {
const [open, setOpen] = useState(false);
const [tiempo, setTiempo] = useState<number>(15);
const [bitacora, setBitacora] = useState<[] | null>([]);
const [error, setError] = useState<string>();
const [error, setError] = useState<string>("Equipo");
const token = Cookies.get("token");
const headers = { Authorization: `Bearer ${token}` };
const fetchByCuenta = async (idCuenta: number) => {
const [result, resultMesa] = await Promise.all([
@@ -35,8 +40,15 @@ export default function PlaticaGate({ inscripcion, numAcount }: Props) {
setBitacora(null);
} else {
setBitacora([]);
if (!result?.error) setError("Equipo");
if (!resultMesa?.error) setError("Mesa");
if (!result?.error) {
setError("Equipo");
return;
}
if (!resultMesa?.error) {
setError("Mesa");
return;
}
}
};
@@ -68,14 +80,16 @@ export default function PlaticaGate({ inscripcion, numAcount }: Props) {
}, [inscripcion]);
useEffect(() => {
if (!puedeContinuar || !numAcount || error === "Equipo" || error === "Mesa") return;
if (!puedeContinuar || !numAcount || !(error === "Equipo" || error === "Mesa")) return;
const fetchEquipos = async () => {
try {
setLoadingEquipos(true);
const res = await axios.get(
`${envConfig.apiUrl}/equipo/student/${numAcount}`
`${envConfig.apiUrl}/equipo/student/${numAcount}`,
{ headers },
);
setEquipos(res.data);
@@ -115,7 +129,8 @@ export default function PlaticaGate({ inscripcion, numAcount }: Props) {
id_alumno_inscrito: inscripcion[0].id_alumno_inscrito,
};
await axios.post(`${envConfig.apiUrl}/bitacora`, body);
await axios.post(`${envConfig.apiUrl}/bitacora`, body, { headers }
);
setBitacora([]);
@@ -154,6 +169,8 @@ export default function PlaticaGate({ inscripcion, numAcount }: Props) {
<option value={40}>40 minutos</option>
<option value={60}>60 minutos</option>
<option value={90}>90 minutos</option>
<option value={120}>120 minutos</option>
</select>
<label>Seleccione un equipo</label>
@@ -4,7 +4,7 @@
position: relative;
flex: 1;
width: 100%;
font-size: 14px;
font-size: 1.4rem;
max-width: 500px;
}
+5
View File
@@ -10,9 +10,14 @@ import { GetRegisterStudent } from "@/app/lib/getRegisterStudent";
import PlaticaGate from "./PlaticaGate";
import "@/app/globals.css";
import { GetRegisterStudentSancion } from "@/app/lib/GetRegisterStudentSancion";
import { Metadata } from "next";
const headers = ["Inscrito", "Tiempo", "Confirmó"];
export const metadata: Metadata = {
title: "AsignacionEquipo",
};
export default async function Page(props: {
searchParams?: Promise<{
key?: string;
@@ -0,0 +1,62 @@
"use client";
import { useEffect, useState } from "react";
import styles from "../Monitor/Page.module.css";
import axios from "axios";
import Cookies from "js-cookie";
type Mesa = {
id_mesa: number;
ocupado: number;
};
export default function TableMesas() {
const [mesas, setMesas] = useState<Mesa[]>([]);
const [loading, setLoading] = useState(true);
const token = Cookies.get("token");
const headers = { Authorization: `Bearer ${token}` };
const fetchMesas = async () => {
try {
const res = await axios.get(
`${process.env.NEXT_PUBLIC_API_URL}/mesa/usoWhitout`,
{ headers },
);
setMesas(res.data);
} catch (error) {
console.error("Error cargando mesas:", error);
} finally {
setLoading(false);
}
};
useEffect(() => {
fetchMesas();
}, []);
if (loading) {
return <p>Cargando mesas...</p>;
}
return (
<div className={styles.tableContainer}>
<table className={styles.machineTable}>
<thead>
<tr>
<th>ID Mesa</th>
</tr>
</thead>
<tbody>
{mesas.map((mesa) => (
<tr key={mesa.id_mesa} className={!mesa.ocupado ? '' : styles.ocupado}>
<td>{mesa.id_mesa}</td>
</tr>
))}
</tbody>
</table>
</div>
);
}
@@ -0,0 +1,10 @@
.tableTable{
margin: 0.1rem;
width: 100%;
max-width: 250px;
}
.asignacion{
display: flex;
flex-wrap: wrap;
gap: 1rem;
}
+48 -36
View File
@@ -4,15 +4,23 @@ import Information from "@/app/Components/Global/Information/information";
import SearchUser from "@/app/Components/Global/SearchUser/searchUser";
import ShowError from "@/app/Components/Global/ShowError";
import Toggle from "@/app/Components/Global/Toggle/Toggle";
import TableMesas from "./TableMesas";
import { GetRegisterStudent } from "@/app/lib/getRegisterStudent";
import { GetRegisterStudentSancion } from "@/app/lib/GetRegisterStudentSancion";
import { Metadata } from "next";
import './asignacion.css'
export const metadata: Metadata = {
title: "AsignacionMesas",
};
export default async function Page(props: {
searchParams?: Promise<{
key?: string;
numAcount?: string;
table?:number
table?: string
}>;
}) {
const params = await props.searchParams;
@@ -20,7 +28,6 @@ export default async function Page(props: {
const numAcount = params?.numAcount ?? null;
const table = params?.table ?? null;
let student: any = null;
let platica: any = null;
let inscripcion: any[] = [];
@@ -40,7 +47,7 @@ export default async function Page(props: {
? Boolean(rawPlatica.data[0])
: Boolean(rawPlatica);
}
const inscResult = await GetRegisterStudent(idCuenta);
if (!inscResult.error && Array.isArray(inscResult)) {
@@ -56,41 +63,46 @@ export default async function Page(props: {
<h2 className="title"> ASIGNACIÓN DE MESAS </h2>
<Toggle
defaultView={key}
options={[
{
key: "Asignar",
label: "Asignar mesa",
content: (
<>
<SearchUser value={numAcount} />
<div className="asignacion">
<Toggle
defaultView={key}
options={[
{
key: "Asignar",
label: "Asignar mesa",
content: (
<>
<SearchUser value={numAcount} />
{student && (
<>
<div>
<Information
NoCuenta={student.id_cuenta}
nombre={student.nombre}
{student && (
<>
<div>
<Information
NoCuenta={student.id_cuenta}
nombre={student.nombre}
/>
</div>
<AsignacionMesas
idCuenta={student.id_cuenta}
inscripcion={inscripcion}
/>
</div>
<AsignacionMesas
idCuenta={student.id_cuenta}
inscripcion={inscripcion}
/>
</>
)}
</>
),
},
{
key: "Liberar",
label: "Cancelar mesa",
content: <CheckBoxMesa numAcount={numAcount} table={table} />,
},
]}
/>
</>
)}
</>
),
},
{
key: "Liberar",
label: "Cancelar mesa",
content: <CheckBoxMesa numAcount={numAcount} table={table} />,
},
]}
/>
<div className="tableTable">
<TableMesas />
</div>
</div>
</section>
);
}
+5
View File
@@ -8,6 +8,11 @@ import ShowError from "@/app/Components/Global/ShowError";
import Toggle from "@/app/Components/Global/Toggle/Toggle";
import QuitarSancion from "@/app/Components/QuitarSancion/QuitarSancion";
import { GetStudentWhitoutSancion } from "@/app/lib/getStudentWhitoutSancion";
import { Metadata } from "next";
export const metadata: Metadata = {
title: "BitacoraSanciones",
};
export default async function Page(props: {
searchParams?: Promise<{
+5
View File
@@ -1,4 +1,9 @@
import ChangePassword from "@/app/Components/auth/ChangePassword/changePassword";
import { Metadata } from "next";
export const metadata: Metadata = {
title: "CambiarPass",
};
export default async function Page(props: {
searchParams?: Promise<{
+34 -9
View File
@@ -6,12 +6,15 @@ import Impressions from "@/app/Components/Impressions/impressions";
import ShowError from "@/app/Components/Global/ShowError";
import { cookies } from "next/headers";
import { getCost } from "@/app/lib/getCost";
import { GetStudentWhitoutSancion } from "@/app/lib/getStudentWhitoutSancion";
import axios from "axios";
import "@/app/globals.css";
import { envConfig } from "@/app/lib/config";
import { Metadata } from "next";
export const metadata: Metadata = {
title: "Impresiones",
};
export default async function Page(props: {
searchParams?: Promise<{
@@ -33,7 +36,6 @@ export default async function Page(props: {
if (numAcount) {
const result = await GetStudentWhitoutSancion(parseInt(numAcount));
if (result.error) {
errorMessage = `${result.error}`;
} else {
@@ -41,14 +43,35 @@ export default async function Page(props: {
}
}
let id_servicio: number;
switch (key) {
case "B/N":
id_servicio = 1;
break;
case "color":
id_servicio = 2;
break;
case "Plotter":
id_servicio = 3;
break;
case "Escaner":
id_servicio = 6;
break;
}
try {
const response = await axios.get(`${envConfig.apiUrl}/costo`);
costos = response.data;
const response = await getCost();
costos = response;
} catch (error) {
console.error("Error obteniendo costos:", error);
}
const getCostsByService = (id_servicio: number) => {
return costos
.filter((c) => c.id_servicio === id_servicio)
@@ -84,6 +107,7 @@ export default async function Page(props: {
label: "Impresiones color",
content: (
<Impressions
key={2}
costs={getCostsByService(2)}
numAcount={student.id_cuenta}
id_servicio={2}
@@ -95,6 +119,7 @@ export default async function Page(props: {
label: "Plotter",
content: (
<Impressions
key={3}
costs={getCostsByService(3)}
numAcount={student.id_cuenta}
id_servicio={3}
@@ -118,8 +143,8 @@ export default async function Page(props: {
const optionsToUse =
roleNumber === 5
? options.filter(
(option) => option.key === "Recibo" || option.key === "B/N"
)
(option) => option.key === "Recibo" || option.key === "B/N"
)
: options;
return (
@@ -15,16 +15,17 @@
.form-container {
gap: 10px;
margin-bottom: 1rem;
}
.form-container label {
font-size: 14px;
font-size: 1.4rem;
display: inline-block;
vertical-align: middle;
}
.form-container select {
font-size: 13px;
font-size: 1.4rem;
padding: 8px 12px;
border: 1px solid #ccc;
border-radius: 6px;
@@ -57,7 +58,7 @@
.checkbox-grid label {
display: flex;
align-items: center;
font-size: 13px;
font-size: 1.4rem;
cursor: pointer;
white-space: nowrap;
width: fit-content;
+5
View File
@@ -1,7 +1,12 @@
import { Metadata } from "next";
import InformacionEquipo from "./InformacionEquipo";
import "./informacionequipo.css";
export const metadata: Metadata = {
title: "InformacionEquipo",
};
export default async function Page(props: {
searchParams?: Promise<{
key?: string;
+21 -4
View File
@@ -3,7 +3,7 @@
top: 0;
background-color: #ffffff;
width: 100%;
max-width: 700px;
max-width: 600px;
border-radius: 4px;
padding: 1rem;
margin-top: 1rem;
@@ -23,18 +23,35 @@
max-width: 450px;
}
.restarPass{
margin-top: 2rem;
.restarPass {
margin-top: 3rem;
height: fit-content;
}
@media(max-height:800px) {
.firstPartInformation {
max-width: 320px;
}
.inscripcion {
max-width: 400px;
padding: 0.5rem;
margin-top: 0.5rem;
}
.restarPass {
margin-top: 2rem;
}
}
@media (max-width: 800px) {
.containeInformation {
flex-direction: column;
justify-content: center;
align-items: center;
}
.restarPass{
.restarPass {
margin-top: 0;
}
}
+5
View File
@@ -9,9 +9,14 @@ import { GetRegisterStudent } from "@/app/lib/getRegisterStudent";
import { GetStudentWhitoutSancion } from "@/app/lib/getStudentWhitoutSancion";
import "./inscripcion.css";
import { Metadata } from "next";
const headers = ["Inscrito", "Tiempo", "Confirmó"];
export const metadata: Metadata = {
title: "Inscripcion",
};
export default async function Page(props: {
searchParams?: Promise<{
numAcount: string;
+9 -2
View File
@@ -2,6 +2,7 @@
import { envConfig } from "@/app/lib/config";
import { useEffect, useState } from "react";
import axios from "axios";
import Cookies from "js-cookie";
import "./inscripciones.css"
@@ -34,9 +35,13 @@ export default function Inscripciones() {
const [selectedPeriodo, setSelectedPeriodo] = useState<number | null>(null);
const [tablaData, setTablaData] = useState<TablaRow[]>([]);
const token = Cookies.get("token");
const headers = { Authorization: `Bearer ${token}` };
useEffect(() => {
const getPeriodo = async () => {
const response = await axios.get(`${envConfig.apiUrl}/periodo`);
const response = await axios.get(`${envConfig.apiUrl}/periodo`, { headers }
);
setPeriodo(response.data);
};
getPeriodo();
@@ -48,7 +53,9 @@ export default function Inscripciones() {
if (!selectedPeriodo) return;
const response = await axios.get(
`${envConfig.apiUrl}/alumno-inscrito/inscritos/${selectedPeriodo}`
`${envConfig.apiUrl}/alumno-inscrito/inscritos/${selectedPeriodo}`,
{ headers }
);
const data: ApiResponse[] = response.data;
+5
View File
@@ -1,5 +1,10 @@
import { Metadata } from "next";
import Inscripciones from "./Inscripciones";
export const metadata: Metadata = {
title: "Inscritos",
};
export default async function Page(props: {
searchParams?: Promise<{
period: string;
+4 -4
View File
@@ -28,7 +28,7 @@
background: none;
border: none;
padding: 10px;
font-size: 14px;
font-size: 1.4rem;
cursor: pointer;
transition: 0.3s;
color: #333;
@@ -48,7 +48,7 @@
}
.formGroup label {
font-size: 14px;
font-size: 1.4rem;
margin-bottom: 6px;
color: #444;
font-weight: 500;
@@ -59,7 +59,7 @@
padding: 8px 10px;
border: 1px solid #ddd;
border-radius: 6px;
font-size: 14px;
font-size: 1.4rem;
transition: border 0.3s, box-shadow 0.3s;
}
@@ -78,7 +78,7 @@
.btn {
padding: 8px 16px;
border-radius: 6px;
font-size: 14px;
font-size: 1.4rem;
cursor: pointer;
border: none;
transition: 0.3s;
+5
View File
@@ -1,6 +1,11 @@
import EnviarMensaje from "@/app/Components/EviarMensaje/EnviarMensaje";
import EnviarMensajeSala from "@/app/Components/EviarMensaje/EnviarMensajeSala";
import Toggle from "@/app/Components/Global/Toggle/Toggle";
import { Metadata } from "next";
export const metadata: Metadata = {
title: "Mensajes",
};
export default async function Page(props: {
searchParams?: Promise<{
+11 -4
View File
@@ -3,6 +3,7 @@
import { useEffect, useState } from "react";
import styles from "./Page.module.css";
import axios from "axios";
import Cookies from "js-cookie";
type AreaUbicacion = {
id_area_ubicacion: number;
@@ -24,10 +25,15 @@ export default function MachineTable() {
const [selectedArea, setSelectedArea] = useState("Todo");
const [loading, setLoading] = useState(true);
const token = Cookies.get("token");
const headers = { Authorization: `Bearer ${token}` };
const fetchMachines = async () => {
try {
const res = await axios.get(
`${process.env.NEXT_PUBLIC_API_URL}/equipo/disable`
`${process.env.NEXT_PUBLIC_API_URL}/equipo/disable`,
{ headers },
);
setMachines(res.data);
@@ -41,7 +47,8 @@ export default function MachineTable() {
const fetchAreas = async () => {
try {
const res = await axios.get(
`${process.env.NEXT_PUBLIC_API_URL}/area-ubicacion`
`${process.env.NEXT_PUBLIC_API_URL}/area-ubicacion`,
{ headers },
);
setAreas(res.data);
@@ -63,8 +70,8 @@ export default function MachineTable() {
selectedArea === "Todo"
? machines
: machines.filter(
(machine) => machine.areaUbicacion.area === selectedArea,
);
(machine) => machine.areaUbicacion.area === selectedArea,
);
return (
<div className={styles.tableContainer}>
+10 -2
View File
@@ -3,6 +3,7 @@
import { useEffect, useState } from "react";
import styles from "./Page.module.css";
import axios from "axios";
import Cookies from "js-cookie";
type AreaUbicacion = {
id_area_ubicacion: number;
@@ -24,10 +25,15 @@ export default function MachineTableActive() {
const [selectedArea, setSelectedArea] = useState("Todo");
const [loading, setLoading] = useState(true);
const token = Cookies.get("token");
const headers = { Authorization: `Bearer ${token}` };
const fetchMachines = async () => {
try {
const res = await axios.get(
`${process.env.NEXT_PUBLIC_API_URL}/equipo/active`
`${process.env.NEXT_PUBLIC_API_URL}/equipo/active`,
{ headers },
);
setMachines(res.data);
@@ -41,7 +47,9 @@ export default function MachineTableActive() {
const fetchAreas = async () => {
try {
const res = await axios.get(
`${process.env.NEXT_PUBLIC_API_URL}/area-ubicacion`
`${process.env.NEXT_PUBLIC_API_URL}/area-ubicacion`,
{ headers },
);
setAreas(res.data);
+1 -1
View File
@@ -17,7 +17,7 @@
}
.ocupado {
background-color: rgb(173, 233, 253);
background-color: #54bbfc !important;
color: red;
font-weight: bold;
}
+66
View File
@@ -0,0 +1,66 @@
"use client";
import { useEffect, useState } from "react";
import styles from "./Page.module.css";
import axios from "axios";
import Cookies from "js-cookie";
type Mesa = {
id_mesa: number;
ocupado: number;
};
export default function TableTable() {
const [mesas, setMesas] = useState<Mesa[]>([]);
const [loading, setLoading] = useState(true);
const token = Cookies.get("token");
const headers = { Authorization: `Bearer ${token}` };
const fetchMesas = async () => {
try {
const res = await axios.get(
`${process.env.NEXT_PUBLIC_API_URL}/mesa/uso`,
{ headers },
);
setMesas(res.data);
} catch (error) {
console.error("Error cargando mesas:", error);
} finally {
setLoading(false);
}
};
useEffect(() => {
fetchMesas();
}, []);
if (loading) {
return <p>Cargando mesas...</p>;
}
return (
<div className={styles.tableContainer}>
<table className={styles.machineTable}>
<thead>
<tr>
<th>ID Mesa</th>
<th>Disponible</th>
</tr>
</thead>
<tbody>
{mesas.map((mesa) => (
<tr key={mesa.id_mesa} className={!mesa.ocupado ? '' : styles.ocupado}>
<td>{mesa.id_mesa}</td>
<td>
{mesa.ocupado === 1 ? "No" : "Si"}
</td>
</tr>
))}
</tbody>
</table>
</div>
);
}
+13 -9
View File
@@ -1,20 +1,24 @@
import Toggle from "@/app/Components/Global/Toggle/Toggle";
import MachineTable from "./MachineTable";
import styles from "./Page.module.css";
import MachineTableActive from "./MachineTableActive";
import DSC from "./DSC";
import ToggleTable from "@/app/Components/Global/Toggle/ToggleTable";
import TableTable from "./TableTable";
import { Metadata } from "next";
export const metadata: Metadata = {
title: "Monitor",
};
export default async function Page(props: {
searchParams?: Promise<{ numAcount: string; key: string }>;
}) {
const params = await props.searchParams;
const numAcount = params?.numAcount ?? null;
const key = params?.key ?? "active";
const key = params?.key ?? "Equipos";
return (
<section className="containerSection">
<h2 className="title">MONITOR DE MÁQUINAS</h2>
<h2 className="title">MONITOR</h2>
<div className={styles.actions}>
<button className={styles.resetButton}>Actualizar información</button>
@@ -23,8 +27,8 @@ export default async function Page(props: {
defaultView={key}
options={[
{
key: "active",
label: "Disponibles",
key: "Equipos",
label: "Equipos",
content: (
<>
<MachineTableActive />
@@ -32,11 +36,11 @@ export default async function Page(props: {
),
},
{
key: "disable",
label: "No Disponibles",
key: "Mesas",
label: "Mesas",
content: (
<>
<MachineTable />
<TableTable />
</>
),
},
+147
View File
@@ -0,0 +1,147 @@
"use client";
import { useState, useEffect } from "react";
import { envConfig } from "@/app/lib/config";
import axios from "axios";
import Cookies from "js-cookie";
import { Metadata } from "next";
interface TotalServicioPeriodo {
nombre_servicio: string;
periodo: string;
monto_total: number;
}
interface Servicio {
id_servicio: number;
servicio: string;
}
interface Periodo {
id_periodo: number;
semestre: string;
}
export default function ReporteTotalesPage() {
const [totales, setTotales] = useState<TotalServicioPeriodo[]>([]);
const [servicios, setServicios] = useState<Servicio[]>([]);
const [periodos, setPeriodos] = useState<Periodo[]>([]);
const [cargando, setCargando] = useState(true);
const [periodoInicio, setPeriodoInicio] = useState<string>("");
const [periodoFin, setPeriodoFin] = useState<string>("");
const [servicioId, setServicioId] = useState<string>("");
const token = Cookies.get("token");
const headers = { Authorization: `Bearer ${token}` };
useEffect(() => {
const fetchData = async () => {
try {
const [serviciosRes, periodosRes] = await Promise.all([
axios.get(`${envConfig.apiUrl}/servicio`, { headers }),
axios.get(`${envConfig.apiUrl}/periodo`, { headers }),
]);
setServicios(serviciosRes.data);
setPeriodos(periodosRes.data);
} catch (error) {
console.error("Error al cargar servicios o periodos", error);
}
};
fetchData();
}, []);
const obtenerTotales = async () => {
setCargando(true);
try {
// Construir query params
const params = new URLSearchParams();
if (periodoInicio) params.append("periodoInicio", periodoInicio);
if (periodoFin) params.append("periodoFin", periodoFin);
if (servicioId) params.append("servicioId", servicioId);
const url = `${envConfig.apiUrl}/detalle-servicio/totales-por-periodo?${params.toString()}`;
const res = await axios.get(url, { headers });
setTotales(res.data);
} catch (error) {
console.error("Error al obtener totales", error);
} finally {
setCargando(false);
}
};
const aplicarFiltros = () => {
obtenerTotales();
};
return (
<div>
<h1 style={{ color: "rgb(3, 1, 72)" }}>REPORTE DE TOTALES POR SERVICIO Y PERIODO</h1>
<div style={{ marginBottom: "20px", display: "flex", gap: "10px", flexWrap: "wrap" }}>
<select
value={periodoInicio}
onChange={(e) => setPeriodoInicio(e.target.value)}
>
<option value="">Periodo inicio (todos)</option>
{periodos.map((p) => (
<option key={p.id_periodo} value={p.id_periodo}>
{p.semestre}
</option>
))}
</select>
<select
value={periodoFin}
onChange={(e) => setPeriodoFin(e.target.value)}
>
<option value="">Periodo fin (todos)</option>
{periodos.map((p) => (
<option key={p.id_periodo} value={p.id_periodo}>
{p.semestre}
</option>
))}
</select>
<select
value={servicioId}
onChange={(e) => setServicioId(e.target.value)}
>
<option value="">Todos los servicios</option>
{servicios.map((s) => (
<option key={s.id_servicio} value={s.id_servicio}>
{s.servicio}
</option>
))}
</select>
<button onClick={aplicarFiltros}>Filtrar</button>
</div>
{cargando ? (
<p>Cargando...</p>
) : (
<div style={{ overflow: "auto", maxHeight: "500px" }}>
<table>
<thead>
<tr>
<th>Servicio</th>
<th>Periodo</th>
<th>Monto Total</th>
</tr>
</thead>
<tbody>
{totales.map((item, index) => (
<tr key={index}>
<td>{item.nombre_servicio}</td>
<td>{item.periodo}</td>
<td>${item.monto_total.toFixed(2)}</td>
</tr>
))}
</tbody>
</table>
</div>
)}
</div>
);
}
+10 -25
View File
@@ -1,15 +1,20 @@
"use client";
import { useState, useEffect } from "react";
import { envConfig } from "@/app/lib/config";
import axios from "axios";
import Cookies from "js-cookie";
import { Metadata } from "next";
interface Periodo {
id_periodo: number;
semestre: string;
fecha_inicio_servicio: string;
fecha_fin_servicio: string;
activo: boolean;
activo: {
type: string;
data: number[];
};
}
export default function PeriodoPage() {
@@ -21,7 +26,7 @@ export default function PeriodoPage() {
const [modoEdicion, setModoEdicion] = useState(false);
const [idEditar, setIdEditar] = useState<number | null>(null);
const API = "http://localhost:5000/periodo";
const API = `${envConfig.apiUrl}/periodo`;
const token = Cookies.get("token");
const headers = { Authorization: `Bearer ${token}` };
@@ -39,10 +44,8 @@ export default function PeriodoPage() {
obtenerPeriodos();
}, []);
// VALIDAR SEMESTRE
const handleSemestreChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const valor = e.target.value;
if (/^\d{0,6}$/.test(valor)) {
setSemestre(valor);
@@ -74,16 +77,6 @@ export default function PeriodoPage() {
}
};
const eliminarPeriodo = async (id_periodo: number) => {
try {
await axios.delete(`${API}/${id_periodo}`, { headers });
obtenerPeriodos();
} catch (error) {
console.error("Error al eliminar periodo", error);
}
};
const cargarPeriodo = (p: Periodo) => {
setModoEdicion(true);
setIdEditar(p.id_periodo);
@@ -129,7 +122,6 @@ export default function PeriodoPage() {
<div>
<h1 style={{ color: "rgb(3, 1, 72)" }}>PERIODO ESCOLAR</h1>
{/* ================= FORMULARIO ================= */}
<div style={{ marginBottom: "10px" }}>
<input
type="text"
@@ -183,7 +175,6 @@ export default function PeriodoPage() {
)}
</div>
{/* ================= TABLA ================= */}
<div style={{ overflow: "auto", maxHeight: "350px" }}>
<table>
<thead>
@@ -203,7 +194,7 @@ export default function PeriodoPage() {
<td>{p.semestre}</td>
<td>{p.fecha_inicio_servicio}</td>
<td>{p.fecha_fin_servicio}</td>
<td>{p.activo === true ? "Sí" : "No"}</td>
<td>{p.activo.data[0] === 1 ? "Sí" : "No"}</td>
<td>
<button
className="button buttonSearch"
@@ -211,13 +202,6 @@ export default function PeriodoPage() {
>
Modificar
</button>
<button
className="button buttonCancel"
onClick={() => eliminarPeriodo(p.id_periodo)}
>
Borrar
</button>
</td>
</tr>
))}
@@ -226,4 +210,5 @@ export default function PeriodoPage() {
</div>
</div>
);
}
}
//IO
+22 -13
View File
@@ -1,10 +1,12 @@
"use client";
import { useState, useEffect } from "react";
import styleprograms from "./programas.module.css";
import { envConfig } from "@/app/lib/config";
import styleprograms from "./programas.module.css";
import axios from "axios";
import Swal from "sweetalert2";
import Cookies from "js-cookie";
import { Metadata } from "next";
interface Programa {
id_programa: number;
@@ -17,9 +19,13 @@ export default function Page() {
const [programas, setProgramas] = useState<Programa[]>([]);
const [nombrePrograma, setNombrePrograma] = useState("");
const token = Cookies.get("token");
const headers = { Authorization: `Bearer ${token}` };
const cargarProgramas = async () => {
try {
const response = await axios.get(`${envConfig.apiUrl}/programa/`);
const response = await axios.get(`${envConfig.apiUrl}/programa/`, { headers }
);
setProgramas(response.data);
} catch (error: any) {
console.error("Error al cargar programas:", error);
@@ -41,7 +47,8 @@ export default function Page() {
try {
await axios.post(`${envConfig.apiUrl}/programa`, {
programa: nombrePrograma,
});
}, { headers }
);
await cargarProgramas();
@@ -63,13 +70,14 @@ export default function Page() {
const handleGuardar = async () => {
if (!programaSeleccionado) return;
try {
await axios.patch(
`${envConfig.apiUrl}/programa/${programaSeleccionado}`,
{
programa: nombrePrograma,
}
},
{ headers },
);
await cargarProgramas();
@@ -107,7 +115,8 @@ export default function Page() {
try {
await axios.delete(
`${envConfig.apiUrl}/programa/${programaSeleccionado}`
`${envConfig.apiUrl}/programa/${programaSeleccionado}`,
{ headers },
);
await cargarProgramas();
@@ -160,13 +169,6 @@ export default function Page() {
>
Nuevo
</button>
<button
className={`button buttonCancel ${styleprograms.button}`}
onClick={handleDelete}
>
Eliminar
</button>
</div>
</section>
)}
@@ -193,6 +195,13 @@ export default function Page() {
>
Cancelar
</button>
<button
className={`button buttonCancel ${styleprograms.button}`}
onClick={handleDelete}
>
Eliminar
</button>
</div>
</section>
)}
+5
View File
@@ -1,5 +1,10 @@
import ShowError from "@/app/Components/Global/ShowError";
import { GetSancionByStudent } from "@/app/lib/getSancionByStudent";
import { Metadata } from "next";
export const metadata: Metadata = {
title: "QuitarSancion",
};
export default async function Page(props: {
searchParams?: Promise<{
+5
View File
@@ -1,5 +1,10 @@
import { Metadata } from 'next';
import ReportesClient from './ReportesClient';
export const metadata: Metadata = {
title: "Reportes",
};
export default async function Page(props: {
searchParams?: Promise<{
key: string;
+2 -1
View File
@@ -1,6 +1,7 @@
import { ReactNode } from "react";
import Logout from "../Components/auth/Logout/Logout";
import BackgroundRotator from "../Components/layout/BackgroundRotator.tsx/BackgroundRotator";
import BackgroundRotator from "../Components/layout/BackgroundRotator/BackgroundRotator";
export default async function PrivateLayout({
children,
}: {
+13 -5
View File
@@ -1,10 +1,12 @@
"use client";
import { useEffect, useState } from "react";
import { envConfig } from "@/app/lib/config";
import axios from "axios";
import Swal from "sweetalert2";
import Cookies from "js-cookie";
import "@/app/globals.css";
import axios from "axios";
import { envConfig } from "@/app/lib/config";
import Swal from "sweetalert2";
export default function Areas() {
const [areas, setAreas] = useState([]);
@@ -14,9 +16,15 @@ export default function Areas() {
"Mantenimiento",
);
const token = Cookies.get("token");
const headers = { Authorization: `Bearer ${token}` };
useEffect(() => {
axios
.get(`${envConfig.apiUrl}/area-ubicacion`)
.get(`${envConfig.apiUrl}/area-ubicacion`,
{ headers }
)
.then((data) => {
setAreas(data.data);
})
@@ -54,7 +62,7 @@ export default function Areas() {
{
id_area_ubicacion: Number(selectedArea),
activo: modo === "Activo",
}
}, { headers }
);
@@ -1,8 +1,9 @@
"use client";
import { envConfig } from "@/app/lib/config";
import axios from "axios";
import { useEffect, useState } from "react";
import axios from "axios";
import Cookies from "js-cookie";
export default function Equipos() {
const [cuenta, setCuenta] = useState("");
@@ -13,7 +14,12 @@ export default function Equipos() {
useEffect(() => {
const fetchEquipos = async () => {
try {
const response = await axios.get(`${envConfig.apiUrl}/equipo`);
const token = Cookies.get("token");
const headers = { Authorization: `Bearer ${token}` };
const response = await axios.get(`${envConfig.apiUrl}/equipo`,
{ headers },
);
setEquipos(response.data);
} catch (error: any) {
setMensaje(
@@ -1,9 +1,10 @@
"use client";
import { useEffect, useState } from "react";
import axios from "axios";
import { envConfig } from "@/app/lib/config";
import axios from "axios";
import Swal from "sweetalert2";
import Cookies from "js-cookie";
interface Mesa {
id_mesa: number;
@@ -14,13 +15,16 @@ export default function MesasDisponibles() {
const [mesas, setMesas] = useState<Mesa[]>();
const [loading, setLoading] = useState(true);
const token = Cookies.get("token");
const headers = { Authorization: `Bearer ${token}` };
useEffect(() => {
obtenerMesas();
}, []);
const obtenerMesas = async () => {
try {
const response = await axios.get(`${envConfig.apiUrl}/mesa`);
const response = await axios.get(`${envConfig.apiUrl}/mesa`,{ headers });
setMesas(response.data);
} catch (error) {
console.error("Error al obtener mesas:", error);
@@ -31,8 +35,11 @@ export default function MesasDisponibles() {
const toggleEquipo = async (id_mesa: number) => {
try {
await axios.patch(
`${envConfig.apiUrl}/mesa/${id_mesa}/activo`
`${envConfig.apiUrl}/mesa/${id_mesa}/activo`,
{},
{ headers },
);
setMesas((prev) =>
+14 -14
View File
@@ -72,22 +72,22 @@ export default function RegisterAlta(props: urlProp) {
await apiClient.post("/student", payload);
setSaved(true);
Swal.fire({
title: "Alumno registrado correctamente!",
icon: "success",
draggable: true,
});
Swal.fire({
title: "Alumno registrado correctamente!",
icon: "success",
draggable: true,
});
} catch (error) {
console.error("Error al guardar alumno:", error);
Swal.fire({
title: "Error al guardar alumno:!",
icon: "error",
draggable: true,
});
Swal.fire({
title: "Error al guardar alumno:!",
icon: "error",
draggable: true,
});
}
};
+18 -12
View File
@@ -6,6 +6,8 @@ import { getEquipoByCount } from "../lib/getEquipoByCount";
import { getMesaByCount } from "../lib/getMesaByCount";
import Swal from "sweetalert2";
import axios from "axios";
import Cookies from "js-cookie";
import { useRouter } from "next/navigation";
type Props = {
inscripcion: any[];
@@ -21,6 +23,8 @@ export default function AsignacionMesas({ idCuenta, inscripcion }: Props) {
const [bitacora, setBitacora] = useState<[] | null>([]);
const [error, setError] = useState<string>();
const router = useRouter();
const fetchByCuenta = async (idCuenta: number) => {
const [result, resultMesa] = await Promise.all([
getEquipoByCount(idCuenta),
@@ -33,19 +37,11 @@ export default function AsignacionMesas({ idCuenta, inscripcion }: Props) {
setBitacora([]);
if (!result?.error) {
setError("Equio")
Swal.fire({
title: "Ya cuentas con un equipo asignado!",
icon: "error",
});
setError("Equipo")
}
if (!resultMesa?.error) {
setError("Mesa")
Swal.fire({
title: "Ya cuentas con mesa asignada!",
icon: "error",
});
}
}
};
@@ -80,10 +76,14 @@ export default function AsignacionMesas({ idCuenta, inscripcion }: Props) {
const fetchMesas = async () => {
try {
const token = Cookies.get("token");
const headers = { Authorization: `Bearer ${token}` };
setLoadingMesas(true);
const response = await axios.get(
`${envConfig.apiUrl}/mesa/activo`
`${envConfig.apiUrl}/mesa/activo`,
{ headers },
);
setMesas(response.data);
@@ -113,6 +113,9 @@ export default function AsignacionMesas({ idCuenta, inscripcion }: Props) {
}
try {
const token = Cookies.get("token");
const headers = { Authorization: `Bearer ${token}` };
const body = {
tiempo_asignado: tiempo,
id_mesa: Number(mesaSeleccionada),
@@ -121,11 +124,12 @@ export default function AsignacionMesas({ idCuenta, inscripcion }: Props) {
await axios.post(
`${envConfig.apiUrl}/bitacora-mesa`,
body
body,
{ headers },
);
setBitacora([]);
router.refresh();
Swal.fire({
title: "Mesa asignada correctamente!",
icon: "success",
@@ -165,6 +169,8 @@ export default function AsignacionMesas({ idCuenta, inscripcion }: Props) {
<option value={30}>30 minutos</option>
<option value={40}>40 minutos</option>
<option value={60}>60 minutos</option>
<option value={90}>90 minutos</option>
<option value={120}>120 minutos</option>
</select>
<label style={{ marginTop: "1rem" }}>Seleccione una mesa</label>
@@ -7,6 +7,7 @@ import { GetSancionByStudent } from "@/app/lib/getSancionByStudent";
import TableSanction from "./TableSanction";
import axios from "axios";
import Swal from "sweetalert2";
import Cookies from "js-cookie";
if (!envConfig.apiUrl) {
console.error("API URL is not defined in envConfig");
@@ -20,16 +21,19 @@ export default function ApplySanction({ idCuenta }: { idCuenta: number }) {
const [loading, setLoading] = useState(false);
const [loadingTable, setLoadingTable] = useState(false);
const token = Cookies.get("token");
const headers = { Authorization: `Bearer ${token}` };
const fetchAlumnoSanciones = async () => {
try {
const res = await GetSancionByStudent(idCuenta);
const res = await GetSancionByStudent(idCuenta);
setAlumno(res.student ?? null);
setAlumnoSanciones(res.alusancion ?? []);
} catch {
} finally {
setLoadingTable(true)
setAlumno(res.student ?? null);
setAlumnoSanciones(res.alusancion ?? []);
setLoadingTable(true)
if (res.error) {
setLoadingTable(false)
}
};
@@ -39,7 +43,7 @@ export default function ApplySanction({ idCuenta }: { idCuenta: number }) {
fetchAlumnoSanciones();
axios
.get(`${envConfig.apiUrl}/sancion`)
.get(`${envConfig.apiUrl}/sancion`, { headers })
.then((res) => setSanciones(res.data))
.catch(() =>
@@ -56,7 +60,7 @@ export default function ApplySanction({ idCuenta }: { idCuenta: number }) {
e.preventDefault();
if (!selectedSancion) {
Swal.fire({
title: "Selecciona una sanción!",
icon: "error",
@@ -71,18 +75,18 @@ export default function ApplySanction({ idCuenta }: { idCuenta: number }) {
await axios.post(`${envConfig.apiUrl}/alumno-sancion/`, {
id_sancion: Number(selectedSancion),
id_cuenta: idCuenta,
});
}, { headers });
await fetchAlumnoSanciones();
setSelectedSancion("");
Swal.fire({
title: "Sanción aplicada correctamente!",
icon: "success",
draggable: true
});
} catch {
Swal.fire({
title: "Error al aplicar la sanción!",
icon: "error",
@@ -2,6 +2,7 @@
import { useEffect, useState } from "react";
import axios from "axios";
import { envConfig } from "@/app/lib/config";
import Cookies from "js-cookie";
interface AlumnoBitacora {
tiempo_entrada: string;
@@ -20,6 +21,9 @@ interface BitacoraAlumnoProps {
export default function BitacoraAlumno({ numAcount, date }: BitacoraAlumnoProps) {
const [alumnos, setAlumnos] = useState<AlumnoBitacora[]>([]);
const token = Cookies.get("token");
const headers = { Authorization: `Bearer ${token}` };
useEffect(() => {
if (!numAcount) return;
if (!date) return;
@@ -27,7 +31,7 @@ export default function BitacoraAlumno({ numAcount, date }: BitacoraAlumnoProps)
axios.post(`${envConfig.apiUrl}/bitacora/equipos-por-dia`, {
numero_cuenta: numAcount,
fecha: date,
})
}, { headers })
.then(res => {
setAlumnos(res.data);
})
@@ -1,11 +1,12 @@
"use client";
import SearchDate from "../SearchDate/SearchDate";
import { useEffect, useState } from "react";
import { envConfig } from "@/app/lib/config";
import SearchDate from "../SearchDate/SearchDate";
import axios from "axios";
import Cookies from "js-cookie";
import "../../(private)/AsignacionEquipo/asignacion.css"
import { envConfig } from "@/app/lib/config";
import axios from "axios";
interface equipos {
hora_entrada: string;
min_utilizados: number;
@@ -20,10 +21,14 @@ export default function BitacoraEquipo({ date }: { date: string | null }) {
const [equipoSeleccionado, setEquipoSeleccionado] = useState<any>(null);
const [equipos, setEquipos] = useState<any[]>([]);
const token = Cookies.get("token");
const headers = { Authorization: `Bearer ${token}` };
useEffect(() => {
const fetchData = async () => {
setLoadingEquipos(true);
const response = await axios.get(`${envConfig.apiUrl}/equipo`);
const response = await axios.get(`${envConfig.apiUrl}/equipo`, { headers },
);
setEquipos(response.data);
setLoadingEquipos(false);
};
@@ -38,7 +43,7 @@ export default function BitacoraEquipo({ date }: { date: string | null }) {
axios.post(`${envConfig.apiUrl}/bitacora/equipos-por-equipo`, {
id_equipo: equipoSeleccionado.id_equipo,
fecha: date,
})
}, { headers })
.then(res => {
setEquipo(res.data);
})
@@ -1,10 +1,12 @@
"use client";
import SearchDate from "../SearchDate/SearchDate";
import { useEffect, useState } from "react";
import { useSearchParams } from "next/navigation";
import axios from "axios";
import { envConfig } from "@/app/lib/config";
import SearchDate from "../SearchDate/SearchDate";
import axios from "axios";
import Cookies from "js-cookie";
interface Tables {
no_mesa: number;
no_cuenta: number;
@@ -18,12 +20,15 @@ export default function BitacoraMesas() {
const searchParams = useSearchParams();
const date = searchParams.get("date");
const token = Cookies.get("token");
const headers = { Authorization: `Bearer ${token}` };
useEffect(() => {
if (!date) return;
axios.post(`${envConfig.apiUrl}/bitacora-mesa/mesas-por-dia`, {
fecha: date,
})
}, { headers })
.then(res => {
setTables(res.data);
})
+105 -53
View File
@@ -1,19 +1,25 @@
"use client";
import { useEffect, useState } from "react";
import { envConfig } from "../lib/config";
import { getEquipoByCount } from "../lib/getEquipoByCount";
import SearchUser from "./Global/SearchUser/searchUser";
import SearchEquipo from "./SearchEquipo";
import axios from "axios";
import Information from "./Global/Information/information";
import Swal from "sweetalert2";
import Cookies from "js-cookie";
async function getEquipoId(idEquipo: number) {
try {
const token = Cookies.get("token");
const headers = { Authorization: `Bearer ${token}` };
const res = await axios.get(
`${envConfig.apiUrl}/bitacora/equipo/${idEquipo}`,
{ headers }
);
return res.data;
} catch (error: any) {
if (axios.isAxiosError(error)) {
@@ -21,7 +27,6 @@ async function getEquipoId(idEquipo: number) {
error: error.response?.data?.message || "Error al consultar equipo",
};
}
return { error: "Error desconocido" };
}
}
@@ -32,20 +37,31 @@ interface Props {
}
export default function CheckBoxEquipo({ numAcount, machine }: Props) {
const [modo, setModo] = useState<"Equipo" | "Cuenta" | null>("Cuenta");
const [bitacora, setBitacora] = useState<any>(null);
const [tiempoRestante, setTiempoRestante] = useState<string>("");
const [minutos, setMinutos] = useState<number>();
const [error, setError] = useState()
const [modo, setModo] = useState<"Equipo" | "Cuenta">("Cuenta");
const [bitacoraCuenta, setBitacoraCuenta] = useState<any>(null);
const [bitacoraEquipo, setBitacoraEquipo] = useState<any>(null);
const [tiempoRestante, setTiempoRestante] = useState("");
const [minutos, setMinutos] = useState<number>(0);
const [errorCuenta, setErrorCuenta] = useState<string | null>(null);
const [errorEquipo, setErrorEquipo] = useState<string | null>(null);
const [loading, setLoading] = useState(false);
const bitacora =
modo === "Cuenta" ? bitacoraCuenta : bitacoraEquipo;
const fetchByCuenta = async (idCuenta: number) => {
const result = await getEquipoByCount(idCuenta);
if (result?.error) {
setError(result.error);
setBitacora(null);
setErrorCuenta(result.error);
setBitacoraCuenta(null);
} else {
setBitacora(result);
setErrorCuenta(null);
setBitacoraCuenta(result);
}
};
@@ -53,28 +69,27 @@ export default function CheckBoxEquipo({ numAcount, machine }: Props) {
const result = await getEquipoId(idEquipo);
if (result?.error) {
setError(result.error);
setBitacora(null);
setErrorEquipo(result.error);
setBitacoraEquipo(null);
} else {
setBitacora(result);
setErrorEquipo(null);
setBitacoraEquipo(result);
}
};
useEffect(() => {
if (!numAcount) return;
const idCuenta = parseInt(numAcount);
if (isNaN(idCuenta)) return;
if (modo !== "Cuenta" || !numAcount) return;
fetchByCuenta(idCuenta);
}, [numAcount]);
const idCuenta = parseInt(numAcount);
if (!isNaN(idCuenta)) fetchByCuenta(idCuenta);
}, [numAcount, modo]);
useEffect(() => {
if (!machine) return;
const idEquipo = parseInt(machine);
if (isNaN(idEquipo)) return;
if (modo !== "Equipo" || !machine) return;
fetchByEquipo(idEquipo);
}, [machine]);
const idEquipo = parseInt(machine);
if (!isNaN(idEquipo)) fetchByEquipo(idEquipo);
}, [machine, modo]);
useEffect(() => {
if (!bitacora) return;
@@ -82,19 +97,32 @@ export default function CheckBoxEquipo({ numAcount, machine }: Props) {
const entrada = new Date(bitacora.tiempo_entrada).getTime();
const asignadoMs = bitacora.tiempo_asignado * 60 * 1000;
const interval = setInterval(() => {
const updateTimer = () => {
const ahora = Date.now();
const restante = entrada + asignadoMs - ahora;
if (restante <= 0) {
setTiempoRestante("agotado");
clearInterval(interval);
} else {
const minutos = Math.floor(restante / 60000);
setMinutos(minutos + 1);
const segundos = Math.floor((restante % 60000) / 1000);
setTiempoRestante(`${minutos} minutos con ${segundos} segundos`);
setMinutos(0);
return false;
}
const minutosRestantes = Math.floor(restante / 60000);
const segundos = Math.floor((restante % 60000) / 1000);
setMinutos(minutosRestantes + 1);
setTiempoRestante(
`${minutosRestantes} minuto(s) con ${segundos} segundo(s)`
);
return true;
};
updateTimer();
const interval = setInterval(() => {
const sigue = updateTimer();
if (!sigue) clearInterval(interval);
}, 1000);
return () => clearInterval(interval);
@@ -102,25 +130,42 @@ export default function CheckBoxEquipo({ numAcount, machine }: Props) {
const handleButton = async (e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault();
if (!bitacora) return;
await axios.patch(
`${envConfig.apiUrl}/bitacora/cancelar/${bitacora.id_bitacora}`,
{ tiempo_asignado: minutos },
);
setLoading(true);
try {
const token = Cookies.get("token");
const headers = { Authorization: `Bearer ${token}` };
Swal.fire({
title: "Tiempo cancelado Correctamente!",
icon: "success",
draggable: true,
});
await axios.patch(
`${envConfig.apiUrl}/bitacora/cancelar/${bitacora.id_bitacora}`,
{ tiempo_asignado: minutos },
{ headers }
);
if (modo === "Cuenta" && numAcount) {
fetchByCuenta(parseInt(numAcount));
}
Swal.fire({
title: "Tiempo cancelado correctamente!",
icon: "success",
});
if (modo === "Equipo" && machine) {
fetchByEquipo(parseInt(machine));
if (modo === "Cuenta" && numAcount) {
fetchByCuenta(parseInt(numAcount));
setBitacoraEquipo(null);
}
if (modo === "Equipo" && machine) {
fetchByEquipo(parseInt(machine));
setBitacoraCuenta(null);
}
} catch (error) {
Swal.fire({
title: "Error al cancelar tiempo",
icon: "error",
});
} finally {
setLoading(false);
}
};
@@ -130,7 +175,6 @@ export default function CheckBoxEquipo({ numAcount, machine }: Props) {
<label className="radio-card">
<input
type="radio"
name="modo"
checked={modo === "Equipo"}
onChange={() => setModo("Equipo")}
/>
@@ -141,7 +185,6 @@ export default function CheckBoxEquipo({ numAcount, machine }: Props) {
<label className="radio-card">
<input
type="radio"
name="modo"
checked={modo === "Cuenta"}
onChange={() => setModo("Cuenta")}
/>
@@ -150,12 +193,21 @@ export default function CheckBoxEquipo({ numAcount, machine }: Props) {
</label>
</div>
{modo === "Cuenta" && <SearchUser value={numAcount ?? null} />}
{modo === "Equipo" && <SearchEquipo value={machine ?? null} />}
{modo === "Cuenta" && (
<>
<SearchUser value={numAcount ?? null} />
<h2>{errorCuenta}</h2>
</>
)}
<h2 style={{ marginTop: "10px" }}>{error}</h2>
{modo === "Equipo" && (
<>
<SearchEquipo value={machine ?? null} />
<h2>{errorEquipo}</h2>
</>
)}
{bitacora && (
{bitacora && tiempoRestante !== "agotado" && (
<>
<Information
NoCuenta={bitacora.alumno_inscrito.alumno.id_cuenta}
@@ -163,11 +215,12 @@ export default function CheckBoxEquipo({ numAcount, machine }: Props) {
Tiempo={tiempoRestante}
Equipo={bitacora.equipo.ubicacion}
/>
<button
className="button buttonSearch"
style={{ marginTop: "1rem" }}
onClick={handleButton}
disabled={minutos ? false : true}
disabled={loading || minutos === 0}
>
Cancelar tiempo
</button>
@@ -175,5 +228,4 @@ export default function CheckBoxEquipo({ numAcount, machine }: Props) {
)}
</>
);
}
//IO
}
+138 -60
View File
@@ -4,49 +4,62 @@ import { useEffect, useState } from "react";
import { getTableByCount } from "../lib/getTableByCount";
import { envConfig } from "../lib/config";
import { getMesaByCount } from "../lib/getMesaByCount";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import SearchUser from "./Global/SearchUser/searchUser";
import Information from "./Global/Information/information";
import SearchMesa from "./SearchMesa";
import axios from "axios";
import Swal from "sweetalert2";
import Cookies from "js-cookie";
interface props {
numAcount: string | null;
table: number | null;
table: string | null;
}
export default function CheckBoxMesa({ numAcount, table }: props) {
const [modo, setModo] = useState<"Mesa" | "Cuenta" | null>("Cuenta");
const [bitacora, setBitacora] = useState<any>(null);
const [bitacoraMesa, setBitacoraMesa] = useState<any>(null);
const [bitacoraCuenta, setBitacoraCuenta] = useState<any>(null);
const [tiempoRestante, setTiempoRestante] = useState<string>("");
const [minutos, setMinutos] = useState<number>();
const [error, setError] = useState()
const [errorMesa, setErrorMesa] = useState<string | null>()
const [errorCount, setErrorCount] = useState<string | null>()
const [loading, setLoading] = useState<boolean>(false)
const bitacora = modo === "Cuenta" ? bitacoraCuenta : bitacoraMesa;
const router = useRouter();
const pathname = usePathname();
const searchParams = useSearchParams();
const fetchByCuenta = async (idCuenta: number) => {
const result = await getMesaByCount(idCuenta);
if (result?.error) {
setError(result.error);
setBitacora(null);
setErrorCount(result.error);
setBitacoraCuenta(null);
} else {
setBitacora(result);
setBitacoraCuenta(result);
setErrorCount(null)
}
};
const fetchByEquipo = async (idEquipo: number) => {
const fetchByMesa = async (idEquipo: number) => {
const result = await getTableByCount(idEquipo);
if (result?.error) {
setError(result.error);
setBitacora(null);
setErrorMesa(result.error);
setBitacoraMesa(null);
} else {
setBitacora(result);
setBitacoraMesa(result);
setErrorMesa(null)
}
};
useEffect(() => {
if (!numAcount) return;
if (modo !== "Cuenta" || !numAcount) return;
const idCuenta = parseInt(numAcount);
if (isNaN(idCuenta)) return;
@@ -54,11 +67,11 @@ export default function CheckBoxMesa({ numAcount, table }: props) {
}, [numAcount]);
useEffect(() => {
if (!table) return;
const idEquipo = table;
if (modo !== "Mesa" || !table) return;
const idEquipo = parseInt(table);
if (isNaN(idEquipo)) return;
fetchByEquipo(idEquipo);
fetchByMesa(idEquipo);
}, [table]);
useEffect(() => {
@@ -67,19 +80,32 @@ export default function CheckBoxMesa({ numAcount, table }: props) {
const entrada = new Date(bitacora.tiempo_entrada).getTime();
const asignadoMs = bitacora.tiempo_asignado * 60 * 1000;
const interval = setInterval(() => {
const updateTimer = () => {
const ahora = Date.now();
const restante = entrada + asignadoMs - ahora;
if (restante <= 0) {
setTiempoRestante("agotado");
clearInterval(interval);
} else {
const minutos = Math.floor(restante / 60000);
setMinutos(minutos + 1);
const segundos = Math.floor((restante % 60000) / 1000);
setTiempoRestante(`${minutos} minutos con ${segundos} segundos`);
setMinutos(0);
return false;
}
const minutosRestantes = Math.floor(restante / 60000);
const segundos = Math.floor((restante % 60000) / 1000);
setMinutos(minutosRestantes + 1);
setTiempoRestante(
`${minutosRestantes} minuto(s) con ${segundos} segundo(s)`
);
return true;
};
updateTimer();
const interval = setInterval(() => {
const sigue = updateTimer();
if (!sigue) clearInterval(interval);
}, 1000);
return () => clearInterval(interval);
@@ -87,29 +113,52 @@ export default function CheckBoxMesa({ numAcount, table }: props) {
const handleButton = async (e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault();
setLoading(false)
setLoading(true);
await axios.patch(
`${envConfig.apiUrl}/bitacora-mesa/cancelar/${bitacora.id_bitacora_mesa}`,
{ tiempo_asignado: minutos },
);
const token = Cookies.get("token");
const headers = { Authorization: `Bearer ${token}` };
Swal.fire({
title: "Tiempo cancelado correctamente!",
icon: "success",
draggable: true,
});
try {
if (!bitacora) return;
if (modo === "Cuenta" && numAcount) {
fetchByCuenta(parseInt(numAcount));
await axios.patch(
`${envConfig.apiUrl}/bitacora-mesa/cancelar/${bitacora.id_bitacora_mesa}`,
{ tiempo_asignado: minutos ?? 0 },
{ headers }
);
Swal.fire({
title: "Tiempo cancelado correctamente!",
icon: "success",
});
const params = new URLSearchParams(searchParams.toString());
if (modo === "Cuenta" && numAcount) {
fetchByCuenta(parseInt(numAcount));
params.delete("numAcount");
router.push(`${pathname}?${params.toString()}`);
}
if (modo === "Mesa" && table) {
fetchByMesa(parseInt(table));
params.delete("table");
router.push(`${pathname}?${params.toString()}`);
}
router.refresh();
setBitacoraMesa(null);
setBitacoraCuenta(null);
} catch (error) {
Swal.fire({
title: "Error al cancelar tiempo",
icon: "error",
});
} finally {
setLoading(false);
}
if (modo === "Mesa" && table) {
fetchByEquipo(table);
}
setLoading(true)
};
return (
<>
<div className="radio-grid">
@@ -136,29 +185,58 @@ export default function CheckBoxMesa({ numAcount, table }: props) {
</label>
</div>
{modo === "Cuenta" && <SearchUser value={numAcount ?? null} />}
{modo === "Mesa" && <SearchMesa />}
<h2 style={{ marginTop: "10px" }}>{error}</h2>
{bitacora && (
{modo === "Cuenta" &&
<>
<Information
NoCuenta={bitacora.alumno_inscrito.alumno.id_cuenta}
Nombre={bitacora.alumno_inscrito.alumno.nombre}
Tiempo={tiempoRestante}
Mesa={bitacora.mesa.id_mesa}
/>
<button
className="button buttonSearch"
style={{ marginTop: "1rem" }}
onClick={handleButton}
disabled={loading || minutos ? false : true}
>
Cancelar tiempo
</button>
<SearchUser value={numAcount ?? null} />
<h2 style={{ marginTop: "10px" }}>{errorCount}</h2>
{bitacoraCuenta && tiempoRestante !== "agotado" && (
<>
<Information
NoCuenta={bitacoraCuenta.alumno_inscrito.alumno.id_cuenta}
Nombre={bitacoraCuenta.alumno_inscrito.alumno.nombre}
Tiempo={tiempoRestante}
Mesa={bitacoraCuenta.mesa.id_mesa}
/>
<button
className="button buttonSearch"
style={{ marginTop: "1rem" }}
onClick={handleButton}
disabled={loading || !minutos}
>
Cancelar tiempo
</button>
</>
)}
</>
)}
}
{modo === "Mesa" &&
<>
<SearchMesa value={table ?? null}/>
<h2 style={{ marginTop: "10px" }}>{errorMesa}</h2>
{bitacoraMesa && tiempoRestante !== "agotado" && (
<>
<Information
NoCuenta={bitacoraMesa.alumno_inscrito.alumno.id_cuenta}
Nombre={bitacoraMesa.alumno_inscrito.alumno.nombre}
Tiempo={tiempoRestante}
Mesa={bitacoraMesa.mesa.id_mesa}
/>
<button
className="button buttonSearch"
style={{ marginTop: "1rem" }}
onClick={handleButton}
disabled={loading || !minutos}
>
Cancelar tiempo
</button>
</>
)}
</>
}
</>
);
}
+1 -1
View File
@@ -12,7 +12,7 @@
padding: 5px 5px;
cursor: pointer;
border-radius: 10px 10px 0 0;
font-size: 14px;
font-size: 1.4rem;
font-weight: 600;
transition: background 0.2s ease;
min-width: 50px;
+25 -15
View File
@@ -1,8 +1,9 @@
"use client";
import axios from "axios";
import { envConfig } from "@/app/lib/config";
import { useState } from "react";
import Swal from "sweetalert2";
import axios from "axios";
import Cookies from "js-cookie";
interface Data {
nombre_equipo: string;
@@ -40,15 +41,21 @@ export default function Equipos() {
const [isEditing, setIsEditing] = useState(false);
const [isCreating, setIsCreating] = useState(false);
const token = Cookies.get("token");
const headers = { Authorization: `Bearer ${token}` };
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
try {
const [equipoRes, plataformaRes, areaRes] = await Promise.all([
axios.get(`${envConfig.apiUrl}/equipo/${id}`),
axios.get(`${envConfig.apiUrl}/alumno-inscrito/plataforma`),
axios.get(`${envConfig.apiUrl}/area-ubicacion`),
axios.get(`${envConfig.apiUrl}/equipo/${id}`, { headers },
),
axios.get(`${envConfig.apiUrl}/alumno-inscrito/plataforma`, { headers },
),
axios.get(`${envConfig.apiUrl}/area-ubicacion`, { headers },
),
]);
const equipo = equipoRes.data as Data;
@@ -84,7 +91,9 @@ export default function Equipos() {
id_plataforma: idPlataforma,
id_area_ubicacion: idArea,
ip: data.ip,
});
},
{ headers }
);
// Actualiza el estado local
setData({
@@ -116,8 +125,8 @@ export default function Equipos() {
const handleNuevo = async () => {
try {
const [plataformaRes, areaRes] = await Promise.all([
axios.get(`${envConfig.apiUrl}/alumno-inscrito/plataforma`),
axios.get(`${envConfig.apiUrl}/area-ubicacion`),
axios.get(`${envConfig.apiUrl}/alumno-inscrito/plataforma`, { headers }),
axios.get(`${envConfig.apiUrl}/area-ubicacion`, { headers }),
]);
setPlataforma(plataformaRes.data);
@@ -156,7 +165,7 @@ export default function Equipos() {
id_plataforma: idPlataforma,
id_area_ubicacion: idArea,
ip: "0.0.0.0",
});
}, { headers });
Swal.fire({
@@ -277,13 +286,14 @@ export default function Equipos() {
</div>
</div>
)}
<button
type="button"
className="button buttonCharge"
onClick={handleNuevo}
>
Nuevo
</button>
<button
type="button"
className="button buttonCharge"
onClick={handleNuevo}
>
Nuevo
</button>
</form>
);
}
//IO
+85 -8
View File
@@ -3,18 +3,48 @@
import { envConfig } from "@/app/lib/config";
import { useEffect, useState } from "react";
import "./tableEquipos.css";
import axios from "axios";
import Cookies from "js-cookie";
import "./tableEquipos.css";
type AreaUbicacion = {
id_area_ubicacion: number;
area: string;
};
type Equipo = {
id_equipo: number;
nombre_equipo: string;
ubicacion: string;
plataforma: {
nombre: string
};
areaUbicacion: {area:string};
ocupado: boolean;
activo: {
data: number[]
}
};
export default function TableEquipos() {
const [equipos, setEquipos] = useState<any[]>([]);
const [machines, setMachines] = useState<Equipo[]>([]);
const [areas, setAreas] = useState<AreaUbicacion[]>([]);
const [selectedArea, setSelectedArea] = useState("Todo");
const [loading, setLoading] = useState(true);
const token = Cookies.get("token");
const headers = { Authorization: `Bearer ${token}` };
useEffect(() => {
const fetchEquipos = async () => {
try {
const response = await axios.get(`${envConfig.apiUrl}/equipo`);
setEquipos(response.data);
const response = await axios.get(`${envConfig.apiUrl}/equipo`,
{ headers },
);
setMachines(response.data);
} catch (error: any) {
console.error("ERROR API:", error.response?.data || error.message);
} finally {
@@ -23,15 +53,33 @@ export default function TableEquipos() {
};
fetchEquipos();
fetchAreas();
}, []);
const fetchAreas = async () => {
try {
const res = await axios.get(
`${process.env.NEXT_PUBLIC_API_URL}/area-ubicacion`,
{ headers },
);
setAreas(res.data);
} catch (error) {
console.error("Error cargando áreas:", error);
}
};
const toggleEquipo = async (id_equipo: number) => {
try {
await axios.patch(
`${envConfig.apiUrl}/equipo/${id_equipo}/activo`
`${envConfig.apiUrl}/equipo/${id_equipo}/activo`,
{},
{ headers },
);
setEquipos((prev) =>
setMachines((prev) =>
prev.map((e) =>
e.id_equipo === id_equipo
? {
@@ -55,6 +103,14 @@ export default function TableEquipos() {
return <p>Cargando equipos...</p>;
}
const filteredMachines =
selectedArea === "Todo"
? machines
: machines.filter(
(machine) => machine.areaUbicacion.area === selectedArea,
);
return (
<div
style={{
@@ -72,9 +128,29 @@ export default function TableEquipos() {
<th>Área</th>
<th>Activo</th>
</tr>
<tr style={{ position: "relative", zIndex: "0" }}>
<th />
<th />
<th />
<th>
<select
style={{ minWidth: "50px" }}
value={selectedArea}
onChange={(e) => setSelectedArea(e.target.value)}
>
<option value="Todo">Todo</option>
{areas.map((area) => (
<option key={area.id_area_ubicacion} value={area.area}>
{area.area}
</option>
))}
</select>
</th>
<th />
</tr>
</thead>
<tbody>
{equipos.map((eq) => {
{filteredMachines.map((eq) => {
const isActivo = eq.activo?.data?.[0] === 1;
return (
@@ -84,7 +160,7 @@ export default function TableEquipos() {
<td className={eq.plataforma?.nombre}>
{eq.plataforma?.nombre}
</td>
<td>{eq.areaUbicacion?.nombre || eq.id_area_ubicacion}</td>
<td>{eq.areaUbicacion.area}</td>
<td
style={{ display: "flex", alignItems: "center", gap: "5px" }}
@@ -105,3 +181,4 @@ export default function TableEquipos() {
</div>
);
}
//IO
@@ -1,8 +1,9 @@
"use client";
import { useEffect, useState } from "react";
import axios from "axios";
import { envConfig } from "@/app/lib/config";
import axios from "axios";
import Cookies from "js-cookie";
import "../../(private)/AsignacionEquipo/asignacion.css";
@@ -39,14 +40,17 @@ const EnviarMensaje = ({ titulo }: EnviarMensajeProps) => {
const [customMsg, setCustomMsg] = useState("");
const token = Cookies.get("token");
const headers = { Authorization: `Bearer ${token}` };
useEffect(() => {
const fetchData = async () => {
try {
setLoadingMensajes(true);
const [equiposRes, mensajesRes] = await Promise.all([
axios.get(`${envConfig.apiUrl}/equipo/busy`),
axios.get(`${envConfig.apiUrl}/mensaje`)
axios.get(`${envConfig.apiUrl}/equipo/busy`, { headers }),
axios.get(`${envConfig.apiUrl}/mensaje`, { headers })
]);
setEquipos(equiposRes.data);
@@ -1,8 +1,9 @@
"use client";
import { useEffect, useState } from "react";
import axios from "axios";
import { envConfig } from "@/app/lib/config";
import axios from "axios";
import Cookies from "js-cookie";
interface Area {
id_area_ubicacion: number;
@@ -20,10 +21,13 @@ const EnviarMensajeSala = ({ titulo }: EnviarMensajeSalaProps) => {
const [mensaje, setMensaje] = useState("");
const [customMsg, setCustomMsg] = useState("");
const token = Cookies.get("token");
const headers = { Authorization: `Bearer ${token}` };
useEffect(() => {
const fetchSalas = async () => {
try {
const response = await axios.get(`${envConfig.apiUrl}/area-ubicacion`);
const response = await axios.get(`${envConfig.apiUrl}/area-ubicacion`, { headers });
setSalas(response.data);
} catch (error) {
console.error("Error cargando salas:", error);
@@ -45,7 +49,7 @@ const EnviarMensajeSala = ({ titulo }: EnviarMensajeSalaProps) => {
return (
<form className="containerForm" onSubmit={handleSubmit}>
<label className="label">{titulo}</label>
<div className="groupInput">
<select
@@ -62,7 +66,7 @@ const EnviarMensajeSala = ({ titulo }: EnviarMensajeSalaProps) => {
</select>
</div>
<label className="label">Seleccione el mensaje</label>
<div className="groupInput">
<select value={mensaje} onChange={(e) => setMensaje(e.target.value)}>
@@ -15,7 +15,7 @@ export default function Information(props: InformationProps) {
{entries.map(([key, value]) => (
<li key={key} className="informationItem">
<span className="informationKey">{key}</span>
<span className="informationValue">{value}</span>
<span className={`informationValue ${key}`}>{value}</span>
</li>
))}
</ul>
@@ -8,7 +8,7 @@ interface urlProp {
}
function SearchUser(props: urlProp) {
const [numAcount, setnumAcount] = useState("");
const [numAcount, setnumAcount] = useState<string>("");
const router = useRouter();
const pathname = usePathname();
const searchParams = useSearchParams();
@@ -17,6 +17,10 @@ function SearchUser(props: urlProp) {
if (props.value) {
setnumAcount(props.value);
}
if(props.value===null){
setnumAcount("")
}
}, [props.value]);
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
@@ -2,6 +2,7 @@
import { useEffect, useState } from "react";
import axios from "axios";
import Cookies from "js-cookie";
interface SearchUserProps {
value?: string | null;
@@ -19,7 +20,9 @@ export default function SearchUserTable({ value }: SearchUserProps) {
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
// Si el prop cambia, actualizar el input
const token = Cookies.get("token");
const headers = { Authorization: `Bearer ${token}` };
useEffect(() => {
if (value) setNumAcount(value);
}, [value]);
@@ -37,8 +40,8 @@ export default function SearchUserTable({ value }: SearchUserProps) {
setAlumno(null);
try {
// Llamada a la API con Axios
const { data } = await axios.get<Alumno>(`/api/alumnos/${numAcount}`);
const { data } = await axios.get<Alumno>(`/api/alumnos/${numAcount}`, { headers },
);
setAlumno(data);
} catch (err: any) {
setAlumno(null);
+10 -2
View File
@@ -7,7 +7,7 @@ import { useState, ReactNode } from "react";
interface ToggleOption {
key: string;
label: string;
content: ReactNode;
content: ReactNode | (() => ReactNode);
}
interface ToggleProps {
@@ -46,7 +46,15 @@ export default function Toggle({ options, defaultView }: ToggleProps) {
</div>
<div className="padding toggleContent">
{options.find((opt) => opt.key === view)?.content}
{(() => {
const active = options.find((opt) => opt.key === view)?.content;
if (typeof active === "function") {
return active();
}
return active;
})()}
</div>
</section>
);
+14 -1
View File
@@ -1,5 +1,5 @@
.tableContainer {
margin-top: 1rem;
margin-top: 2rem;
width: 100%;
max-width: 450px;
overflow-x: hidden;
@@ -43,4 +43,17 @@
background-repeat: no-repeat;
margin-right: 6px;
vertical-align: middle;
}
@media(max-height:800px) {
.tableContainer {
margin-top: 1.5rem;
max-width: 320px;
}
}
@media(max-width:800px) {
.tableContainer {
margin-top: 0px;
}
}
+8 -8
View File
@@ -18,10 +18,11 @@ interface ImpressionsProps {
function Impressions({ costs, numAcount, id_servicio }: ImpressionsProps) {
const [pages, setPages] = useState("");
const [cost, setCost] = useState("");
const [cost, setCost] = useState(String(costs[0].value));
const total = Number(cost) * Number(pages);
const router = useRouter();
const handleLogout = () => {
Cookies.remove("token");
Cookies.remove("session");
@@ -29,7 +30,7 @@ function Impressions({ costs, numAcount, id_servicio }: ImpressionsProps) {
};
const handlePayment = async () => {
if (!numAcount) {
if (numAcount == null) {
Swal.fire({
title: "busca de nuevo al estudiante!",
@@ -62,7 +63,7 @@ function Impressions({ costs, numAcount, id_servicio }: ImpressionsProps) {
const result = await PostImpressions({
id_cuenta: numAcount,
numero_hojas: parseInt(pages),
monto: parseInt(cost) * parseInt(pages),
monto: total,
id_servicio,
});
@@ -80,7 +81,7 @@ function Impressions({ costs, numAcount, id_servicio }: ImpressionsProps) {
}
setPages("");
setCost("");
setCost(String(costs[0].value));
Swal.fire({
title: "Impresion cobrada correctamente!",
@@ -128,14 +129,13 @@ function Impressions({ costs, numAcount, id_servicio }: ImpressionsProps) {
</div>
<div
className="groupInput"
style={{ height: "35px", flexWrap: "nowrap" }}
className="groupInput total"
>
<label className="label">Total:</label>
<label
style={{ width: "100%", minWidth: "200px", maxWidth: "500px" }}
>
{pages && cost && `$${parseInt(cost) * parseInt(pages)}.00`}
{pages && cost && `$${total}.00`}
</label>
</div>
@@ -3,6 +3,7 @@ import { envConfig } from "@/app/lib/config";
import axios from "axios";
import { useEffect, useState } from "react";
import Swal from "sweetalert2";
import Cookies from "js-cookie";
interface Programa {
id_programa: number;
@@ -19,11 +20,14 @@ export default function ProgramSelector({
const [programas, setProgramas] = useState<Programa[]>([]);
const [checkboxes, setCheckboxes] = useState<Record<number, boolean>>({});
const token = Cookies.get("token");
const headers = { Authorization: `Bearer ${token}` };
useEffect(() => {
const fetchData = async () => {
const [programasRes] = await Promise.all([
axios.get(`${envConfig.apiUrl}/programa`),
]);
axios.get(`${envConfig.apiUrl}/programa`, { headers },
)]);
setProgramas(programasRes.data);
@@ -58,9 +62,10 @@ export default function ProgramSelector({
{
programas: programasSeleccionados,
},
{ headers },
);
Swal.fire({
title: "Programas actualizados en la máquina!",
icon: "success",
@@ -70,12 +75,15 @@ export default function ProgramSelector({
}
if (id) {
await axios.patch(`${envConfig.apiUrl}/programa-equipo/sala`, {
sala: id,
programas: programasSeleccionados,
});
await axios.patch(`${envConfig.apiUrl}/programa-equipo/sala`,
{
sala: id,
programas: programasSeleccionados,
},
{ headers },
);
Swal.fire({
title: "Programas actualizados en la sala",
icon: "success",
@@ -90,7 +98,7 @@ export default function ProgramSelector({
draggable: true
});
} catch (error) {
Swal.fire({
title: "Error al guardar cambios!",
@@ -116,12 +124,15 @@ export default function ProgramSelector({
if (ubicacion && ubicacion !== "0") {
res = await axios.get(
`${envConfig.apiUrl}/programa-equipo/${ubicacion}`,
{ headers },
);
}
if (id) {
res = await axios.get(
`${envConfig.apiUrl}/area-ubicacion/programs/${id}`,
{ headers },
);
}
@@ -131,14 +142,14 @@ export default function ProgramSelector({
} catch (error: any) {
if (axios.isAxiosError(error)) {
if (error.response?.status === 404) {
Swal.fire({
title: "Sin programas asignados!",
icon: "error",
draggable: true
});
} else {
Swal.fire({
title: "Error al cargar programas!",
icon: "error",
@@ -147,7 +158,7 @@ export default function ProgramSelector({
}
} else {
Swal.fire({
title: "Error inesperado!",
icon: "error",
@@ -1,8 +1,10 @@
"use client";
import { envConfig } from "@/app/lib/config";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { useEffect, useState } from "react";
import axios from "axios";
import Cookies from "js-cookie";
import "../../(private)/AsignacionEquipo/asignacion.css";
@@ -33,10 +35,15 @@ export default function SelectorEquipo({ onSearch }: Props) {
const [loadingEquipos, setLoadingEquipos] = useState(false);
const [open, setOpen] = useState(false);
const token = Cookies.get("token");
const headers = { Authorization: `Bearer ${token}` };
useEffect(() => {
const fetchData = async () => {
setLoadingEquipos(true);
const response = await axios.get(`${envConfig.apiUrl}/equipo`);
const response = await axios.get(`${envConfig.apiUrl}/equipo`, { headers },
);
setEquipos(response.data);
setLoadingEquipos(false);
};
@@ -85,7 +92,7 @@ export default function SelectorEquipo({ onSearch }: Props) {
</div>
{open && (
<div className="options" style={{ bottom: "auto"}}>
<div className="options" style={{ bottom: "auto" }}>
{equipos.length === 0 && (
<div className="option disabled">
No hay equipos disponibles
@@ -3,6 +3,7 @@ import { envConfig } from "@/app/lib/config";
import { useEffect, useState } from "react";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import axios from "axios";
import Cookies from "js-cookie";
interface Area {
id_area_ubicacion: number;
@@ -45,8 +46,13 @@ export default function SelectorSala({ onSearch }: Props) {
};
useEffect(() => {
const token = Cookies.get("token");
const headers = { Authorization: `Bearer ${token}` };
const fetchData = async () => {
const response = await axios.get(`${envConfig.apiUrl}/area-ubicacion`);
const response = await axios.get(`${envConfig.apiUrl}/area-ubicacion`, { headers },
);
setSala(response.data);
};
+10 -4
View File
@@ -2,10 +2,11 @@
import { envConfig } from "@/app/lib/config";
import { useEffect, useState } from "react";
import TableSanction from "../BitacoraSanciones/TableSanction";
import { Alumno, AlumnoSancion } from "@/app/types/sanction";
import axios from "axios";
import { GetSancionByStudent } from "@/app/lib/getSancionByStudent";
import { Alumno, AlumnoSancion } from "@/app/types/sanction";
import TableSanction from "../BitacoraSanciones/TableSanction";
import axios from "axios";
import Cookies from "js-cookie";
function QuitarSancion({ id_cuenta }: { id_cuenta: number }) {
const [alumno, setAlumno] = useState<Alumno>();
@@ -32,8 +33,12 @@ function QuitarSancion({ id_cuenta }: { id_cuenta: number }) {
const handleButton = async (e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault();
const token = Cookies.get("token");
const headers = { Authorization: `Bearer ${token}` };
setLoading(true)
await axios.delete(`${envConfig.apiUrl}/alumno-sancion/${id_cuenta}`)
await axios.delete(`${envConfig.apiUrl}/alumno-sancion/${id_cuenta}`, { headers })
setAlumnoSanciones([])
setLoading(false)
}
@@ -56,3 +61,4 @@ function QuitarSancion({ id_cuenta }: { id_cuenta: number }) {
}
export default QuitarSancion;
//IO
+22 -7
View File
@@ -1,14 +1,14 @@
"use client";
import { useState } from "react";
import { useRouter } from "next/navigation";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { envConfig } from "@/app/lib/config";
import Selection from "../Selection/Selection";
import Cookies from "js-cookie";
import axios from "axios";
import Swal from "sweetalert2";
import "./Receipt.css";
interface ReceiptsProps {
@@ -32,6 +32,8 @@ export default function Inscripcion({
>(null);
const router = useRouter();
const pathname = usePathname();
const searchParams = useSearchParams();
const [folio, setFolio] = useState("");
const [amount, setAmount] = useState("");
@@ -45,12 +47,17 @@ export default function Inscripcion({
const month = day.getMonth();
const today = day.getDate();
const minFecha = new Date(year, month, 1).toISOString().split("T")[0];
let minMount = month
if(!lock){
minMount = month-1
}
const minFecha = new Date(year, minMount, 1).toISOString().split("T")[0];
const maxFecha = new Date(year, month, today).toISOString().split("T")[0];
//restrict this month//
const handleSaveReceipt = async () => {
if (!numAcount) {
if (numAcount == null) {
Swal.fire({
title: "busca de nuevo al estudiante!",
@@ -128,7 +135,10 @@ export default function Inscripcion({
setAmount("");
setDate(todayISO);
router.refresh();
const params = new URLSearchParams(searchParams.toString());
params.delete("numAcount");
router.push(`${pathname}?${params.toString()}`);
} catch (error: any) {
const msg =
error.response?.data?.message ||
@@ -143,7 +153,7 @@ export default function Inscripcion({
};
const handleInscripcionSinPago = async () => {
if (!numAcount) {
if (numAcount == null) {
Swal.fire({
title: "busca de nuevo al estudiante!",
@@ -166,13 +176,18 @@ export default function Inscripcion({
const id_plataforma = PLATAFORMA_MAP[plataformaSeleccionada];
try {
const token = Cookies.get("token");
const headers = { Authorization: `Bearer ${token}` };
await axios.post(
`${envConfig.apiUrl}/alumno-inscrito`,
{
id_cuenta: numAcount,
id_plataforma,
realizo_pago: false,
}
},
{ headers },
);
Swal.fire({
+11 -5
View File
@@ -23,21 +23,21 @@
background-color: #cfcfcf;
}
.buttonLock{
.buttonLock {
padding: 0.8rem;
position: absolute;
right: 0;
right: 100px;
background-color: #d32f2f;
}
.buttonOpenLock{
.buttonOpenLock {
padding: 0.8rem;
position: absolute;
right: 0;
right: 100px;
background-color: #8cd32f;
}
.buttonOpenLock:hover{
.buttonOpenLock:hover {
background-color: #78b32c;
}
@@ -61,4 +61,10 @@
filter: invert(1);
background-size: contain;
background-repeat: no-repeat;
}
@media(max-height:800px) {
.buttonLock {
padding: 0.5rem;
}
}
+7 -2
View File
@@ -26,12 +26,17 @@ export default function Receipt({ numAcount }: ReceiptsProps) {
const month = day.getMonth();
const today = day.getDate();
const minFecha = new Date(year, month, 1).toISOString().split("T")[0];
let minMount = month
if(!lock){
minMount = month-1
}
const minFecha = new Date(year, minMount, 1).toISOString().split("T")[0];
const maxFecha = new Date(year, month, today).toISOString().split("T")[0];
//restrict this month//
const handleSaveReceipt = async () => {
if (!numAcount) {
if (numAcount == null) {
Swal.fire({
title: "busca de nuevo al estudiante!",
+6 -1
View File
@@ -3,6 +3,7 @@
import { useEffect, useState } from "react";
import axios from "axios";
import DownloadReporteXLSX from "../Dowload/Reporte";
import Cookies from "js-cookie";
interface Recibo {
id_recibo: number;
@@ -38,9 +39,13 @@ export default function PorRecibos({ desde, hasta }: Props) {
const fetchRecibos = async () => {
setLoading(true);
try {
const token = Cookies.get("token");
const headers = { Authorization: `Bearer ${token}` };
const res = await axios.post(
`${process.env.NEXT_PUBLIC_API_URL}/recibo/rango`,
{ desde, hasta }
{ desde, hasta },
{ headers },
);
setRecibos(res.data);
+6 -1
View File
@@ -2,6 +2,7 @@
import { useEffect, useState } from "react";
import axios from "axios";
import Cookies from "js-cookie";
interface ServicioReporte {
id_servicio: number;
@@ -24,9 +25,13 @@ export default function PorServicio({ desde, hasta }: Props) {
const fetchServicios = async () => {
setLoading(true);
try {
const token = Cookies.get("token");
const headers = { Authorization: `Bearer ${token}` };
const res = await axios.post(
`${process.env.NEXT_PUBLIC_API_URL}/detalle-servicio/rango`,
{ desde, hasta }
{ desde, hasta },
{ headers },
);
setServicios(res.data);
+16 -3
View File
@@ -1,15 +1,28 @@
"use client";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { useState } from "react";
import { useEffect, useState } from "react";
interface urlProp {
value: string | null;
}
export default function SearchMesa() {
export default function SearchMesa(props: urlProp) {
const [inputValue, setInputValue] = useState("");
const router = useRouter();
const pathname = usePathname();
const searchParams = useSearchParams();
useEffect(() => {
if (props.value) {
setInputValue(props.value);
}
if(props.value===null){
setInputValue("")
}
}, [props.value]);
const buscar = (e: React.FormEvent) => {
e.preventDefault();
const params = new URLSearchParams(searchParams.toString());
@@ -26,7 +39,7 @@ export default function SearchMesa() {
<div className="groupInput">
<input
type="number"
type="text"
placeholder="Coloca el numero de mesa"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
+8 -2
View File
@@ -1,7 +1,8 @@
"use client";
import axios from "axios";
import { useEffect, useState } from "react";
import { envConfig } from "../lib/config";
import axios from "axios";
import Cookies from "js-cookie";
if (!envConfig.apiUrl) {
console.error("API URL is not defined in envConfig");
@@ -15,9 +16,14 @@ export default function SelectAreas(props: proms) {
const [areas, setAreas] = useState([]);
const [selectedArea, setSelectedArea] = useState("");
const token = Cookies.get("token");
const headers = { Authorization: `Bearer ${token}` };
useEffect(() => {
axios
.get(`${envConfig.apiUrl}/area-ubicacion`)
.get(`${envConfig.apiUrl}/area-ubicacion`, { headers }
)
.then((data) => {
setAreas(data.data);
})
+39
View File
@@ -15,6 +15,10 @@
}
.buttonSelection {
display: flex;
align-items: center;
justify-content: center;
position: relative;
width: 50px;
height: 50px;
border-radius: 100%;
@@ -24,6 +28,13 @@
padding: 5px;
}
.imageSelection {
width: 30px;
height: 30px;
position: relative;
object-fit: contain;
}
.buttonSelection:hover {
transform: scale(1.1);
background-color: #d0e1ff;
@@ -41,3 +52,31 @@
color: #333;
text-align: center;
}
@media(max-height:550px) {
.buttonLabel {
margin-top: 2px;
font-size: 1rem;
}
}
@media(max-height:550px) {
.selection {
margin-bottom: 0rem;
gap: 2rem;
}
.buttonSelection {
width: 40px;
height: 40px;
padding: 0px;
}
.imageSelection {
width: 20px;
height: 20px;
position: relative;
object-fit: contain;
}
}
+12 -11
View File
@@ -1,6 +1,7 @@
"use client";
import { useState } from "react";
import Image from "next/image";
import "./Selection.css";
export default function Selection({
@@ -24,11 +25,11 @@ export default function Selection({
},
{
name: "MACINTOSH",
img: "apple.png",
img: "/apple.png",
},
{
name: "PROFESORES",
img: "teacher.png",
img: "/teacher.png",
},
];
@@ -45,16 +46,16 @@ export default function Selection({
onClick={() => handleSelect(option.name)}
>
<button
className={`buttonSelection ${
selected === option.name ? "active" : ""
}`}
className={`buttonSelection ${selected === option.name ? "active" : ""
}`}
>
<img
src={option.img}
alt={option.name.toLowerCase()}
height={30}
width={30}
/>
<div className="imageSelection">
<Image
src={option.img}
alt={option.name.toLowerCase()}
fill
/>
</div>
</button>
<span className="buttonLabel">{option.name}</span>
</div>
+12 -11
View File
@@ -2,6 +2,7 @@
import { useState } from "react";
import "./Selection.css";
import Image from "next/image";
export default function SelectionCo({
plataformasInscritas = [],
@@ -19,11 +20,11 @@ export default function SelectionCo({
},
{
name: "MACINTOSH",
img: "apple.png",
img: "/apple.png",
},
{
name: "PROFESORES",
img: "teacher.png",
img: "/teacher.png",
},
];
@@ -46,16 +47,16 @@ export default function SelectionCo({
onClick={() => handleSelect(option.name)}
>
<button
className={`buttonSelection ${
selected === option.name ? "active" : ""
}`}
className={`buttonSelection ${selected === option.name ? "active" : ""
}`}
>
<img
src={option.img}
alt={option.name.toLowerCase()}
height={30}
width={30}
/>
<div className="imageSelection">
<Image
src={option.img}
alt={option.name.toLowerCase()}
fill
/>
</div>
</button>
<span className="buttonLabel">{option.name}</span>
</div>
+15 -6
View File
@@ -10,7 +10,7 @@
background-color: #d12020;
}
.session{
.session {
position: absolute;
top: 10px;
right: 10px;
@@ -19,11 +19,19 @@
gap: 2rem;
}
.userName{
.userName {
background-color: white;
border-radius: 6px;
padding: 6px 12px;
z-index: 1;
outline: 1px solid #cfcfcf;
}
@media(max-height: 800px) {
.session {
top: 5px;
right: 5px;
}
}
@media (max-width: 800px) {
@@ -57,16 +65,17 @@
transform: translate(0, -50%);
}
.userName{
.userName {
position: absolute;
top: 0px;
right: 50px;
}
}
@media(max-width:450px){
.userName{
@media(max-width:450px) {
.userName {
position: absolute;
top: 50px;
right: 0px;
}
}
}
@@ -24,7 +24,7 @@
transition:
background-color 0.3s ease,
border 0.3s ease;
font-size: 1.5rem;
font-size: 1.4rem;
}
.barNavigation li:hover {
@@ -107,12 +107,12 @@
align-items: center;
justify-content: center;
color: #545454;
font-size: 1.5rem;
font-size: 1.4rem;
padding: 1rem;
}
.subMenu:hover > span,
.subMenu > a:hover > span {
.subMenu:hover>span,
.subMenu>a:hover>span {
color: black;
}
@@ -129,7 +129,7 @@
color: white;
width: 100%;
height: 100%;
font-size: 1.5rem;
font-size: 1.4rem;
}
thead,
@@ -137,6 +137,12 @@ tbody {
font-size: 1.25rem;
}
@media(max-height:550px) {
.barNavigation {
max-height: 35px;
}
}
@media (min-width: 1001px) {
.subMenu:hover ul {
opacity: 1;
@@ -158,7 +164,7 @@ tbody {
}
.barNavigation {
font-size: 15px;
font-size: 1.4rem;
justify-content: end;
}
@@ -166,6 +172,7 @@ tbody {
position: absolute;
top: 76px;
left: 0;
top: 100%;
width: 100%;
background-color: #fff;
flex-direction: column;
@@ -235,13 +242,13 @@ tbody {
transform: translateY(0);
}
.subMenu.open ul a{
.subMenu.open ul a {
display: flex;
pointer-events:auto;
pointer-events: auto;
}
thead,
tbody {
font-size: 1rem;
}
}
}
+44 -1
View File
@@ -1,3 +1,9 @@
.link {
display: flex;
align-items: center;
margin: 10px 5px;
}
.logo {
position: relative;
z-index: 3;
@@ -86,15 +92,50 @@
max-height: 60%;
}
@media (max-height: 550px) {
.containerBarNav {
max-height: 70%;
}
.yellowPart {
height: 15px;
}
.logoContainer {
min-width: 150px;
aspect-ratio: 250/70;
}
.link {
display: flex;
align-items: center;
margin: 5px 2px;
}
.header::after {
left: -60px;
min-width: 300px;
}
.header::before {
left: -40px;
width: 10%;
min-width: 300px;
}
}
@media (max-width: 800px) {
.yellowPart {
left: 0;
background: #bd8c01;
transform: skew(0deg);
}
.header::after {
left: -100px;
}
.header::before {
left: -80px;
}
@@ -105,11 +146,13 @@
min-width: 100%;
transform: skew(25deg);
}
.header::before {
min-width: 100%;
transform: skew(25deg);
}
.containerBarNav {
padding-left: 0;
}
}
}
+1 -2
View File
@@ -27,8 +27,7 @@ export default async function Header() {
<Link
href="https://www.unam.mx/"
target="_blank"
className={header.center}
style={{ display: "flex", alignItems: "center", margin: "10px 5px" }}
className={`${header.center} ${header.link}`}
>
<div className={header.logoContainer}>
<Image
+4 -3
View File
@@ -1,11 +1,12 @@
import "./creadores.css";
import BackgroundRotator from "../Components/layout/BackgroundRotator/BackgroundRotator";
import CreatorCard from "./CreatorCard";
import "./creadores.css";
export default function Page() {
return (
<div className="mainContainer">
<div className="container" style={{ display: "flex",flexDirection:"row", justifyContent: "center", gap: "3rem", flexWrap:"wrap" }}>
<div className="img"></div>
<div className="container" style={{ display: "flex", flexDirection: "row", justifyContent: "center", gap: "3rem", flexWrap: "wrap" }}>
<BackgroundRotator />
<CreatorCard title="IO" img="/IO.png" width={150} height={200} />
<CreatorCard title="CarloSpak" img="/SPAK.png" width={160} height={100} />
+135 -32
View File
@@ -1,5 +1,6 @@
* {
color: #333333;
font-size: 1.4rem;
}
*,
@@ -12,7 +13,7 @@
html {
box-sizing: border-box;
font-size: 62.5%;
font-size: 62%;
overflow-y: auto;
scrollbar-width: none;
}
@@ -116,9 +117,10 @@ select {
border: 1px solid #cfcfcf;
background-color: #fff;
border-radius: 4px;
font-size: 1.5rem;
font-size: 1.4rem;
color: black;
height: 3.5rem;
transition: all 0.2s ease-in-out;
}
input:focus,
@@ -129,12 +131,18 @@ select:focus {
transition: all 0.2s ease-in-out;
}
input:disabled,
select:disabled {
background-color: #cfcfcf;
transition: all 0.2s ease-in-out;
}
select:-webkit-scrollbar {
width: 6px;
}
option {
font-size: 1.5rem;
font-size: 1.4rem;
}
input[type="checkbox"] {
@@ -215,17 +223,25 @@ input[type="checkbox"] {
}
label {
font-size: 1.5rem;
font-size: 1.4rem;
font-weight: bold;
display: block;
}
button {
font-size: 1.5rem;
font-size: 1.4rem;
padding: 1rem 1.75rem;
border-radius: 4px;
cursor: pointer;
height: 3.5rem;
max-width: 240px;
font-weight: bold;
border: none;
transition: background-color 0.2s ease;
}
.button {
color: #ffffff;
}
button:disabled {
@@ -243,12 +259,9 @@ button:disabled {
width: 100%;
}
.button {
font-weight: bold;
border: none;
color: #ffffff;
transition: background-color 0.2s ease;
max-width: 240px;
.total {
height: 35px;
flex-wrap: nowrap;
}
.buttonSearch {
@@ -288,7 +301,7 @@ button:disabled {
ul {
list-style: none;
font-size: 1.5rem;
font-size: 1.4rem;
}
.containerInput {
@@ -300,7 +313,7 @@ ul {
.containerButton {
display: flex;
gap: 10px;
justify-content: start;
justify-content: end;
align-items: center;
width: 100%;
}
@@ -349,8 +362,13 @@ a {
}
.informationValue {
color: #555;
font-size: 1.25rem;
color: #000000;
font-size: 1.5rem;
}
.Credito {
font-weight: bold;
font-size: 2rem;
}
.title {
@@ -386,7 +404,7 @@ form {
.toggleSection {
width: 100%;
max-width: fit-content;
min-width: 750px;
min-width: 600px;
border-radius: 4px;
background-color: #fff;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
@@ -416,6 +434,7 @@ form {
padding: 1rem 0.5rem;
min-width: 100px;
min-height: 45px;
max-width: none;
}
.toggleButton.active {
@@ -424,6 +443,7 @@ form {
color: rgb(1, 92, 184);
border-radius: 4px 4px 0 0;
border-bottom: none;
box-shadow: 0px -8px 10px 3px #cfcfcf;
}
.toggleContent {
@@ -432,7 +452,7 @@ form {
}
p {
font-size: 1.5rem;
font-size: 1.4rem;
}
table {
@@ -441,7 +461,7 @@ table {
border-spacing: 0 1rem;
table-layout: auto;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 1.5rem;
font-size: 1.4rem;
color: #333;
}
@@ -481,7 +501,7 @@ thead tr {
background-color: #2563eb;
position: relative;
z-index: 1;
}
}
tbody tr {
transition: transform 0.3s ease, opacity 0.3s ease;
@@ -539,12 +559,6 @@ table td:last-child {
align-items: center;
}
.impressions-title {
font-size: 1.75rem;
font-weight: bold;
text-align: start;
}
.loginContainer {
position: relative;
display: flex;
@@ -569,7 +583,7 @@ table td:last-child {
.checkbox-grid label {
display: inline-flex;
align-items: center;
font-size: 13px;
font-size: 1.4rem;
cursor: pointer;
}
@@ -592,6 +606,7 @@ table td:last-child {
.container {
width: 100%;
max-width: none;
padding: 1rem;
}
.containerSection {
@@ -628,13 +643,9 @@ table td:last-child {
font-size: 1.2rem;
}
label {
font-size: 1.5rem;
}
input,
select {
font-size: 1.5rem;
font-size: 1.4rem;
}
button {
@@ -651,6 +662,98 @@ table td:last-child {
}
@media(max-height:800px) {
* {
font-size: 1rem;
}
.title {
font-size: 1.9rem;
}
label {
font-size: 1.2rem;
}
button {
font-size: 1.2rem;
padding: 0.5rem 1.5rem;
height: 3rem;
}
.informationValue {
font-size: 1.01rem;
}
.informationItem {
height: 25px;
}
input,
select {
padding: 0.5rem;
height: 3rem;
}
.containerForm {
gap: 0.5rem;
}
.toggleGroup {
min-height: 30px;
}
.toggleButton {
font-weight: 400;
padding: 1rem 0.5rem;
min-width: 100px;
min-height: 30px;
}
.gap {
gap: 0.5rem;
}
.information {
margin-top: 0.5rem;
}
table {
border-spacing: 0 0.5rem;
font-size: 1.4rem;
}
.container {
padding: 0.7rem;
}
.total {
height: 30px;
}
.information {
max-width: 320px;
}
.containerForm {
max-width: 320px;
}
.Credito {
font-size: 1.5rem;
}
table th,
table td {
padding: 0.65rem 1rem;
}
.toggleSection {
min-width: 570px;
}
}
@media (max-height: 960px) {
.container {
margin: 0;
@@ -667,7 +770,7 @@ table td:last-child {
.title {
max-width: 250px;
overflow-wrap: break-word;
font-size: 2.2rem;
font-size: 2rem;
min-height: 50px;
align-items: center;
}
+10 -4
View File
@@ -9,10 +9,16 @@ import "./globals.css";
const inter = Inter({ subsets: ["latin"], weight: ["400", "700"] });
export const metadata: Metadata = {
title: "Servicio AT",
title: {
default: "Servicio AT",
template: "Servicio AT | %s",
},
description: "Servicio de administracion de la FES Acatlan",
authors: [{ name: "FES Acatlán" }],
creator: "Lino,Carlos,Axel",
icons: {
icon: "/icon.svg",
},
};
export default function RootLayout({
@@ -23,9 +29,9 @@ export default function RootLayout({
return (
<html lang="es">
<body className={inter.className} suppressHydrationWarning>
<Header />
<main>{children}</main>
<Footer />
<Header />
<main>{children}</main>
<Footer />
</body>
</html>
);
-1
View File
@@ -36,7 +36,6 @@ apiClient.interceptors.response.use(
if (status === 401) {
Cookies.remove("token");
Cookies.remove("user");
}
if (status === 403) {
+28
View File
@@ -0,0 +1,28 @@
import axios from "axios";
import { envConfig } from "./config";
import { cookies } from "next/headers";
if (!envConfig.apiUrl) {
console.error("API URL is not defined in envConfig");
}
export async function getCost() {
const cookieStore = cookies();
const token = (await cookieStore).get("token")?.value;
try {
const response = await axios.get(`${envConfig.apiUrl}/costo`, {
headers: {
Authorization: `Bearer ${token}`,
},
});
return response.data;
} catch (error: any) {
const msg =
error.response?.data?.error ||
error.message ||
"Error desconocido al cobrar impresión";
return { error: msg };
}
}
//IO
+5
View File
@@ -1,10 +1,15 @@
import axios from "axios";
import { envConfig } from "./config";
import Cookies from "js-cookie";
export async function getEquipoByCount(idCuenta: number) {
try {
const token = Cookies.get("token");
const headers = { Authorization: `Bearer ${token}` };
const res = await axios.get(
`${envConfig.apiUrl}/bitacora/cuenta/${idCuenta}`,
{ headers },
);
return res.data;
} catch (error: any) {
+5
View File
@@ -1,10 +1,15 @@
import axios from "axios";
import { envConfig } from "./config";
import Cookies from "js-cookie";
export async function getMesaByCount(idCuenta: number) {
try {
const token = Cookies.get("token");
const headers = { Authorization: `Bearer ${token}` };
const res = await axios.get(
`${envConfig.apiUrl}/bitacora-mesa/cuenta/${idCuenta}`,
{ headers },
);
return res.data;
} catch (error: any) {
+5 -1
View File
@@ -1,10 +1,14 @@
import axios from "axios";
import { envConfig } from "./config";
import Cookies from "js-cookie";
export async function GetSancionByStudent(numAcount: number) {
try {
const token = Cookies.get("token");
const headers = { Authorization: `Bearer ${token}` };
const response = await axios.get(
`${envConfig.apiUrl}/alumno-sancion/${numAcount}`
`${envConfig.apiUrl}/alumno-sancion/${numAcount}`, { headers }
);
return response.data;
+5
View File
@@ -1,10 +1,15 @@
import axios from "axios";
import { envConfig } from "./config";
import Cookies from "js-cookie";
export async function getTableByCount(idCuenta: number) {
try {
const token = Cookies.get("token");
const headers = { Authorization: `Bearer ${token}` };
const res = await axios.get(
`${envConfig.apiUrl}/bitacora-mesa/table/${idCuenta}`,
{ headers },
);
return res.data;
} catch (error: any) {
+1 -1
View File
@@ -1,5 +1,5 @@
import Login from "./Components/auth/Login/Login";
import BackgroundRotator from "./Components/layout/BackgroundRotator.tsx/BackgroundRotator";
import BackgroundRotator from "./Components/layout/BackgroundRotator/BackgroundRotator";
import { LoginRedirect } from "./Routes/LoginRedirect";
export default function Home() {
+6 -6
View File
@@ -2093,9 +2093,9 @@
}
},
"node_modules/minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
"integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
"license": "ISC",
"dependencies": {
"brace-expansion": "^1.1.7"
@@ -2371,9 +2371,9 @@
}
},
"node_modules/readdir-glob/node_modules/minimatch": {
"version": "5.1.6",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
"integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
"version": "5.1.9",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz",
"integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==",
"license": "ISC",
"dependencies": {
"brace-expansion": "^2.0.1"
+33 -2002
View File
File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 151 KiB

After

Width:  |  Height:  |  Size: 39 KiB

+1 -1
View File
@@ -34,7 +34,7 @@
"**/*.tsx",
".next/types/**/*.ts",
".next/dev/types/**/*.ts"
],
, "app/Components/layout/BackgroundRotator" ],
"exclude": [
"node_modules"
]