Files
paad/ts/horario.ts
2023-10-03 18:22:51 +00:00

181 lines
6.0 KiB
TypeScript

import { createApp, reactive } from 'https://unpkg.com/petite-vue?module'
type Profesor = {
profesor_clave: string;
profesor_correo: string;
profesor_grado: null | string;
profesor_id: number;
profesor_nombre: string;
}
type Horario = {
carrera: string;
carrera_id: number;
dia: string;
duracion: string;
duracion_id: number;
facultad: string;
facultad_id: number;
fecha_carga: Date;
horario_dia: number;
horario_fecha_fin: null;
horario_fecha_inicio: Date;
horario_fin: string;
horario_grupo: string;
horario_hora: string;
horario_id: number;
limite: null;
materia: string;
materia_id: number;
nivel: string;
nivel_id: number;
periodo: string;
periodo_fecha_fin: Date;
periodo_fecha_inicio: Date;
periodo_id: number;
profesor_id: number;
salon: string;
salon_id: number;
bloques: number;
}
type Facultad = {
clave_dependencia: string;
facultad_id: number;
facultad_nombre: string;
carreras: Carrera[];
}
type Carrera = {
carrera_id: number;
carrera_nombre: string;
clave_carrera: string;
facultad_id: number;
}
const profesores = reactive({
data: [] as Profesor[],
search: null as null | string,
fetch: async function () {
const response = await fetch('action/action_profesor.php')
this.data = await response.json() as Profesor[]
},
get clave() {
const match = this.search.match(/^\((.+)\)/)
return match ? match[1] : ''
},
get current() {
return this.data.find((profesor: Profesor) => profesor.profesor_clave === profesores.clave)
},
})
const facultades = reactive({
data: [] as Facultad[],
fetch: async function () {
const facultades = await fetch('action/action_facultad.php').then(response => response.json()) as Facultad[]
const carreras = await fetch(`action/carrera.php`).then(response => response.json()) as Carrera[]
this.data = await Promise.all(facultades.map(async facultad => ({
...facultad,
carreras: await Promise.all(carreras.filter((carrera: Carrera) => carrera.facultad_id === facultad.facultad_id).map(async (carrera: Carrera) => {
const grupos = await fetch(`action/action_grupo.php?carrera_id=${carrera.carrera_id}`).then(response => response.json())
return {
...carrera,
grupos,
}
})),
})))
this.data = this.data.filter((facultad: Facultad) => facultad.carreras.length > 0)
}
})
type Structure = {
sábado: boolean;
hora_mínima: number;
hora_máxima: number;
horas_totales: number;
}
const horarios = reactive({
data: [] as Horario[],
fetch: async function (grupo: number | null = null, carrera_id: number | null = null) {
if (grupo && carrera_id) {
const response = await fetch(`action/action_horario.php?grupo=${grupo}&carrera_id=${carrera_id}`)
this.data = await response.json()
}
else if (profesores.current) {
const response = await fetch(`action/action_horario.php?profesor_id=${profesores.current.profesor_id}`)
this.data = await response.json()
}
},
get structure() {
if (this.data.length === 0) return null;
const structure: Structure = {
sábado: this.data.some((horario: Horario) => horario.horario_dia === 6),
hora_mínima: Math.min(...this.data.map((horario: Horario) => parseInt(horario.horario_hora.split(':')[0]))),
hora_máxima: Math.max(...this.data.map((horario: Horario) => {
const [hour, minute] = horario.horario_fin.split(':').map(Number);
return hour + Math.ceil(minute / 60);
})),
horas_totales: 0
};
structure.horas_totales = structure.hora_máxima - structure.hora_mínima;
return structure;
},
get blocks() {
if (this.data.length === 0) return null;
return [...Array(this.structure.horas_totales).keys()].flatMap(hora => {
const baseHour = hora + this.structure.hora_mínima;
return [0, 15, 30, 45].map(block => ({ hour: baseHour, block }));
});
},
getHorarioData(hour: number, block: number, día: number) {
const foundHorario = this.data.find((horario: Horario) =>
parseInt(horario.horario_hora.split(':')[0]) === hour &&
parseInt(horario.horario_hora.split(':')[1]) === block &&
horario.horario_dia === día
);
return foundHorario;
},
isOccupied(hora: number, bloque: number, day: number) {
if (this.getHorarioData(hora, bloque, day)) {
return false;
}
const currentTimeInMinutes = hora * 60 + bloque;
for (const item of this.data) {
if (item.horario_dia !== day) {
continue; // Skip items that are not on the specified day
}
// Split the hour and minute from horario_hora
const [startHour, startMinute] = item.horario_hora.split(":").map(Number);
const startTimeInMinutes = startHour * 60 + startMinute;
// Calculate end time using duracion
const [durationHours, durationMinutes] = item.duracion.split(":").map(Number);
const endTimeInMinutes = startTimeInMinutes + (durationHours * 60) + durationMinutes;
if (currentTimeInMinutes >= startTimeInMinutes && currentTimeInMinutes < endTimeInMinutes) {
return true; // The block is occupied
}
}
return false; // The block is not occupied by any class
}
})
const app = createApp({
profesores,
horarios,
facultades,
mounted: async function () {
await profesores.fetch()
await facultades.fetch()
}
}).mount('#app')