diff --git a/app/(private)/Periodo/page.tsx b/app/(private)/Periodo/page.tsx new file mode 100644 index 0000000..1605a02 --- /dev/null +++ b/app/(private)/Periodo/page.tsx @@ -0,0 +1,229 @@ +"use client"; + +import { useState, useEffect } from "react"; +import axios from "axios"; +import Cookies from "js-cookie"; + +interface Periodo { + id_periodo: number; + semestre: string; + fecha_inicio_servicio: string; + fecha_fin_servicio: string; + activo: boolean; +} + +export default function PeriodoPage() { + + const [periodos, setPeriodos] = useState([]); + const [semestre, setSemestre] = useState(""); + const [fechaInicio, setFechaInicio] = useState(""); + const [fechaFin, setFechaFin] = useState(""); + const [modoEdicion, setModoEdicion] = useState(false); + const [idEditar, setIdEditar] = useState(null); + + const API = "http://localhost:5000/periodo"; + + const token = Cookies.get("token"); + const headers = { Authorization: `Bearer ${token}` }; + + const obtenerPeriodos = async () => { + try { + const res = await axios.get(API, { headers }); + setPeriodos(res.data); + } catch (error) { + console.error("Error al obtener periodos", error); + } + }; + + useEffect(() => { + obtenerPeriodos(); + }, []); + + // VALIDAR SEMESTRE + const handleSemestreChange = (e: React.ChangeEvent) => { + const valor = e.target.value; + + + if (/^\d{0,6}$/.test(valor)) { + setSemestre(valor); + } + }; + + const crearPeriodo = async () => { + if (semestre.length !== 6) { + alert("El semestre debe tener exactamente 6 dígitos."); + return; + } + + try { + await axios.post( + API, + { + semestre, + fecha_inicio_servicio: fechaInicio, + fecha_fin_servicio: fechaFin, + activo: true, + }, + { headers } + ); + + limpiarFormulario(); + obtenerPeriodos(); + } catch (error) { + console.error("Error al crear periodo", error); + } + }; + + + const eliminarPeriodo = async (id_periodo: number) => { + try { + await axios.delete(`${API}/${id_periodo}`, { headers }); + obtenerPeriodos(); + } catch (error) { + console.error("Error al eliminar periodo", error); + } + }; + + const cargarPeriodo = (p: Periodo) => { + setModoEdicion(true); + setIdEditar(p.id_periodo); + setSemestre(p.semestre); + setFechaInicio(p.fecha_inicio_servicio); + setFechaFin(p.fecha_fin_servicio); + }; + + + const modificarPeriodo = async () => { + if (semestre.length !== 6) { + alert("El semestre debe tener exactamente 6 dígitos."); + return; + } + + try { + await axios.put( + `${API}/${idEditar}`, + { + semestre, + fecha_inicio_servicio: fechaInicio, + fecha_fin_servicio: fechaFin, + }, + { headers } + ); + + limpiarFormulario(); + obtenerPeriodos(); + } catch (error) { + console.error("Error al modificar periodo", error); + } + }; + + const limpiarFormulario = () => { + setSemestre(""); + setFechaInicio(""); + setFechaFin(""); + setModoEdicion(false); + setIdEditar(null); + }; + + return ( +
+

PERIODO ESCOLAR

+ + {/* ================= FORMULARIO ================= */} +
+ + + + setFechaInicio(e.target.value)} + /> + + + setFechaFin(e.target.value)} + /> + + {modoEdicion ? ( + <> + + + + + ) : ( + + )} +
+ + {/* ================= TABLA ================= */} +
+ + + + + + + + + + + + + {periodos.map((p) => ( + + + + + + + + + ))} + +
IDPERIODOInicioFinActivoAcción
{p.id_periodo}{p.semestre}{p.fecha_inicio_servicio}{p.fecha_fin_servicio}{p.activo === true ? "Sí" : "No"} + + + +
+
+
+ ); +} \ No newline at end of file diff --git a/app/globals.css b/app/globals.css index c8e242a..59f4716 100644 --- a/app/globals.css +++ b/app/globals.css @@ -268,10 +268,13 @@ button:disabled { background-color: #2563eb; } + + .buttonSearch:hover { background-color: #1d4ed8; } + .buttonCharge { background-color: #16a34a; } @@ -493,7 +496,7 @@ thead tr { background-color: #2563eb; position: relative; z-index: 1; -} +} tbody tr { transition: transform 0.3s ease, opacity 0.3s ease; diff --git a/package-lock.json b/package-lock.json index 259868d..8ade54c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -693,6 +693,7 @@ "version": "2.5.6", "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.6.tgz", "integrity": "sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==", + "dev": true, "hasInstallScript": true, "license": "MIT", "optional": true, @@ -732,6 +733,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -752,6 +754,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -772,6 +775,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -792,6 +796,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -812,6 +817,7 @@ "cpu": [ "arm" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -832,6 +838,7 @@ "cpu": [ "arm" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -852,6 +859,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -872,6 +880,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -892,6 +901,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -912,6 +922,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -932,6 +943,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -952,6 +964,7 @@ "cpu": [ "ia32" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -972,6 +985,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1841,6 +1855,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, "license": "MIT", "optional": true, "engines": { @@ -1851,6 +1866,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -2200,6 +2216,7 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "dev": true, "license": "MIT", "optional": true }, @@ -2246,6 +2263,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, "license": "MIT", "optional": true, "engines": { diff --git a/proxy.ts b/proxy.ts index 36cf5db..66a5657 100644 --- a/proxy.ts +++ b/proxy.ts @@ -41,6 +41,7 @@ export async function proxy(request: NextRequest) { "/AsignacionEquipo", "/Monitor", "/ActivosMantenimiento", + "/Periodo", ]; if (role === 5 && !onlyImpresiones.includes(pathname)) { @@ -66,6 +67,7 @@ export const config = { matcher: [ "/", "/Reportes", + "/Periodo", "/Monitor", "/QuitarSancion", "/Programas",