Stable
This commit is contained in:
514
ts/auditoría.ts
514
ts/auditoría.ts
@@ -1,237 +1,277 @@
|
||||
import { createApp, reactive } from 'https://unpkg.com/petite-vue?module'
|
||||
import { text } from 'stream/consumers';
|
||||
type Registro = {
|
||||
carrera: string;
|
||||
carrera_id: number;
|
||||
comentario: null;
|
||||
dia: string;
|
||||
duracion: string;
|
||||
duracion_id: number;
|
||||
estado_supervisor_id: number;
|
||||
facultad: string;
|
||||
facultad_id: number;
|
||||
horario_dia: number;
|
||||
horario_fin: string;
|
||||
horario_grupo: string;
|
||||
horario_hora: string;
|
||||
horario_id: number;
|
||||
materia: string;
|
||||
materia_id: number;
|
||||
nombre: string;
|
||||
periodo: string;
|
||||
periodo_id: number;
|
||||
profesor_clave: string;
|
||||
profesor_correo: string;
|
||||
profesor_grado: null;
|
||||
profesor_id: number;
|
||||
profesor_nombre: string;
|
||||
registro_fecha: null;
|
||||
registro_fecha_ideal: Date;
|
||||
registro_fecha_supervisor: Date;
|
||||
registro_id: number;
|
||||
registro_justificada: null;
|
||||
registro_retardo: null;
|
||||
salon: string;
|
||||
salon_id: number;
|
||||
supervisor_id: number;
|
||||
}
|
||||
|
||||
type Estado = {
|
||||
color: string;
|
||||
icon: string;
|
||||
estado_supervisor_id: number;
|
||||
}
|
||||
|
||||
type Facultad = {
|
||||
clave_dependencia: string;
|
||||
facultad_id: number;
|
||||
facultad_nombre: string;
|
||||
}
|
||||
|
||||
type Filter = {
|
||||
type: string;
|
||||
value: string;
|
||||
icon: string;
|
||||
field: string;
|
||||
label: string;
|
||||
}
|
||||
|
||||
const store = reactive({
|
||||
loading: false,
|
||||
current: {
|
||||
comentario: '',
|
||||
clase_vista: null,
|
||||
empty: '',
|
||||
},
|
||||
facultades: {
|
||||
data: [] as Facultad[],
|
||||
async fetch() {
|
||||
this.data = [] as Facultad[]
|
||||
const res = await fetch('action/action_facultad.php')
|
||||
this.data = await res.json()
|
||||
},
|
||||
},
|
||||
filters: {
|
||||
facultad_id: null,
|
||||
fecha: null,
|
||||
fecha_inicio: null,
|
||||
fecha_fin: null,
|
||||
profesor: null,
|
||||
estados: [],
|
||||
|
||||
switchFecha: false,
|
||||
switchFechas() {
|
||||
$(function () {
|
||||
store.filters.fecha_inicio = store.filters.fecha_fin = store.filters.fecha = null
|
||||
|
||||
$("#fecha, #fecha_inicio, #fecha_fin").datepicker({
|
||||
minDate: -3,
|
||||
maxDate: new Date(),
|
||||
dateFormat: "yy-mm-dd",
|
||||
showAnim: "slide",
|
||||
});
|
||||
|
||||
const fecha = $("#fecha"), inicio = $("#fecha_inicio"), fin = $("#fecha_fin")
|
||||
inicio.on("change", function () {
|
||||
store.filters.fecha_inicio = inicio.val()
|
||||
fin.datepicker("option", "minDate", inicio.val());
|
||||
});
|
||||
fin.on("change", function () {
|
||||
store.filters.fecha_fin = fin.val()
|
||||
inicio.datepicker("option", "maxDate", fin.val());
|
||||
});
|
||||
fecha.on("change", function () {
|
||||
store.filters.fecha = fecha.val()
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
estados: {
|
||||
data: [] as Estado[],
|
||||
async fetch() {
|
||||
this.data = [] as Estado[]
|
||||
const res = await fetch('action/action_estado_supervisor.php')
|
||||
this.data = await res.json()
|
||||
},
|
||||
getEstado(id: number): Estado {
|
||||
return this.data.find((estado: Estado) => estado.estado_supervisor_id === id)
|
||||
},
|
||||
printEstados() {
|
||||
if (store.filters.estados.length > 0)
|
||||
document.querySelector('#estados')!.innerHTML = store.filters.estados.map((estado: number) =>
|
||||
`<span class="mx-2 badge badge-${store.estados.getEstado(estado).estado_color}">
|
||||
<i class="${store.estados.getEstado(estado).estado_icon}"></i> ${store.estados.getEstado(estado).nombre}
|
||||
</span>`
|
||||
).join('')
|
||||
else
|
||||
document.querySelector('#estados')!.innerHTML = `Todos los registros`
|
||||
}
|
||||
},
|
||||
toggle(arr: any, element: any) {
|
||||
const newArray = arr.includes(element) ? arr.filter((item: any) => item !== element) : [...arr, element]
|
||||
// if all are selected, then unselect all
|
||||
if (newArray.length === this.estados.data.length) return []
|
||||
return newArray
|
||||
},
|
||||
})
|
||||
|
||||
declare var $: any
|
||||
|
||||
|
||||
|
||||
type Profesor = {
|
||||
profesor_id: number;
|
||||
profesor_nombre: string;
|
||||
profesor_correo: string;
|
||||
profesor_clave: string;
|
||||
profesor_grado: string;
|
||||
}
|
||||
|
||||
createApp({
|
||||
store,
|
||||
get clase_vista() {
|
||||
return store.current.clase_vista
|
||||
},
|
||||
registros: {
|
||||
data: [] as Registro[],
|
||||
async fetch() {
|
||||
this.loading = true
|
||||
this.data = [] as Registro[]
|
||||
const res = await fetch('action/action_auditoria.php')
|
||||
this.data = await res.json()
|
||||
this.loading = false
|
||||
},
|
||||
invertir() {
|
||||
this.data = this.data.reverse()
|
||||
},
|
||||
mostrarComentario(registro_id: number) {
|
||||
const registro = this.data.find((registro: Registro) => registro.registro_id === registro_id)
|
||||
store.current.comentario = registro.comentario
|
||||
$('#ver-comentario').modal('show')
|
||||
},
|
||||
|
||||
get relevant() {
|
||||
/*
|
||||
facultad_id: null,
|
||||
fecha: null,
|
||||
fecha_inicio: null,
|
||||
fecha_fin: null,
|
||||
profesor: null,
|
||||
asistencia: null,
|
||||
estado_id: null,
|
||||
if one of the filters is null, then it is not relevant
|
||||
|
||||
*/
|
||||
const filters = Object.keys(store.filters).filter((filtro) => store.filters[filtro] || store.filters[filtro]?.length > 0)
|
||||
return this.data.filter((registro: Registro) => {
|
||||
return filters.every((filtro) => {
|
||||
switch (filtro) {
|
||||
case 'fecha':
|
||||
return registro.registro_fecha_ideal === store.filters[filtro];
|
||||
case 'fecha_inicio':
|
||||
return registro.registro_fecha_ideal >= store.filters[filtro];
|
||||
case 'fecha_fin':
|
||||
return registro.registro_fecha_ideal <= store.filters[filtro];
|
||||
case 'profesor':
|
||||
const textoFiltro = store.filters[filtro].toLowerCase();
|
||||
if (/^\([^)]+\)\s[\s\S]+$/.test(textoFiltro)) {
|
||||
const clave = registro.profesor_clave.toLowerCase();
|
||||
const filtroClave = textoFiltro.match(/\((.*?)\)/)?.[1];
|
||||
console.log(clave, filtroClave);
|
||||
return clave.includes(filtroClave);
|
||||
} else {
|
||||
const nombre = registro.profesor_nombre.toLowerCase();
|
||||
return nombre.includes(textoFiltro);
|
||||
}
|
||||
case 'facultad_id':
|
||||
return registro.facultad_id === store.filters[filtro];
|
||||
case 'estados':
|
||||
if (store.filters[filtro].length === 0) return true;
|
||||
return store.filters[filtro].includes(registro.estado_supervisor_id);
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
},
|
||||
get profesores() {
|
||||
return this.registros.data.map((registro: Registro) => (
|
||||
{
|
||||
profesor_id: registro.profesor_id,
|
||||
profesor_nombre: registro.profesor_nombre,
|
||||
profesor_correo: registro.profesor_correo,
|
||||
profesor_clave: registro.profesor_clave,
|
||||
profesor_grado: registro.profesor_grado,
|
||||
}
|
||||
)).sort((a: Profesor, b: Profesor) =>
|
||||
a.profesor_nombre.localeCompare(b.profesor_nombre)
|
||||
)
|
||||
},
|
||||
async mounted() {
|
||||
await this.registros.fetch()
|
||||
await store.facultades.fetch()
|
||||
await store.estados.fetch()
|
||||
store.filters.switchFechas()
|
||||
}
|
||||
}).mount('#app')
|
||||
import { createApp, reactive } from 'https://unpkg.com/petite-vue?module'
|
||||
|
||||
type Registro = {
|
||||
carrera: string;
|
||||
carrera_id: number;
|
||||
comentario: null;
|
||||
dia: string;
|
||||
duracion: string;
|
||||
duracion_id: number;
|
||||
estado_supervisor_id: number;
|
||||
facultad: string;
|
||||
facultad_id: number;
|
||||
horario_dia: number;
|
||||
horario_fin: string;
|
||||
horario_grupo: string;
|
||||
horario_hora: string;
|
||||
horario_id: number;
|
||||
materia: string;
|
||||
materia_id: number;
|
||||
nombre: string;
|
||||
periodo: string;
|
||||
periodo_id: number;
|
||||
profesor_clave: string;
|
||||
profesor_correo: string;
|
||||
profesor_grado: null;
|
||||
profesor_id: number;
|
||||
profesor_nombre: string;
|
||||
registro_fecha: null;
|
||||
registro_fecha_ideal: Date;
|
||||
registro_fecha_supervisor: Date;
|
||||
registro_id: number;
|
||||
registro_justificada: null;
|
||||
registro_retardo: null;
|
||||
salon: string;
|
||||
salon_id: number;
|
||||
supervisor_id: number;
|
||||
}
|
||||
|
||||
type Estado = {
|
||||
color: string;
|
||||
icon: string;
|
||||
estado_supervisor_id: number;
|
||||
}
|
||||
|
||||
type Facultad = {
|
||||
clave_dependencia: string;
|
||||
facultad_id: number;
|
||||
facultad_nombre: string;
|
||||
}
|
||||
|
||||
type Bloque_Horario = {
|
||||
hora_fin: string;
|
||||
hora_inicio: string;
|
||||
id: number;
|
||||
selected: boolean;
|
||||
}
|
||||
|
||||
|
||||
type Filter = {
|
||||
type: string;
|
||||
value: string;
|
||||
icon: string;
|
||||
field: string;
|
||||
label: string;
|
||||
}
|
||||
|
||||
const store = reactive({
|
||||
loading: false,
|
||||
current: {
|
||||
comentario: '',
|
||||
clase_vista: null,
|
||||
empty: '',
|
||||
},
|
||||
facultades: {
|
||||
data: [] as Facultad[],
|
||||
async fetch() {
|
||||
this.data = [] as Facultad[]
|
||||
const res = await fetch('action/action_facultad.php')
|
||||
this.data = await res.json()
|
||||
},
|
||||
},
|
||||
filters: {
|
||||
facultad_id: null,
|
||||
fecha: null,
|
||||
fecha_inicio: null,
|
||||
fecha_fin: null,
|
||||
profesor: null,
|
||||
bloque_horario: null,
|
||||
estados: [],
|
||||
|
||||
switchFecha: false,
|
||||
switchFechas() {
|
||||
$(function () {
|
||||
store.filters.fecha_inicio = store.filters.fecha_fin = store.filters.fecha = null
|
||||
|
||||
$("#fecha, #fecha_inicio, #fecha_fin").datepicker({
|
||||
minDate: -3,
|
||||
maxDate: new Date(),
|
||||
dateFormat: "yy-mm-dd",
|
||||
showAnim: "slide",
|
||||
});
|
||||
|
||||
const fecha = $("#fecha"), inicio = $("#fecha_inicio"), fin = $("#fecha_fin")
|
||||
inicio.on("change", function () {
|
||||
store.filters.fecha_inicio = inicio.val()
|
||||
fin.datepicker("option", "minDate", inicio.val());
|
||||
});
|
||||
fin.on("change", function () {
|
||||
store.filters.fecha_fin = fin.val()
|
||||
inicio.datepicker("option", "maxDate", fin.val());
|
||||
});
|
||||
fecha.on("change", function () {
|
||||
store.filters.fecha = fecha.val()
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
estados: {
|
||||
data: [] as Estado[],
|
||||
async fetch() {
|
||||
this.data = [] as Estado[]
|
||||
const res = await fetch('action/action_estado_supervisor.php')
|
||||
this.data = await res.json()
|
||||
},
|
||||
getEstado(id: number): Estado {
|
||||
return this.data.find((estado: Estado) => estado.estado_supervisor_id === id)
|
||||
},
|
||||
printEstados() {
|
||||
if (store.filters.estados.length > 0)
|
||||
document.querySelector('#estados')!.innerHTML = store.filters.estados.map((estado: number) =>
|
||||
`<span class="mx-2 badge badge-${store.estados.getEstado(estado).estado_color}">
|
||||
<i class="${store.estados.getEstado(estado).estado_icon}"></i> ${store.estados.getEstado(estado).nombre}
|
||||
</span>`
|
||||
).join('')
|
||||
else
|
||||
document.querySelector('#estados')!.innerHTML = `Todos los registros`
|
||||
}
|
||||
},
|
||||
bloques_horario: {
|
||||
data: [] as Bloque_Horario[],
|
||||
async fetch() {
|
||||
this.data = [] as Bloque_Horario[]
|
||||
const res = await fetch('action/action_grupo_horario.php')
|
||||
this.data = await res.json()
|
||||
|
||||
if (this.data.every((bloque: Bloque_Horario) => !bloque.selected))
|
||||
this.data[0].selected = true
|
||||
},
|
||||
},
|
||||
toggle(arr: any, element: any) {
|
||||
const newArray = arr.includes(element) ? arr.filter((item: any) => item !== element) : [...arr, element]
|
||||
// if all are selected, then unselect all
|
||||
if (newArray.length === this.estados.data.length) return []
|
||||
return newArray
|
||||
},
|
||||
})
|
||||
|
||||
declare var $: any
|
||||
|
||||
|
||||
|
||||
type Profesor = {
|
||||
profesor_id: number;
|
||||
profesor_nombre: string;
|
||||
profesor_correo: string;
|
||||
profesor_clave: string;
|
||||
profesor_grado: string;
|
||||
}
|
||||
|
||||
createApp({
|
||||
store,
|
||||
get clase_vista() {
|
||||
return store.current.clase_vista
|
||||
},
|
||||
registros: {
|
||||
data: [] as Registro[],
|
||||
async fetch() {
|
||||
this.loading = true
|
||||
this.data = [] as Registro[]
|
||||
const res = await fetch('action/action_auditoria.php')
|
||||
this.data = await res.json()
|
||||
this.loading = false
|
||||
},
|
||||
invertir() {
|
||||
this.data = this.data.reverse()
|
||||
},
|
||||
mostrarComentario(registro_id: number) {
|
||||
const registro = this.data.find((registro: Registro) => registro.registro_id === registro_id)
|
||||
store.current.comentario = registro.comentario
|
||||
$('#ver-comentario').modal('show')
|
||||
},
|
||||
|
||||
get relevant() {
|
||||
/*
|
||||
facultad_id: null,
|
||||
fecha: null,
|
||||
fecha_inicio: null,
|
||||
fecha_fin: null,
|
||||
profesor: null,
|
||||
asistencia: null,
|
||||
estado_id: null,
|
||||
if one of the filters is null, then it is not relevant
|
||||
|
||||
*/
|
||||
const filters = Object.keys(store.filters).filter((filtro) => store.filters[filtro] || store.filters[filtro]?.length > 0)
|
||||
return this.data.filter((registro: Registro) => {
|
||||
return filters.every((filtro) => {
|
||||
|
||||
switch (filtro) {
|
||||
case 'fecha':
|
||||
return registro.registro_fecha_ideal === store.filters[filtro];
|
||||
case 'fecha_inicio':
|
||||
return registro.registro_fecha_ideal >= store.filters[filtro];
|
||||
case 'fecha_fin':
|
||||
return registro.registro_fecha_ideal <= store.filters[filtro];
|
||||
case 'profesor':
|
||||
const textoFiltro = store.filters[filtro].toLowerCase();
|
||||
if (/^\([^)]+\)\s[\s\S]+$/.test(textoFiltro)) {
|
||||
const clave = registro.profesor_clave.toLowerCase();
|
||||
const filtroClave = textoFiltro.match(/\((.*?)\)/)?.[1];
|
||||
console.log(clave, filtroClave);
|
||||
return clave.includes(filtroClave);
|
||||
} else {
|
||||
const nombre = registro.profesor_nombre.toLowerCase();
|
||||
return nombre.includes(textoFiltro);
|
||||
}
|
||||
case 'facultad_id':
|
||||
return registro.facultad_id === store.filters[filtro];
|
||||
case 'estados':
|
||||
if (store.filters[filtro].length === 0) return true;
|
||||
return store.filters[filtro].includes(registro.estado_supervisor_id);
|
||||
case 'bloque_horario':
|
||||
const bloque = store.bloques_horario.data.find((bloque: Bloque_Horario) => bloque.id === store.filters[filtro]) as Bloque_Horario;
|
||||
return registro.horario_hora <= bloque.hora_fin && registro.horario_fin >= bloque.hora_inicio;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
async descargar() {
|
||||
if (this.relevant.length === 0) return;
|
||||
const res = await fetch('export/supervisor_excel.php', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify(this.relevant)
|
||||
});
|
||||
const blob = await res.blob();
|
||||
(window as any).saveAs(blob, `auditoria_${new Date().toISOString().slice(0, 10)}.xlsx`);
|
||||
}
|
||||
},
|
||||
get profesores() {
|
||||
return this.registros.data.map((registro: Registro) => (
|
||||
{
|
||||
profesor_id: registro.profesor_id,
|
||||
profesor_nombre: registro.profesor_nombre,
|
||||
profesor_correo: registro.profesor_correo,
|
||||
profesor_clave: registro.profesor_clave,
|
||||
profesor_grado: registro.profesor_grado,
|
||||
}
|
||||
)).sort((a: Profesor, b: Profesor) =>
|
||||
a.profesor_nombre.localeCompare(b.profesor_nombre)
|
||||
)
|
||||
},
|
||||
async mounted() {
|
||||
await this.registros.fetch()
|
||||
await store.facultades.fetch()
|
||||
await store.estados.fetch()
|
||||
await store.bloques_horario.fetch()
|
||||
|
||||
store.filters.bloque_horario = store.bloques_horario.data.find((bloque: Bloque_Horario) => bloque.selected)?.id
|
||||
store.filters.switchFechas()
|
||||
}
|
||||
}).mount('#app')
|
||||
|
||||
296
ts/client.ts
296
ts/client.ts
@@ -1,149 +1,149 @@
|
||||
// @ts-ignore Import module
|
||||
import { createApp, reactive } from 'https://unpkg.com/petite-vue?module'
|
||||
|
||||
export interface PeridoV1 {
|
||||
IdNivel: number;
|
||||
IdPeriodo: number;
|
||||
NombreNivel: string;
|
||||
NombrePeriodo: string;
|
||||
in_db: boolean;
|
||||
linked: boolean;
|
||||
}
|
||||
|
||||
|
||||
export interface PeridoV2 {
|
||||
ClaveCarrera: string;
|
||||
FechaFin: string;
|
||||
FechaInicio: string;
|
||||
IdPeriodo: number;
|
||||
NombreCarrera: string;
|
||||
}
|
||||
|
||||
const webServices = {
|
||||
getPeriodosV1: async (): Promise<PeridoV1[]> => {
|
||||
try {
|
||||
const response = await fetch('periodos.v1.php');
|
||||
return await response.json();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
return [];
|
||||
}
|
||||
},
|
||||
getPeriodosV2: async (): Promise<PeridoV2[]> => {
|
||||
try {
|
||||
const response = await fetch('periodos.v2.php');
|
||||
return await response.json();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const store = reactive({
|
||||
periodosV1: [] as PeridoV1[],
|
||||
periodosV2: [] as PeridoV2[],
|
||||
|
||||
errors: [] as string[],
|
||||
fechas(idPeriodo: number): { inicio: string, fin: string } {
|
||||
const periodo = this.periodosV2.find((periodo: PeridoV2) => periodo.IdPeriodo === idPeriodo);
|
||||
return {
|
||||
inicio: periodo ? periodo.FechaInicio : '',
|
||||
fin: periodo ? periodo.FechaFin : ''
|
||||
}
|
||||
},
|
||||
periodov1(idPeriodo: number): PeridoV1 | undefined {
|
||||
return this.periodosV1.find((periodo: PeridoV1) => periodo.IdPeriodo === idPeriodo);
|
||||
},
|
||||
periodov2(idPeriodo: number): PeridoV2[] {
|
||||
return this.periodosV2.filter((periodo: PeridoV2) => periodo.IdPeriodo === idPeriodo);
|
||||
},
|
||||
async addPeriodo(periodo: PeridoV1 | PeridoV2) {
|
||||
try {
|
||||
const result = await fetch('backend/periodos.php', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
...periodo,
|
||||
...this.fechas(periodo.IdPeriodo)
|
||||
}),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}).then((response) => response.json());
|
||||
if (result.success) {
|
||||
this.periodosV1 = this.periodosV1.map((periodoV1: PeridoV1) => {
|
||||
if (periodoV1.IdPeriodo === periodo.IdPeriodo) {
|
||||
periodoV1.in_db = true;
|
||||
}
|
||||
return periodoV1;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
this.errors.push(result.message);
|
||||
}
|
||||
} catch (error) {
|
||||
this.errors.push(error);
|
||||
}
|
||||
},
|
||||
|
||||
async addCarreras(idPeriodo: number) {
|
||||
try {
|
||||
const periodoV1 = this.periodov1(idPeriodo) as PeridoV1;
|
||||
const periodoV2 = this.periodov2(idPeriodo) as PeridoV2[];
|
||||
|
||||
const data = periodoV2.map(({ ClaveCarrera, NombreCarrera }: PeridoV2) =>
|
||||
({
|
||||
ClaveCarrera: ClaveCarrera,
|
||||
NombreCarrera: NombreCarrera,
|
||||
IdNivel: periodoV1.IdNivel,
|
||||
})
|
||||
);
|
||||
|
||||
const result = await fetch('backend/carreras.php', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(data),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}).then((response) => response.json());
|
||||
if (result.success) {
|
||||
await webServices.getPeriodosV1().then((periodosV1) => {
|
||||
this.periodosV1 = periodosV1;
|
||||
});
|
||||
|
||||
await webServices.getPeriodosV2().then((periodosV2) => {
|
||||
this.periodosV2 = periodosV2;
|
||||
});
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
this.errors.push(error);
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
createApp({
|
||||
store,
|
||||
info(IdPeriodo: number): PeridoV2 {
|
||||
const periodo = store.periodosV2.find((periodo: PeridoV2) => periodo.IdPeriodo === IdPeriodo &&
|
||||
periodo.FechaInicio != '' && periodo.FechaFin != '');
|
||||
return periodo
|
||||
},
|
||||
complete(IdPeriodo: number): boolean {
|
||||
const info = this.info(IdPeriodo);
|
||||
return info !== undefined;
|
||||
},
|
||||
mounted: async () => {
|
||||
|
||||
await webServices.getPeriodosV1().then((periodosV1) => {
|
||||
store.periodosV1 = periodosV1;
|
||||
});
|
||||
|
||||
await webServices.getPeriodosV2().then((periodosV2) => {
|
||||
store.periodosV2 = periodosV2;
|
||||
});
|
||||
|
||||
}
|
||||
// @ts-ignore Import module
|
||||
import { createApp, reactive } from 'https://unpkg.com/petite-vue?module'
|
||||
|
||||
export interface PeridoV1 {
|
||||
IdNivel: number;
|
||||
IdPeriodo: number;
|
||||
NombreNivel: string;
|
||||
NombrePeriodo: string;
|
||||
in_db: boolean;
|
||||
linked: boolean;
|
||||
}
|
||||
|
||||
|
||||
export interface PeridoV2 {
|
||||
ClaveCarrera: string;
|
||||
FechaFin: string;
|
||||
FechaInicio: string;
|
||||
IdPeriodo: number;
|
||||
NombreCarrera: string;
|
||||
}
|
||||
|
||||
const webServices = {
|
||||
getPeriodosV1: async (): Promise<PeridoV1[]> => {
|
||||
try {
|
||||
const response = await fetch('periodos.v1.php');
|
||||
return await response.json();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
return [];
|
||||
}
|
||||
},
|
||||
getPeriodosV2: async (): Promise<PeridoV2[]> => {
|
||||
try {
|
||||
const response = await fetch('periodos.v2.php');
|
||||
return await response.json();
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const store = reactive({
|
||||
periodosV1: [] as PeridoV1[],
|
||||
periodosV2: [] as PeridoV2[],
|
||||
|
||||
errors: [] as string[],
|
||||
fechas(idPeriodo: number): { inicio: string, fin: string } {
|
||||
const periodo = this.periodosV2.find((periodo: PeridoV2) => periodo.IdPeriodo === idPeriodo);
|
||||
return {
|
||||
inicio: periodo ? periodo.FechaInicio : '',
|
||||
fin: periodo ? periodo.FechaFin : ''
|
||||
}
|
||||
},
|
||||
periodov1(idPeriodo: number): PeridoV1 | undefined {
|
||||
return this.periodosV1.find((periodo: PeridoV1) => periodo.IdPeriodo === idPeriodo);
|
||||
},
|
||||
periodov2(idPeriodo: number): PeridoV2[] {
|
||||
return this.periodosV2.filter((periodo: PeridoV2) => periodo.IdPeriodo === idPeriodo);
|
||||
},
|
||||
async addPeriodo(periodo: PeridoV1 | PeridoV2) {
|
||||
try {
|
||||
const result = await fetch('backend/periodos.php', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
...periodo,
|
||||
...this.fechas(periodo.IdPeriodo)
|
||||
}),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}).then((response) => response.json());
|
||||
if (result.success) {
|
||||
this.periodosV1 = this.periodosV1.map((periodoV1: PeridoV1) => {
|
||||
if (periodoV1.IdPeriodo === periodo.IdPeriodo) {
|
||||
periodoV1.in_db = true;
|
||||
}
|
||||
return periodoV1;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
this.errors.push(result.message);
|
||||
}
|
||||
} catch (error) {
|
||||
this.errors.push(error);
|
||||
}
|
||||
},
|
||||
|
||||
async addCarreras(idPeriodo: number) {
|
||||
try {
|
||||
const periodoV1 = this.periodov1(idPeriodo) as PeridoV1;
|
||||
const periodoV2 = this.periodov2(idPeriodo) as PeridoV2[];
|
||||
|
||||
const data = periodoV2.map(({ ClaveCarrera, NombreCarrera }: PeridoV2) =>
|
||||
({
|
||||
ClaveCarrera: ClaveCarrera,
|
||||
NombreCarrera: NombreCarrera,
|
||||
IdNivel: periodoV1.IdNivel,
|
||||
})
|
||||
);
|
||||
|
||||
const result = await fetch('backend/carreras.php', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(data),
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}).then((response) => response.json());
|
||||
if (result.success) {
|
||||
await webServices.getPeriodosV1().then((periodosV1) => {
|
||||
this.periodosV1 = periodosV1;
|
||||
});
|
||||
|
||||
await webServices.getPeriodosV2().then((periodosV2) => {
|
||||
this.periodosV2 = periodosV2;
|
||||
});
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
this.errors.push(error);
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
createApp({
|
||||
store,
|
||||
info(IdPeriodo: number): PeridoV2 {
|
||||
const periodo = store.periodosV2.find((periodo: PeridoV2) => periodo.IdPeriodo === IdPeriodo &&
|
||||
periodo.FechaInicio != '' && periodo.FechaFin != '');
|
||||
return periodo
|
||||
},
|
||||
complete(IdPeriodo: number): boolean {
|
||||
const info = this.info(IdPeriodo);
|
||||
return info !== undefined;
|
||||
},
|
||||
mounted: async () => {
|
||||
|
||||
await webServices.getPeriodosV1().then((periodosV1) => {
|
||||
store.periodosV1 = periodosV1;
|
||||
});
|
||||
|
||||
await webServices.getPeriodosV2().then((periodosV2) => {
|
||||
store.periodosV2 = periodosV2;
|
||||
});
|
||||
|
||||
}
|
||||
}).mount()
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,272 +1,272 @@
|
||||
import { type } from "os";
|
||||
|
||||
declare function triggerMessage(message: string, title: string, type?: string): void;
|
||||
declare const write: boolean;
|
||||
declare const moment: any;
|
||||
// from this 'horario_id', 'fecha', 'hora', 'duracion_id', 'descripcion', 'profesor_id', 'salon', 'unidad', 'periodo_id', 'fecha_clase' make a type of ReposicionParams
|
||||
export interface ReposicionParams {
|
||||
horario_id: number;
|
||||
fecha: string;
|
||||
hora: string;
|
||||
duracion_id: number;
|
||||
descripcion: string;
|
||||
profesor_id: number;
|
||||
salon: string;
|
||||
unidad: number;
|
||||
periodo_id: number;
|
||||
fecha_clase: string;
|
||||
}
|
||||
|
||||
type Horario = {
|
||||
id: number;
|
||||
carrera_id: number;
|
||||
materia_id: number;
|
||||
grupo: string;
|
||||
profesores: Profesor[];
|
||||
dia: string;
|
||||
hora: string;
|
||||
hora_final: string;
|
||||
salon: string;
|
||||
fecha_inicio: string;
|
||||
fecha_final: string;
|
||||
fecha_carga: string;
|
||||
nivel_id: number;
|
||||
periodo_id: number;
|
||||
facultad_id: number;
|
||||
materia: string;
|
||||
horas: number;
|
||||
minutos: number;
|
||||
duracion: number;
|
||||
retardo: boolean;
|
||||
original_id: number;
|
||||
last: boolean;
|
||||
bloques: number;
|
||||
};
|
||||
|
||||
type Profesor = {
|
||||
id: number;
|
||||
clave: string;
|
||||
grado: string;
|
||||
profesor: string;
|
||||
nombre: string;
|
||||
facultad_id: number;
|
||||
};
|
||||
// Get references to the HTML elements
|
||||
const form = document.getElementById('form') as HTMLFormElement;
|
||||
const steps = Array.from(form.querySelectorAll('.step')) as HTMLElement[];
|
||||
|
||||
const nextButton = document.getElementById('next-button') as HTMLButtonElement;
|
||||
const prevButton = document.getElementById('prev-button') as HTMLButtonElement;
|
||||
|
||||
let currentStep = 0;
|
||||
|
||||
// #clave_profesor on change => show step 2
|
||||
const clave_profesor = document.getElementById('clave_profesor') as HTMLInputElement;
|
||||
const horario_reponer = document.getElementById('horario_reponer') as HTMLInputElement;
|
||||
const fechas_clase = document.getElementById('fechas_clase') as HTMLInputElement;
|
||||
|
||||
const fecha_reponer = $('#fecha_reponer') as JQuery<HTMLElement>;
|
||||
const hora_reponer = $('#hora_reponer') as JQuery<HTMLElement>;
|
||||
const minutos_reponer = $('#minutos_reponer') as JQuery<HTMLElement>;
|
||||
|
||||
clave_profesor.addEventListener('change', async () => {
|
||||
const step2 = document.getElementById('step-2') as HTMLElement;
|
||||
clave_profesor.disabled = true;
|
||||
// get option which value is the same as clave_profesor.value
|
||||
const option = document.querySelector(`option[value="${clave_profesor.value}"]`) as HTMLOptionElement;
|
||||
|
||||
// make a form data with #form
|
||||
const profesor_id = document.getElementById('profesor_id') as HTMLInputElement;
|
||||
profesor_id.value = option.dataset.id;
|
||||
|
||||
const formData = new FormData(form);
|
||||
|
||||
const response = await fetch(`./action/action_horario_profesor.php`, {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
});
|
||||
const data = await response.json();
|
||||
if (data['success'] === false) {
|
||||
const message = "Hubo un error al obtener los horarios del profesor."
|
||||
const title = 'Error';
|
||||
const color = 'danger';
|
||||
triggerMessage(message, title, color);
|
||||
return;
|
||||
}
|
||||
const horarios = data.data as Horario[];
|
||||
const initial = document.createElement('option');
|
||||
initial.value = '';
|
||||
initial.textContent = 'Seleccione un horario';
|
||||
initial.selected = true;
|
||||
initial.disabled = true;
|
||||
horario_reponer.innerHTML = '';
|
||||
horario_reponer.appendChild(initial);
|
||||
|
||||
horarios.forEach((horario) => {
|
||||
const dias = ['Lunes', 'Martes', 'Miercoles', 'Jueves', 'Viernes', 'Sabado', 'Domingo'];
|
||||
const option = document.createElement('option');
|
||||
option.value = `${horario.id}`;
|
||||
// materia máx 25 caracteres, if materia.length > 25 then slice(0, 20)
|
||||
const max = 25;
|
||||
option.textContent = `${horario.materia.slice(0, max) + (horario.materia.length > max ? '...' : '')} - Grupo: ${horario.grupo} - ${horario.hora.slice(0, 5)}-${horario.hora_final.slice(0, 5)} - Salon: ${horario.salon} - ${horario.dia}`;
|
||||
|
||||
option.dataset.materia = `${horario.materia}`;
|
||||
option.dataset.grupo = `${horario.grupo}`;
|
||||
option.dataset.hora = `${horario.hora.slice(0, 5)}`; // slice(0, 5) => HH:MM
|
||||
option.dataset.hora_final = `${horario.hora_final.slice(0, 5)}`;
|
||||
option.dataset.salon = `${horario.salon}`;
|
||||
option.dataset.dia = `${horario.dia}`;
|
||||
|
||||
option.dataset.id = `${horario.id}`;
|
||||
horario_reponer.appendChild(option);
|
||||
});
|
||||
currentStep = 1;
|
||||
step2.style.display = 'block';
|
||||
prevButton.disabled = false;
|
||||
});
|
||||
// disable clave_profesor
|
||||
|
||||
// from second step to first step
|
||||
prevButton.addEventListener('click', () => {
|
||||
const inputs = [clave_profesor, horario_reponer, fechas_clase, fecha_reponer, hora_reponer] as HTMLInputElement[];
|
||||
switch (currentStep) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
const step = document.getElementById(`step-${currentStep + 1}`) as HTMLElement;
|
||||
step.style.display = 'none';
|
||||
inputs[currentStep - 1].disabled = false;
|
||||
inputs[currentStep - 1].value = '';
|
||||
if (--currentStep === 0) {
|
||||
prevButton.disabled = true;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
const step5 = document.getElementById('step-5') as HTMLElement;
|
||||
step5.style.display = 'none';
|
||||
fecha_reponer.prop('disabled', false);
|
||||
fecha_reponer.val('');
|
||||
|
||||
hora_reponer.parent().removeClass('disabled');
|
||||
hora_reponer.siblings('.datalist-input').text('hh');
|
||||
hora_reponer.val('');
|
||||
|
||||
minutos_reponer.parent().removeClass('disabled');
|
||||
minutos_reponer.siblings('.datalist-input').text('mm');
|
||||
minutos_reponer.val('');
|
||||
|
||||
currentStep--;
|
||||
break;
|
||||
}
|
||||
|
||||
nextButton.disabled = true;
|
||||
|
||||
});
|
||||
|
||||
// #horario_reponer on change => show step 3
|
||||
horario_reponer.addEventListener('change', async () => {
|
||||
const selected = horario_reponer.querySelector(`option[value="${horario_reponer.value}"]`) as HTMLOptionElement;
|
||||
horario_reponer.title = `Materia: ${selected.dataset.materia} - Grupo: ${selected.dataset.grupo} - Horario: ${selected.dataset.hora}-${selected.dataset.hora_final} - Salon: ${selected.dataset.salon} - Día: ${selected.dataset.dia}`;
|
||||
const step3 = document.getElementById('step-3') as HTMLElement;
|
||||
horario_reponer.disabled = true;
|
||||
// make a form data with #form
|
||||
const response = await fetch(`./action/action_fechas_clase.php?horario_id=${horario_reponer.value}`, {
|
||||
method: 'GET',
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
if (data['success'] === false) {
|
||||
const message = "Hubo un error al obtener las fechas de clase."
|
||||
const title = 'Error';
|
||||
const color = 'danger';
|
||||
triggerMessage(message, title, color);
|
||||
return;
|
||||
}
|
||||
type Fecha = {
|
||||
fecha: string;
|
||||
dia_mes: number;
|
||||
day: number;
|
||||
month: number;
|
||||
year: number;
|
||||
}
|
||||
|
||||
const meses = ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'];
|
||||
|
||||
const fechas = data.data as Fecha[];
|
||||
const initial = document.createElement('option');
|
||||
initial.value = '';
|
||||
initial.textContent = 'Seleccione la fecha de la falta';
|
||||
initial.selected = true;
|
||||
initial.disabled = true;
|
||||
fechas_clase.innerHTML = '';
|
||||
fechas_clase.appendChild(initial);
|
||||
fechas_clase.title = 'Seleccione la fecha de la falta';
|
||||
|
||||
fechas.forEach((fecha) => {
|
||||
const option = document.createElement('option');
|
||||
option.value = `${fecha}`;
|
||||
option.textContent = `${fecha.dia_mes} de ${meses[fecha.month - 1]} de ${fecha.year}`;
|
||||
fechas_clase.appendChild(option);
|
||||
});
|
||||
|
||||
|
||||
step3.style.display = 'block';
|
||||
currentStep = 2;
|
||||
});
|
||||
|
||||
// #fechas_clase on change => show step 4
|
||||
fechas_clase.addEventListener('change', () => {
|
||||
const step4 = document.getElementById('step-4') as HTMLElement;
|
||||
step4.style.display = 'block';
|
||||
fechas_clase.disabled = true;
|
||||
currentStep = 3;
|
||||
});
|
||||
|
||||
// when both #fecha_reponer and #hora_reponer are selected => show step 5
|
||||
|
||||
const lastStep = () => {
|
||||
// timeout to wait for the value to be set
|
||||
setTimeout(() => {
|
||||
if (fecha_reponer.val() !== '' && hora_reponer.val() !== '' && minutos_reponer.val() !== '') {
|
||||
const step5 = document.getElementById('step-5') as HTMLElement;
|
||||
step5.style.display = 'block';
|
||||
// disable both
|
||||
fecha_reponer.prop('disabled', true);
|
||||
hora_reponer.parent().addClass('disabled');
|
||||
minutos_reponer.parent().addClass('disabled');
|
||||
|
||||
const nextButton = document.getElementById('next-button') as HTMLButtonElement;
|
||||
// remove property disabled
|
||||
nextButton.removeAttribute('disabled');
|
||||
currentStep = 4;
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
fecha_reponer.on('change', lastStep);
|
||||
// on click on the sibling ul>li of #hora_reponer and #minutos_reponer
|
||||
|
||||
hora_reponer.siblings('ul').children('li').on('click', lastStep);
|
||||
minutos_reponer.siblings('ul').children('li').on('click', lastStep);
|
||||
|
||||
// Initialize the form
|
||||
hideSteps();
|
||||
showCurrentStep();
|
||||
|
||||
|
||||
function hideSteps() {
|
||||
steps.forEach((step) => {
|
||||
step.style.display = 'none';
|
||||
});
|
||||
}
|
||||
|
||||
function showCurrentStep() {
|
||||
steps[currentStep].style.display = 'block';
|
||||
prevButton.disabled = currentStep === 0;
|
||||
}
|
||||
|
||||
function handleSubmit(event: Event) {
|
||||
event.preventDefault();
|
||||
|
||||
// Handle form submission
|
||||
// You can access the form data using the FormData API or serialize it manually
|
||||
import { type } from "os";
|
||||
|
||||
declare function triggerMessage(message: string, title: string, type?: string): void;
|
||||
declare const write: boolean;
|
||||
declare const moment: any;
|
||||
// from this 'horario_id', 'fecha', 'hora', 'duracion_id', 'descripcion', 'profesor_id', 'salon', 'unidad', 'periodo_id', 'fecha_clase' make a type of ReposicionParams
|
||||
export interface ReposicionParams {
|
||||
horario_id: number;
|
||||
fecha: string;
|
||||
hora: string;
|
||||
duracion_id: number;
|
||||
descripcion: string;
|
||||
profesor_id: number;
|
||||
salon: string;
|
||||
unidad: number;
|
||||
periodo_id: number;
|
||||
fecha_clase: string;
|
||||
}
|
||||
|
||||
type Horario = {
|
||||
id: number;
|
||||
carrera_id: number;
|
||||
materia_id: number;
|
||||
grupo: string;
|
||||
profesores: Profesor[];
|
||||
dia: string;
|
||||
hora: string;
|
||||
hora_final: string;
|
||||
salon: string;
|
||||
fecha_inicio: string;
|
||||
fecha_final: string;
|
||||
fecha_carga: string;
|
||||
nivel_id: number;
|
||||
periodo_id: number;
|
||||
facultad_id: number;
|
||||
materia: string;
|
||||
horas: number;
|
||||
minutos: number;
|
||||
duracion: number;
|
||||
retardo: boolean;
|
||||
original_id: number;
|
||||
last: boolean;
|
||||
bloques: number;
|
||||
};
|
||||
|
||||
type Profesor = {
|
||||
id: number;
|
||||
clave: string;
|
||||
grado: string;
|
||||
profesor: string;
|
||||
nombre: string;
|
||||
facultad_id: number;
|
||||
};
|
||||
// Get references to the HTML elements
|
||||
const form = document.getElementById('form') as HTMLFormElement;
|
||||
const steps = Array.from(form.querySelectorAll('.step')) as HTMLElement[];
|
||||
|
||||
const nextButton = document.getElementById('next-button') as HTMLButtonElement;
|
||||
const prevButton = document.getElementById('prev-button') as HTMLButtonElement;
|
||||
|
||||
let currentStep = 0;
|
||||
|
||||
// #clave_profesor on change => show step 2
|
||||
const clave_profesor = document.getElementById('clave_profesor') as HTMLInputElement;
|
||||
const horario_reponer = document.getElementById('horario_reponer') as HTMLInputElement;
|
||||
const fechas_clase = document.getElementById('fechas_clase') as HTMLInputElement;
|
||||
|
||||
const fecha_reponer = $('#fecha_reponer') as JQuery<HTMLElement>;
|
||||
const hora_reponer = $('#hora_reponer') as JQuery<HTMLElement>;
|
||||
const minutos_reponer = $('#minutos_reponer') as JQuery<HTMLElement>;
|
||||
|
||||
clave_profesor.addEventListener('change', async () => {
|
||||
const step2 = document.getElementById('step-2') as HTMLElement;
|
||||
clave_profesor.disabled = true;
|
||||
// get option which value is the same as clave_profesor.value
|
||||
const option = document.querySelector(`option[value="${clave_profesor.value}"]`) as HTMLOptionElement;
|
||||
|
||||
// make a form data with #form
|
||||
const profesor_id = document.getElementById('profesor_id') as HTMLInputElement;
|
||||
profesor_id.value = option.dataset.id;
|
||||
|
||||
const formData = new FormData(form);
|
||||
|
||||
const response = await fetch(`./action/action_horario_profesor.php`, {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
});
|
||||
const data = await response.json();
|
||||
if (data['success'] === false) {
|
||||
const message = "Hubo un error al obtener los horarios del profesor."
|
||||
const title = 'Error';
|
||||
const color = 'danger';
|
||||
triggerMessage(message, title, color);
|
||||
return;
|
||||
}
|
||||
const horarios = data.data as Horario[];
|
||||
const initial = document.createElement('option');
|
||||
initial.value = '';
|
||||
initial.textContent = 'Seleccione un horario';
|
||||
initial.selected = true;
|
||||
initial.disabled = true;
|
||||
horario_reponer.innerHTML = '';
|
||||
horario_reponer.appendChild(initial);
|
||||
|
||||
horarios.forEach((horario) => {
|
||||
const dias = ['Lunes', 'Martes', 'Miercoles', 'Jueves', 'Viernes', 'Sabado', 'Domingo'];
|
||||
const option = document.createElement('option');
|
||||
option.value = `${horario.id}`;
|
||||
// materia máx 25 caracteres, if materia.length > 25 then slice(0, 20)
|
||||
const max = 25;
|
||||
option.textContent = `${horario.materia.slice(0, max) + (horario.materia.length > max ? '...' : '')} - Grupo: ${horario.grupo} - ${horario.hora.slice(0, 5)}-${horario.hora_final.slice(0, 5)} - Salon: ${horario.salon} - ${horario.dia}`;
|
||||
|
||||
option.dataset.materia = `${horario.materia}`;
|
||||
option.dataset.grupo = `${horario.grupo}`;
|
||||
option.dataset.hora = `${horario.hora.slice(0, 5)}`; // slice(0, 5) => HH:MM
|
||||
option.dataset.hora_final = `${horario.hora_final.slice(0, 5)}`;
|
||||
option.dataset.salon = `${horario.salon}`;
|
||||
option.dataset.dia = `${horario.dia}`;
|
||||
|
||||
option.dataset.id = `${horario.id}`;
|
||||
horario_reponer.appendChild(option);
|
||||
});
|
||||
currentStep = 1;
|
||||
step2.style.display = 'block';
|
||||
prevButton.disabled = false;
|
||||
});
|
||||
// disable clave_profesor
|
||||
|
||||
// from second step to first step
|
||||
prevButton.addEventListener('click', () => {
|
||||
const inputs = [clave_profesor, horario_reponer, fechas_clase, fecha_reponer, hora_reponer] as HTMLInputElement[];
|
||||
switch (currentStep) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
const step = document.getElementById(`step-${currentStep + 1}`) as HTMLElement;
|
||||
step.style.display = 'none';
|
||||
inputs[currentStep - 1].disabled = false;
|
||||
inputs[currentStep - 1].value = '';
|
||||
if (--currentStep === 0) {
|
||||
prevButton.disabled = true;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
const step5 = document.getElementById('step-5') as HTMLElement;
|
||||
step5.style.display = 'none';
|
||||
fecha_reponer.prop('disabled', false);
|
||||
fecha_reponer.val('');
|
||||
|
||||
hora_reponer.parent().removeClass('disabled');
|
||||
hora_reponer.siblings('.datalist-input').text('hh');
|
||||
hora_reponer.val('');
|
||||
|
||||
minutos_reponer.parent().removeClass('disabled');
|
||||
minutos_reponer.siblings('.datalist-input').text('mm');
|
||||
minutos_reponer.val('');
|
||||
|
||||
currentStep--;
|
||||
break;
|
||||
}
|
||||
|
||||
nextButton.disabled = true;
|
||||
|
||||
});
|
||||
|
||||
// #horario_reponer on change => show step 3
|
||||
horario_reponer.addEventListener('change', async () => {
|
||||
const selected = horario_reponer.querySelector(`option[value="${horario_reponer.value}"]`) as HTMLOptionElement;
|
||||
horario_reponer.title = `Materia: ${selected.dataset.materia} - Grupo: ${selected.dataset.grupo} - Horario: ${selected.dataset.hora}-${selected.dataset.hora_final} - Salon: ${selected.dataset.salon} - Día: ${selected.dataset.dia}`;
|
||||
const step3 = document.getElementById('step-3') as HTMLElement;
|
||||
horario_reponer.disabled = true;
|
||||
// make a form data with #form
|
||||
const response = await fetch(`./action/action_fechas_clase.php?horario_id=${horario_reponer.value}`, {
|
||||
method: 'GET',
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
if (data['success'] === false) {
|
||||
const message = "Hubo un error al obtener las fechas de clase."
|
||||
const title = 'Error';
|
||||
const color = 'danger';
|
||||
triggerMessage(message, title, color);
|
||||
return;
|
||||
}
|
||||
type Fecha = {
|
||||
fecha: string;
|
||||
dia_mes: number;
|
||||
day: number;
|
||||
month: number;
|
||||
year: number;
|
||||
}
|
||||
|
||||
const meses = ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'];
|
||||
|
||||
const fechas = data.data as Fecha[];
|
||||
const initial = document.createElement('option');
|
||||
initial.value = '';
|
||||
initial.textContent = 'Seleccione la fecha de la falta';
|
||||
initial.selected = true;
|
||||
initial.disabled = true;
|
||||
fechas_clase.innerHTML = '';
|
||||
fechas_clase.appendChild(initial);
|
||||
fechas_clase.title = 'Seleccione la fecha de la falta';
|
||||
|
||||
fechas.forEach((fecha) => {
|
||||
const option = document.createElement('option');
|
||||
option.value = `${fecha}`;
|
||||
option.textContent = `${fecha.dia_mes} de ${meses[fecha.month - 1]} de ${fecha.year}`;
|
||||
fechas_clase.appendChild(option);
|
||||
});
|
||||
|
||||
|
||||
step3.style.display = 'block';
|
||||
currentStep = 2;
|
||||
});
|
||||
|
||||
// #fechas_clase on change => show step 4
|
||||
fechas_clase.addEventListener('change', () => {
|
||||
const step4 = document.getElementById('step-4') as HTMLElement;
|
||||
step4.style.display = 'block';
|
||||
fechas_clase.disabled = true;
|
||||
currentStep = 3;
|
||||
});
|
||||
|
||||
// when both #fecha_reponer and #hora_reponer are selected => show step 5
|
||||
|
||||
const lastStep = () => {
|
||||
// timeout to wait for the value to be set
|
||||
setTimeout(() => {
|
||||
if (fecha_reponer.val() !== '' && hora_reponer.val() !== '' && minutos_reponer.val() !== '') {
|
||||
const step5 = document.getElementById('step-5') as HTMLElement;
|
||||
step5.style.display = 'block';
|
||||
// disable both
|
||||
fecha_reponer.prop('disabled', true);
|
||||
hora_reponer.parent().addClass('disabled');
|
||||
minutos_reponer.parent().addClass('disabled');
|
||||
|
||||
const nextButton = document.getElementById('next-button') as HTMLButtonElement;
|
||||
// remove property disabled
|
||||
nextButton.removeAttribute('disabled');
|
||||
currentStep = 4;
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
fecha_reponer.on('change', lastStep);
|
||||
// on click on the sibling ul>li of #hora_reponer and #minutos_reponer
|
||||
|
||||
hora_reponer.siblings('ul').children('li').on('click', lastStep);
|
||||
minutos_reponer.siblings('ul').children('li').on('click', lastStep);
|
||||
|
||||
// Initialize the form
|
||||
hideSteps();
|
||||
showCurrentStep();
|
||||
|
||||
|
||||
function hideSteps() {
|
||||
steps.forEach((step) => {
|
||||
step.style.display = 'none';
|
||||
});
|
||||
}
|
||||
|
||||
function showCurrentStep() {
|
||||
steps[currentStep].style.display = 'block';
|
||||
prevButton.disabled = currentStep === 0;
|
||||
}
|
||||
|
||||
function handleSubmit(event: Event) {
|
||||
event.preventDefault();
|
||||
|
||||
// Handle form submission
|
||||
// You can access the form data using the FormData API or serialize it manually
|
||||
}
|
||||
Reference in New Issue
Block a user