Merge branch 'Lino' of https://github.com/IO420/Nexus into Carlos

This commit is contained in:
2025-09-30 22:52:09 -06:00
71 changed files with 1076 additions and 724 deletions
+28 -8
View File
@@ -1,21 +1,40 @@
"use client";
import SearchUser from "@/app/Components/SearchUser/searchUser";
import Equipos from "@/app/Components/ActivosMantenimiento/Equipos";
import Toggle from "@/app/Components/Toggle/Toggle";
import Areas from "@/app/Components/ActivosMantenimiento/Areas";
import Mesas from "@/app/Components/ActivosMantenimiento/Mesas";
import Equipos from "@/app/Components/Equipos/equipos";
import AlertBox from "@/app/Components/Global/AlertBox/AlertBox";
import ClearParams from "@/app/Components/Global/ClearParams/ClearParams";
import SearchUser from "@/app/Components/Global/SearchUser/searchUser";
import Toggle from "@/app/Components/Global/Toggle/Toggle";
export default function Page(props: {
export default async function Page(props: {
searchParams?: Promise<{
numAcount: string;
numAcount?: string;
machine?: string;
success?: string;
error?: string;
}>;
}) {
const params = props.searchParams;
const params = await props.searchParams;
const numAcount = params?.numAcount ? params.numAcount : null;
const showSuccess = params?.success ? params.success : null;
const showError = params?.error ? params.error : null;
return (
<section className="containerSection">
{showError && (
<>
<AlertBox key={Date.now()} message={showError} type="error" />
<ClearParams paramsToClear={["error"]} />
</>
)}
{showSuccess && (
<>
<AlertBox key={Date.now()} message={showSuccess} type="success" />
<ClearParams paramsToClear={["success"]} />
</>
)}
<h2 className="title">EQUIPOS ACTIVOS Y EN MANTENIMIENTO</h2>
<Toggle
@@ -26,7 +45,7 @@ export default function Page(props: {
label: "Equipos",
content: (
<>
<SearchUser urlBase="ActivosMantenimiento" value={"2"} />
<SearchUser value={numAcount} />
<Equipos />
</>
),
@@ -54,3 +73,4 @@ export default function Page(props: {
</section>
);
}
//IO
+23 -10
View File
@@ -1,11 +1,12 @@
import SearchUser from "@/app/Components/SearchUser/searchUser";
import Information from "@/app/Components/Information/information";
import SearchUser from "@/app/Components/Global/SearchUser/searchUser";
import Information from "@/app/Components/Global/Information/information";
import Receipt from "@/app/Components/Receipt/Receipt";
import AlertBox from "@/app/Components/AlertBox/AlertBox";
import AlertBox from "@/app/Components/Global/AlertBox/AlertBox";
import { GetStudent } from "@/app/lib/getStudent";
import "./addTime.css";
import ClearParams from "@/app/Components/Global/ClearParams/ClearParams";
export default async function Page(props: {
searchParams?: Promise<{
@@ -16,34 +17,46 @@ export default async function Page(props: {
}) {
const params = await props.searchParams;
const numAcount = params?.numAcount ? params.numAcount : null;
const showSuccess = params?.success ? parseInt(params.success) : null;
const showError = params?.error ? params.error : null;
const showSuccess = params?.success ? params.success : null;
let showError = params?.error ? params.error : null;
let student: any = null;
if (numAcount) {
student = await GetStudent(parseInt(numAcount));
const result = await GetStudent(parseInt(numAcount));
if (result.error) {
showError = "Alumno no encontrado";
} else {
student = result;
}
}
return (
<section className="containerSection">
{showError && (
<AlertBox key={Date.now()} message={showError} type="error" />
<>
<AlertBox key={Date.now()} message={showError} type="error" />
<ClearParams paramsToClear={["error"]} />
</>
)}
{showSuccess && (
<AlertBox message="Recibo guardado correctamente" type="success" />
<>
<AlertBox message="Recibo guardado correctamente" type="success" />
<ClearParams paramsToClear={["success"]} />
</>
)}
<h2 className="title"> AGREGAR TIEMPO </h2>
<SearchUser urlBase="AgregarTiempo" value={numAcount} />
<SearchUser value={numAcount} />
{student ? (
<>
<Information NoCuenta={student.id_cuenta} Nombre={student.nombre} />
<div className="addTime">
<Receipt urlBase={"/AgregarTiempo"} numAcount={student.id_cuenta} />
<Receipt numAcount={student.id_cuenta} />
</div>
</>
) : (
+30 -82
View File
@@ -1,91 +1,39 @@
'use client'
import { useState } from "react";
import StepNavigator from "@/app/Components/StepNavigator/StepNavigator";
import AlertBox from "@/app/Components/Global/AlertBox/AlertBox";
import RegisterAlta from "@/app/Components/Alta/registerAlta";
export default function Page() {
const [step, setStep] = useState(1);
const [major, setMajor] = useState("");
import "./style.css";
import ClearParams from "@/app/Components/Global/ClearParams/ClearParams";
const handleNext = (e: any) => {
e.preventDefault();
if (step < 3) setStep(step + 1);
};
const handlePrev = (e: any) => {
e.preventDefault();
if (step > 1) setStep(step - 1);
};
export default async function Page(props: {
searchParams?: Promise<{
success?: string;
error?: string;
}>;
}) {
const params = await props.searchParams;
const showSuccess = params?.success ? params.success : null;
const showError = params?.error ? params.error : null;
return (
<section className="containerSection">
{showError && (
<>
<AlertBox key={Date.now()} message={showError} type="error" />
<ClearParams paramsToClear={["error"]} />
</>
)}
{showSuccess && (
<>
<AlertBox key={Date.now()} message={showSuccess} type="success" />
<ClearParams paramsToClear={["success"]} />
</>
)}
<h1 className="title">ALTA</h1>
<StepNavigator totalSteps={2} onFinish={() => console.log()}>
<form className='containerForm'>
<label className='label'>No.Cuenta</label>
<input
type='text'
//value={user}
//onChange={(e) => setUser(e.target.value)}
placeholder='Coloca un número de cuenta...'
/>
<label className='label'>Nombre</label>
<input
type='text'
//value={user}
//onChange={(e) => setUser(e.target.value)}
placeholder='Coloca el nombre'
/>
<label className='label'>Apellido Paterno</label>
<input
type='text'
//value={user}
//onChange={(e) => setUser(e.target.value)}
placeholder='Coloca el apellido paterno'
/>
<label className='label'>Apellido Materno</label>
<input
type='text'
//value={user}
//onChange={(e) => setUser(e.target.value)}
placeholder='Coloca el apellido materno'
/>
</form>
<form>
<label className='label'>Email</label>
<input
type='text'
//value={user}
//onChange={(e) => setUser(e.target.value)}
placeholder='Coloca '
/>
<label className='label'>Fecha Nacimiento</label>
<input
type='text'
//value={user}
//onChange={(e) => setUser(e.target.value)}
placeholder='Coloca '
/>
<label className='label'>Carrera</label>
<select
value={major}
onChange={(e) => setMajor(e.target.value)}
>
<option value="">-- Selecciona un tiempo --</option>
<option value="15">15 minutos</option>
</select>
<button className="button buttonSearch">registrar</button>
</form>
</StepNavigator>
</section >
<RegisterAlta />
</section>
);
}
//IO
//IO
+23
View File
@@ -0,0 +1,23 @@
.gridAlta {
display: grid;
grid-template-columns: 1fr 1fr;
}
.containerAlta {
background-color: #f9f9f9;
width: 100%;
max-width: 900px;
padding: 1rem;
border-radius: 4px;
}
@media (max-width: 800px) {
.gridAlta {
grid-template-columns: 1fr;
justify-items: center;
min-width: max-content;
}
.containerAlta {
width: 80%;
}
}
@@ -1,29 +0,0 @@
.availableTablesContainer {
/* You can add specific styles for the table list here */
width: 45%; /* Adjust width to fit the layout */
background-color: #f9f9f9;
border-radius: 8px;
padding: 10px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.tableList {
list-style: none;
padding: 0;
display: flex;
flex-direction: column; /* Or use flex-wrap to make it a grid */
height: 200px; /* Or a fixed height with overflow */
overflow-y: auto;
}
.tableList li {
padding: 8px;
border-bottom: 1px solid #ddd;
cursor: pointer;
transition: background-color 0.2s;
}
.tableList li:hover {
background-color: #f0f0f0;
}
+51 -7
View File
@@ -1,10 +1,52 @@
"use client";
import SearchUser from "@/app/Components/SearchUser/searchUser";
import Toggle from "@/app/Components/Toggle/Toggle";
import AlertBox from "@/app/Components/Global/AlertBox/AlertBox";
import ClearParams from "@/app/Components/Global/ClearParams/ClearParams";
import SearchUser from "@/app/Components/Global/SearchUser/searchUser";
import Toggle from "@/app/Components/Global/Toggle/Toggle";
import { GetStudent } from "@/app/lib/getStudent";
import '@/app/globals.css'
export default async function Page(props: {
searchParams?: Promise<{
numAcount?: string;
machine?: string;
success?: string;
error?: string;
}>;
}) {
const params = await props.searchParams;
const numAcount = params?.numAcount ? params.numAcount : null;
const machine = params?.machine ? params.machine : null;
const showSuccess = params?.success ? params.success : null;
const showError = params?.error ? params.error : null;
let student: any = null;
if (numAcount) {
const result = await GetStudent(parseInt(numAcount));
if (result.error) {
} else {
student = result;
}
}
export default function Page() {
return (
<section className="containerSection">
{showError && (
<>
<AlertBox key={Date.now()} message={showError} type="error" />
<ClearParams paramsToClear={["error"]} />
</>
)}
{showSuccess && (
<>
<AlertBox key={Date.now()} message={showSuccess} type="success" />
<ClearParams paramsToClear={["success"]} />
</>
)}
<h2 className="title"> ASIGNACION DE EQUIPOS </h2>
<Toggle
@@ -15,9 +57,9 @@ export default function Page() {
label: "Asignar tiempo",
content: (
<>
<SearchUser urlBase="AsignacionEquipo" value={"2"} />
<SearchUser value={numAcount} />
<form className="containerForm"></form>
{student && <h1>No hay records disponibles</h1>}
</>
),
},
@@ -34,7 +76,8 @@ export default function Page() {
<input type="checkbox" /> Cuenta
</label>
</div>
<SearchUser urlBase="AsignacionEquipo" value={"2"} />
<SearchUser value={numAcount} />
</>
),
},
@@ -43,3 +86,4 @@ export default function Page() {
</section>
);
}
//IO
@@ -1,29 +0,0 @@
.availableTablesContainer {
/* You can add specific styles for the table list here */
width: 45%; /* Adjust width to fit the layout */
background-color: #f9f9f9;
border-radius: 8px;
padding: 10px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.tableList {
list-style: none;
padding: 0;
display: flex;
flex-direction: column; /* Or use flex-wrap to make it a grid */
height: 200px; /* Or a fixed height with overflow */
overflow-y: auto;
}
.tableList li {
padding: 8px;
border-bottom: 1px solid #ddd;
cursor: pointer;
transition: background-color 0.2s;
}
.tableList li:hover {
background-color: #f0f0f0;
}
+4 -4
View File
@@ -1,6 +1,6 @@
"use client";
import SearchUser from "@/app/Components/SearchUser/searchUser";
import Toggle from "@/app/Components/Toggle/Toggle";
import SearchUser from "@/app/Components/Global/SearchUser/searchUser";
import Toggle from "@/app/Components/Global/Toggle/Toggle";
import { useState } from "react";
export default function Page() {
@@ -18,7 +18,7 @@ export default function Page() {
label: "Asignar mesa",
content: (
<>
<SearchUser urlBase="AsignacionMesas" value={"3"} />
<SearchUser value={"3"} />
<form className="containerForm">
<label className="label">Mesas disponibles</label>
@@ -56,7 +56,7 @@ export default function Page() {
<input type="checkbox" /> Cuenta
</label>
</div>
<SearchUser urlBase="AsignacionMesas" value={"3"} />
<SearchUser value={"3"} />
</>
),
},
+51 -12
View File
@@ -1,21 +1,60 @@
"use client";
import Toggle from "@/app/Components/Toggle/Toggle";
import Sanciones from "@/app/Components/BitacoraSanciones/Sanciones";
import BitacoraMesas from "@/app/Components/BitacoraSanciones/BitacoraMesas";
import BitacoraAlumno from "@/app/Components/BitacoraSanciones/BitacoraAlumno";
import BitacoraEquipo from "@/app/Components/BitacoraSanciones/BitacoraEquipo";
import BitacoraMesas from "@/app/Components/BitacoraSanciones/BitacoraMesas";
import Sanciones from "@/app/Components/BitacoraSanciones/Sanciones";
import Toggle from "@/app/Components/Global/Toggle/Toggle";
import AlertBox from "@/app/Components/Global/AlertBox/AlertBox";
import { GetStudent } from "@/app/lib/getStudent";
import ClearParams from "@/app/Components/Global/ClearParams/ClearParams";
export default async function Page(props: {
searchParams?: Promise<{
key?: string;
numAcount?: string;
success?: string;
error?: string;
}>;
}) {
const params = await props.searchParams;
const key = params?.key && params.key ;
const numAcount = params?.numAcount ? params.numAcount : null;
const showSuccess = params?.success ? params.success : null;
const showError = params?.error ? params.error : null;
let student: any = null;
if (numAcount) {
const result = await GetStudent(parseInt(numAcount));
if (result.error) {
} else {
student = result;
}
}
export default function Page() {
return (
<section className="containerSection">
{showError && (
<>
<AlertBox key={Date.now()} message={showError} type="error" />
<ClearParams paramsToClear={["error"]} />
</>
)}
{showSuccess && (
<>
<AlertBox key={Date.now()} message={showSuccess} type="success" />
<ClearParams paramsToClear={["success"]} />
</>
)}
<h2 className="title"> BITACORA Y SANCIONES </h2>
<Toggle
defaultView="1"
defaultView={key}
options={[
{
key: "1",
key: "Equipo",
label: "Bitacora equipo",
content: (
<>
@@ -24,7 +63,7 @@ export default function Page() {
),
},
{
key: "2",
key: "Alumno",
label: "Bitacora alumno",
content: (
<>
@@ -33,7 +72,7 @@ export default function Page() {
),
},
{
key: "3",
key: "Mesas",
label: "Bitacora mesas",
content: (
<>
@@ -42,11 +81,11 @@ export default function Page() {
),
},
{
key: "4",
key: "Sanciones",
label: "Sanciones",
content: (
<>
<Sanciones />
<Sanciones student={student}/>
</>
),
},
+31 -7
View File
@@ -1,13 +1,37 @@
import ChangePassword from "../../Components/ChangePassword/changePassword";
import ChangePassword from "@/app/Components/auth/ChangePassword/changePassword";
import AlertBox from "@/app/Components/Global/AlertBox/AlertBox";
import ClearParams from "@/app/Components/Global/ClearParams/ClearParams";
export default async function Page(props: {
searchParams?: Promise<{
success?: string;
error?: string;
}>;
}) {
const params = await props.searchParams;
const showSuccess = params?.success ? params.success : null;
const showError = params?.error ? params.error : null;
export default function Page() {
return (
<section className='containerSection'>
<h2 className='title'> Cambiar contraseña </h2>
<section className="containerSection">
{showError && (
<>
<AlertBox key={Date.now()} message={showError} type="error" />
<ClearParams paramsToClear={["error"]} />
</>
)}
<ChangePassword/>
{showSuccess && (
<>
<AlertBox key={Date.now()} message={showSuccess} type="success" />
<ClearParams paramsToClear={["success"]} />
</>
)}
<h2 className="title"> Cambiar contraseña </h2>
<ChangePassword />
</section>
);
}
//IO
//IO
+31 -25
View File
@@ -1,31 +1,34 @@
import SearchUser from "../../Components/SearchUser/searchUser";
import SearchUser from "../../Components/Global/SearchUser/searchUser";
import Receipt from "../../Components/Receipt/Receipt";
import Impressions from "../../Components/Impressions/impressions";
import Toggle from "../../Components/Toggle/Toggle";
import Information from "../../Components/Information/information";
import AlertBox from "@/app/Components/AlertBox/AlertBox";
import Toggle from "../../Components/Global/Toggle/Toggle";
import Information from "../../Components/Global/Information/information";
import AlertBox from "@/app/Components/Global/AlertBox/AlertBox";
import Impressions from "@/app/Components/Impressions/impressions";
import { GetStudent } from "@/app/lib/getStudent";
import "@/app/globals.css";
import ClearParams from "@/app/Components/Global/ClearParams/ClearParams";
export default async function Page(props: {
searchParams?: Promise<{
key: string;
numAcount: string;
success?: string;
error?: string;
}>;
}) {
const params = await props.searchParams;
const key = params?.key && params.key;
const numAcount = params?.numAcount ? params.numAcount : null;
const showSuccess = params?.success ? params.success : null;
let showError = params?.error ? params.error : null;
const showError = params?.error ? params.error : null;
let student: any = null;
if (numAcount) {
const result = await GetStudent(parseInt(numAcount));
if (result.error) {
showError = "Alumno no encontrado";
} else {
student = result;
}
@@ -34,17 +37,23 @@ export default async function Page(props: {
return (
<section className="containerSection">
{showError && (
<AlertBox key={Date.now()} message={showError} type="error" />
<>
<AlertBox key={Date.now()} message={showError} type="error" />
<ClearParams paramsToClear={["error"]} />
</>
)}
{showSuccess && (
<AlertBox key={Date.now()} message={showSuccess} type="success" />
<>
<AlertBox key={Date.now()} message={showSuccess} type="success" />
<ClearParams paramsToClear={["success"]} />
</>
)}
<h2 className="title">IMPRESIONES Y PLOTEO</h2>
<SearchUser urlBase="Impresiones" value={numAcount} />
<SearchUser value={numAcount} />
{student ? (
{student && (
<>
<Information
NoCuenta={student.id_cuenta}
@@ -54,33 +63,30 @@ export default async function Page(props: {
/>
<Toggle
defaultView="1"
defaultView={key}
options={[
{
key: "1",
key: "Recibo",
label: "Recibo",
content: (
<Receipt
urlBase="/Impresiones"
numAcount={student.id_cuenta}
/>
),
content: <Receipt numAcount={student.id_cuenta} />,
},
{
key: "2",
key: "B/N",
label: "Impresiones B/N",
content: (
<Impressions
key={1}
costs={[{ value: 1 }, { value: 2 }]}
numAcount={student.id_cuenta}
/>
),
},
{
key: "3",
key: "color",
label: "Impresiones color",
content: (
<Impressions
key={2}
costs={[
{ value: 4 },
{ value: 5 },
@@ -96,10 +102,11 @@ export default async function Page(props: {
),
},
{
key: "4",
key: "Plotter",
label: "Plotter",
content: (
<Impressions
key={3}
costs={[
{ value: 15 },
{ value: 18 },
@@ -124,10 +131,11 @@ export default async function Page(props: {
),
},
{
key: "5",
key: "Escaner",
label: "Escaner",
content: (
<Impressions
key={4}
costs={[{ value: 1 }, { value: 2 }, { value: 5 }]}
numAcount={student.id_cuenta}
/>
@@ -136,8 +144,6 @@ export default async function Page(props: {
]}
/>
</>
) : (
<></>
)}
</section>
);
@@ -44,7 +44,6 @@
display: grid;
grid-template-columns: repeat(3, 240px); /* ancho fijo por columna */
gap: 6px 20px;
margin-bottom: 20px;
flex-wrap: wrap;
margin-right: 2px;
}
+39 -9
View File
@@ -1,24 +1,53 @@
import ProgramSelector from "@/app/Components/ProgramSelector/ProgramSelector";
import Toggle from "@/app/Components/Toggle/Toggle";
import Toggle from "@/app/Components/Global/Toggle/Toggle";
import Equipos from "@/app/Components/Equipos/equipos";
import AlertBox from "@/app/Components/Global/AlertBox/AlertBox";
import ProgramSelector from "@/app/Components/InformacionEquipos/ProgramSelector";
import "./informacionequipo.css";
import Equipos from "@/app/Components/Equipos/equipos";
import ClearParams from "@/app/Components/Global/ClearParams/ClearParams";
export default async function Page(props: {
searchParams?: Promise<{
key?:string;
machine?: string;
success?: string;
error?: string;
}>;
}) {
const params = await props.searchParams;
const key = params?.key && params.key;
const machine = params?.machine ? params.machine : null;
const showSuccess = params?.success ? params.success : null;
const showError = params?.error ? params.error : null;
export default function Page() {
return (
<section className="containerSection">
{showError && (
<>
<AlertBox key={Date.now()} message={showError} type="error" />
<ClearParams paramsToClear={["error"]} />
</>
)}
{showSuccess && (
<>
<AlertBox key={Date.now()} message={showSuccess} type="success" />
<ClearParams paramsToClear={["success"]} />
</>
)}
<h2 className="title"> INFORMACION DE EQUIPOS </h2>
<Toggle
defaultView="1"
defaultView={key}
options={[
{
key: "1",
key: "Equipos",
label: "Equipos",
content: <Equipos key={2} />,
content: <Equipos />,
},
{
key: "2",
key: "Equipo",
label: "Programa por equipo",
content: (
<ProgramSelector
@@ -29,7 +58,7 @@ export default function Page() {
),
},
{
key: "3",
key: "Sala",
label: "Programa por sala",
content: (
<ProgramSelector
@@ -44,3 +73,4 @@ export default function Page() {
</section>
);
}
//IO
@@ -0,0 +1,9 @@
.inscripcion{
background-color: #f9f9f9;
width: 100%;
max-width: 700px;
border-radius: 4px;
padding: 1rem;
margin-top: 1rem;
outline: 1px solid #cfcfcf;
}
+71
View File
@@ -0,0 +1,71 @@
import SearchUser from "@/app/Components/Global/SearchUser/searchUser";
import Information from "@/app/Components/Global/Information/information";
import Receipt from "@/app/Components/Receipt/Receipt";
import Selection from "@/app/Components/Selection/Selection";
import AlertBox from "@/app/Components/Global/AlertBox/AlertBox";
import ClearParams from "@/app/Components/Global/ClearParams/ClearParams";
import { GetStudent } from "@/app/lib/getStudent";
import "./inscripcion.css";
export default async function Page(props: {
searchParams?: Promise<{
numAcount: string;
success?: string;
error?: string;
}>;
}) {
const params = await props.searchParams;
const numAcount = params?.numAcount ? params.numAcount : null;
const showSuccess = params?.success ? params.success : null;
let showError = params?.error ? params.error : null;
let student: any = null;
if (numAcount) {
const result = await GetStudent(parseInt(numAcount));
if (result.error) {
showError = "Alumno no encontrado";
} else {
student = result;
}
}
return (
<section className="containerSection">
{showError && (
<>
<AlertBox key={Date.now()} message={showError} type="error" />
<ClearParams paramsToClear={["error"]} />
</>
)}
{showSuccess && (
<>
<AlertBox key={Date.now()} message={showSuccess} type="success" />
<ClearParams paramsToClear={["success"]} />
</>
)}
<h2 className="title"> INSCRIPCION </h2>
<SearchUser value={numAcount} />
{student && (
<>
<Information
NoCuenta={student.id_cuenta}
Nombre={student.nombre}
Carrera={student.carrera.carrera}
Credito={student.credito}
/>
<section className="inscripcion">
<Selection />
<Receipt numAcount={student.id_cuenta} />
</section>
</>
)}
</section>
);
}
//IO
-56
View File
@@ -1,56 +0,0 @@
import SearchUser from "@/app/Components/SearchUser/searchUser";
import Information from "@/app/Components/Information/information";
import StepNavigator from "@/app/Components/StepNavigator/StepNavigator";
import Receipt from "@/app/Components/Receipt/Receipt";
import Selection from "@/app/Components/Selection/Selection";
import { GetStudent } from "@/app/lib/getStudent";
import "./inscriptions.css";
export default async function Page(props: {
searchParams?: Promise<{
numAcount: string;
}>;
}) {
const params = await props.searchParams;
const numAcount = params?.numAcount ? params.numAcount : null;
let student: any = null;
let error: string | null = null;
if (numAcount) {
const result = await GetStudent(parseInt(numAcount));
if (result.error) {
error = result.error;
} else {
student = result;
}
}
return (
<section className="containerSection">
<h2 className="title"> INSCRIPCION </h2>
<SearchUser urlBase="Inscripciones" value={numAcount} />
{student ? (
<>
<Information
NoCuenta={student.id_cuenta}
Nombre={student.nombre}
Carrera={student.carrera.carrera}
Credito={student.credito}
/>
<StepNavigator totalSteps={2}>
<Selection />
<Receipt urlBase={"Inscripciones"} numAcount={student.id_cuenta} />
</StepNavigator>
</>
) : (
<></>
)}
</section>
);
}
//IO
+35 -15
View File
@@ -1,14 +1,39 @@
import AlertBox from "@/app/Components/Global/AlertBox/AlertBox";
import ClearParams from "@/app/Components/Global/ClearParams/ClearParams";
export default async function Page(props: {
searchParams?: Promise<{
period: string;
success?: string;
error?: string;
}>;
}) {
const params = await props.searchParams;
const period = params?.period ? params.period : null;
const showSuccess = params?.success ? params.success : null;
const showError = params?.error ? params.error : null;
export default function Page() {
return (
<section className='containerSection'>
<h2 className='title'> INSCRITOS </h2>
<section className="containerSection">
{showError && (
<>
<AlertBox key={Date.now()} message={showError} type="error" />
<ClearParams paramsToClear={["error"]} />
</>
)}
{showSuccess && (
<>
<AlertBox key={Date.now()} message={showSuccess} type="success" />
<ClearParams paramsToClear={["success"]} />
</>
)}
<h2 className="title"> INSCRITOS </h2>
<form className="containerForm">
<label>Seleccione el periodo</label>
<div className="groupInput">
<select
>
<select>
<option value="">-- Seleccione el periodo --</option>
<option value="15">1 </option>
<option value="30">2 </option>
@@ -17,17 +42,14 @@ export default function Page() {
<option value="90">5 </option>
<option value="120">6 </option>
</select>
<button
className='button buttonSearch'
type='submit'
>Buscar
<button className="button buttonSearch" type="submit">
Buscar
</button>
</div>
</form>
<div className="tableContainer">
<table >
<table>
<thead>
<tr>
<th>Carrera</th>
@@ -37,12 +59,10 @@ export default function Page() {
<th>Profesores</th>
</tr>
</thead>
<tbody>
</tbody>
<tbody></tbody>
</table>
</div>
</section>
);
}
//IO
//IO
+30 -5
View File
@@ -1,15 +1,40 @@
"use client";
import EnviarMensaje from "@/app/Components/EviarMensaje/EnviarMensaje";
import Toggle from "@/app/Components/Toggle/Toggle";
import AlertBox from "@/app/Components/Global/AlertBox/AlertBox";
import ClearParams from "@/app/Components/Global/ClearParams/ClearParams";
import Toggle from "@/app/Components/Global/Toggle/Toggle";
export default async function Page(props: {
searchParams?: Promise<{
key:string;
success?: string;
error?: string;
}>;
}) {
const params = await props.searchParams;
const key = params?.key && params.key ;
const showSuccess = params?.success ? params.success : null;
const showError = params?.error ? params.error : null;
export default function Page() {
return (
<section className="containerSection">
{showError && (
<>
<AlertBox key={Date.now()} message={showError} type="error" />
<ClearParams paramsToClear={["error"]} />
</>
)}
{showSuccess && (
<>
<AlertBox key={Date.now()} message={showSuccess} type="success" />
<ClearParams paramsToClear={["success"]} />
</>
)}
<h2 className="title">Enviar mensaje</h2>
<Toggle
defaultView="Equipo"
defaultView={key}
options={[
{
key: "Equipo",
+14 -124
View File
@@ -1,126 +1,16 @@
"use client";
import styles from "./Page.module.css";
import { useState } from "react";
import styles from "./Page.module.css"; // importamos el css
export default function Page() {
const [machines] = useState([
{
ubicacion: "Laboratorio 1",
nombre: "PC-01",
plataforma: "Windows 10",
area: "Diseño",
disponible: true,
},
{
ubicacion: "Laboratorio 2",
nombre: "PC-15",
plataforma: "Linux",
area: "Programación",
disponible: false,
},
{
ubicacion: "Laboratorio 3",
nombre: "PC-23",
plataforma: "MacOS",
area: "Edición",
disponible: true,
},
{
ubicacion: "Laboratorio 3",
nombre: "PC-23",
plataforma: "MacOS",
area: "Edición",
disponible: true,
},
{
ubicacion: "Laboratorio 3",
nombre: "PC-23",
plataforma: "MacOS",
area: "Edición",
disponible: true,
},
{
ubicacion: "Laboratorio 3",
nombre: "PC-23",
plataforma: "MacOS",
area: "Edición",
disponible: true,
},
{
ubicacion: "Laboratorio 3",
nombre: "PC-23",
plataforma: "MacOS",
area: "Edición",
disponible: true,
},
{
ubicacion: "Laboratorio 3",
nombre: "PC-23",
plataforma: "MacOS",
area: "Edición",
disponible: true,
},
{
ubicacion: "Laboratorio 3",
nombre: "PC-23",
plataforma: "MacOS",
area: "Edición",
disponible: true,
},
{
ubicacion: "Laboratorio 3",
nombre: "PC-23",
plataforma: "MacOS",
area: "Edición",
disponible: true,
},
{
ubicacion: "Laboratorio 3",
nombre: "PC-23",
plataforma: "MacOS",
area: "Edición",
disponible: true,
},
{
ubicacion: "Laboratorio 3",
nombre: "PC-23",
plataforma: "MacOS",
area: "Edición",
disponible: true,
},
{
ubicacion: "Laboratorio 3",
nombre: "PC-23",
plataforma: "MacOS",
area: "Edición",
disponible: true,
}, {
ubicacion: "Laboratorio 3",
nombre: "PC-23",
plataforma: "MacOS",
area: "Edición",
disponible: true,
}, {
ubicacion: "Laboratorio 3",
nombre: "PC-23",
plataforma: "MacOS",
area: "Edición",
disponible: true,
}, {
ubicacion: "Laboratorio 3",
nombre: "PC-23",
plataforma: "MacOS",
area: "Edición",
disponible: true,
}, {
ubicacion: "Laboratorio 3",
nombre: "PC-23",
plataforma: "MacOS",
area: "Edición",
disponible: true,
},
]);
export default async function Page(props: {
searchParams?: Promise<{
numAcount: string;
success?: string;
error?: string;
}>;
}) {
const params = await props.searchParams;
const numAcount = params?.numAcount ? params.numAcount : null;
const showSuccess = params?.success ? params.success : null;
const showError = params?.error ? params.error : null;
return (
<section className='containerSection'>
@@ -144,7 +34,7 @@ export default function Page() {
</tr>
</thead>
<tbody>
{machines.map((machine, index) => (
{/* {machines.map((machine, index) => (
<tr key={index}>
<td>{machine.ubicacion}</td>
<td>{machine.nombre}</td>
@@ -154,7 +44,7 @@ export default function Page() {
{machine.disponible ? "si" : "no"}
</td>
</tr>
))}
))} */}
</tbody>
</table>
</div>
+2 -3
View File
@@ -3,7 +3,6 @@ import { useState } from "react";
import styleprograms from "./programas.module.css";
export default function Page() {
// modo puede ser: "ver", "editar", "nuevo"
const [modo, setModo] = useState("ver");
const handleNuevo = () => {
@@ -62,7 +61,7 @@ export default function Page() {
<div className="margin">
<button className="button buttonSearch">Guardar</button>
<button
className={`button buttonSearch ${styleprograms.button}`}
className={`button buttonCancel ${styleprograms.button}`}
onClick={handleCancelar}
>
Cancelar
@@ -79,7 +78,7 @@ export default function Page() {
<div className="margin">
<button className="button buttonSearch">Insertar</button>
<button
className={`button buttonSearch ${styleprograms.button}`}
className={`button buttonCancel ${styleprograms.button}`}
onClick={handleCancelar}
>
Cancelar
+17 -6
View File
@@ -1,15 +1,26 @@
"use client";
import SearchUser from "@/app/Components/SearchUser/searchUser";
import SearchUser from "@/app/Components/Global/SearchUser/searchUser";
import QuitarSancion from "@/app/Components/QuitarSancion/QuitarSancion";
export default function Page() {
export default async function Page(props: {
searchParams?: Promise<{
numAcount: string;
success?: string;
error?: string;
}>;
}) {
const params = await props.searchParams;
const numAcount = params?.numAcount ? params.numAcount : null;
const showSuccess = params?.success ? params.success : null;
const showError = params?.error ? params.error : null;
return (
<>
<h2 className="title"> Quitar Sanciones </h2>
<div style={{ display: "flex", gap: "1rem", flexDirection: "column" }}>
<h2 className="title"> Quitar Sanciones </h2>
<SearchUser urlBase="QuitarSancion" value={"2"} />
<SearchUser value={numAcount} />
<QuitarSancion />
</div>
</>
);
}
//IO
+5 -4
View File
@@ -1,10 +1,11 @@
"use client";
import { useState } from "react";
import styles from "./Page.module.css"; // importamos el css
import Toggle from "@/app/Components/Toggle/Toggle";
import styles from "./Page.module.css";
import Toggle from "@/app/Components/Global/Toggle/Toggle";
import SearchDateBetween from "@/app/Components/SearchDateBetween/SearchDateBetween";
import { useState } from "react";
export default function Page() {
const [reportes] = useState([
{
@@ -69,7 +70,7 @@ export default function Page() {
label: "Por Servicio",
content: (
<>
<SearchDateBetween />
<SearchDateBetween />
<div className={styles.tableContainer}>
<table className={styles.machineTable}>
<thead>
+8 -5
View File
@@ -1,14 +1,17 @@
import { ReactNode } from "react";
import { PrivateRoute } from "../Routes/PrivateRoute";
import BarNavigation from "../Components/BarNavigation/BarNavigation";
import Logout from "../Components/Logout/Logout";
import BarNavigation from "../Components/layout/BarNavigation/BarNavigation";
import Logout from "../Components/auth/Logout/Logout";
export default function PrivateLayout({ children }: { children: ReactNode }) {
export default async function PrivateLayout({
children,
}: {
children: ReactNode;
}) {
return (
<div className="mainContainer">
<BarNavigation />
<div className="container">
<Logout/>
<Logout />
<div className="img"></div>
{children}
</div>
@@ -37,14 +37,9 @@ function Mesas() {
<option value="15">15</option>
</select>
{/* Checkbox Mantenimiento */}
<div className="checkbox" style={{ marginTop: "10px" }}>
<div className="checkbox-grid">
<label>
<input
type="checkbox"
checked={mantenimiento}
onChange={(e) => setMantenimiento(e.target.checked)}
/>
<input type="checkbox" />
Mantenimiento
</label>
</div>
+68
View File
@@ -0,0 +1,68 @@
"use client";
import { useState } from "react";
export default function RegisterAlta() {
const [major, setMajor] = useState("");
return (
<form className="containerAlta gap gridAlta">
<div className="containerForm">
<label className="label">No.Cuenta</label>
<input
type="text"
//value={user}
//onChange={(e) => setUser(e.target.value)}
placeholder="Coloca un número de cuenta..."
/>
</div>
<div className="containerForm">
<label className="label">Nombre</label>
<input
type="text"
//value={user}
//onChange={(e) => setUser(e.target.value)}
placeholder="Coloca el nombre"
/>
</div>
<div className="containerForm">
<label className="label">Apellido Paterno</label>
<input
type="text"
//value={user}
//onChange={(e) => setUser(e.target.value)}
placeholder="Coloca el apellido paterno"
/>
</div>
<div className="containerForm">
<label className="label">Apellido Materno</label>
<input
type="text"
//value={user}
//onChange={(e) => setUser(e.target.value)}
placeholder="Coloca el apellido materno"
/>
</div>
<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"
/>
</div>
<div className="containerForm">
<label className="label">Carrera</label>
<select value={major} onChange={(e) => setMajor(e.target.value)}>
<option value="">Selecciona la carrera</option>
</select>
</div>
<button className="button buttonSearch">registrar</button>
</form>
);
}
@@ -1,7 +1,8 @@
"use client";
import { useState } from "react";
import styles from "./Page.module.css";
import SearchDate from "../SearchDate/SearchDate";
import { useState } from "react";
import styles from "./Page.module.css";
interface alumnos {
tiempo_entrada: string;
@@ -1,7 +1,8 @@
"use client";
import { useState } from "react";
import styles from "./Page.module.css";
import SearchDate from "../SearchDate/SearchDate";
import { useState } from "react";
import styles from "./Page.module.css";
interface equipos {
hora_entrada: string;
@@ -1,8 +1,8 @@
"use client";
import { useState } from "react";
import styles from "./Page.module.css";
import SearchDate from "../SearchDate/SearchDate";
import { useState } from "react";
import styles from "./Page.module.css";
interface tables {
no_mesa: number;
@@ -14,7 +14,7 @@ interface tables {
function BitacoraMesas() {
const [tables, setTables] = useState<tables[]>([]);
const [ubicacion_equipo, setUbicacionEquipo] = useState("");
return (
<>
<SearchDate />
+17 -86
View File
@@ -1,97 +1,28 @@
"use client";
import { useEffect, useState } from "react";
import styles from "./Page.module.css";
import SearchUser from "../SearchUser/searchUser";
import Information from "../Information/information";
import { GetStudent } from "@/app/lib/getStudent";
import { envConfig } from "@/app/lib/config";
import Information from "../Global/Information/information";
import SearchUser from "../Global/SearchUser/searchUser";
import TableSancion from "./TableSancion";
interface sancion {
no_cuenta: number;
interface Student {
id_cuenta: string;
nombre: string;
motivo: string;
duracion: number;
fecha_sancion: string;
utilizar_hasta: number;
}
export default function Sanciones() {
const [sanciones, setSanciones] = useState<sancion[]>([]);
const [ubicacion_equipo, setUbicacionEquipo] = useState("");
const [no_cuenta, setNo_cuenta] = useState("");
useEffect(() => {
fetch(`${envConfig.apiUrl}/student/${no_cuenta}`).then(
(
response // Revisar
) => response.json().then((data) => setNo_cuenta(data[0].sancion))
);
}, [no_cuenta]);
export default async function Sanciones(props: { student?: Student }) {
const idCuenta = props?.student?.id_cuenta ?? null;
return (
<>
<SearchUser urlBase="BitacoraSanciones" value="3" />
<SearchUser value={idCuenta} />
{props.student && (
<>
<Information
NoCuenta={props.student.id_cuenta}
Nombre={props.student.nombre}
/>
{/* <Information NoCuenta={sancion.id_cuenta} Nombre={student.nombre} /> */}
<form className="containerForm">
<label className="label">Ubicacion de equipo</label>
<div
className="groupInput"
style={{ display: "flex", gap: "1rem", flexDirection: "row" }}
>
<select
value={ubicacion_equipo}
onChange={(e) => setUbicacionEquipo(e.target.value)}
>
<option value="">-- Selecciona un equipo --</option>
<option value="255">Equipo 255</option>
</select>
<button className="button buttonSearch" type="submit">
Asignar
</button>
</div>
</form>
<div className={styles.tableContainer}>
<table className={styles.machineTable}>
<thead>
<tr>
<th>Cuenta</th>
<th>Motivo de la sancion</th>
<th>Duracion (Semanas) </th>
<th>Fecha Sancion</th>
<th>Podra utilizar el servicio hasta</th>
</tr>
</thead>
<tbody>
{sanciones.map((sancion, index) => (
<tr key={index}>
<td>{sancion.no_cuenta}</td>
<td>{sancion.motivo}</td>
<td>{sancion.fecha_sancion}</td>
<td>{sancion.duracion}</td>
<td>{sancion.utilizar_hasta}</td>
</tr>
))}
</tbody>
</table>
</div>
<form className="containerForm">
<div className="groupInput">
<select
value={ubicacion_equipo}
onChange={(e) => setUbicacionEquipo(e.target.value)}
>
<option value="">-- Selecciona una sancion --</option>
<option value="sancion 1">No cerrar sesion (Una semana)</option>
</select>
<button className="button buttonSearch" type="submit">
Aplicar sancion
</button>
</div>
</form>
<TableSancion />
</>
)}
</>
);
}
@@ -0,0 +1,76 @@
"use client";
import { useEffect, useState } from "react";
import styles from "./Page.module.css";
import axios from "axios";
interface alumno_sancion {
id_alumno_sancion: number;
fecha_inicio: string;
alumno: alumno;
sancion: sancion;
}
interface alumno {
id_cuenta: number;
nombre: string;
credito: number;
}
interface sancion {
id_sancion: number;
sancion: string;
duracion: number;
}
export default function TableSancion() {
const [sanciones, setSanciones] = useState<any>();
const [button, setButton] = useState<boolean>(false);
useEffect(() => {
const getSanciones = async () => {
const response = await axios.get(
""
);
setSanciones(response);
};
getSanciones();
}, [button]);
const handlebutton = () => {
setButton(!button);
};
return (
<>
<h1>{sanciones}</h1>
<div className={styles.tableContainer}>
<table className={styles.machineTable}>
<thead>
<tr>
<th>Cuenta</th>
<th>Motivo de la sancion</th>
<th>Duracion (Semanas) </th>
<th>Fecha Sancion</th>
<th>Podra utilizar el servicio hasta</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
<form className="containerForm">
<div className="groupInput">
<select>
<option value="">-- Selecciona una sancion --</option>
<option value="sancion 1">No cerrar sesion (Una semana)</option>
</select>
</div>
</form>
<button className="button buttonSearch" onClick={handlebutton}>
Aplicar sancion
</button>
<h1>{button ? <p>desactivado</p> : <p>activado</p>}</h1>
</>
);
}
//IO
+1 -1
View File
@@ -30,7 +30,7 @@ export default function Equipos() {
<form className="containerForm">
<div className="groupInput">
<input
placeholder="text"
placeholder="Numero de Equipo a buscar..."
value={Equipo}
onChange={(e) => {
setEquipo(e.target.value);
@@ -1,3 +1,25 @@
@keyframes slideInLeft {
0% {
opacity: 0;
transform: translateX(-100%);
}
100% {
opacity: 0.9;
transform: translateX(0);
}
}
@keyframes slideOutRight {
0% {
opacity: 0.9;
transform: translateX(0);
}
100% {
opacity: 0;
transform: translateX(100%);
}
}
.messageBox {
display: flex;
position: absolute;
@@ -6,20 +28,20 @@
font-weight: bold;
font-size: 2rem;
text-align: center;
opacity: 1;
z-index: 100;
top: 0;
left: 0;
width: 100%;
max-width: 500px;
max-height: min-content;
opacity: 0.9;
transition: opacity 0.5s ease, transform 0.5s ease;
opacity: 0;
}
.messageBox:not(.hidden) {
animation: slideInLeft 0.5s ease forwards;
}
.messageBox.hidden {
opacity: 0;
pointer-events: none;
transition: opacity 1s ease-out,transform 0.5 ease;
animation: slideOutRight 0.5s ease forwards;
}
.success {
@@ -32,4 +54,4 @@
background-color: #ffcdd2;
color: #000000;
border: 1px solid #ef9a9a;
}
}
@@ -2,6 +2,7 @@
import { useEffect, useState } from "react";
import "./AlertBox.css";
import ClearParams from "../ClearParams/ClearParams";
interface AlertBoxProps {
message: string | null;
@@ -0,0 +1,28 @@
"use client";
import { useEffect } from "react";
interface ClearParamsProps {
paramsToClear: string[];
}
export default function ClearParams({ paramsToClear }: ClearParamsProps) {
useEffect(() => {
if (typeof window === "undefined") return;
const url = new URL(window.location.href);
let changed = false;
paramsToClear.forEach((param) => {
if (url.searchParams.has(param)) {
url.searchParams.delete(param);
changed = true;
}
});
if (changed) {
window.history.replaceState({}, "", url.toString());
}
}, [paramsToClear]);
return null;
}
+40
View File
@@ -0,0 +1,40 @@
"use client";
import { ReactNode, useCallback } from "react";
import { useRouter, usePathname, useSearchParams } from "next/navigation";
interface FormHandlerProps {
children: ReactNode;
onSubmit: () => Promise<void>;
}
export default function FormHandler({ children, onSubmit }: FormHandlerProps) {
const router = useRouter();
const searchParams = useSearchParams();
const pathname = usePathname();
const updateParams = useCallback(
(updates: Record<string, string | null>) => {
const params = new URLSearchParams(searchParams.toString());
Object.entries(updates).forEach(([key, value]) => {
if (value === null) params.delete(key);
else params.set(key, value);
});
router.push(`${pathname}?${params.toString()}`);
},
[searchParams, router, pathname]
);
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
try {
await onSubmit();
} catch (err: any) {
updateParams({ error: String(err) });
}
};
return <form onSubmit={handleSubmit}>{children}</form>;
}
@@ -1,16 +1,17 @@
'use client'
"use client";
import { useRouter } from "next/navigation";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { useEffect, useState } from "react";
interface urlProp{
urlBase:string
value:string|null
interface urlProp {
value: string | null;
}
function SearchUser(props:urlProp) {
function SearchUser(props: urlProp) {
const [numAcount, setnumAcount] = useState("");
const router = useRouter();
const pathname = usePathname();
const searchParams = useSearchParams();
useEffect(() => {
if (props.value) {
@@ -20,16 +21,17 @@ function SearchUser(props:urlProp) {
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
const params = new URLSearchParams(searchParams.toString());
if (numAcount) {
router.push(`/${props.urlBase}?numAcount=${numAcount}`);
params.delete("error");
params.set("numAcount", `${numAcount}`);
router.push(`${pathname}?${params.toString()}`);
}
};
return (
<>
<form className="containerForm"
onSubmit={handleSubmit}>
<form className="containerForm" onSubmit={handleSubmit}>
<label className="label">No.Cuenta</label>
<div className="groupInput">
<input
@@ -0,0 +1,12 @@
.stepNavigator {
position: relative;
width: 100%;
max-width: 600px;
margin-top: 1rem;
border: 1px solid #e5e7eb;
border-radius: 4px;
background-color: #f9fafb;
padding: 1rem;
display: flex;
flex-direction: column;
}
@@ -1,5 +1,7 @@
"use client";
import { usePathname, useSearchParams } from "next/navigation";
import { useRouter } from "next/navigation";
import { useState, ReactNode } from "react";
interface ToggleOption {
@@ -14,8 +16,20 @@ interface ToggleProps {
}
export default function Toggle({ options, defaultView }: ToggleProps) {
const router = useRouter();
const searchParams = useSearchParams();
const pathname = usePathname();
const [view, setView] = useState(defaultView || options[0].key);
const handleClick = (key: string) => {
setView(key);
const params = new URLSearchParams(searchParams.toString());
params.set("key", key);
router.replace(`${pathname}?${params.toString()}`);
};
return (
<section className="toggleSection">
<div className="toggleGroup">
@@ -23,7 +37,7 @@ export default function Toggle({ options, defaultView }: ToggleProps) {
<button
key={opt.key}
className={`toggleButton ${view === opt.key ? "active" : ""}`}
onClick={() => setView(opt.key)}
onClick={() => handleClick(opt.key)}
>
{opt.label}
</button>
@@ -36,3 +50,4 @@ export default function Toggle({ options, defaultView }: ToggleProps) {
</section>
);
}
//IO
@@ -0,0 +1,36 @@
"use client";
import { useEffect, useState } from "react";
import AlertBox from "@/app/Components/Global/AlertBox/AlertBox";
import ClearParams from "@/app/Components/Global/ClearParams/ClearParams";
import { useSearchParams } from "next/navigation";
export default function GlobalAlert() {
const searchParams = useSearchParams();
const [showSuccess, setShowSuccess] = useState<string | null>(null);
const [showError, setShowError] = useState<string | null>(null);
useEffect(() => {
const success = searchParams.get("success");
const error = searchParams.get("error");
if (success) setShowSuccess(success);
if (error) setShowError(error);
}, []);
return (
<section className="containerAlerts">
{showError && (
<>
<AlertBox key={Date.now()} message={showError} type="error" />
</>
)}
{showSuccess && (
<>
<AlertBox key={Date.now()} message={showSuccess} type="success" />
</>
)}
</section>
);
}
-31
View File
@@ -1,31 +0,0 @@
import Image from "next/image";
import header from"./Header.module.css";
import Link from "next/link";
function Header() {
return (
<header>
<Link href="https://www.unam.mx/" className={header.center}>
<Image
className={header.logo}
src="/logo_fes.png"
alt="Logo FES"
width={200}
height={50}
/>
</Link>
<div className={header.yellowPart}></div>
<div className={header.cedetecContainer}>
<Image
src="/cedetec.jpg"
alt="Image of CEDETEC"
width={300}
height={71}
/>
</div>
</header>
);
}
export default Header;
//IO
+22 -24
View File
@@ -5,8 +5,6 @@ import { useState } from "react";
import { useRouter } from "next/navigation";
import { PostImpressions } from "@/app/lib/postImpressions";
import "./Impressions.css";
interface CostOption {
value: number;
}
@@ -29,25 +27,24 @@ function Impressions({ costs, numAcount }: ImpressionsProps) {
};
const handlePayment = async () => {
const currentUrl = new URL(window.location.href);
const params = new URLSearchParams();
const setError = (msg: string) => {
params.set("error", msg);
router.push(`${currentUrl}&${params.toString()}`);
};
if (!numAcount) {
router.push(
`/Impresiones?numAcount=${numAcount}&error=Error busca denuevo al estudiante`
);
return;
return setError("busca de nuevo al estudiante");
}
if (!pages) {
router.push(
`/Impresiones?numAcount=${numAcount}&error=Ingresa el numero de hojas a imprimir`
);
return;
return setError("Ingresa el numero de hojas a imprimir");
}
if (!cost) {
router.push(
`/Impresiones?numAcount=${numAcount}&error=Selecciona un costo`
);
return;
return setError("Selecciona un costo");
}
const result = await PostImpressions({
@@ -59,18 +56,16 @@ function Impressions({ costs, numAcount }: ImpressionsProps) {
if (result.error) {
if (result.error === "Token inválido") handleLogout();
else {
router.push(
`/Impresiones?numAcount=${numAcount}&error=${result.error}`
);
return setError(`Error: ${result.error}`);
}
return;
}
setPages("");
setCost("");
router.push(
`/Impresiones?numAcount=${numAcount}&success=Impresion cobrada correctamente`
);
params.delete("error");
params.set("success", "Impresion cobrada correctamente");
router.push(`${currentUrl}&${params.toString()}`);
};
return (
@@ -84,7 +79,7 @@ function Impressions({ costs, numAcount }: ImpressionsProps) {
<div className="groupInput">
<label className="label">Costo:</label>
<select value={cost} onChange={(e) => setCost(e.target.value)}>
<option value="">-- Selecciona un tiempo --</option>
<option value="">Selecciona el costo</option>
{costs.map((c) => (
<option key={c.value} value={c.value}>
${c.value}
@@ -110,9 +105,12 @@ function Impressions({ costs, numAcount }: ImpressionsProps) {
/>
</div>
<div className="groupLabel">
<label className="label">
Total: {pages && cost && `$${parseInt(cost) * parseInt(pages)}.00`}
<div className="groupInput">
<label className="label">Total:</label>
<label
style={{ width: "100%", minWidth: "200px", maxWidth: "500px" }}
>
{pages && cost && `$${parseInt(cost) * parseInt(pages)}.00`}
</label>
</div>
@@ -1,5 +1,6 @@
"use client";
import { useState } from "react";
import styles from "./Page.module.css";
interface quitarSanciones {
+23 -24
View File
@@ -7,11 +7,10 @@ import { useRouter } from "next/navigation";
import "./Receipt.css";
interface ReceiptsProps {
urlBase: string;
numAcount: number | null;
}
function Receipt({ urlBase, numAcount }: ReceiptsProps) {
function Receipt({ numAcount }: ReceiptsProps) {
const router = useRouter();
const [folio, setFolio] = useState("");
@@ -29,30 +28,28 @@ function Receipt({ urlBase, numAcount }: ReceiptsProps) {
//restrict this month//
const handleSaveReceipt = async () => {
const currentUrl = new URL(window.location.href);
const params = new URLSearchParams();
const setError = (msg: string) => {
params.set("error", msg);
router.push(`${currentUrl}&${params.toString()}`);
};
if (!numAcount) {
router.push(
`${urlBase}?numAcount=${numAcount}&error=Error busca denuevo al estudiante`
);
return;
return setError("busca de nuevo al estudiante");
}
if (!folio) {
router.push(
`${urlBase}?numAcount=${numAcount}&error=Ingresa el folio del tiket`
);
return;
return setError("Ingresa el folio del ticket");
}
if (!amount) {
router.push(
`${urlBase}?numAcount=${numAcount}&error=coloca el monto a depositar`
);
return;
return setError("Coloca el monto a depositar");
}
if (!date) {
router.push(`${urlBase}?numAcount=${numAcount}&error=coloca la fecha`);
return;
return setError("Coloca la fecha");
}
try {
@@ -67,10 +64,11 @@ function Receipt({ urlBase, numAcount }: ReceiptsProps) {
setAmount("");
setDate("");
router.push(`${urlBase}?numAcount=${numAcount}&success=Recibo guardado`);
params.delete("error");
params.set("success", "Recibo guardado");
router.push(`${currentUrl}&${params.toString()}`);
} catch (err: any) {
console.error(err);
router.push(`${urlBase}?numAcount=${numAcount}&error=${err}`);
setError(String(err));
}
};
@@ -89,11 +87,11 @@ function Receipt({ urlBase, numAcount }: ReceiptsProps) {
value={folio}
onChange={(error) => {
const value = error.target.value;
if (/^\d*$/.test(value)) {
if (/^\d*$/.test(value) && value.length <= 7) {
setFolio(value);
}
}}
placeholder="Numero de folio..."
placeholder="Numero de tiket..."
inputMode="numeric"
pattern="[0-9]*"
/>
@@ -113,9 +111,10 @@ function Receipt({ urlBase, numAcount }: ReceiptsProps) {
if (value === "" || numericValue <= 1000) {
setAmount(value);
} else {
router.push(
`/Impresiones?numAcount=${numAcount}&error=El monto no puede superar $1000.00`
);
const currentUrl = new URL(window.location.href);
const params = new URLSearchParams();
params.set("error", "El monto no puede superar $1000.00");
router.push(`${currentUrl}&${params.toString()}`);
}
}
}}
@@ -1,5 +1,5 @@
"use client";
import { Margarine } from "next/font/google";
import { useState } from "react";
function SearchDateBetween() {
@@ -1,11 +0,0 @@
.stepNavigator {
position: relative;
max-width: 600px;
margin-top: 1rem;
border: 1px solid #e5e7eb;
border-radius: 4px;
background-color: #f9fafb;
padding: 1rem;
display: flex;
flex-direction: column;
}
@@ -14,7 +14,7 @@ export default function ChangePassword() {
return (
<section className="centerGrid containerSection">
<form onSubmit={handleChangePass}>
<form onSubmit={handleChangePass} className="pass">
<div className="containerInput relative">
<label className="label">Contraseña actual</label>
<input
@@ -42,7 +42,7 @@ export default function ChangePassword() {
<div className="containerInput relative">
<label className="label">Confirmar la contraña</label>
<input
placeholder="Coloca tu contraseña..."
placeholder="Coloca tu nueva contraseña..."
value={confirmNewPass}
onChange={(e) => {
setconfirmNewPass(e.target.value);
@@ -61,7 +61,7 @@ export default function ChangePassword() {
</button>
<button
className="button buttonSearch"
className="button buttonCancel"
style={{ maxWidth: "100%", width: "100%" }}
type="submit"
>
@@ -3,8 +3,8 @@ import { useState } from "react";
import { loginUser } from "@/app/lib/login";
import { useRouter } from "next/navigation";
import AlertBox from "../AlertBox/AlertBox";
import "./Login.css";
import AlertBox from "../../Global/AlertBox/AlertBox";
function Login() {
const [user, setUser] = useState("");
@@ -24,10 +24,10 @@ function Login() {
} else {
const token = data.access_token;
const payload = JSON.parse(atob(token.split(".")[1]));
const id_usuario = payload.id;
const usuario = payload.usuario;
document.cookie = `token=${token}; path=/; SameSite=Strict`;
document.cookie = `id_usuario=${id_usuario}; path=/; SameSite=Strict`;
document.cookie = `usuario=${usuario}; path=/; SameSite=Strict`;
setAlert("Inicio de sesión exitoso");
router.push("/Impresiones");
@@ -23,8 +23,8 @@
content: "";
border: 3px solid white;
border-radius: 2px;
height: 15px;
width: 15px;
height: 2rem;
width: 2rem;
position: absolute;
left: 50%;
top: 50%;
@@ -36,7 +36,7 @@
border: 2px solid white;
border-radius: 1px;
height: 0px;
width: 10px;
width: 1.5rem;
position: absolute;
left: 50%;
top: 50%;
@@ -56,20 +56,25 @@
align-items: center;
justify-content: center;
width: 100%;
gap: 10px;
position: relative;
z-index: 1;
border-radius: 4px 4px 0 0;
}
.subMenu ul {
display: none;
opacity: 0;
max-height: 0;
position: absolute;
flex-direction: column;
top: 100%;
width: 100%;
background-color: #003e79;
transition: color 0.3s ease, opacity 0.3s ease;
transition: color 0.3s ease;
transition: opacity 0.4s ease, max-height 0.4s ease;
}
.subMenu ul a {
display: none;
}
.subMenu.open ul {
@@ -82,6 +87,11 @@
}
.subMenu:hover ul {
opacity: 1;
max-height: 500px;
}
.subMenu:hover ul a {
display: flex;
}
@@ -139,7 +149,7 @@ tbody {
.barNavigation ul {
position: absolute;
background-color: rgb(1, 92, 184);
background-color: #003e79;
flex-direction: column;
padding: 10px 0;
align-items: center;
@@ -160,10 +170,10 @@ tbody {
}
.subMenu ul {
width: 90%;
width: 100%;
border-radius: 4px;
position: relative;
background-color: rgba(0, 61, 121, 1);
background-color: rgb(1, 92, 184);
}
thead,
@@ -24,7 +24,7 @@ function BarNavigation() {
<ul className={openMenu ? "active" : ""}>
<li className={`subMenu ${openSubMenu === 0 ? "open" : ""}`}>
<span onClick={() => toggleSubMenu(0)}>Inscripciones</span>
<span onClick={() => toggleSubMenu(0)}>Inscripcion</span>
<ul className="containerLinks" onClick={toggleMenu}>
<Link href="/Alta" className="links">
<li>Alta</li>
@@ -32,8 +32,8 @@ function BarNavigation() {
<Link href="/AgregarTiempo" className="links">
<li>Agregar Tiempo</li>
</Link>
<Link href="/Inscripciones" className="links">
<li>Inscripciones</li>
<Link href="/Inscripcion" className="links">
<li>Inscripcion</li>
</Link>
</ul>
</li>
@@ -26,10 +26,16 @@
content: "";
top: 0;
left: -20px;
width: 50%;
width: 65%;
height: 100%;
min-width: 300px;
background: #bd8c01;
background: linear-gradient(to right, #bd8c01, #f9f9f9);
transform: skew(-45deg);
z-index: 0;
}
@media (max-width: 800px) {
.yellowPart {
background: #bd8c01;
}
}
+35
View File
@@ -0,0 +1,35 @@
import Image from "next/image";
import header from "./Header.module.css";
import Link from "next/link";
function Header() {
return (
<header>
<Link
href="https://www.unam.mx/"
target="_blank"
className={header.center}
>
<Image
className={header.logo}
src="/logo_fes.png"
alt="Logo FES"
width={200}
height={50}
/>
</Link>
<div className={header.yellowPart}></div>
<div className={header.cedetecContainer}>
<Image
src="/cedetec.jpg"
alt="Image of CEDETEC"
width={300}
height={71}
/>
</div>
</header>
);
}
export default Header;
//IO
-33
View File
@@ -1,33 +0,0 @@
import { NextResponse } from "next/server";
export async function POST(req: Request) {
try {
const { user, password } = await req.json();
const res = await fetch(`${process.env.API_URL}/login`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ user, password }),
});
if (!res.ok) {
return NextResponse.json({ error: "Credenciales incorrectas" }, { status: 401 });
}
const data = await res.json();
const response = NextResponse.json({ success: true });
response.cookies.set("token", data.token, {
httpOnly: true,
secure: true,
path: "/",
maxAge: 60 * 60 * 24,
});
return response;
} catch (err) {
return NextResponse.json({ error: "Error en el servidor" }, { status: 500 });
}
}
//IO
+101 -11
View File
@@ -14,6 +14,7 @@ html {
box-sizing: border-box;
font-size: 62.5%;
overflow-y: auto;
scrollbar-width: none;
}
body {
@@ -26,6 +27,10 @@ body {
overflow: hidden;
}
main {
position: relative;
}
header {
display: grid;
grid-template-columns: auto 1fr;
@@ -90,6 +95,17 @@ footer p {
width: 100%;
}
@keyframes fadeInUp {
0% {
opacity: 0;
transform: translateY(20px);
}
100% {
opacity: 1;
transform: translateY(0);
}
}
.container {
display: flex;
flex-direction: column;
@@ -108,6 +124,7 @@ footer p {
overflow: hidden;
background-color: #f9f9f9;
z-index: 0;
animation: fadeInUp 1s ease forwards;
}
.containerSection {
@@ -129,7 +146,7 @@ footer p {
right: 0;
width: 725px;
height: 615px;
background-image: url("https://www.acatlan.unam.mx/images/fes_05.jpg");
background-image: url("/rock2.jpg");
background-size: cover;
background-position: center;
overflow: hidden;
@@ -148,14 +165,28 @@ footer p {
input,
select {
flex: 1;
width: 100%;
min-width: 200px;
max-width: 500px;
padding: 1rem;
padding: 0.75rem;
border: 1px solid #cfcfcf;
background-color: #fff;
border-radius: 4px;
font-size: 2rem;
color: black;
height: 4rem;
}
input:focus,
select:focus {
background-color: #f9f9f9;
outline:none;
box-shadow: 0px 0px 8px 2px rgba(0, 62, 121, 0.5);
transition: all 0.2s ease-in-out;
}
input[type="checkbox"]{
min-width: 3rem;
}
label {
@@ -169,6 +200,7 @@ button {
padding: 1rem 1.75rem;
border-radius: 4px;
cursor: pointer;
height: 4rem;
}
.groupInput {
@@ -203,6 +235,14 @@ button {
background-color: #15803d;
}
.buttonCancel {
background-color: #d32f2f;
}
.buttonCancel:hover {
background-color: #d12020;
}
.absoluteButton {
position: absolute;
bottom: 1rem;
@@ -253,9 +293,10 @@ a {
top: 0;
left: 0;
width: 100%;
font-size: 2.5rem;
font-size: 3rem;
font-weight: bold;
text-align: start;
color:#bd8c01;
border-bottom: 1px solid #cfcfcf;
margin-bottom: 10px;
}
@@ -289,7 +330,6 @@ form {
.toggleGroup {
display: flex;
gap: 5px;
background-color: #f3f4f6;
border-radius: 6px;
flex-wrap: wrap;
@@ -306,6 +346,9 @@ form {
font-weight: 500;
overflow: hidden;
max-height: 60px;
padding: 1rem 0.5rem;
min-width: 100px;
min-height: 45px;
}
.toggleButton.active {
@@ -387,9 +430,56 @@ table tr {
width: 100%;
}
.pass {
display: flex;
width: 300px;
}
.containerAlert {
position: absolute;
background-color: #003e79;
z-index: 10;
}
.checkbox-grid label {
display: inline-flex;
align-items: center;
font-size: 13px;
cursor: pointer;
margin-right: 1rem;
}
.checkbox-grid input[type="checkbox"] {
margin: 0;
padding: 0;
transform: scale(1); /* mantiene el tamaño */
}
@media (max-width: 1330px) {
.mainContainer {
grid-template-rows: 60px 1fr;
.centerGrid {
display: flex !important;
justify-content: center;
align-items: center;
}
.img {
width: 100%;
}
.img::after {
background: linear-gradient(to right, #f9f9f993, rgba(128, 128, 128, 0));
}
.img::before {
display: flex;
content: "";
position: absolute;
inset: 0;
background: linear-gradient(to left, #f9f9f993, rgba(128, 128, 128, 0));
}
.title {
text-align: center;
}
}
@@ -449,10 +539,6 @@ table tr {
background: linear-gradient(to left, #f9f9f9, rgba(128, 128, 128, 0));
}
.title {
text-align: center;
}
.containerSection {
align-items: center;
}
@@ -480,6 +566,10 @@ table tr {
font-size: 1.5rem;
padding: 1rem 1.5rem;
}
.toggleButton {
padding: 0;
}
}
@media (max-height: 960px) {
@@ -490,7 +580,7 @@ table tr {
@media (max-width: 450px) {
.title {
max-width: 300px;
max-width: 250px;
overflow-wrap: break-word;
}
}
+4 -5
View File
@@ -1,9 +1,8 @@
import type { Metadata } from "next";
import { Poppins } from "next/font/google";
import Header from "./Components/Header/Header";
import Footer from "./Components/Footer/Footer";
import FallingSquares from "./Components/visual/FallingSquares/FallingSquares";
import WavesBackground from "./Components/visual/Wave/wavesBack";
import Header from "./Components/layout/Header/Header";
import Footer from "./Components/layout/Footer/Footer";
import "./globals.css";
@@ -27,7 +26,7 @@ export default function RootLayout({
}>) {
return (
<html lang="es">
<body className={poppins.variable}>
<body className={poppins.variable} suppressHydrationWarning>
<Header />
<main>{children}</main>
<Footer />
+2 -2
View File
@@ -1,4 +1,4 @@
import Login from "./Components/Login/Login";
import Login from "./Components/auth/Login/Login";
import { LoginRedirect } from "./Routes/LoginRedirect";
export default function Home() {
@@ -13,4 +13,4 @@ export default function Home() {
</div>
);
}
//IO
//IO
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 537 KiB