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