fixing some tings barnavigation, asignacion mesa and alta

This commit is contained in:
2026-01-22 10:11:08 -06:00
parent fb3aac0592
commit df3b189276
14 changed files with 378 additions and 180 deletions
+12 -10
View File
@@ -88,7 +88,7 @@ export default async function Page(props: {
<section className="containerSection">
{errorMessage && <ShowError key={Date.now()} message={errorMessage} />}
<h2 className="title"> ASIGNACION DE EQUIPOS </h2>
<h2 className="title"> ASIGNACIÓN DE EQUIPOS </h2>
<Toggle
defaultView={key}
@@ -102,16 +102,18 @@ export default async function Page(props: {
{student && (
<>
<div>
<Information
NoCuenta={student.id_cuenta}
nombre={student.nombre}
<div>
<Information
NoCuenta={student.id_cuenta}
nombre={student.nombre}
/>
<Table headers={headers} data={tableData} />
</div>
<Table headers={headers} data={tableData} />
</div>
<PlaticaGate inscripcion={inscripcion} idCuenta={student.id_cuenta}/>
<PlaticaGate
inscripcion={inscripcion}
idCuenta={student.id_cuenta}
/>
</>
)}
</>
@@ -122,7 +124,7 @@ export default async function Page(props: {
label: "Cancelar tiempo",
content: (
<>
<CheckBoxEquipo numAcount={params?.numAcount}/>
<CheckBoxEquipo numAcount={params?.numAcount} />
</>
),
},
+64 -34
View File
@@ -1,38 +1,76 @@
import AsignacionMesas from "@/app/Components/AsignacionMesas";
import CheckBox from "@/app/Components/CheckBox";
import CheckBoxMesa from "@/app/Components/CheckBoxMesa";
import Information from "@/app/Components/Global/Information/information";
import SearchUser from "@/app/Components/Global/SearchUser/searchUser";
import ShowError from "@/app/Components/Global/ShowError";
import Toggle from "@/app/Components/Global/Toggle/Toggle";
import { GetStudent } from "@/app/lib/getStudent";
import Table from "@/app/Components/Global/table";
import { envConfig } from "@/app/lib/config";
import { GetRegisterStudent } from "@/app/lib/getRegisterStudent";
async function getInscripcion(idCuenta: number) {
try {
const res = await fetch(
`${envConfig.apiUrl}/alumno-inscrito/${idCuenta}`,
{ cache: "no-store" }
);
if (!res.ok) throw new Error("Error al cargar inscripción");
return await res.json();
} catch (error: any) {
return { error: error.message };
}
}
const headers = ["Inscrito", "Tiempo", "Confirmó"];
export default async function Page(props: {
searchParams?: Promise<{
key: string;
numAcount: string;
key?: string;
numAcount?: string;
}>;
}) {
const params = await props.searchParams;
const key = params?.key && params.key;
const numAcount = params?.numAcount ? params.numAcount : null;
const key = params?.key;
const numAcount = params?.numAcount ?? null;
let student: any = null;
let inscripcion: any[] = [];
let errorMessage = "";
if (numAcount) {
const result = await GetStudent(parseInt(numAcount));
const idCuenta = parseInt(numAcount);
const result = await GetRegisterStudent(idCuenta);
if (result.error) {
errorMessage = `${result.error}`;
errorMessage = result.error;
} else {
student = result as Student;
student = result[0]?.alumno;
}
const inscResult = await getInscripcion(idCuenta);
if (!inscResult.error && Array.isArray(inscResult)) {
inscripcion = inscResult;
}
}
const tableData = Array.isArray(inscripcion)
? inscripcion.map((ins) => ({
Inscrito: ins.plataforma?.nombre || "—",
Tiempo: ins.tiempo_disponible
? `${ins.tiempo_disponible} minutos`
: "—",
Confirmó: ins.platica?.data?.[0] === 1 ? "sí" : "no",
}))
: [];
return (
<section className="containerSection">
{errorMessage && <ShowError key={Date.now()} message={errorMessage} />}
<h2 className="title"> ASIGNACION DE MESAS </h2>
{errorMessage && <ShowError message={errorMessage} />}
<h2 className="title"> ASIGNACIÓN DE MESAS </h2>
<Toggle
defaultView={key}
@@ -43,38 +81,30 @@ export default async function Page(props: {
content: (
<>
<SearchUser value={numAcount} />
{student && (
<>
<Information
cuenta={student.id_cuenta}
nombre={student.nombre}
/>
{/* <div
className="containerForm"
style={{ margin: "1rem 0" }}
>
<label>Tiempo</label>
<div className="groupInput">
<select name="" id="">
<option value="1">Seleciona el tiempo </option>{" "}
</select>
<button className="button buttonSearch">Asignar</button>
<div>
<Information
NoCuenta={student.id_cuenta}
nombre={student.nombre}
/>
<Table headers={headers} data={tableData} />
</div>
</div> */}
<AsignacionMesas />
<AsignacionMesas
idCuenta={student.id_cuenta}
inscripcion={inscripcion}
/>
</>
)}
</>
),
},
{
key: "Tiempo",
label: "Cancelar Tiempo",
content: (
<>
<CheckBox />
</>
),
key: "Liberar",
label: "Cancelar mesa",
content: <CheckBoxMesa numAcount={numAcount} />,
},
]}
/>
+17 -20
View File
@@ -7,6 +7,7 @@ import { GetStudent } from "@/app/lib/getStudent";
import { envConfig } from "@/app/lib/config";
import "./inscripcion.css";
import Link from "next/link";
if (!envConfig.apiUrl) {
console.error("API URL is not defined in envConfig");
@@ -14,16 +15,13 @@ if (!envConfig.apiUrl) {
async function getInscripcion(idCuenta: number) {
try {
const res = await fetch(
`${envConfig.apiUrl}/alumno-inscrito/${idCuenta}`,
{
method: "GET",
headers: {
"Content-Type": "application/json",
},
cache: "no-store",
}
);
const res = await fetch(`${envConfig.apiUrl}/alumno-inscrito/${idCuenta}`, {
method: "GET",
headers: {
"Content-Type": "application/json",
},
cache: "no-store",
});
if (!res.ok) {
throw new Error(`Error ${res.status}: ${res.statusText}`);
@@ -98,21 +96,21 @@ export default async function Page(props: {
</>
)}
{!student && numAcount && (
<button
className="button buttonSearch"
style={{ marginTop: "1rem" }}
>
Registrar Estudiante
</button>
<Link href={`/Alta?numAcount=${numAcount}`}>
<button
className="button buttonSearch"
style={{ marginTop: "1rem" }}
>
Alta Usuario
</button>
</Link>
)}
</div>
{student && (
<>
<Table headers={headers} data={tableData} />
<button
className="button buttonSearch restarPass"
>
<button className="button buttonSearch restarPass">
Restablecer contraseña
</button>
</>
@@ -122,7 +120,6 @@ export default async function Page(props: {
{student && (
<>
<section className="inscripcion">
<Inscripcion numAcount={student.id_cuenta} />
</section>
</>
+32
View File
@@ -0,0 +1,32 @@
.containerForm {
display: flex;
flex-direction: column;
}
.buttonSave {
background-color: #002b7a;
color: #ffffff;
}
.buttonSave:not(:disabled):hover {
background-color: #001f5c;
}
button:disabled {
background-color: #bfc6d1;
cursor: not-allowed;
opacity: 0.7;
}
.altaContainerButton{
display: flex;
width: 100%;
justify-content: space-evenly;
}
/* ===== RESPONSIVE ===== */
@media (max-width: 768px) {
.gridAlta {
grid-template-columns: 1fr;
}
}
+103 -38
View File
@@ -1,37 +1,85 @@
"use client";
import { useEffect, useState } from "react";
import apiClient from "@/app/lib/apiClient";
import { useEffect, useState } from "react";
import "./registerAlta.css";
import toast from "react-hot-toast";
type Carrera = {
id_carrera: number;
carrera: string;
};
export default function RegisterAlta() {
const [listMajor, setListMajor] = useState([]);
const [major, setMajor] = useState("");
const [listMajor, setListMajor] = useState<Carrera[]>([]);
const [saved, setSaved] = useState(false);
const [form, setForm] = useState({
cuenta: "",
nombre: "",
apellidoP: "",
apellidoM: "",
fecha: "",
email: "",
genero: "",
carrera: "",
});
useEffect(() => {
const fetchCarreras = async () => {
try {
const response = await apiClient.get("/carrera");
const sortedCarreras = response.data.sort((a: any, b: any) =>
a.carrera.localeCompare(b.carrera)
const sorted = response.data.sort((a: Carrera, b: Carrera) =>
a.carrera.localeCompare(b.carrera),
);
setListMajor(sortedCarreras);
setListMajor(sorted);
} catch (error) {
console.error("Error al obtener carreras:", error);
}
};
fetchCarreras();
}, []);
const handleChange = (
e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>,
) => {
const { name, value } = e.target;
setForm((prev) => ({ ...prev, [name]: value }));
};
const isFormComplete = Object.values(form).every(
(value) => value.trim() !== "",
);
const handleSave = async (e: React.MouseEvent) => {
e.preventDefault();
try {
await apiClient.post("/alumno", form);
setSaved(true);
toast.error("Alumno registrado correctamente");
} catch (error) {
console.error("Error al guardar alumno:", error);
toast.error("Error al guardar alumno");
}
};
const handleInscripcion = (e: React.MouseEvent) => {
e.preventDefault();
toast.success("Continuar con inscripción");
};
return (
<form className="containerAlta gap gridAlta">
<div className="containerForm">
<label className="label">No.Cuenta</label>
<label className="label">No. Cuenta</label>
<input
type="text"
//value={user}
//onChange={(e) => setUser(e.target.value)}
name="cuenta"
value={form.cuenta}
onChange={handleChange}
placeholder="Coloca un número de cuenta..."
/>
</div>
@@ -40,8 +88,9 @@ export default function RegisterAlta() {
<label className="label">Nombre</label>
<input
type="text"
//value={user}
//onChange={(e) => setUser(e.target.value)}
name="nombre"
value={form.nombre}
onChange={handleChange}
placeholder="Coloca el nombre"
/>
</div>
@@ -50,8 +99,9 @@ export default function RegisterAlta() {
<label className="label">Apellido Paterno</label>
<input
type="text"
//value={user}
//onChange={(e) => setUser(e.target.value)}
name="apellidoP"
value={form.apellidoP}
onChange={handleChange}
placeholder="Coloca el apellido paterno"
/>
</div>
@@ -60,8 +110,9 @@ export default function RegisterAlta() {
<label className="label">Apellido Materno</label>
<input
type="text"
//value={user}
//onChange={(e) => setUser(e.target.value)}
name="apellidoM"
value={form.apellidoM}
onChange={handleChange}
placeholder="Coloca el apellido materno"
/>
</div>
@@ -69,49 +120,63 @@ export default function RegisterAlta() {
<div className="containerForm">
<label className="label">Fecha Nacimiento</label>
<input
type="text"
//value={user}
//onChange={(e) => setUser(e.target.value)}
placeholder="Coloca fecha empezando por año"
type="date"
name="fecha"
value={form.fecha}
onChange={handleChange}
/>
</div>
<div className="containerForm">
<label className="label">Email</label>
<input
type="text"
//value={user}
//onChange={(e) => setUser(e.target.value)}
type="email"
name="email"
value={form.email}
onChange={handleChange}
placeholder="Coloca el email"
/>
</div>
<div className="containerForm">
<label htmlFor="gender" className="label">
Género
</label>
<select id="gender" name="gender">
<option value="">Selecciona Género</option>
<option value="masculino">Masculino</option>
<option value="femenino">Femenino</option>
<option value="otro">Otro</option>
<label className="label">Género</label>
<select name="genero" value={form.genero} onChange={handleChange}>
<option value="">Selecciona género</option>
<option value="MUJER">Mujer</option>
<option value="HOMBRE">Hombre</option>
<option value="OTRO">Otro</option>
</select>
</div>
<div className="containerForm">
<label className="label">Carrera</label>
<select value={major} onChange={(e) => setMajor(e.target.value)}>
<select name="carrera" value={form.carrera} onChange={handleChange}>
<option value="">Selecciona la carrera</option>
{listMajor.map((carrera: any, index) => (
<option key={index} value={carrera.id_carrera}>
{carrera.carrera}
{listMajor.map((c) => (
<option key={c.id_carrera} value={c.id_carrera}>
{c.carrera}
</option>
))}
</select>
</div>
<button className="button buttonSearch">Guardar</button>
<button className="button buttonSearch">Inscripcion</button>
<div className="altaContainerButton">
<button
className="button buttonSave"
disabled={!isFormComplete}
onClick={handleSave}
>
Guardar
</button>
<button
className="button"
disabled={!saved}
onClick={handleInscripcion}
>
Inscripción
</button>
</div>
</form>
);
}
+70 -26
View File
@@ -1,39 +1,83 @@
"use client";
import axios from "axios";
import { useEffect, useState } from "react";
import { envConfig } from "../lib/config";
interface mesas {
idMesa: number;
active: number;
}
export default function AsignacionMesas() {
const [tiempo, setTiempo] = useState("");
const [mesa, setMesa] = useState<mesas[]>([]);
import { useEffect, useState } from "react";
import { envConfig } from "@/app/lib/config";
import toast from "react-hot-toast";
type Props = {
idCuenta: number;
inscripcion: any[];
};
export default function AsignacionMesas({ idCuenta }: Props) {
const [mesas, setMesas] = useState<any[]>([]);
const [loadingMesas, setLoadingMesas] = useState(false);
useEffect(() => {
const getMesa = async() => {
const response = await axios.get(`${envConfig.apiUrl}/mesa/activo`);
setMesa(response.data);
if (!idCuenta) return;
const fetchMesas = async () => {
try {
setLoadingMesas(true);
const res = await fetch(
`${envConfig.apiUrl}/mesa/activo`,
{ cache: "no-store" }
);
if (!res.ok) {
throw new Error("No se pudieron cargar las mesas");
}
const data = await res.json();
setMesas(data);
} catch (error) {
toast.error("Error al cargar mesas disponibles");
} finally {
setLoadingMesas(false);
}
};
getMesa()
}, []);
fetchMesas();
}, [idCuenta]);
return (
<form className="containerForm">
<label className="label">Mesas disponibles</label>
<div className="groupInput">
<select value={tiempo} onChange={(e) => setTiempo(e.target.value)}>
<option value="">-- Mesas disponibles --</option>
<div className="containerForm">
<label style={{ marginTop: "1rem" }}>Seleccionar tiempo</label>
{mesa.map((mesa, key) => (
<option key={key} value={mesa.idMesa}>{mesa.idMesa}</option>
))}
<select>
<option>6 minutos</option>
<option>15 minutos</option>
<option>30 minutos</option>
<option>40 minutos</option>
<option>60 minutos</option>
</select>
<label style={{ marginTop: "1rem" }}>Seleccione una mesa</label>
<div className="groupInput">
<select disabled={loadingMesas || mesas.length === 0}>
{loadingMesas && <option>Cargando mesas...</option>}
{!loadingMesas && mesas.length === 0 && (
<option>No hay mesas disponibles</option>
)}
{!loadingMesas &&
mesas.map((mesa) => (
<option key={mesa.idMesa} value={mesa.idMesa}>
Mesa {mesa.idMesa}
</option>
))}
</select>
<button className="button buttonSearch" type="submit">
Actualizar
<button
className="button buttonSearch"
disabled={loadingMesas || mesas.length === 0}
>
Asignar Mesa
</button>
</div>
</form>
</div>
);
}
@@ -36,27 +36,28 @@ export default function TableSancion({ idCuenta }: { idCuenta: number }) {
useEffect(() => {
if (!idCuenta) return;
// Obtener sanciones del alumno
axios
.get(
`${envConfig.apiUrl}/asignacionTiempo_test/alumno-sancion/${idCuenta}`
)
.get(`${envConfig.apiUrl}/alumno-sancion/${idCuenta}`)
.then((res) => {
setAlumno(res.data.student);
setAlumnoSanciones(
res.data.alusancion?.length ? res.data.alusancion : []
res.data.alusancion?.length ? res.data.alusancion : [],
);
})
.catch((err) =>
toast.error("Error al obtener las sanciones del alumno:", err)
);
.catch((err) => {
const mensaje =
err.response?.data?.message ||
"Error al obtener las sanciones del alumno";
toast.error(mensaje);
});
// Obtener catálogo de sanciones
axios
.get(`${envConfig.apiUrl}/asignacionTiempo_test/sancion`)
.get(`${envConfig.apiUrl}/sancion`)
.then((res) => setSanciones(res.data))
.catch((err) =>
toast.error("Error al obtener el catálogo de sanciones:", err)
toast.error("Error al obtener el catálogo de sanciones:", err),
);
}, [idCuenta]);
@@ -120,7 +121,6 @@ export default function TableSancion({ idCuenta }: { idCuenta: number }) {
<button
className="button buttonSearch"
style={{ margin: "1rem 0" }}
onClick={() => alert(`Sanción ${selectedSancion} aplicada`)}
>
Aplicar sanción
</button>
+44
View File
@@ -0,0 +1,44 @@
"use client";
import { useState } from "react";
import SearchUser from "./Global/SearchUser/searchUser";
import SearchBoxEquipo from "./SearchEquipo";
export default function CheckBoxMesa({
numAcount,
}: {
numAcount?: string | null;
}) {
const [modo, setModo] = useState<"Equipo" | "Cuenta" | null>(null);
return (
<>
<div className="radio-grid">
<label className="radio-card">
<input
type="radio"
name="modo"
checked={modo === "Equipo"}
onChange={() => setModo("Equipo")}
/>
<span className="radio-ui"></span>
<span className="radio-text">Equipo</span>
</label>
<label className="radio-card">
<input
type="radio"
name="modo"
checked={modo === "Cuenta"}
onChange={() => setModo("Cuenta")}
/>
<span className="radio-ui"></span>
<span className="radio-text">Cuenta</span>
</label>
</div>
{modo === "Cuenta" && <SearchUser value={numAcount ?? null} />}
{modo === "Equipo" && <SearchBoxEquipo />}
</>
);
}
@@ -68,14 +68,6 @@ export default function ProgramSelector() {
return (
<form className="form-container" onSubmit={handleSubmit}>
<select value={equipoSeleccionado} onChange={handleChangeEquipo}>
<option value="">-- Selecciona un equipo --</option>
{equipos.map((eq) => (
<option key={eq.id_equipo} value={eq.id_equipo}>
{eq.nombre_equipo}
</option>
))}
</select>
<div className="checkbox-grid">
{programas.map((prog) => (
@@ -15,6 +15,9 @@ export default function ChangePassword() {
try{
const response = await apiClient.post("/user/changePassword", data);
toast.success( `${response.data.message}`)
setPass('');
setNewPass('');
setconfirmNewPass('');
}catch{
toast.error( `No es la contraseña actual`)
}
+1
View File
@@ -41,6 +41,7 @@ function Login() {
toast.success("Inicio de sesión exitoso");
router.push("/Impresiones");
router.refresh();
}
};
+2
View File
@@ -14,6 +14,8 @@ export default function Logout() {
Cookies.remove("user", { path: "/" });
router.push("/");
router.refresh();
};
return (
@@ -31,16 +31,6 @@ function BarNavigation() {
<li className={`subMenu ${openSubMenu === 0 ? "open" : ""}`}>
<span onClick={() => toggleSubMenu(0)}>Inscripciónes</span>
<ul onClick={toggleMenu}>
<Link
href="/AgregarTiempo"
className="links"
onClick={(e) => {
e.stopPropagation();
closeAllMenus();
}}
>
<li>Agregar Tiempo</li>
</Link>
<Link
href="/Inscripcion"
className="links"
@@ -51,6 +41,16 @@ function BarNavigation() {
>
<li>Inscripción Usuario</li>
</Link>
<Link
href="/AgregarTiempo"
className="links"
onClick={(e) => {
e.stopPropagation();
closeAllMenus();
}}
>
<li>Agregar Tiempo</li>
</Link>
</ul>
</li>
@@ -75,7 +75,7 @@ function BarNavigation() {
closeAllMenus();
}}
>
<li>Asignacion de Mesas</li>
<li>Asignación de Mesas</li>
</Link>
<Link
href="/AsignacionEquipo"
@@ -85,7 +85,7 @@ function BarNavigation() {
closeAllMenus();
}}
>
<li>Asignacion de Equipos</li>
<li>Asignación de Equipos</li>
</Link>
<Link
href="/Monitor"
@@ -211,4 +211,4 @@ function BarNavigation() {
}
export default BarNavigation;
//IO
//IO
+6 -20
View File
@@ -1,19 +1,12 @@
"use client";
import Image from "next/image";
import header from "./Header.module.css";
import Link from "next/link";
import BarNavigation from "../BarNavigation/BarNavigation";
import { useEffect, useState } from "react";
import header from "./Header.module.css";
import { cookies } from "next/headers";
function Header() {
const [role, setRole] = useState("");
useEffect(() => {
const cookies = Object.fromEntries(
document.cookie.split("; ").map((c) => c.split("="))
);
setRole(cookies.role || "");
}, []);
export default async function Header() {
const cookieStore = await cookies();
const role = cookieStore.get("role")?.value || "";
return (
<header className={header.header}>
@@ -21,11 +14,7 @@ function Header() {
href="https://www.unam.mx/"
target="_blank"
className={header.center}
style={{
display: "flex",
alignItems: "center",
margin: "10px 5px",
}}
style={{ display: "flex", alignItems: "center", margin: "10px 5px" }}
>
<div className={header.logoContainer}>
<Image
@@ -47,6 +36,3 @@ function Header() {
</header>
);
}
export default Header;
//IO