Stable 2-ago-2023

This commit is contained in:
2023-08-02 09:12:46 -06:00
parent 6a7c6b7ed9
commit f0cc3c585d
60 changed files with 6497 additions and 908 deletions

View File

@@ -17,7 +17,9 @@ $write = $user->admin || in_array($user->acceso, ['w']);
<html lang="en">
<head>
<title>Consultar horario | <?= $user->facultad['facultad'] ?? 'General' ?></title>
<title>Consultar horario |
<?= $user->facultad['facultad'] ?? 'General' ?>
</title>
<meta charset="utf-8">
<meta http-equiv="content-type" content="text/plain; charset=UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
@@ -44,7 +46,7 @@ $write = $user->admin || in_array($user->acceso, ['w']);
#$carreras = query("SELECT * FROM FS_CARRERA WHERE FACULTAD = :fac AND PERIODO = COALESCE(:per, PERIODO) ORDER BY CARRERA", [":fac" => $user->facultad['facultad_id'], ":per" => $user->periodo], single: false);
// repliaction of the query in the database with database class
$nivel = $user->periodo ? $db->where('id', $user->periodo)->getOne('fs_periodo') : false;
$carreras = $nivel ? $db
->orderBy('carrera')
->where('facultad', $nivel['facultad_id'])
@@ -61,11 +63,11 @@ $write = $user->admin || in_array($user->acceso, ['w']);
<ul style="display:none">
<?php
foreach ($carreras as $carrera) {
?>
?>
<li data-id="<?= $carrera['id'] ?>">
<?= $carrera['carrera'] ?>
</li>
<?php
<?php
}
?>
</ul>
@@ -91,7 +93,8 @@ $write = $user->admin || in_array($user->acceso, ['w']);
<div class="form-group mt-4 row justify-content-center">
<?php if ($write) { ?>
<button type="button" id="nuevo" class="btn btn-outline-primary ml-4 d-none" title="Nuevo horario" data-toggle="modal" data-target="#modal-editar">
<button type="button" id="nuevo" class="btn btn-outline-primary ml-4 d-none"
title="Nuevo horario" data-toggle="modal" data-target="#modal-editar">
<span class="ing-mas ing-fw"></span> Nuevo
</button>
<?php } ?>
@@ -127,7 +130,8 @@ $write = $user->admin || in_array($user->acceso, ['w']);
</table>
</div>
<div class="modal fade" id="modal-editar" tabindex="-1" aria-labelledby="modal-editar" aria-hidden="true" data-backdrop="static" data-keyboard="false">
<div class="modal fade" id="modal-editar" tabindex="-1" aria-labelledby="modal-editar" aria-hidden="true"
data-backdrop="static" data-keyboard="false">
<div class="modal-dialog modal-dialog-centered modal-lg">
<div class="modal-content">
<div class="modal-header">
@@ -158,7 +162,8 @@ $write = $user->admin || in_array($user->acceso, ['w']);
<div class="form-grupo row mb-3">
<div class="col-4"></div>
<div class="col-6">
<input type="text" id="grupo" name="grupo" value="" class="form-control" placeholder="Grupo" required="required" hidden>
<input type="text" id="grupo" name="grupo" value="" class="form-control"
placeholder="Grupo" required="required" hidden>
<div class="invalid-feedback">
Por favor, ingrese un grupo.
</div>
@@ -167,7 +172,8 @@ $write = $user->admin || in_array($user->acceso, ['w']);
<div class="form-group row">
<label for="materia" class="col-4 col-form-label">Materia</label>
<div class="col-6">
<input list="lista_materias" name="dlMateria" id="dlMateria" class="form-control text-center" placeholder="Materia" required="required">
<input list="lista_materias" name="dlMateria" id="dlMateria"
class="form-control text-center" placeholder="Materia" required="required">
<datalist id="lista_materias"></datalist>
<input type="hidden" id="materia" name="materia" value="">
<div class="invalid-feedback">
@@ -196,7 +202,8 @@ $write = $user->admin || in_array($user->acceso, ['w']);
<span class="ing-buscar icono"></span>
<ul style="display:none">
<?php foreach (range(0, 45, 15) as $minuto) { ?>
<li data-id='<?= $minuto ?>'><?= str_pad($minuto, 2, "0", STR_PAD_LEFT) ?></li>
<li data-id='<?= $minuto ?>'><?= str_pad($minuto, 2, "0", STR_PAD_LEFT) ?>
</li>
<?php } ?>
</ul>
<input type="hidden" id="selector_minutos" name="minutos" value="">
@@ -238,9 +245,10 @@ $write = $user->admin || in_array($user->acceso, ['w']);
$nombre = $duración['duracion_nombre'];
$id = $duración['duracion_id'];
$bloques = $duración['duracion_bloques'];
?>
<li data-id="<?= $id; ?>" data-bloques="<?= $bloques; ?>"><?= $nombre; ?></li>
<?php
?>
<li data-id="<?= $id; ?>" data-bloques="<?= $bloques; ?>"><?= $nombre; ?>
</li>
<?php
}
?>
</ul>
@@ -256,7 +264,8 @@ $write = $user->admin || in_array($user->acceso, ['w']);
<div class="form-group row">
<label for="editor_profesor" class="col-4 col-form-label">Profesor</label>
<div class="col-6">
<input list="lista_profesores" name="dlProfesor" id="dlProfesor" class="form-control" placeholder="Profesor" required="required">
<input list="lista_profesores" name="dlProfesor" id="dlProfesor"
class="form-control" placeholder="Profesor" required="required">
<div class="valid-feedback">
Profesor encontrado
</div>
@@ -265,11 +274,10 @@ $write = $user->admin || in_array($user->acceso, ['w']);
</div>
<datalist id="lista_profesores">
<?php
$profesores = $db->where('facultad_id', $user->facultad['facultad_id'])->get("fs_profesor");
$profesores = $db->get("profesor");
foreach ($profesores as $profesor) {
extract($profesor);
?>
<option data-grado="<?= $grado ?>" data-clave="<?= $clave ?>" data-profesor="<?= $profesor ?>" data-id="<?= $id; ?>" value="<?= "$clave | $grado $profesor" ?>"></option>
<option data-clave="<?= $profesor['profesor_clave'] ?>" data-profesor="<?= $profesor['profesor_nombre'] ?>" data-id="<?= $id; ?>" value="<?= "{$profesor['profesor_clave']} | {$profesor['profesor_grado']} {$profesor['profesor_nombre']}" ?>"></option>
<?php
}
?>
@@ -283,7 +291,8 @@ $write = $user->admin || in_array($user->acceso, ['w']);
<div class="form-group row">
<label for="editor_salón" class="col-4 col-form-label">Salón</label>
<div class="col-6">
<input type="text" class="form-control" id="editor_salón" name="salón" placeholder="Salón" maxlength="100" required="required">
<input type="text" class="form-control" id="editor_salón" name="salón"
placeholder="Salón" maxlength="100" required="required">
<div class="invalid-feedback">
El salón no puede estar vacío.
</div>
@@ -292,7 +301,8 @@ $write = $user->admin || in_array($user->acceso, ['w']);
</div>
</div>
<div class="modal-footer">
<button data-id="" type="button" class="btn btn-primary" id="btn-guardar"><i class="ing-guardar ing"></i> Guardar</button>
<button data-id="" type="button" class="btn btn-primary" id="btn-guardar"><i
class="ing-guardar ing"></i> Guardar</button>
<button type="button" class="btn btn-outline-primary" data-dismiss="modal">Cancelar</button>
</div>
</div>
@@ -425,8 +435,8 @@ require_once("import/html_footer.php");
function compareHours(hora1, hora2) {
// parseInt each hour and minute
const [h1, m1, ] = hora1.split(":").map(x => parseInt(x));
const [h2, m2, ] = hora2.split(":").map(x => parseInt(x));
const [h1, m1,] = hora1.split(":").map(x => parseInt(x));
const [h2, m2,] = hora2.split(":").map(x => parseInt(x));
if (h1 > h2)
return 1;
@@ -588,11 +598,11 @@ require_once("import/html_footer.php");
<b class="title">${materia}</b> <br>
<br><span>Salón: </span>${salon} <br>
<small class="my-2">
${profesores.map(({grado, profesor}) => /*html*/ ` <span class="ing ing-formacion mx-1"></span>${grado ?? ''} ${profesor}`).join("<br>")}
${profesores.map(({ grado, profesor }) => /*html*/ ` <span class="ing ing-formacion mx-1"></span>${grado ?? ''} ${profesor}`).join("<br>")}
</small>
</div>
${edit && float_menu}`
cell.classList.add("bloque-clase", "position-relative");
cell.rowSpan = bloques;
// draggable
@@ -712,8 +722,8 @@ require_once("import/html_footer.php");
}
const conflictBlocks = horarios.filter((horario, index, arrayHorario) =>
arrayHorario.filter((_, i) => i != index).some(horario2 =>
conflicts(horario, horario2)))
arrayHorario.filter((_, i) => i != index).some(horario2 =>
conflicts(horario, horario2)))
.sort((a, b) => compareHours(a.hora, b.hora));
const classes = horarios.filter(horario => !conflictBlocks.includes(horario));
@@ -749,7 +759,7 @@ require_once("import/html_footer.php");
document.querySelectorAll("tbody#horario tr").forEach(hora => {
const hora_id = parseInt(hora.id.split("-")[1].split(":")[0]);
(hora_id < min_hour || hora_id > max_hour) ? hora.remove(): null;
(hora_id < min_hour || hora_id > max_hour) ? hora.remove() : null;
})
// if there is no sábado, remove the column
@@ -788,7 +798,7 @@ require_once("import/html_footer.php");
// droppables
// forall the .bloque-elements add the event listeners for drag and drop
<?php if ($write) : ?>
<?php if ($write): ?>
document.querySelectorAll(".bloque-clase").forEach(element => {
function dragStart() {
this.classList.add("dragging");
@@ -802,69 +812,69 @@ require_once("import/html_footer.php");
element.addEventListener("dragend", dragEnd);
});
// forall the cells that are not .bloque-clase add the event listeners for drag and drop
document.querySelectorAll("td:not(.bloque-clase)").forEach(element => {
function dragOver(e) {
e.preventDefault();
this.classList.add("dragging-over");
// forall the cells that are not .bloque-clase add the event listeners for drag and drop
document.querySelectorAll("td:not(.bloque-clase)").forEach(element => {
function dragOver(e) {
e.preventDefault();
this.classList.add("dragging-over");
}
function dragLeave() {
this.classList.remove("dragging-over");
}
function drop() {
this.classList.remove("dragging-over");
const dragging = document.querySelector(".dragging");
const id = /* for data-ids */ dragging.getAttribute("data-ids");
const hora = /* for data-hora */ this.id.split("-")[1];
const días = ["lunes", "martes", "miércoles", "jueves", "viernes", "sábado"];
let día = /* for data-dia */ this.id.split("-")[2];
día = días.indexOf(día) + 1;
// rowspan
const bloques = parseInt(dragging.getAttribute("rowspan"));
const horaMoment = moment(hora, "HH:mm");
const horaFin = horaMoment.add(bloques * 15, "minutes");
const limit = moment('22:00', 'HH:mm');
if (horaFin.isAfter(limit)) {
triggerMessage("No se puede mover el bloque a esa hora", "Error");
// scroll to the top
window.scrollTo(0, 0);
return;
}
function dragLeave() {
this.classList.remove("dragging-over");
// get the horario
// remove the horario
const bloque = document.querySelector(`.bloque-clase[data-ids="${id}"]`);
// remove all children
while (bloque.firstChild) {
bloque.removeChild(bloque.firstChild);
}
function drop() {
this.classList.remove("dragging-over");
const dragging = document.querySelector(".dragging");
const id = /* for data-ids */ dragging.getAttribute("data-ids");
const hora = /* for data-hora */ this.id.split("-")[1];
const días = ["lunes", "martes", "miércoles", "jueves", "viernes", "sábado"];
let día = /* for data-dia */ this.id.split("-")[2];
día = días.indexOf(día) + 1;
// rowspan
const bloques = parseInt(dragging.getAttribute("rowspan"));
const horaMoment = moment(hora, "HH:mm");
const horaFin = horaMoment.add(bloques * 15, "minutes");
const limit = moment('22:00', 'HH:mm');
if (horaFin.isAfter(limit)) {
triggerMessage("No se puede mover el bloque a esa hora", "Error");
// scroll to the top
window.scrollTo(0, 0);
return;
}
// get the horario
// remove the horario
const bloque = document.querySelector(`.bloque-clase[data-ids="${id}"]`);
// remove all children
while (bloque.firstChild) {
bloque.removeChild(bloque.firstChild);
}
// prepend a loading child
const loading = `<div class="spinner-border" role="status" style="width: 3rem; height: 3rem;">
// prepend a loading child
const loading = `<div class="spinner-border" role="status" style="width: 3rem; height: 3rem;">
<span class="sr-only">Loading...</span>
</div>`;
bloque.insertAdjacentHTML("afterbegin", loading);
// add style vertical-align: middle
bloque.style.verticalAlign = "middle";
bloque.classList.add("text-center");
// remove draggable
bloque.removeAttribute("draggable");
bloque.insertAdjacentHTML("afterbegin", loading);
// add style vertical-align: middle
bloque.style.verticalAlign = "middle";
bloque.classList.add("text-center");
// remove draggable
bloque.removeAttribute("draggable");
moveHorario(id, día, hora);
}
moveHorario(id, día, hora);
}
element.addEventListener("dragover", dragOver);
element.addEventListener("dragleave", dragLeave);
element.addEventListener("drop", drop);
});
element.addEventListener("dragover", dragOver);
element.addEventListener("dragleave", dragLeave);
element.addEventListener("drop", drop);
});
<?php endif; ?>
}
async function guardar(id) {
@@ -980,7 +990,6 @@ require_once("import/html_footer.php");
}
}
function guardarHorario() {
let goBack = false;
const data = {
@@ -1111,7 +1120,6 @@ require_once("import/html_footer.php");
// buscarGrupo();
}
function moveHorario(id, día, hora) {
const formData = new FormData();
@@ -1136,7 +1144,6 @@ require_once("import/html_footer.php");
});
}
function extractFromModal() {
// remove all is-valid and is-invalid
document.querySelectorAll(".is-valid, .is-invalid").forEach(el =>
@@ -1213,7 +1220,6 @@ require_once("import/html_footer.php");
return formData;
}
function resetFormModal() {
const modalNuevo = document.querySelector("#modal-editar");
modalNuevo.querySelectorAll("input").forEach(input => input.value = "");
@@ -1231,7 +1237,6 @@ require_once("import/html_footer.php");
// remove bg-info
modalNuevo.querySelectorAll(".bg-info").forEach(el => el.classList.remove("bg-info"));
}
function insertHorario(horario) {
const fetchOptions = {
method: "POST",
@@ -1256,7 +1261,6 @@ require_once("import/html_footer.php");
triggerMessage(err, "Error");
});
}
// initial state
{
// fill the table with empty cells
@@ -1289,7 +1293,7 @@ require_once("import/html_footer.php");
// query selector All tds and ths inside the tbody#horario
// previous query selector: "tbody#horario td, tbody#horario tr"
document.querySelectorAll("tbody#horario td, tbody#horario tr").forEach(element => element.style.height = "2.5rem");
document.getElementById('dlProfesor').addEventListener('input', function(e) {
document.getElementById('dlProfesor').addEventListener('input', function (e) {
var input = document.getElementById('dlProfesor');
var value = input.value;
var option = document.querySelector(`option[value="${value}"]`);
@@ -1318,7 +1322,7 @@ require_once("import/html_footer.php");
});
e.target.value = "";
});
document.getElementById('dlMateria').addEventListener('input', function(e) {
document.getElementById('dlMateria').addEventListener('input', function (e) {
var input = document.getElementById('dlMateria');
var value = input.value;
var option = document.querySelector(`option[value="${value}"]`);
@@ -1373,9 +1377,9 @@ require_once("import/html_footer.php");
}, 0));
fetch("export/horario_excel.php", {
method: "POST",
body: formData
})
method: "POST",
body: formData
})
.then(response => response.blob())
.then(blob => {
const url = window.URL.createObjectURL(blob);
@@ -1479,7 +1483,7 @@ require_once("import/html_footer.php");
})
// on modal edit, show the data
$("#modal-editar").on("show.bs.modal", async function(event) {
$("#modal-editar").on("show.bs.modal", async function (event) {
document.querySelectorAll("#modal-editar .is-invalid, #modal-editar .is-valid")?.forEach(element => element.classList.remove("is-invalid", "is-valid"));
@@ -1597,7 +1601,7 @@ require_once("import/html_footer.php");
backdrop: "static",
keyboard: false,
})
$("#modal-borrar").on("show.bs.modal", async function(event) {
$("#modal-borrar").on("show.bs.modal", async function (event) {
const button = event.relatedTarget;
const id = button.parentElement.parentElement.getAttribute("data-ids");