diff --git a/app/(private)/AgregarTiempo/page.tsx b/app/(private)/AgregarTiempo/page.tsx index df7fc96..e5d16b0 100644 --- a/app/(private)/AgregarTiempo/page.tsx +++ b/app/(private)/AgregarTiempo/page.tsx @@ -1,11 +1,11 @@ import SearchUser from "@/app/Components/Global/SearchUser/searchUser"; import Information from "@/app/Components/Global/Information/information"; import Receipt from "@/app/Components/Receipt/Receipt"; -import toast from "react-hot-toast"; - -import { GetStudent } from "@/app/lib/getStudent"; import "./addTime.css"; +import Selection from "@/app/Components/Selection/Selection"; +import ShowError from "@/app/Components/Global/ShowError"; +import { GetRegisterStudent } from "@/app/lib/getRegisterStudent"; export default async function Page(props: { searchParams?: Promise<{ @@ -14,13 +14,14 @@ export default async function Page(props: { }) { const params = await props.searchParams; const numAcount = params?.numAcount ? params.numAcount : null; + let errorMessage = ""; let student: any = null; if (numAcount) { - const result = await GetStudent(parseInt(numAcount)); + const result = await GetRegisterStudent(parseInt(numAcount)); if (result.error) { - toast.error("Alumno no encontrado"); + errorMessage = `${result.error}`; return; } else { student = result; @@ -29,6 +30,8 @@ export default async function Page(props: { return (
+ {errorMessage && } +

AGREGAR TIEMPO

@@ -38,7 +41,7 @@ export default async function Page(props: {
-
+
diff --git a/app/(private)/Alta/page.tsx b/app/(private)/Alta/page.tsx index 6f534c4..a90117a 100644 --- a/app/(private)/Alta/page.tsx +++ b/app/(private)/Alta/page.tsx @@ -2,15 +2,11 @@ import RegisterAlta from "@/app/Components/Alta/registerAlta"; import "./style.css"; -export default async function Page(props: { - searchParams?: Promise<{ - }>; -}) { +export default async function Page(props: { searchParams?: Promise<{}> }) { const params = await props.searchParams; return (
- -

ALTA

+

ALTA USUARIO

diff --git a/app/(private)/AsignacionEquipo/page.tsx b/app/(private)/AsignacionEquipo/page.tsx index 700a708..a0a4659 100644 --- a/app/(private)/AsignacionEquipo/page.tsx +++ b/app/(private)/AsignacionEquipo/page.tsx @@ -10,7 +10,7 @@ import "@/app/globals.css"; export default async function Page(props: { searchParams?: Promise<{ - key?:string + key?: string; numAcount?: string; machine?: string; }>; @@ -52,7 +52,7 @@ export default async function Page(props: { {student && ( <> - {/*
+
@@ -74,7 +74,7 @@ export default async function Page(props: { Asignar Equipo
-
*/} + )} diff --git a/app/(private)/BitacoraSanciones/page.tsx b/app/(private)/BitacoraSanciones/page.tsx index 5ebe1ff..78cb26d 100644 --- a/app/(private)/BitacoraSanciones/page.tsx +++ b/app/(private)/BitacoraSanciones/page.tsx @@ -2,9 +2,11 @@ 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 SearchUser from "@/app/Components/Global/SearchUser/searchUser"; +import SearchUserWithDate from "@/app/Components/Global/SearchUser/SearchUserWithDate"; +import ShowError from "@/app/Components/Global/ShowError"; import Toggle from "@/app/Components/Global/Toggle/Toggle"; import { GetStudent } from "@/app/lib/getStudent"; +import { GetSancionByStudent } from "@/app/lib/getStudent copy"; export default async function Page(props: { searchParams?: Promise<{ @@ -13,23 +15,26 @@ export default async function Page(props: { }>; }) { const params = await props.searchParams; - const key = params?.key && params.key ; + const key = params?.key && params.key; const numAcount = params?.numAcount ? params.numAcount : null; - let student: any = null; - - if (numAcount) { - const result = await GetStudent(parseInt(numAcount)); - - if (result.error) { - } else { - student = result; - } + let student: any = null; + let errorMessage = ""; + + if (numAcount) { + const result = await GetStudent(parseInt(numAcount)); + + if (result.error) { + errorMessage = `${result.error}`; + } else { + student = result; } + } return (
- + {errorMessage && } +

BITACORA Y SANCIONES

- + ), @@ -68,7 +73,7 @@ export default async function Page(props: { label: "Sanciones", content: ( <> - + ), }, diff --git a/app/(private)/Impresiones/page.tsx b/app/(private)/Impresiones/page.tsx index ca95c16..48e43df 100644 --- a/app/(private)/Impresiones/page.tsx +++ b/app/(private)/Impresiones/page.tsx @@ -34,7 +34,6 @@ export default async function Page(props: { return (
- {errorMessage && }

IMPRESIONES Y PLOTEO

diff --git a/app/(private)/InformacionEquipo/page.tsx b/app/(private)/InformacionEquipo/page.tsx index a6da985..4705192 100644 --- a/app/(private)/InformacionEquipo/page.tsx +++ b/app/(private)/InformacionEquipo/page.tsx @@ -31,9 +31,6 @@ export default async function Page(props: { content: ( ), }, @@ -43,9 +40,6 @@ export default async function Page(props: { content: ( ), }, diff --git a/app/(private)/Inscripcion/page.tsx b/app/(private)/Inscripcion/page.tsx index 6dc0f1c..1d08034 100644 --- a/app/(private)/Inscripcion/page.tsx +++ b/app/(private)/Inscripcion/page.tsx @@ -4,9 +4,40 @@ import Receipt from "@/app/Components/Receipt/Receipt"; import Selection from "@/app/Components/Selection/Selection"; import ShowError from "@/app/Components/Global/ShowError"; import { GetStudent } from "@/app/lib/getStudent"; +import Table from "@/app/Components/Global/table"; +import { envConfig } from "@/app/lib/config"; import "./inscripcion.css"; -import Table from "@/app/Components/Global/table"; +import Inscripcion from "@/app/Components/Receipt/Inscripcion"; + +if (!envConfig.apiUrl) { + console.error("API URL is not defined in envConfig"); +} + +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", + } + ); + + if (!res.ok) { + throw new Error(`Error ${res.status}: ${res.statusText}`); + } + + return await res.json(); + } catch (error: any) { + return { error: error.message || "No se pudo cargar la inscripción" }; + } +} + +const headers = ["Inscrito", "Tiempo", "Confirmó"]; export default async function Page(props: { searchParams?: Promise<{ @@ -17,35 +48,36 @@ export default async function Page(props: { const numAcount = params?.numAcount ? params.numAcount : null; let student: any = null; + let inscripcion: any = null; let errorMessage = ""; - if (numAcount) { - const result = await GetStudent(parseInt(numAcount)); - if (result.error) { - errorMessage = `${result.error}`; + if (numAcount) { + const idCuenta = parseInt(numAcount); + + const studentResult = await GetStudent(idCuenta); + if (studentResult.error) { + errorMessage = `${studentResult.error}`; } else { - student = result; + student = studentResult; + } + const inscResult = await getInscripcion(idCuenta); + + if (!inscResult.error && Array.isArray(inscResult)) { + inscripcion = inscResult; + } else { + inscripcion = []; } } - const headers = ["Inscrito", "Tiempo", "Confirmó"]; - const data = [ - { - Inscrito: "WINDOWS", - Tiempo: "9 minutos", - Confirmó: "si", - }, - { - Inscrito: "WINDOWS", - Tiempo: "9 minutos", - Confirmó: "si/no", - }, - { - Inscrito: "WINDOWS", - Tiempo: "9 minutos", - Confirmó: "si/no", - }, - ]; + const tableData = Array.isArray(inscripcion) + ? inscripcion.map((ins) => ({ + Inscrito: ins.plataforma?.nombre || "—", + Tiempo: ins.tiempo_disponible + ? `${Math.floor(ins.tiempo_disponible / 60)} horas` + : "—", + Confirmó: ins.platica.data === 1 ? "sí" : "no", + })) + : []; return (
@@ -58,39 +90,46 @@ export default async function Page(props: { {student && ( - + <> + + + )} + {!student && numAcount && ( + )} - {student && } + {student && ( + <> +
+ + + )} {student && ( <>
- - - - +
)} ); } -//IO diff --git a/app/(private)/Inscritos/Inscripciones.tsx b/app/(private)/Inscritos/Inscripciones.tsx new file mode 100644 index 0000000..02924ce --- /dev/null +++ b/app/(private)/Inscritos/Inscripciones.tsx @@ -0,0 +1,79 @@ +"use client" +import { envConfig } from "@/app/lib/config"; +import axios from "axios"; +import { useEffect, useState } from "react"; + +interface Periodo{ + semestre:string, +} + +export default function Inscripciones() { + const [periodo,setPeriodo]= useState([]) + + useEffect(()=>{ + const getPeriodo = async()=>{ + const response = await axios.get(`${envConfig.apiUrl}/periodo`) + setPeriodo(response.data) + } + getPeriodo() + },[]) + + return ( +
+

INSCRITOS

+ +
+ +
+ + +
+ + +
+
+ + + + + + + + + +
CarreraGeneroProfesoresTotal
+ + +
+ + + + + + + + + + + + + + + + + + + +
Impresione B/NImpresiones ColorPlotteoEscanerTotal
5,00010,00010,00020,00045,000
+
+
+ ); +} +//IO diff --git a/app/(private)/Inscritos/page.tsx b/app/(private)/Inscritos/page.tsx index 33e0605..1181c94 100644 --- a/app/(private)/Inscritos/page.tsx +++ b/app/(private)/Inscritos/page.tsx @@ -1,3 +1,4 @@ +import Inscripciones from "./Inscripciones"; export default async function Page(props: { searchParams?: Promise<{ @@ -7,67 +8,6 @@ export default async function Page(props: { const params = await props.searchParams; const period = params?.period ? params.period : null; - return ( -
- -

INSCRITOS

- -
- -
- - -
-
- -
- - - - - - - - - - -
CarreraGeneroProfesoresTotal
-
- -
- - - - - - - - - - - - - - - - - - - - -
Impresione B/NImpresiones ColorPlotteoEscanerTotal
5,00010,00010,00020,00045,000
-
-
- ); + return ; } //IO diff --git a/app/(private)/QuitarSancion/page.tsx b/app/(private)/QuitarSancion/page.tsx index 7e2a7ed..83c7dcf 100644 --- a/app/(private)/QuitarSancion/page.tsx +++ b/app/(private)/QuitarSancion/page.tsx @@ -1,5 +1,7 @@ import SearchUser from "@/app/Components/Global/SearchUser/searchUser"; +import ShowError from "@/app/Components/Global/ShowError"; import QuitarSancion from "@/app/Components/QuitarSancion/QuitarSancion"; +import { GetSancionByStudent } from "@/app/lib/getStudent copy"; export default async function Page(props: { searchParams?: Promise<{ @@ -9,13 +11,25 @@ export default async function Page(props: { const params = await props.searchParams; const numAcount = params?.numAcount ? params.numAcount : null; + let student: any = null; + let errorMessage = ""; + + if (numAcount) { + const result = await GetSancionByStudent(parseInt(numAcount)); + if (result.error) { + errorMessage = `${result.error}`; + } else { + student = result as Student; + } + } return ( <> + {errorMessage && } +

Quitar Sanciones

-
+
- +
); diff --git a/app/(private)/Reportes/Page.module.css b/app/(private)/Reportes/Page.module.css index d48a3c1..7c33f48 100644 --- a/app/(private)/Reportes/Page.module.css +++ b/app/(private)/Reportes/Page.module.css @@ -67,3 +67,9 @@ .resetButton:hover { background-color: #cc0000; } + +.download{ + display: flex; + align-items: end; + justify-content: end; +} \ No newline at end of file diff --git a/app/(private)/Reportes/ReportesClient.tsx b/app/(private)/Reportes/ReportesClient.tsx new file mode 100644 index 0000000..e6004fb --- /dev/null +++ b/app/(private)/Reportes/ReportesClient.tsx @@ -0,0 +1,59 @@ +"use client"; + +import { useState } from "react"; +import Toggle from "@/app/Components/Global/Toggle/Toggle"; +import SearchDateBetween from "@/app/Components/SearchDateBetween/SearchDateBetween"; +import PorServicios from "@/app/Components/Reportes/porServicio"; +import PorRecibos from "@/app/Components/Reportes/porRecibo"; +import DownloadReporteXLSX from "@/app/Components/Dowload/Reporte"; + +export default function ReportesClient({ + defaultKey, +}: { + defaultKey?: string; +}) { + const [desde, setDesde] = useState(null); + const [hasta, setHasta] = useState(null); + + return ( +
+

REPORTES

+ + + { + setDesde(d); + setHasta(h); + }} + /> + + + ), + }, + { + key: "Por Servicio", + label: "Por Servicio", + content: ( + <> + { + setDesde(d); + setHasta(h); + }} + /> + + + ), + }, + ]} + /> +
+ ); +} diff --git a/app/(private)/Reportes/page.tsx b/app/(private)/Reportes/page.tsx index a328a07..b361760 100644 --- a/app/(private)/Reportes/page.tsx +++ b/app/(private)/Reportes/page.tsx @@ -1,48 +1,11 @@ -import Toggle from "@/app/Components/Global/Toggle/Toggle"; -import SearchDateBetween from "@/app/Components/SearchDateBetween/SearchDateBetween"; -import PorServicios from "@/app/Components/Reportes/porServicio"; -import PorRecibos from "@/app/Components/Reportes/porRecibo"; +import ReportesClient from './ReportesClient'; export default async function Page(props: { searchParams?: Promise<{ key: string; - numAcount: string; }>; }) { const params = await props.searchParams; - const key = params?.key && params.key; - return ( -
-

REPORTES

- - - - - - ), - }, - - { - key: "Por Servicio", - label: "Por Servicio", - content: ( - <> - - - - ), - }, - ]} - /> -
- ); + return ; } -//IO diff --git a/app/(private)/layout.tsx b/app/(private)/layout.tsx index 565678d..ae14491 100644 --- a/app/(private)/layout.tsx +++ b/app/(private)/layout.tsx @@ -9,7 +9,6 @@ export default async function PrivateLayout({ }) { return (
-
diff --git a/app/Components/ActivosMantenimiento/MesasDisponibles.tsx b/app/Components/ActivosMantenimiento/MesasDisponibles.tsx index fa89767..aef9e8b 100644 --- a/app/Components/ActivosMantenimiento/MesasDisponibles.tsx +++ b/app/Components/ActivosMantenimiento/MesasDisponibles.tsx @@ -1,13 +1,10 @@ -import styles from "./Page.module.css"; - export default async function MesasDisponibles() { return (
- -
- +
+
- + diff --git a/app/Components/Alta/registerAlta.tsx b/app/Components/Alta/registerAlta.tsx index 5a078c4..6e43cbf 100644 --- a/app/Components/Alta/registerAlta.tsx +++ b/app/Components/Alta/registerAlta.tsx @@ -76,6 +76,28 @@ export default function RegisterAlta() { /> +
+ + setUser(e.target.value)} + placeholder="Coloca el email" + /> +
+ +
+ + +
+
- + + ); } diff --git a/app/Components/AsignacionMesas.tsx b/app/Components/AsignacionMesas.tsx index 2af6100..b87282a 100644 --- a/app/Components/AsignacionMesas.tsx +++ b/app/Components/AsignacionMesas.tsx @@ -1,19 +1,34 @@ "use client"; -import { SetStateAction, useState } from "react"; +import axios from "axios"; +import { SetStateAction, 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([]); + + useEffect(() => { + const getMesa = async() => { + const response = await axios.get(`${envConfig.apiUrl}/mesa/activo`); + setMesa(response.data); + }; + getMesa() + }, []); + return (
Mesa Activo
- - - - - +
Tiempo EntradaTiempo AsignadoUbicacion del equipo
+ + + + + + + + + {alumnos.map((alumno, index) => ( + + + + - - - {alumnos.map((alumno, index) => ( - - - - - - ))} - -
Tiempo EntradaTiempo AsignadoUbicacion del equipo
{alumno.tiempo_entrada}{alumno.tiempo_asignado}{alumno.Ubicacion_equipo}
{alumno.tiempo_entrada}{alumno.tiempo_asignado}{alumno.Ubicacion_equipo}
-
+ ))} + + ); } diff --git a/app/Components/BitacoraSanciones/BitacoraEquipo.tsx b/app/Components/BitacoraSanciones/BitacoraEquipo.tsx index a335743..36f01c2 100644 --- a/app/Components/BitacoraSanciones/BitacoraEquipo.tsx +++ b/app/Components/BitacoraSanciones/BitacoraEquipo.tsx @@ -2,8 +2,6 @@ import SearchDate from "../SearchDate/SearchDate"; import { useState } from "react"; -import styles from "./Page.module.css"; - interface equipos { hora_entrada: string; min_utilizados: number; @@ -16,7 +14,6 @@ function BitacoraEquipo() { const [ubicacion_equipo, setUbicacionEquipo] = useState(""); return ( <> - @@ -28,13 +25,11 @@ function BitacoraEquipo() { -
-
- + +
+
diff --git a/app/Components/BitacoraSanciones/BitacoraMesas.tsx b/app/Components/BitacoraSanciones/BitacoraMesas.tsx index d27e3d3..14c2d6f 100644 --- a/app/Components/BitacoraSanciones/BitacoraMesas.tsx +++ b/app/Components/BitacoraSanciones/BitacoraMesas.tsx @@ -2,8 +2,6 @@ import SearchDate from "../SearchDate/SearchDate"; import { useState } from "react"; -import styles from "./Page.module.css"; - interface tables { no_mesa: number; no_cuenta: number; @@ -18,8 +16,8 @@ function BitacoraMesas() { return ( <> -
-
Hora Entrada
+
+
diff --git a/app/Components/BitacoraSanciones/Sanciones.tsx b/app/Components/BitacoraSanciones/Sanciones.tsx index b4442e9..e85d14d 100644 --- a/app/Components/BitacoraSanciones/Sanciones.tsx +++ b/app/Components/BitacoraSanciones/Sanciones.tsx @@ -5,24 +5,22 @@ import TableSancion from "./TableSancion"; interface Student { id_cuenta: string; nombre: string; + credito?: number; } -export default async function Sanciones(props: { student?: Student }) { - const idCuenta = props?.student?.id_cuenta ?? null; +export default function Sanciones({ student }: { student?: Student }) { + const idCuenta = student?.id_cuenta ?? null; return ( <> - {props.student && ( + {student && ( <> - - - + + )} ); } +// diff --git a/app/Components/BitacoraSanciones/TableSancion.tsx b/app/Components/BitacoraSanciones/TableSancion.tsx index e45662e..4e065d4 100644 --- a/app/Components/BitacoraSanciones/TableSancion.tsx +++ b/app/Components/BitacoraSanciones/TableSancion.tsx @@ -1,73 +1,129 @@ "use client"; import { useEffect, useState } from "react"; -import styles from "./Page.module.css"; import axios from "axios"; +import toast from "react-hot-toast"; +import { envConfig } from "@/app/lib/config"; -interface alumno_sancion { - id_alumno_sancion: number; - fecha_inicio: string; - alumno: alumno; - sancion: sancion; -} - -interface alumno { +interface Alumno { id_cuenta: number; nombre: string; credito: number; } -interface sancion { +interface Sancion { id_sancion: number; sancion: string; duracion: number; } -export default function TableSancion() { - const [sanciones, setSanciones] = useState(); - const [button, setButton] = useState(false); +interface AlumnoSancion { + id_alumno_sancion: number; + fecha_inicio: string; + sancion: Sancion; +} - // useEffect(() => { - // const getSanciones = async () => { - // const response = await axios.get(""); - // setSanciones(response); - // }; - // getSanciones(); - // }, [button]); +if (!envConfig.apiUrl) { + console.error("API URL is not defined in envConfig"); +} - const handlebutton = () => { - setButton(!button); +export default function TableSancion({ idCuenta }: { idCuenta: number }) { + const [sanciones, setSanciones] = useState([]); + const [alumno, setAlumno] = useState(null); + const [alumnoSanciones, setAlumnoSanciones] = useState([]); + const [selectedSancion, setSelectedSancion] = useState(""); + + useEffect(() => { + if (!idCuenta) return; + + // Obtener sanciones del alumno + axios + .get( + `${envConfig.apiUrl}/asignacionTiempo_test/alumno-sancion/${idCuenta}` + ) + .then((res) => { + setAlumno(res.data.student); + setAlumnoSanciones( + res.data.alusancion?.length ? res.data.alusancion : [] + ); + }) + .catch((err) => + toast.error("Error al obtener las sanciones del alumno:", err) + ); + + // Obtener catálogo de sanciones + axios + .get(`${envConfig.apiUrl}/asignacionTiempo_test/sancion`) + .then((res) => setSanciones(res.data)) + .catch((err) => + toast.error("Error al obtener el catálogo de sanciones:", err) + ); + }, [idCuenta]); + + const calcularFechaFin = (fechaInicio: string, duracionSemanas: number) => { + const fecha = new Date(fechaInicio); + fecha.setDate(fecha.getDate() + duracionSemanas * 7); + return fecha.toLocaleDateString(); }; - + return ( <> -
-
Mesa
+
+
- + - + - + + {alumnoSanciones.length > 0 ? ( + alumnoSanciones.map((item) => ( + + + + + + + + )) + ) : ( + + + + )} +
Cuenta Motivo de la sanciónDuracion (Semanas) Duración (Semanas) Fecha SanciónPodra utilizar el servicio hastaPodrá utilizar el servicio hasta
{alumno?.id_cuenta}{item.sancion.sancion}{item.sancion.duracion}{new Date(item.fecha_inicio).toLocaleDateString()} + {calcularFechaFin(item.fecha_inicio, item.sancion.duracion)} +
No hay sanciones registradas
- setSelectedSancion(e.target.value)} + > - + {sanciones.map((sancion) => ( + + ))}
- ); } -//IO diff --git a/app/Components/Dowload/Reporte.tsx b/app/Components/Dowload/Reporte.tsx new file mode 100644 index 0000000..42e0a8d --- /dev/null +++ b/app/Components/Dowload/Reporte.tsx @@ -0,0 +1,59 @@ +"use client"; + +import styles from "./style.module.css"; +import Cookies from "js-cookie"; +import { useState } from "react"; +import toast from "react-hot-toast"; + +export default function DownloadReporteXLSX() { + const [loading, setLoading] = useState(false); + + const handleDownload = async () => { + setLoading(true); + const token = Cookies.get("token"); + const headers = { Authorization: `Bearer ${token}` }; + + try { + const response = await fetch( + `${process.env.NEXT_PUBLIC_API_URL}/equipos/reporteXLSX`,//Modificar + { headers } + ); + + if (!response.ok) { + toast.error("Error al descargar el archivo"); + return; + } + + const blob = await response.blob(); + const url = window.URL.createObjectURL(blob); + + const a = document.createElement("a"); + a.href = url; + a.download = "Reporte Recibos.xlsx"; + document.body.appendChild(a); + a.click(); + a.remove(); + + window.URL.revokeObjectURL(url); + } catch (error) { + console.error(error); + toast.error("Hubo un problema al descargar el archivo."); + } finally { + setLoading(false); + } + }; + + return ( + + ); +} diff --git a/app/Components/Dowload/style.module.css b/app/Components/Dowload/style.module.css new file mode 100644 index 0000000..936347b --- /dev/null +++ b/app/Components/Dowload/style.module.css @@ -0,0 +1,46 @@ +.downloadBtn { + position: absolute; + right: 15px; + top:-35px; + display: flex; + justify-content: center; + align-items: center; + gap: 8px; + background: #ffffff; + border: 1px solid #ddd; + border-bottom: none; + padding: 5px 5px; + cursor: pointer; + border-radius: 10px 10px 0 0; + font-size: 14px; + font-weight: 600; + transition: background 0.2s ease; + min-width: 50px; +} + +.downloadBtn:hover { + background: #95d2b0; +} + +.downloadBtn:disabled { + background: #a5a5a5; + cursor: not-allowed; +} + +.loader { + border: 3px solid #ffffff55; + border-top: 3px solid white; + border-radius: 50%; + width: 16px; + height: 16px; + animation: spin 0.8s linear infinite; +} + +@keyframes spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} diff --git a/app/Components/Equipos/equipos.tsx b/app/Components/Equipos/equipos.tsx index 2902ca0..f77917f 100644 --- a/app/Components/Equipos/equipos.tsx +++ b/app/Components/Equipos/equipos.tsx @@ -8,75 +8,118 @@ interface Data { id_equipo: number; id_plataforma: number; id_area_ubicacion: number; + ubicacion: string; +} + +interface Plataforma { + id_plataforma: number; + nombre: string; +} + +interface Area { + id_area_ubicacion: number; + area: string; + extra: string; } export default function Equipos() { - const [Equipo, setEquipo] = useState(""); - const [Data, setData] = useState(); + const [id, setId] = useState(""); + const [data, setData] = useState(null); - const handleSubmit = async (e: React.MouseEvent) => { + const [plataforma, setPlataforma] = useState([]); + const [area, setArea] = useState([]); + + const [ubicacion, setUbicacion] = useState(""); + const [nombre, setNombre] = useState(""); + + const [idPlataforma, setIdPlataforma] = useState(""); + const [idArea, setIdArea] = useState(""); + + const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); - // const response = await axios.get( - // `${envConfig.apiUrl}/equipo/${Equipo}` - // ); - // if (!response) { - // return; - // } - setData("response"); + const [equipoRes, plataformaRes, areaRes] = await Promise.all([ + axios.get(`${envConfig.apiUrl}/equipo/${id}`), + axios.get(`${envConfig.apiUrl}/alumno-inscrito/plataforma`), + axios.get(`${envConfig.apiUrl}/area-ubicacion`) + ]); + + const equipo = equipoRes.data as Data; + + setData(equipo); + setNombre(equipo.nombre_equipo); + setUbicacion(equipo.ubicacion); + setIdPlataforma(equipo.id_plataforma); + setIdArea(equipo.id_area_ubicacion); + + setPlataforma(plataformaRes.data); + setArea(areaRes.data); }; return ( -
+
{ - setEquipo(e.target.value); - }} + placeholder="Número de Equipo a buscar..." + value={id} + onChange={(e) => setId(e.target.value)} /> -
- {Data && ( + {data && (
- + setUbicacion(e.target.value)} /> - + setNombre(e.target.value)} + /> - setIdPlataforma(Number(e.target.value))} + > + + {plataforma.map((plat) => ( + + ))} - - setIdArea(Number(e.target.value))} + > + + {area.map((a) => ( + + ))} -
- - + +
+ +
)} diff --git a/app/Components/Equipos/tableequipos.tsx b/app/Components/Equipos/tableequipos.tsx index a072348..a5811ce 100644 --- a/app/Components/Equipos/tableequipos.tsx +++ b/app/Components/Equipos/tableequipos.tsx @@ -1,13 +1,10 @@ -import styles from "./Page.module.css"; - export default async function TableEquipos() { return (
- -
- +
+
- + diff --git a/app/Components/Global/SearchUser/SearchUserWithDate.tsx b/app/Components/Global/SearchUser/SearchUserWithDate.tsx new file mode 100644 index 0000000..595101d --- /dev/null +++ b/app/Components/Global/SearchUser/SearchUserWithDate.tsx @@ -0,0 +1,58 @@ +"use client"; + +import { usePathname, useRouter, useSearchParams } from "next/navigation"; +import { useEffect, useState } from "react"; +import SearchDate from "../../SearchDate/SearchDate"; + +interface urlProp { + value: string | null; +} + +function SearchUserWithDate(props: urlProp) { + const [numAcount, setnumAcount] = useState(""); + const router = useRouter(); + const pathname = usePathname(); + const searchParams = useSearchParams(); + + useEffect(() => { + if (props.value) { + setnumAcount(props.value); + } + }, [props.value]); + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + const params = new URLSearchParams(searchParams.toString()); + if (numAcount) { + params.set("numAcount", `${numAcount}`); + router.push(`${pathname}?${params.toString()}`); + } + }; + + return ( + <> + + +
+ { + const value = e.target.value; + if (/^\d*$/.test(value) && value.length <= 9) { + setnumAcount(value); + } + }} + placeholder="Coloca un número de cuenta..." + inputMode="numeric" + pattern="[0-9]*" + /> +
+ + + + ); +} + +export default SearchUserWithDate; +//IO diff --git a/app/Components/Global/Toggle/Toggle.tsx b/app/Components/Global/Toggle/Toggle.tsx index 999bf9b..6c3a237 100644 --- a/app/Components/Global/Toggle/Toggle.tsx +++ b/app/Components/Global/Toggle/Toggle.tsx @@ -29,7 +29,7 @@ export default function Toggle({ options, defaultView }: ToggleProps) { router.replace(`${pathname}?${params.toString()}`); }; - + return (
@@ -44,10 +44,10 @@ export default function Toggle({ options, defaultView }: ToggleProps) { ))}
-
+
{options.find((opt) => opt.key === view)?.content}
); } -//IO \ No newline at end of file +//IO diff --git a/app/Components/Global/table.module.css b/app/Components/Global/table.module.css index b25dd2e..d4c065c 100644 --- a/app/Components/Global/table.module.css +++ b/app/Components/Global/table.module.css @@ -1,4 +1,5 @@ .tableContainer { + margin-top: 1rem; width: 100%; max-width: 450px; overflow-x: hidden; diff --git a/app/Components/Impressions/impressions.tsx b/app/Components/Impressions/impressions.tsx index 6a03ba4..b0e9029 100644 --- a/app/Components/Impressions/impressions.tsx +++ b/app/Components/Impressions/impressions.tsx @@ -101,7 +101,7 @@ function Impressions({ costs, numAcount }: ImpressionsProps) { /> -
+
Ubicación Nombre Plataforma
+
+
- + - + - + - {quitarSanciones.map((quitarSanciones, index) => ( - - - - - - - + {data && data.alusancion.length !== 0 ? ( + data.alusancion.map((item) => ( + + + + + + + + + )) + ) : ( + + - ))} + )}
idID Nombre Motivo SanciónDuracion (semanas) Duración (semanas) Fecha SanciónPodria utilizar el servicio hastaPodría utilizar el servicio hasta
{quitarSanciones.id}{quitarSanciones.nombre}{quitarSanciones.motivo}{quitarSanciones.duracion}{quitarSanciones.fecha_sancion}{quitarSanciones.utilizar_equipo}
{item.id_alumno_sancion}{data.student.nombre}{item.sancion.sancion}{item.sancion.duracion}{new Date(item.fecha_inicio).toLocaleDateString()} + {calcularFechaFin(item.fecha_inicio, item.sancion.duracion)} +
No hay sanciones registradas
-
); } diff --git a/app/Components/Receipt/Inscripcion.tsx b/app/Components/Receipt/Inscripcion.tsx new file mode 100644 index 0000000..11817af --- /dev/null +++ b/app/Components/Receipt/Inscripcion.tsx @@ -0,0 +1,154 @@ +"use client"; + +import toast from "react-hot-toast"; +import { useState } from "react"; +import { PostReceipt } from "@/app/lib/postReceipt"; +import { useRouter } from "next/navigation"; + +import "./Receipt.css"; +import Selection from "../Selection/Selection"; + +interface ReceiptsProps { + numAcount: number | null; +} + +export default function Inscripcion({ numAcount }: ReceiptsProps) { + const router = useRouter(); + + const [folio, setFolio] = useState(""); + const [amount, setAmount] = useState(""); + const [date, setDate] = useState(""); + + //restrict this month// + const day = new Date(); + const year = day.getFullYear(); + const month = day.getMonth(); + const today = day.getDate(); + + const minFecha = new Date(year, month, 1).toISOString().split("T")[0]; + const maxFecha = new Date(year, month, today).toISOString().split("T")[0]; + //restrict this month// + + const handleSaveReceipt = async () => { + if (!numAcount) { + toast.error("busca de nuevo al estudiante"); + return; + } + + if (!folio) { + toast.error("Ingresa el folio del ticket"); + return; + } + + if (!amount) { + toast.error("Coloca el monto a depositar"); + return; + } + + if (!date) { + toast.error("Coloca la fecha"); + return; + } + + try { + await PostReceipt({ + id_cuenta: numAcount, + folio_recibo: folio, + monto: Number(amount), + fecha_recibo: date, + }); + + setFolio(""); + setAmount(""); + setDate(""); + + toast.success("Recibo guardado"); + router.refresh(); + } catch (err: any) { + toast.error(String(err)); + } + }; + + return ( +
+ + + + + { + e.preventDefault(); + handleSaveReceipt(); + }} + > +
+
+ + { + const value = error.target.value; + if (/^\d*$/.test(value) && value.length <= 7) { + setFolio(value); + } + }} + placeholder="Numero de tiket..." + inputMode="numeric" + pattern="[0-9]*" + /> +
+ +
+ + { + const value = e.target.value; + + if (/^\d*\.?\d*$/.test(value)) { + const numericValue = parseFloat(value); + + if (value === "" || numericValue <= 1000) { + setAmount(value); + } else { + toast.error("El monto no puede superar $1000.00"); + } + } + }} + placeholder="Monto recibido..." + inputMode="numeric" + pattern="^\d*\.?\d+$" + /> +
+ +
+ + setDate(e.target.value)} + min={minFecha} + max={maxFecha} + /> +
+ +
+ +
+
+ +
+ ); +} +//IO diff --git a/app/Components/Receipt/Receipt.tsx b/app/Components/Receipt/Receipt.tsx index 4c0891d..c156f61 100644 --- a/app/Components/Receipt/Receipt.tsx +++ b/app/Components/Receipt/Receipt.tsx @@ -129,7 +129,7 @@ function Receipt({ numAcount }: ReceiptsProps) {
- +
diff --git a/app/Components/Reportes/porRecibo.tsx b/app/Components/Reportes/porRecibo.tsx index 8590296..39da5a2 100644 --- a/app/Components/Reportes/porRecibo.tsx +++ b/app/Components/Reportes/porRecibo.tsx @@ -1,32 +1,93 @@ "use client"; -import { useState } from "react"; -import styles from "./Page.module.css"; -interface reportes { - Servicio: "Plotter"; - Total: "$1440.00"; +import { useEffect, useState } from "react"; +import axios from "axios"; +import DownloadReporteXLSX from "../Dowload/Reporte"; + +interface Recibo { + id_recibo: number; + folio_recibo: string; + fecha_recibo: string; + fecha_registro: string; + monto: string; + user: { + nombre: string; + }; } -function PorRecibos() { - const [reportes, SetQuitarSanciones] = useState([]); +interface Props { + desde: string | null; + hasta: string | null; +} + +function PorRecibos({ desde, hasta }: Props) { + const [recibos, setRecibos] = useState([]); + const [loading, setLoading] = useState(false); + + useEffect(() => { + if (!desde || !hasta) return; + + const fetchRecibos = async () => { + setLoading(true); + try { + const res = await axios.post( + `${process.env.NEXT_PUBLIC_API_URL}/recibo/rango`, + { desde, hasta } + ); + + setRecibos(res.data); + } catch (error) { + console.error("Error al obtener recibos", error); + } finally { + setLoading(false); + } + }; + + fetchRecibos(); + }, [desde, hasta]); + return ( -
- - - - - - - - - {reportes.map((reporte, index) => ( - - - +
+ {recibos.length > 0 && } +
+ {loading &&

Cargando...

} + +
ServicioTotal
{reporte.Servicio}{reporte.Total}
+ + + + + + + - ))} - -
FolioMontofecha recibofecha registroUsuario
+ + + + {!loading && recibos.length === 0 && ( + + No hay recibos en este rango + + )} + + {recibos.map((recibo) => ( + + {recibo.folio_recibo} + ${Number(recibo.monto).toFixed(2)} + {recibo.fecha_recibo} + {recibo.fecha_registro} + {recibo.user.nombre} + + ))} + + +
); } diff --git a/app/Components/Reportes/porServicio.tsx b/app/Components/Reportes/porServicio.tsx index 0259344..0f1e2cb 100644 --- a/app/Components/Reportes/porServicio.tsx +++ b/app/Components/Reportes/porServicio.tsx @@ -1,43 +1,86 @@ "use client"; -import { useState } from "react"; -import styles from "./Page.module.css"; -interface servicios { - folio_recibo: "100255"; - monto: "40.00"; - fecha_recibo: "10/10/2025"; - fecha_registro: "10/10/2025 05:32:20 pm"; - usuario: "modulo1"; +import { useEffect, useState } from "react"; +import axios from "axios"; +import DownloadReporteXLSX from "../Dowload/Reporte"; + + +interface ServicioReporte { + id_servicio: number; + servicio: string; + total: string; } -function PorServicios() { - const [recibos, setRecibos] = useState([]); +interface Props { + desde: string | null; + hasta: string | null; +} + +function PorServicio({ desde, hasta }: Props) { + const [servicios, setServicios] = useState([]); + const [loading, setLoading] = useState(false); + + useEffect(() => { + if (!desde || !hasta) return; + + const fetchServicios = async () => { + setLoading(true); + try { + const res = await axios.post( + `${process.env.NEXT_PUBLIC_API_URL}/detalle-servicio/rango`, + { desde, hasta } + ); + + setServicios(res.data); + } catch (error) { + console.error("Error al obtener reporte por servicio", error); + } finally { + setLoading(false); + } + }; + + fetchServicios(); + }, [desde, hasta]); + return ( -
- - - - - - - - - - - - {recibos.map((recibo, index) => ( - - - - - - +
+ {servicios.length > 0 && } + +
+ {loading &&

Cargando...

} + +
Folio ReciboMontoFecha ReciboFecha RegistroUsuario
{recibo.folio_recibo}{recibo.monto}{recibo.fecha_recibo}{recibo.fecha_registro}{recibo.usuario}
+ + + + - ))} - -
ServicioMonto total
+ + + + {!loading && servicios.length === 0 && ( + + No hay servicios en este rango + + )} + + {servicios.map((servicio) => ( + + {servicio.servicio} + ${Number(servicio.total).toFixed(2)} + + ))} + + +
); } -export default PorServicios; +export default PorServicio; diff --git a/app/Components/SearchDateBetween/SearchDateBetween.tsx b/app/Components/SearchDateBetween/SearchDateBetween.tsx index 38102bb..3ccbba4 100644 --- a/app/Components/SearchDateBetween/SearchDateBetween.tsx +++ b/app/Components/SearchDateBetween/SearchDateBetween.tsx @@ -1,51 +1,46 @@ -"use client"; +'use client'; -import { useState } from "react"; +import { useState } from 'react'; -function SearchDateBetween() { - const [startDate, setStartDate] = useState(""); - const [endDate, setEndDate] = useState(""); +interface Props { + onSearch: (desde: string, hasta: string) => void; +} + +function SearchDateBetween({ onSearch }: Props) { + const [startDate, setStartDate] = useState(''); + const [endDate, setEndDate] = useState(''); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); - console.log("Fecha inicio:", startDate); - console.log("Fecha fin:", endDate); - // Aquí puedes hacer la lógica para buscar entre fechas + if (!startDate || !endDate) return; + onSearch(startDate, endDate); }; return ( - <> -
- -
- setStartDate(e.target.value)} - placeholder="Fecha inicio" - /> -
- -
- setEndDate(e.target.value)} - placeholder="Fecha fin" - /> -
- -
- +
+ +
+ setStartDate(e.target.value)} + /> +
+ + +
+ setEndDate(e.target.value)} + /> +
+ + +
); } export default SearchDateBetween; - -// By Tyrannuss diff --git a/app/Components/SelectAreas.tsx b/app/Components/SelectAreas.tsx index 144fd5c..85b3521 100644 --- a/app/Components/SelectAreas.tsx +++ b/app/Components/SelectAreas.tsx @@ -1,6 +1,11 @@ "use client"; import axios from "axios"; import { useEffect, useState } from "react"; +import { envConfig } from "../lib/config"; + +if (!envConfig.apiUrl) { + console.error("API URL is not defined in envConfig"); +} interface proms { url: string; @@ -12,9 +17,13 @@ export default function SelectAreas(props: proms) { useEffect(() => { axios - .get(props.url) - .then((data) => setAreas(data.data)) - .catch((error) => console.error("Error al traer las áreas:", error)); + .get(`${envConfig.apiUrl}/area-ubicacion`) + .then((data) => { + setAreas(data.data); + }) + .catch((error) => { + console.error("Error al traer las áreas:", error); + }); }, []); return ( diff --git a/app/Components/auth/ChangePassword/changePassword.tsx b/app/Components/auth/ChangePassword/changePassword.tsx index e59abfc..48b7b0b 100644 --- a/app/Components/auth/ChangePassword/changePassword.tsx +++ b/app/Components/auth/ChangePassword/changePassword.tsx @@ -1,17 +1,24 @@ "use client"; import apiClient from "@/app/lib/apiClient"; import { useState } from "react"; +import toast from "react-hot-toast"; export default function ChangePassword() { - const [pass, setPass] = useState(""); - const [newPass, setNewPass] = useState(""); + const [password, setPass] = useState(""); + const [newPassword, setNewPass] = useState(""); const [confirmNewPass, setconfirmNewPass] = useState(""); const handleChangePass = async (e: React.FormEvent) => { - e.preventDefault; - const data = { pass, newPass, confirmNewPass }; + e.preventDefault(); + const data = { password, newPassword }; - await apiClient.post("/user/create", data); + try{ + const response = await apiClient.post("/user/changePassword", data); + toast.success( `${response.data.message}`) + }catch{ + toast.error( `No es la contraseña actual`) + } + }; return ( @@ -21,7 +28,8 @@ export default function ChangePassword() { { setPass(e.target.value); }} @@ -33,7 +41,8 @@ export default function ChangePassword() { { setNewPass(e.target.value); }} @@ -46,6 +55,7 @@ export default function ChangePassword() { { setconfirmNewPass(e.target.value); }} @@ -57,7 +67,6 @@ export default function ChangePassword() { @@ -65,7 +74,6 @@ export default function ChangePassword() { @@ -74,3 +82,4 @@ export default function ChangePassword() {
); } +//IO \ No newline at end of file diff --git a/app/Components/auth/Login/Login.tsx b/app/Components/auth/Login/Login.tsx index 4cd7228..25dc5cb 100644 --- a/app/Components/auth/Login/Login.tsx +++ b/app/Components/auth/Login/Login.tsx @@ -33,9 +33,11 @@ function Login() { const token = data.access_token; const payload = JSON.parse(atob(token.split(".")[1])); const usuario = payload.usuario; + const role = payload.role; document.cookie = `token=${token}; path=/; SameSite=Strict`; document.cookie = `user=${usuario}; path=/; SameSite=Strict`; + document.cookie = `role=${role}; path=/; SameSite=Strict`; toast.success("Inicio de sesión exitoso"); router.push("/Impresiones"); @@ -45,7 +47,7 @@ function Login() { return (
-

Inicio de sesión

+

Bienvenido a AT

diff --git a/app/Components/auth/Logout/Logout.css b/app/Components/auth/Logout/Logout.css index a346fa3..88d5711 100644 --- a/app/Components/auth/Logout/Logout.css +++ b/app/Components/auth/Logout/Logout.css @@ -16,7 +16,6 @@ color: transparent; padding: 2rem; font-size: 0px; - top: 15px; } .button-logout::after { diff --git a/app/Components/auth/Logout/Logout.tsx b/app/Components/auth/Logout/Logout.tsx index 3f8ab15..580eb85 100644 --- a/app/Components/auth/Logout/Logout.tsx +++ b/app/Components/auth/Logout/Logout.tsx @@ -10,6 +10,9 @@ export default function Logout() { const handleLogout = () => { Cookies.remove("token", { path: "/" }); + Cookies.remove("role", { path: "/" }); + Cookies.remove("user", { path: "/" }); + router.push("/"); }; diff --git a/app/Components/layout/BarNavigation/BarNavigation.css b/app/Components/layout/BarNavigation/BarNavigation.css index 0f3debf..6e42464 100644 --- a/app/Components/layout/BarNavigation/BarNavigation.css +++ b/app/Components/layout/BarNavigation/BarNavigation.css @@ -1,11 +1,11 @@ .barNavigation { text-align: center; - background-color: #003e79; - padding: 0 20px; + background-color: #ffffff; display: flex; width: 100%; top: 0; - min-height: 40px; + height: 45px; + max-height: 40px; } .barNavigation ul { @@ -13,24 +13,23 @@ justify-content: space-around; width: 100%; gap: 10px; + transition: width 0.5 ease-in-out; } .barNavigation li { transition: all 0.3s ease; cursor: pointer; - color: white; + color: #585858; width: 100%; - transition: background-color 0.3s ease; + transition: background-color 0.3s ease, border 0.3s ease; font-size: 1.5rem; } .barNavigation li:hover { - background-color: #bd8c01; -} - -.barNavigation ul.active { - display: flex; - width: 100%; + background-color: #f3f4f6; + color: black !important; + border-radius: 8px; + z-index: 2; } .menuToggle { @@ -40,13 +39,12 @@ gap: 4px; cursor: pointer; padding: 10px; - margin-right: 10px; } .menuToggle div { width: 25px; height: 3px; - background-color: white; + background-color: #000000; border-radius: 4px; } @@ -68,7 +66,10 @@ flex-direction: column; top: 100%; width: 100%; - background-color: #003e79; + min-width: 200px; + border: 1px solid #cfcfcf; + border-radius: 8px; + background-color: #ffffff; transition: color 0.3s ease; transition: opacity 0.4s ease, max-height 0.4s ease; } @@ -83,7 +84,7 @@ } .subMenu ul:hover { - color: #5b8cc9; + color: #101113; } .subMenu:hover ul { @@ -100,18 +101,26 @@ } .subMenu span { + font-weight: bold; display: flex; width: 100%; height: 100%; align-items: center; justify-content: center; - color: rgb(255, 255, 255); - font-size: 2rem; + color: #545454; + font-size: 1.5rem; + padding: 1rem; +} + +.subMenu:hover > span, +.subMenu > a:hover > span { + color: black; } .containerLinks { padding: 0 !important; border-radius: 0 0 4px 4px; + top: 20px; } .links { @@ -129,7 +138,7 @@ tbody { font-size: 1.25rem; } -@media (max-width: 800px) { +@media (max-width: 1000px) { .menuToggle { display: flex; position: relative; @@ -149,13 +158,36 @@ tbody { .barNavigation ul { position: absolute; - background-color: #003e79; + top: 76px; + left: 0; + width: 100%; + background-color: #fff; flex-direction: column; - padding: 10px 0; align-items: center; - display: none; - z-index: 1; - height: auto; + z-index: 10; + + transform: translateY(-15px); + opacity: 0; + + pointer-events: none; + + transition: transform 0.35s ease-in-out, opacity 0.35s ease-in-out, + visibility 0.35s ease-in-out; + } + + .barNavigation ul.active { + position: absolute; + left: 0; + display: flex; + width: 100%; + transform: translateY(0); + opacity: 1; + visibility: visible; + pointer-events: auto; + } + + .containerLinks { + top: 20px; } .barNavigation { @@ -163,17 +195,34 @@ tbody { } .barNavigation li:hover { - background-color: #d59f0f; color: white; border-radius: 0; border: none; } .subMenu ul { - width: 100%; - border-radius: 4px; position: relative; + top: 0px; + width: 100%; background-color: rgb(1, 92, 184); + + max-height: 0; + opacity: 0; + overflow: hidden; + + transform: translateY(-5px); + + transition: max-height 0.35s ease, opacity 0.3s ease, transform 0.3s ease; + } + + .subMenu.open ul { + max-height: 500px; + opacity: 1; + transform: translateY(0); + } + + .subMenu ul { + opacity: 0; } thead, diff --git a/app/Components/layout/BarNavigation/BarNavigation.tsx b/app/Components/layout/BarNavigation/BarNavigation.tsx index 1b8b2a0..c5d7804 100644 --- a/app/Components/layout/BarNavigation/BarNavigation.tsx +++ b/app/Components/layout/BarNavigation/BarNavigation.tsx @@ -9,7 +9,7 @@ function BarNavigation() { const toggleMenu = () => setOpenMenu(!openMenu); const toggleSubMenu = (index: number) => { - if (typeof window !== "undefined" && window.innerWidth <= 800) { + if (typeof window !== "undefined" && window.innerWidth <= 1000) { setOpenSubMenu(openSubMenu === index ? null : index); } }; @@ -24,16 +24,13 @@ function BarNavigation() {
  • - toggleSubMenu(0)}>Inscripción + toggleSubMenu(0)}>Inscripciónes
      - -
    • Alta
    • -
    • Agregar Tiempo
    • -
    • Inscripción
    • +
    • Inscripción Usuario
  • diff --git a/app/Components/layout/Header/Header.module.css b/app/Components/layout/Header/Header.module.css index f1773e4..6ce8d21 100644 --- a/app/Components/layout/Header/Header.module.css +++ b/app/Components/layout/Header/Header.module.css @@ -1,8 +1,16 @@ .logo { position: relative; - filter: invert(1); z-index: 3; - margin: 5px; + object-fit: contain; +} + +.logoContainer { + position: relative; + width: 100%; + max-width: 250px; + min-width: 200px; + height: auto; + aspect-ratio: 250/70; } .cedetecContainer { @@ -26,16 +34,82 @@ content: ""; top: 0; left: -20px; - width: 65%; - height: 100%; - min-width: 300px; - background: linear-gradient(to right, #bd8c01, #f9f9f9); + width: 100%; + height: 30px; + background: linear-gradient(to right, #bd8c01 40%, #fff 100%); transform: skew(-45deg); z-index: 0; } +.header { + width: 100vw; + background-color: #fff; + display: grid; + grid-template-columns: auto 1fr; + padding: 0 10px; + position: relative; + z-index: 1; + align-items: end; +} + +.header::after { + content: ""; + top: 0; + left: -60px; + position: absolute; + background-color: #003e79; + height: 100%; + min-width: 350px; + transform: skew(45deg); + z-index: 2; +} + +.header::before { + content: ""; + top: 0; + left: -40px; + position: absolute; + background-color: rgb(1, 92, 184); + height: 100%; + width: 10%; + min-width: 350px; + transform: skew(45deg); + z-index: 2; +} + +.containerBarNav { + display: flex; + align-items: center; + width: 100%; + height: 100%; + padding-left: 110px; + max-height: 60%; +} + @media (max-width: 800px) { .yellowPart { + left: 0; background: #bd8c01; + transform: skew(0deg); + } + .header::after { + left: -100px; + } + .header::before { + left: -80px; + } +} + +@media (max-width: 400px) { + .header::after { + min-width: 100%; + transform: skew(25deg); + } + .header::before { + min-width: 100%; + transform: skew(25deg); + } + .containerBarNav { + padding-left: 0; } } diff --git a/app/Components/layout/Header/Header.tsx b/app/Components/layout/Header/Header.tsx index ac8c4d1..b70c1f2 100644 --- a/app/Components/layout/Header/Header.tsx +++ b/app/Components/layout/Header/Header.tsx @@ -1,31 +1,48 @@ +"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"; function Header() { + const [role, setRole] = useState(""); + + useEffect(() => { + const cookies = Object.fromEntries( + document.cookie.split("; ").map((c) => c.split("=")) + ); + setRole(cookies.role || ""); + }, []); + return ( -
    +
    - Logo FES +
    + Logo FES +
    -
    - Image of CEDETEC +
    + {role === "ADMINISTRADOR" && } + {role === "SUPER ADMINISTRADOR (quita sanciones)" && } + {role === "SERVICIO SOCIAL" && } + {role === "ATENCION A USUARIO" && }
    ); diff --git a/app/globals.css b/app/globals.css index d6fa085..1626223 100644 --- a/app/globals.css +++ b/app/globals.css @@ -1,12 +1,12 @@ * { - padding: 0; - margin: 0; color: #333333; } *, *::before, *::after { + margin: 0; + padding: 0; box-sizing: inherit; } @@ -25,49 +25,13 @@ body { min-height: 100dvh; width: 100vw; overflow: hidden; + background-color: #f9f9f9; } main { position: relative; } -header { - display: grid; - grid-template-columns: auto 1fr; - padding: 5px 40px; - position: relative; - overflow: hidden; - background-color: #f9f9f9; - z-index: 1; - height: 70px; -} - -header::after { - content: ""; - top: 0; - left: -40px; - position: absolute; - background-color: #003e79; - height: 100%; - width: 30%; - min-width: 300px; - transform: skew(45deg); - z-index: 1; -} - -header::before { - content: ""; - top: 0; - left: -20px; - position: absolute; - background-color: rgb(1, 92, 184); - height: 100%; - width: 30%; - min-width: 300px; - transform: skew(45deg); - z-index: 1; -} - footer { position: relative; display: flex; @@ -88,12 +52,10 @@ footer p { .mainContainer { position: relative; display: grid; - grid-template-rows: auto 1fr; align-items: center; justify-items: center; height: 100%; width: 100%; - background-color: #f9f9f9; } @keyframes fadeInUp { @@ -139,6 +101,7 @@ footer p { .containerForm { width: 100%; max-width: 450px; + gap:10px; } .img { @@ -219,7 +182,6 @@ button { align-items: center; justify-content: space-between; width: 100%; - max-width: 450px; } .button { @@ -295,6 +257,7 @@ a { margin-top: 1rem; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); overflow: hidden; + min-height: fit-content; transition: box-shadow 0.3s ease, transform 0.3s ease; } @@ -310,6 +273,7 @@ a { align-items: center; padding: 5px 0; border-bottom: 1px solid #e5e5e5; + height: 35px; } .informationItem:last-child { @@ -324,7 +288,7 @@ a { .informationValue { color: #555; - font-size: 1.5rem; + font-size: 1.25rem; } .title { @@ -364,6 +328,8 @@ form { border-radius: 4px; background-color: #fff; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); + height: fit-content; + overflow: hidden; } .toggleGroup { @@ -397,6 +363,11 @@ form { border-bottom: none; } +.toggleContent { + overflow-y: auto; + scrollbar-width: none; +} + p { font-size: 1.5rem; } @@ -413,19 +384,21 @@ table { table th, table td { - padding: 0.85rem 1.5rem; + padding: 1rem 1.5rem; } table th { position: sticky; top: 0; color: #ffffff; + background-color: #2563eb; font-weight: 800; text-transform: uppercase; letter-spacing: 1px; text-align: center; z-index: 2; border: none; + min-height: 35px; } table td { @@ -564,9 +537,6 @@ table td:last-child { } @media (max-width: 800px) { - header { - padding: 6px 16px; - } .container { display: flex; @@ -579,10 +549,6 @@ table td:last-child { border-radius: 0; } - .mainContainer { - grid-template-rows: 40px 1fr; - } - .img { background-image: url("/rock.jpg"); right: 50%; diff --git a/app/layout.tsx b/app/layout.tsx index bb5e5fe..60aff7e 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,5 +1,5 @@ import type { Metadata } from "next"; -import { Poppins } from "next/font/google"; +import { Inter } from "next/font/google"; import Header from "./Components/layout/Header/Header"; import Footer from "./Components/layout/Footer/Footer"; @@ -7,11 +7,7 @@ import Footer from "./Components/layout/Footer/Footer"; import "./globals.css"; import { ToastProvider } from "./Components/layout/ToastProvider"; -const poppins = Poppins({ - variable: "--font-poppins", - subsets: ["latin"], - weight: ["400", "600", "700"], -}); +const inter = Inter({ subsets: ["latin"], weight: ["400", "700"] }); export const metadata: Metadata = { title: "Servicio AT", @@ -27,7 +23,7 @@ export default function RootLayout({ }>) { return ( - +
    {children}
    diff --git a/app/lib/apiClient.ts b/app/lib/apiClient.ts index 4d321e6..648bbe8 100644 --- a/app/lib/apiClient.ts +++ b/app/lib/apiClient.ts @@ -3,7 +3,7 @@ import Cookies from "js-cookie"; import { envConfig } from "./config"; if (!envConfig.apiUrl) { - throw new Error("API URL is not defined in envConfig"); + console.error("API URL is not defined in envConfig"); } const apiClient = axios.create({ @@ -37,16 +37,9 @@ apiClient.interceptors.response.use( Cookies.remove("token"); Cookies.remove("user"); - if ( - typeof window !== "undefined" && - !window.location.pathname.includes("/") - ) { - window.location.href = "/"; - } } if (status === 403) { - window.location.href = "/Impresiones"; } } return Promise.reject(error); diff --git a/app/lib/getRegisterStudent.ts b/app/lib/getRegisterStudent.ts new file mode 100644 index 0000000..79437f1 --- /dev/null +++ b/app/lib/getRegisterStudent.ts @@ -0,0 +1,34 @@ +import axios from "axios"; +import { envConfig } from "./config"; +import { redirect } from "next/navigation"; +import { cookies } from "next/headers"; + +if (!envConfig.apiUrl) { + console.error("API URL is not defined in envConfig"); +} + +export async function GetRegisterStudent(numAcount: number) { + const cookieStore = cookies(); + const token = (await cookieStore).get("token")?.value; + + if (!token) redirect("/"); + try { + const response = await axios.get( + `${envConfig.apiUrl}/alumno-inscrito/${numAcount}`, + { + headers: { + Authorization: `Bearer ${token}`, + }, + } + ); + + return response.data; + } catch (error: any) { + const msg = + error.response?.data?.message || + error.message || + "Error desconocido al obtener estudiante"; + return { error: msg }; + } +} +//IO diff --git a/app/lib/getStudent copy.ts b/app/lib/getStudent copy.ts new file mode 100644 index 0000000..27f0431 --- /dev/null +++ b/app/lib/getStudent copy.ts @@ -0,0 +1,19 @@ +import axios from "axios"; +import { envConfig } from "./config"; + +export async function GetSancionByStudent(numAcount: number) { + try { + const response = await axios.get( + `${envConfig.apiUrl}/alumno-sancion/${numAcount}` + ); + + return response.data; + } catch (error: any) { + const msg = + error.response?.data?.message || + error.message || + "Error desconocido al obtener estudiante"; + return { error: msg }; + } +} +//IO diff --git a/app/lib/getStudent.ts b/app/lib/getStudent.ts index 001a23b..2f9cee3 100644 --- a/app/lib/getStudent.ts +++ b/app/lib/getStudent.ts @@ -1,10 +1,25 @@ import axios from "axios"; import { envConfig } from "./config"; +import { redirect } from "next/navigation"; +import { cookies } from "next/headers"; + +if (!envConfig.apiUrl) { + console.error("API URL is not defined in envConfig"); +} export async function GetStudent(numAcount: number) { + const cookieStore = cookies(); + const token = (await cookieStore).get("token")?.value; + + if (!token) redirect("/"); try { const response = await axios.get( - `${envConfig.apiUrl}/student/${numAcount}` + `${envConfig.apiUrl}/student/${numAcount}`, + { + headers: { + Authorization: `Bearer ${token}`, + }, + } ); return response.data; diff --git a/middleware.ts b/middleware.ts index f068a83..e39f043 100644 --- a/middleware.ts +++ b/middleware.ts @@ -2,10 +2,15 @@ import { NextResponse } from "next/server"; import type { NextRequest } from "next/server"; export function middleware(request: NextRequest) { - const token = request.cookies.get("token"); + const token = request.cookies.get("token")?.value; + const pathname = request.nextUrl.pathname; - if (!token) { - console.log("No hay token, redirigiendo a la página de inicio de sesión"); + if (pathname === "/" && token) { + return NextResponse.redirect(new URL("/Impresiones", request.url)); + } + + if (!token && pathname != "/") { + console.log("No hay token, redirigiendo a login"); return NextResponse.redirect(new URL("/", request.url)); } @@ -13,6 +18,23 @@ export function middleware(request: NextRequest) { } export const config = { - matcher: [], + matcher: [ + "/Reportes", + "/Monitor", + "/QuitarSancion", + "/Programas", + "/Mensajes", + "/Inscritos", + "/Inscripciones", + "/InformacionEquipo", + "/Impresiones", + "/CambiarPass", + "/BitacoraSanciones", + "/AsignacionMesas", + "/AsignacionEquipo", + "/Alta", + "/AgregarTiempo", + "/ActivosMantenimiento", + ], }; -//IO +//IO \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 9bc5488..39c6e1e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,11 +10,12 @@ "dependencies": { "axios": "^1.11.0", "js-cookie": "^3.0.5", - "next": "^15.5.3", + "next": "^16.0.7", "react": "19.1.0", "react-dom": "19.1.0", "react-hot-toast": "^2.6.0", - "react-icons": "^5.5.0" + "react-icons": "^5.5.0", + "react-toastify": "^11.0.5" }, "devDependencies": { "@types/js-cookie": "^3.0.6", @@ -25,19 +26,29 @@ } }, "node_modules/@emnapi/runtime": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.5.tgz", - "integrity": "sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.8.1.tgz", + "integrity": "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==", "license": "MIT", "optional": true, "dependencies": { "tslib": "^2.4.0" } }, + "node_modules/@img/colour": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.0.0.tgz", + "integrity": "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=18" + } + }, "node_modules/@img/sharp-darwin-arm64": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.3.tgz", - "integrity": "sha512-ryFMfvxxpQRsgZJqBd4wsttYQbCxsJksrv9Lw/v798JcQ8+w84mBWuXwl+TT0WJ/WrYOLaYpwQXi3sA9nTIaIg==", + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz", + "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==", "cpu": [ "arm64" ], @@ -53,13 +64,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-darwin-arm64": "1.2.0" + "@img/sharp-libvips-darwin-arm64": "1.2.4" } }, "node_modules/@img/sharp-darwin-x64": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.3.tgz", - "integrity": "sha512-yHpJYynROAj12TA6qil58hmPmAwxKKC7reUqtGLzsOHfP7/rniNGTL8tjWX6L3CTV4+5P4ypcS7Pp+7OB+8ihA==", + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz", + "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==", "cpu": [ "x64" ], @@ -75,13 +86,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-darwin-x64": "1.2.0" + "@img/sharp-libvips-darwin-x64": "1.2.4" } }, "node_modules/@img/sharp-libvips-darwin-arm64": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.0.tgz", - "integrity": "sha512-sBZmpwmxqwlqG9ueWFXtockhsxefaV6O84BMOrhtg/YqbTaRdqDE7hxraVE3y6gVM4eExmfzW4a8el9ArLeEiQ==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz", + "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==", "cpu": [ "arm64" ], @@ -95,9 +106,9 @@ } }, "node_modules/@img/sharp-libvips-darwin-x64": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.0.tgz", - "integrity": "sha512-M64XVuL94OgiNHa5/m2YvEQI5q2cl9d/wk0qFTDVXcYzi43lxuiFTftMR1tOnFQovVXNZJ5TURSDK2pNe9Yzqg==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz", + "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==", "cpu": [ "x64" ], @@ -111,9 +122,9 @@ } }, "node_modules/@img/sharp-libvips-linux-arm": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.0.tgz", - "integrity": "sha512-mWd2uWvDtL/nvIzThLq3fr2nnGfyr/XMXlq8ZJ9WMR6PXijHlC3ksp0IpuhK6bougvQrchUAfzRLnbsen0Cqvw==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz", + "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==", "cpu": [ "arm" ], @@ -127,9 +138,9 @@ } }, "node_modules/@img/sharp-libvips-linux-arm64": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.0.tgz", - "integrity": "sha512-RXwd0CgG+uPRX5YYrkzKyalt2OJYRiJQ8ED/fi1tq9WQW2jsQIn0tqrlR5l5dr/rjqq6AHAxURhj2DVjyQWSOA==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz", + "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==", "cpu": [ "arm64" ], @@ -143,9 +154,9 @@ } }, "node_modules/@img/sharp-libvips-linux-ppc64": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.0.tgz", - "integrity": "sha512-Xod/7KaDDHkYu2phxxfeEPXfVXFKx70EAFZ0qyUdOjCcxbjqyJOEUpDe6RIyaunGxT34Anf9ue/wuWOqBW2WcQ==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz", + "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==", "cpu": [ "ppc64" ], @@ -158,10 +169,26 @@ "url": "https://opencollective.com/libvips" } }, + "node_modules/@img/sharp-libvips-linux-riscv64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz", + "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==", + "cpu": [ + "riscv64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, "node_modules/@img/sharp-libvips-linux-s390x": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.0.tgz", - "integrity": "sha512-eMKfzDxLGT8mnmPJTNMcjfO33fLiTDsrMlUVcp6b96ETbnJmd4uvZxVJSKPQfS+odwfVaGifhsB07J1LynFehw==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz", + "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==", "cpu": [ "s390x" ], @@ -175,9 +202,9 @@ } }, "node_modules/@img/sharp-libvips-linux-x64": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.0.tgz", - "integrity": "sha512-ZW3FPWIc7K1sH9E3nxIGB3y3dZkpJlMnkk7z5tu1nSkBoCgw2nSRTFHI5pB/3CQaJM0pdzMF3paf9ckKMSE9Tg==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz", + "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==", "cpu": [ "x64" ], @@ -191,9 +218,9 @@ } }, "node_modules/@img/sharp-libvips-linuxmusl-arm64": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.0.tgz", - "integrity": "sha512-UG+LqQJbf5VJ8NWJ5Z3tdIe/HXjuIdo4JeVNADXBFuG7z9zjoegpzzGIyV5zQKi4zaJjnAd2+g2nna8TZvuW9Q==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz", + "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==", "cpu": [ "arm64" ], @@ -207,9 +234,9 @@ } }, "node_modules/@img/sharp-libvips-linuxmusl-x64": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.0.tgz", - "integrity": "sha512-SRYOLR7CXPgNze8akZwjoGBoN1ThNZoqpOgfnOxmWsklTGVfJiGJoC/Lod7aNMGA1jSsKWM1+HRX43OP6p9+6Q==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz", + "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==", "cpu": [ "x64" ], @@ -223,9 +250,9 @@ } }, "node_modules/@img/sharp-linux-arm": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.3.tgz", - "integrity": "sha512-oBK9l+h6KBN0i3dC8rYntLiVfW8D8wH+NPNT3O/WBHeW0OQWCjfWksLUaPidsrDKpJgXp3G3/hkmhptAW0I3+A==", + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz", + "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==", "cpu": [ "arm" ], @@ -241,13 +268,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-arm": "1.2.0" + "@img/sharp-libvips-linux-arm": "1.2.4" } }, "node_modules/@img/sharp-linux-arm64": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.3.tgz", - "integrity": "sha512-QdrKe3EvQrqwkDrtuTIjI0bu6YEJHTgEeqdzI3uWJOH6G1O8Nl1iEeVYRGdj1h5I21CqxSvQp1Yv7xeU3ZewbA==", + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz", + "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==", "cpu": [ "arm64" ], @@ -263,13 +290,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-arm64": "1.2.0" + "@img/sharp-libvips-linux-arm64": "1.2.4" } }, "node_modules/@img/sharp-linux-ppc64": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.3.tgz", - "integrity": "sha512-GLtbLQMCNC5nxuImPR2+RgrviwKwVql28FWZIW1zWruy6zLgA5/x2ZXk3mxj58X/tszVF69KK0Is83V8YgWhLA==", + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz", + "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==", "cpu": [ "ppc64" ], @@ -285,13 +312,35 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-ppc64": "1.2.0" + "@img/sharp-libvips-linux-ppc64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-riscv64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz", + "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==", + "cpu": [ + "riscv64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-riscv64": "1.2.4" } }, "node_modules/@img/sharp-linux-s390x": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.3.tgz", - "integrity": "sha512-3gahT+A6c4cdc2edhsLHmIOXMb17ltffJlxR0aC2VPZfwKoTGZec6u5GrFgdR7ciJSsHT27BD3TIuGcuRT0KmQ==", + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz", + "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==", "cpu": [ "s390x" ], @@ -307,13 +356,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-s390x": "1.2.0" + "@img/sharp-libvips-linux-s390x": "1.2.4" } }, "node_modules/@img/sharp-linux-x64": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.3.tgz", - "integrity": "sha512-8kYso8d806ypnSq3/Ly0QEw90V5ZoHh10yH0HnrzOCr6DKAPI6QVHvwleqMkVQ0m+fc7EH8ah0BB0QPuWY6zJQ==", + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz", + "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==", "cpu": [ "x64" ], @@ -329,13 +378,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-x64": "1.2.0" + "@img/sharp-libvips-linux-x64": "1.2.4" } }, "node_modules/@img/sharp-linuxmusl-arm64": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.3.tgz", - "integrity": "sha512-vAjbHDlr4izEiXM1OTggpCcPg9tn4YriK5vAjowJsHwdBIdx0fYRsURkxLG2RLm9gyBq66gwtWI8Gx0/ov+JKQ==", + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz", + "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==", "cpu": [ "arm64" ], @@ -351,13 +400,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-arm64": "1.2.0" + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" } }, "node_modules/@img/sharp-linuxmusl-x64": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.3.tgz", - "integrity": "sha512-gCWUn9547K5bwvOn9l5XGAEjVTTRji4aPTqLzGXHvIr6bIDZKNTA34seMPgM0WmSf+RYBH411VavCejp3PkOeQ==", + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz", + "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==", "cpu": [ "x64" ], @@ -373,20 +422,20 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-x64": "1.2.0" + "@img/sharp-libvips-linuxmusl-x64": "1.2.4" } }, "node_modules/@img/sharp-wasm32": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.3.tgz", - "integrity": "sha512-+CyRcpagHMGteySaWos8IbnXcHgfDn7pO2fiC2slJxvNq9gDipYBN42/RagzctVRKgxATmfqOSulgZv5e1RdMg==", + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz", + "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==", "cpu": [ "wasm32" ], "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", "optional": true, "dependencies": { - "@emnapi/runtime": "^1.4.4" + "@emnapi/runtime": "^1.7.0" }, "engines": { "node": "^18.17.0 || ^20.3.0 || >=21.0.0" @@ -396,9 +445,9 @@ } }, "node_modules/@img/sharp-win32-arm64": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.3.tgz", - "integrity": "sha512-MjnHPnbqMXNC2UgeLJtX4XqoVHHlZNd+nPt1kRPmj63wURegwBhZlApELdtxM2OIZDRv/DFtLcNhVbd1z8GYXQ==", + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz", + "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==", "cpu": [ "arm64" ], @@ -415,9 +464,9 @@ } }, "node_modules/@img/sharp-win32-ia32": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.3.tgz", - "integrity": "sha512-xuCdhH44WxuXgOM714hn4amodJMZl3OEvf0GVTm0BEyMeA2to+8HEdRPShH0SLYptJY1uBw+SCFP9WVQi1Q/cw==", + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz", + "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==", "cpu": [ "ia32" ], @@ -434,9 +483,9 @@ } }, "node_modules/@img/sharp-win32-x64": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.3.tgz", - "integrity": "sha512-OWwz05d++TxzLEv4VnsTz5CmZ6mI6S05sfQGEMrNrQcOEERbX46332IvE7pO/EUiw7jUrrS40z/M7kPyjfl04g==", + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz", + "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==", "cpu": [ "x64" ], @@ -453,15 +502,15 @@ } }, "node_modules/@next/env": { - "version": "15.5.3", - "resolved": "https://registry.npmjs.org/@next/env/-/env-15.5.3.tgz", - "integrity": "sha512-RSEDTRqyihYXygx/OJXwvVupfr9m04+0vH8vyy0HfZ7keRto6VX9BbEk0J2PUk0VGy6YhklJUSrgForov5F9pw==", + "version": "16.1.1", + "resolved": "https://registry.npmjs.org/@next/env/-/env-16.1.1.tgz", + "integrity": "sha512-3oxyM97Sr2PqiVyMyrZUtrtM3jqqFxOQJVuKclDsgj/L728iZt/GyslkN4NwarledZATCenbk4Offjk1hQmaAA==", "license": "MIT" }, "node_modules/@next/swc-darwin-arm64": { - "version": "15.5.3", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.5.3.tgz", - "integrity": "sha512-nzbHQo69+au9wJkGKTU9lP7PXv0d1J5ljFpvb+LnEomLtSbJkbZyEs6sbF3plQmiOB2l9OBtN2tNSvCH1nQ9Jg==", + "version": "16.1.1", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.1.1.tgz", + "integrity": "sha512-JS3m42ifsVSJjSTzh27nW+Igfha3NdBOFScr9C80hHGrWx55pTrVL23RJbqir7k7/15SKlrLHhh/MQzqBBYrQA==", "cpu": [ "arm64" ], @@ -475,9 +524,9 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "15.5.3", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.5.3.tgz", - "integrity": "sha512-w83w4SkOOhekJOcA5HBvHyGzgV1W/XvOfpkrxIse4uPWhYTTRwtGEM4v/jiXwNSJvfRvah0H8/uTLBKRXlef8g==", + "version": "16.1.1", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.1.1.tgz", + "integrity": "sha512-hbyKtrDGUkgkyQi1m1IyD3q4I/3m9ngr+V93z4oKHrPcmxwNL5iMWORvLSGAf2YujL+6HxgVvZuCYZfLfb4bGw==", "cpu": [ "x64" ], @@ -491,9 +540,9 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "15.5.3", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.5.3.tgz", - "integrity": "sha512-+m7pfIs0/yvgVu26ieaKrifV8C8yiLe7jVp9SpcIzg7XmyyNE7toC1fy5IOQozmr6kWl/JONC51osih2RyoXRw==", + "version": "16.1.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.1.1.tgz", + "integrity": "sha512-/fvHet+EYckFvRLQ0jPHJCUI5/B56+2DpI1xDSvi80r/3Ez+Eaa2Yq4tJcRTaB1kqj/HrYKn8Yplm9bNoMJpwQ==", "cpu": [ "arm64" ], @@ -507,9 +556,9 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "15.5.3", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.5.3.tgz", - "integrity": "sha512-u3PEIzuguSenoZviZJahNLgCexGFhso5mxWCrrIMdvpZn6lkME5vc/ADZG8UUk5K1uWRy4hqSFECrON6UKQBbQ==", + "version": "16.1.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.1.1.tgz", + "integrity": "sha512-MFHrgL4TXNQbBPzkKKur4Fb5ICEJa87HM7fczFs2+HWblM7mMLdco3dvyTI+QmLBU9xgns/EeeINSZD6Ar+oLg==", "cpu": [ "arm64" ], @@ -523,9 +572,9 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "15.5.3", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.5.3.tgz", - "integrity": "sha512-lDtOOScYDZxI2BENN9m0pfVPJDSuUkAD1YXSvlJF0DKwZt0WlA7T7o3wrcEr4Q+iHYGzEaVuZcsIbCps4K27sA==", + "version": "16.1.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.1.1.tgz", + "integrity": "sha512-20bYDfgOQAPUkkKBnyP9PTuHiJGM7HzNBbuqmD0jiFVZ0aOldz+VnJhbxzjcSabYsnNjMPsE0cyzEudpYxsrUQ==", "cpu": [ "x64" ], @@ -539,9 +588,9 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "15.5.3", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.5.3.tgz", - "integrity": "sha512-9vWVUnsx9PrY2NwdVRJ4dUURAQ8Su0sLRPqcCCxtX5zIQUBES12eRVHq6b70bbfaVaxIDGJN2afHui0eDm+cLg==", + "version": "16.1.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.1.1.tgz", + "integrity": "sha512-9pRbK3M4asAHQRkwaXwu601oPZHghuSC8IXNENgbBSyImHv/zY4K5udBusgdHkvJ/Tcr96jJwQYOll0qU8+fPA==", "cpu": [ "x64" ], @@ -555,9 +604,9 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "15.5.3", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.5.3.tgz", - "integrity": "sha512-1CU20FZzY9LFQigRi6jM45oJMU3KziA5/sSG+dXeVaTm661snQP6xu3ykGxxwU5sLG3sh14teO/IOEPVsQMRfA==", + "version": "16.1.1", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.1.1.tgz", + "integrity": "sha512-bdfQkggaLgnmYrFkSQfsHfOhk/mCYmjnrbRCGgkMcoOBZ4n+TRRSLmT/CU5SATzlBJ9TpioUyBW/vWFXTqQRiA==", "cpu": [ "arm64" ], @@ -571,9 +620,9 @@ } }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "15.5.3", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.5.3.tgz", - "integrity": "sha512-JMoLAq3n3y5tKXPQwCK5c+6tmwkuFDa2XAxz8Wm4+IVthdBZdZGh+lmiLUHg9f9IDwIQpUjp+ysd6OkYTyZRZw==", + "version": "16.1.1", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.1.1.tgz", + "integrity": "sha512-Ncwbw2WJ57Al5OX0k4chM68DKhEPlrXBaSXDCi2kPi5f4d8b3ejr3RRJGfKBLrn2YJL5ezNS7w2TZLHSti8CMw==", "cpu": [ "x64" ], @@ -603,9 +652,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "20.19.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.11.tgz", - "integrity": "sha512-uug3FEEGv0r+jrecvUUpbY8lLisvIjg6AAic6a2bSP5OEOLeJsDSnvhCDov7ipFFMXS3orMpzlmi0ZcuGkBbow==", + "version": "20.19.27", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.27.tgz", + "integrity": "sha512-N2clP5pJhB2YnZJ3PIHFk5RkygRX5WO/5f0WC08tp0wd+sv0rsJk3MqWn3CbNmT2J505a5336jaQj4ph1AdMug==", "dev": true, "license": "MIT", "dependencies": { @@ -613,23 +662,23 @@ } }, "node_modules/@types/react": { - "version": "19.1.10", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.10.tgz", - "integrity": "sha512-EhBeSYX0Y6ye8pNebpKrwFJq7BoQ8J5SO6NlvNwwHjSj6adXJViPQrKlsyPw7hLBLvckEMO1yxeGdR82YBBlDg==", + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.7.tgz", + "integrity": "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==", "dev": true, "license": "MIT", "dependencies": { - "csstype": "^3.0.2" + "csstype": "^3.2.2" } }, "node_modules/@types/react-dom": { - "version": "19.1.7", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.7.tgz", - "integrity": "sha512-i5ZzwYpqjmrKenzkoLM2Ibzt6mAsM7pxB6BCIouEVVmgiqaMj1TjaK7hnA36hbW5aZv20kx7Lw6hWzPWg0Rurw==", + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", "dev": true, "license": "MIT", "peerDependencies": { - "@types/react": "^19.0.0" + "@types/react": "^19.2.0" } }, "node_modules/asynckit": { @@ -639,9 +688,9 @@ "license": "MIT" }, "node_modules/axios": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.12.1.tgz", - "integrity": "sha512-Kn4kbSXpkFHCGE6rBFNwIv0GQs4AvDT80jlveJDKFxjbTYMUeB4QtsdPCv6H8Cm19Je7IU6VFtRl2zWZI0rudQ==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz", + "integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==", "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", @@ -649,6 +698,15 @@ "proxy-from-env": "^1.1.0" } }, + "node_modules/baseline-browser-mapping": { + "version": "2.9.14", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.14.tgz", + "integrity": "sha512-B0xUquLkiGLgHhpPBqvl7GWegWBUNuujQ6kXd/r1U38ElPT6Ok8KZ8e+FpUGEc2ZoRQUzq/aUnaKFc/svWUGSg==", + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", @@ -663,9 +721,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001735", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001735.tgz", - "integrity": "sha512-EV/laoX7Wq2J9TQlyIXRxTJqIw4sxfXS4OYgudGxBYRuTv0q7AM6yMEpU/Vo1I94thg9U6EZ2NfZx9GJq83u7w==", + "version": "1.0.30001762", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001762.tgz", + "integrity": "sha512-PxZwGNvH7Ak8WX5iXzoK1KPZttBXNPuaOvI2ZYU7NrlM+d9Ov+TUvlLOBNGzVXAntMSMMlJPd+jY6ovrVjSmUw==", "funding": [ { "type": "opencollective", @@ -688,49 +746,13 @@ "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", "license": "MIT" }, - "node_modules/color": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", - "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", "license": "MIT", - "optional": true, - "dependencies": { - "color-convert": "^2.0.1", - "color-string": "^1.9.0" - }, "engines": { - "node": ">=12.5.0" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "optional": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT", - "optional": true - }, - "node_modules/color-string": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", - "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", - "license": "MIT", - "optional": true, - "dependencies": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" + "node": ">=6" } }, "node_modules/combined-stream": { @@ -746,9 +768,9 @@ } }, "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", "license": "MIT" }, "node_modules/delayed-stream": { @@ -761,9 +783,9 @@ } }, "node_modules/detect-libc": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", - "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", "license": "Apache-2.0", "optional": true, "engines": { @@ -850,9 +872,9 @@ } }, "node_modules/form-data": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", - "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", "license": "MIT", "dependencies": { "asynckit": "^0.4.0", @@ -912,9 +934,9 @@ } }, "node_modules/goober": { - "version": "2.1.16", - "resolved": "https://registry.npmjs.org/goober/-/goober-2.1.16.tgz", - "integrity": "sha512-erjk19y1U33+XAMe1VTvIONHYoSqE4iS7BYUZfHaqeohLmnC0FdxEh7rQU+6MZ4OajItzjZFSRtVANrQwNq6/g==", + "version": "2.1.18", + "resolved": "https://registry.npmjs.org/goober/-/goober-2.1.18.tgz", + "integrity": "sha512-2vFqsaDVIT9Gz7N6kAL++pLpp41l3PfDuusHcjnGLfR6+huZkl6ziX+zgVC3ZxpqWhzH6pyDdGrCeDhMIvwaxw==", "license": "MIT", "peerDependencies": { "csstype": "^3.0.10" @@ -971,13 +993,6 @@ "node": ">= 0.4" } }, - "node_modules/is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", - "license": "MIT", - "optional": true - }, "node_modules/js-cookie": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz", @@ -1036,13 +1051,14 @@ } }, "node_modules/next": { - "version": "15.5.3", - "resolved": "https://registry.npmjs.org/next/-/next-15.5.3.tgz", - "integrity": "sha512-r/liNAx16SQj4D+XH/oI1dlpv9tdKJ6cONYPwwcCC46f2NjpaRWY+EKCzULfgQYV6YKXjHBchff2IZBSlZmJNw==", + "version": "16.1.1", + "resolved": "https://registry.npmjs.org/next/-/next-16.1.1.tgz", + "integrity": "sha512-QI+T7xrxt1pF6SQ/JYFz95ro/mg/1Znk5vBebsWwbpejj1T0A23hO7GYEaVac9QUOT2BIMiuzm0L99ooq7k0/w==", "license": "MIT", "dependencies": { - "@next/env": "15.5.3", + "@next/env": "16.1.1", "@swc/helpers": "0.5.15", + "baseline-browser-mapping": "^2.8.3", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" @@ -1051,18 +1067,18 @@ "next": "dist/bin/next" }, "engines": { - "node": "^18.18.0 || ^19.8.0 || >= 20.0.0" + "node": ">=20.9.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "15.5.3", - "@next/swc-darwin-x64": "15.5.3", - "@next/swc-linux-arm64-gnu": "15.5.3", - "@next/swc-linux-arm64-musl": "15.5.3", - "@next/swc-linux-x64-gnu": "15.5.3", - "@next/swc-linux-x64-musl": "15.5.3", - "@next/swc-win32-arm64-msvc": "15.5.3", - "@next/swc-win32-x64-msvc": "15.5.3", - "sharp": "^0.34.3" + "@next/swc-darwin-arm64": "16.1.1", + "@next/swc-darwin-x64": "16.1.1", + "@next/swc-linux-arm64-gnu": "16.1.1", + "@next/swc-linux-arm64-musl": "16.1.1", + "@next/swc-linux-x64-gnu": "16.1.1", + "@next/swc-linux-x64-musl": "16.1.1", + "@next/swc-win32-arm64-msvc": "16.1.1", + "@next/swc-win32-x64-msvc": "16.1.1", + "sharp": "^0.34.4" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", @@ -1174,6 +1190,19 @@ "react": "*" } }, + "node_modules/react-toastify": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-11.0.5.tgz", + "integrity": "sha512-EpqHBGvnSTtHYhCPLxML05NLY2ZX0JURbAdNYa6BUkk+amz4wbKBQvoKQAB0ardvSarUBuY4Q4s1sluAzZwkmA==", + "license": "MIT", + "dependencies": { + "clsx": "^2.1.1" + }, + "peerDependencies": { + "react": "^18 || ^19", + "react-dom": "^18 || ^19" + } + }, "node_modules/scheduler": { "version": "0.26.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz", @@ -1181,9 +1210,9 @@ "license": "MIT" }, "node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", "license": "ISC", "optional": true, "bin": { @@ -1194,16 +1223,16 @@ } }, "node_modules/sharp": { - "version": "0.34.3", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.3.tgz", - "integrity": "sha512-eX2IQ6nFohW4DbvHIOLRB3MHFpYqaqvXd3Tp5e/T/dSH83fxaNJQRvDMhASmkNTsNTVF2/OOopzRCt7xokgPfg==", + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", + "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", "hasInstallScript": true, "license": "Apache-2.0", "optional": true, "dependencies": { - "color": "^4.2.3", - "detect-libc": "^2.0.4", - "semver": "^7.7.2" + "@img/colour": "^1.0.0", + "detect-libc": "^2.1.2", + "semver": "^7.7.3" }, "engines": { "node": "^18.17.0 || ^20.3.0 || >=21.0.0" @@ -1212,38 +1241,30 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-darwin-arm64": "0.34.3", - "@img/sharp-darwin-x64": "0.34.3", - "@img/sharp-libvips-darwin-arm64": "1.2.0", - "@img/sharp-libvips-darwin-x64": "1.2.0", - "@img/sharp-libvips-linux-arm": "1.2.0", - "@img/sharp-libvips-linux-arm64": "1.2.0", - "@img/sharp-libvips-linux-ppc64": "1.2.0", - "@img/sharp-libvips-linux-s390x": "1.2.0", - "@img/sharp-libvips-linux-x64": "1.2.0", - "@img/sharp-libvips-linuxmusl-arm64": "1.2.0", - "@img/sharp-libvips-linuxmusl-x64": "1.2.0", - "@img/sharp-linux-arm": "0.34.3", - "@img/sharp-linux-arm64": "0.34.3", - "@img/sharp-linux-ppc64": "0.34.3", - "@img/sharp-linux-s390x": "0.34.3", - "@img/sharp-linux-x64": "0.34.3", - "@img/sharp-linuxmusl-arm64": "0.34.3", - "@img/sharp-linuxmusl-x64": "0.34.3", - "@img/sharp-wasm32": "0.34.3", - "@img/sharp-win32-arm64": "0.34.3", - "@img/sharp-win32-ia32": "0.34.3", - "@img/sharp-win32-x64": "0.34.3" - } - }, - "node_modules/simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", - "license": "MIT", - "optional": true, - "dependencies": { - "is-arrayish": "^0.3.1" + "@img/sharp-darwin-arm64": "0.34.5", + "@img/sharp-darwin-x64": "0.34.5", + "@img/sharp-libvips-darwin-arm64": "1.2.4", + "@img/sharp-libvips-darwin-x64": "1.2.4", + "@img/sharp-libvips-linux-arm": "1.2.4", + "@img/sharp-libvips-linux-arm64": "1.2.4", + "@img/sharp-libvips-linux-ppc64": "1.2.4", + "@img/sharp-libvips-linux-riscv64": "1.2.4", + "@img/sharp-libvips-linux-s390x": "1.2.4", + "@img/sharp-libvips-linux-x64": "1.2.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", + "@img/sharp-libvips-linuxmusl-x64": "1.2.4", + "@img/sharp-linux-arm": "0.34.5", + "@img/sharp-linux-arm64": "0.34.5", + "@img/sharp-linux-ppc64": "0.34.5", + "@img/sharp-linux-riscv64": "0.34.5", + "@img/sharp-linux-s390x": "0.34.5", + "@img/sharp-linux-x64": "0.34.5", + "@img/sharp-linuxmusl-arm64": "0.34.5", + "@img/sharp-linuxmusl-x64": "0.34.5", + "@img/sharp-wasm32": "0.34.5", + "@img/sharp-win32-arm64": "0.34.5", + "@img/sharp-win32-ia32": "0.34.5", + "@img/sharp-win32-x64": "0.34.5" } }, "node_modules/source-map-js": { @@ -1285,9 +1306,9 @@ "license": "0BSD" }, "node_modules/typescript": { - "version": "5.9.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", - "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", "bin": { diff --git a/package.json b/package.json index c888ba7..2696614 100644 --- a/package.json +++ b/package.json @@ -11,11 +11,12 @@ "dependencies": { "axios": "^1.11.0", "js-cookie": "^3.0.5", - "next": "^15.5.3", + "next": "^16.0.7", "react": "19.1.0", "react-dom": "19.1.0", "react-hot-toast": "^2.6.0", - "react-icons": "^5.5.0" + "react-icons": "^5.5.0", + "react-toastify": "^11.0.5" }, "devDependencies": { "@types/js-cookie": "^3.0.6", diff --git a/public/excel.svg b/public/excel.svg new file mode 100644 index 0000000..1d47514 --- /dev/null +++ b/public/excel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/logo_fes.png b/public/logo_fes.png index ac3aec2..01cc19c 100644 Binary files a/public/logo_fes.png and b/public/logo_fes.png differ diff --git a/tsconfig.json b/tsconfig.json index d8b9323..e7ff3a2 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,11 @@ { "compilerOptions": { "target": "ES2017", - "lib": ["dom", "dom.iterable", "esnext"], + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], "allowJs": true, "skipLibCheck": true, "strict": true, @@ -11,7 +15,7 @@ "moduleResolution": "bundler", "resolveJsonModule": true, "isolatedModules": true, - "jsx": "preserve", + "jsx": "react-jsx", "incremental": true, "plugins": [ { @@ -19,9 +23,19 @@ } ], "paths": { - "@/*": ["./*"] + "@/*": [ + "./*" + ] } }, - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], - "exclude": ["node_modules"] + "include": [ + "next-env.d.ts", + "**/*.ts", + "**/*.tsx", + ".next/types/**/*.ts", + ".next/dev/types/**/*.ts" + ], + "exclude": [ + "node_modules" + ] }