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')