horario.ts 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. import { createApp, reactive } from 'https://unpkg.com/petite-vue?module'
  2. type Profesor = {
  3. profesor_clave: string;
  4. profesor_correo: string;
  5. profesor_grado: null | string;
  6. profesor_id: number;
  7. profesor_nombre: string;
  8. }
  9. type Horario = {
  10. carrera: string;
  11. carrera_id: number;
  12. dia: string;
  13. duracion: string;
  14. duracion_id: number;
  15. facultad: string;
  16. facultad_id: number;
  17. fecha_carga: Date;
  18. horario_dia: number;
  19. horario_fecha_fin: null;
  20. horario_fecha_inicio: Date;
  21. horario_fin: string;
  22. horario_grupo: string;
  23. horario_hora: string;
  24. horario_id: number;
  25. limite: null;
  26. materia: string;
  27. materia_id: number;
  28. nivel: string;
  29. nivel_id: number;
  30. periodo: string;
  31. periodo_fecha_fin: Date;
  32. periodo_fecha_inicio: Date;
  33. periodo_id: number;
  34. profesor_id: number;
  35. salon: string;
  36. salon_id: number;
  37. bloques: number;
  38. }
  39. type Facultad = {
  40. clave_dependencia: string;
  41. facultad_id: number;
  42. facultad_nombre: string;
  43. carreras: Carrera[];
  44. }
  45. type Carrera = {
  46. carrera_id: number;
  47. carrera_nombre: string;
  48. clave_carrera: string;
  49. facultad_id: number;
  50. }
  51. const profesores = reactive({
  52. data: [] as Profesor[],
  53. search: null as null | string,
  54. fetch: async function () {
  55. const response = await fetch('action/action_profesor.php')
  56. this.data = await response.json() as Profesor[]
  57. },
  58. get clave() {
  59. const match = this.search.match(/^\((.+)\)/)
  60. return match ? match[1] : ''
  61. },
  62. get current() {
  63. return this.data.find((profesor: Profesor) => profesor.profesor_clave === profesores.clave)
  64. },
  65. })
  66. const facultades = reactive({
  67. data: [] as Facultad[],
  68. fetch: async function () {
  69. const facultades = await fetch('action/action_facultad.php').then(response => response.json()) as Facultad[]
  70. const carreras = await fetch(`action/carrera.php`).then(response => response.json()) as Carrera[]
  71. this.data = await Promise.all(facultades.map(async facultad => ({
  72. ...facultad,
  73. carreras: await Promise.all(carreras.filter((carrera: Carrera) => carrera.facultad_id === facultad.facultad_id).map(async (carrera: Carrera) => {
  74. const grupos = await fetch(`action/action_grupo.php?carrera_id=${carrera.carrera_id}`).then(response => response.json())
  75. return {
  76. ...carrera,
  77. grupos,
  78. }
  79. })),
  80. })))
  81. this.data = this.data.filter((facultad: Facultad) => facultad.carreras.length > 0)
  82. }
  83. })
  84. type Structure = {
  85. sábado: boolean;
  86. hora_mínima: number;
  87. hora_máxima: number;
  88. horas_totales: number;
  89. }
  90. const horarios = reactive({
  91. data: [] as Horario[],
  92. fetch: async function (grupo: number | null = null, carrera_id: number | null = null) {
  93. if (grupo && carrera_id) {
  94. const response = await fetch(`action/action_horario.php?grupo=${grupo}&carrera_id=${carrera_id}`)
  95. this.data = await response.json()
  96. }
  97. else if (profesores.current) {
  98. const response = await fetch(`action/action_horario.php?profesor_id=${profesores.current.profesor_id}`)
  99. this.data = await response.json()
  100. }
  101. },
  102. get structure() {
  103. if (this.data.length === 0) return null;
  104. const structure: Structure = {
  105. sábado: this.data.some((horario: Horario) => horario.horario_dia === 6),
  106. hora_mínima: Math.min(...this.data.map((horario: Horario) => parseInt(horario.horario_hora.split(':')[0]))),
  107. hora_máxima: Math.max(...this.data.map((horario: Horario) => {
  108. const [hour, minute] = horario.horario_fin.split(':').map(Number);
  109. return hour + Math.ceil(minute / 60);
  110. })),
  111. horas_totales: 0
  112. };
  113. structure.horas_totales = structure.hora_máxima - structure.hora_mínima;
  114. return structure;
  115. },
  116. get blocks() {
  117. if (this.data.length === 0) return null;
  118. return [...Array(this.structure.horas_totales).keys()].flatMap(hora => {
  119. const baseHour = hora + this.structure.hora_mínima;
  120. return [0, 15, 30, 45].map(block => ({ hour: baseHour, block }));
  121. });
  122. },
  123. getHorarioData(hour: number, block: number, día: number) {
  124. const foundHorario = this.data.find((horario: Horario) =>
  125. parseInt(horario.horario_hora.split(':')[0]) === hour &&
  126. parseInt(horario.horario_hora.split(':')[1]) === block &&
  127. horario.horario_dia === día
  128. );
  129. return foundHorario;
  130. },
  131. isOccupied(hora: number, bloque: number, day: number) {
  132. if (this.getHorarioData(hora, bloque, day)) {
  133. return false;
  134. }
  135. const currentTimeInMinutes = hora * 60 + bloque;
  136. for (const item of this.data) {
  137. if (item.horario_dia !== day) {
  138. continue; // Skip items that are not on the specified day
  139. }
  140. // Split the hour and minute from horario_hora
  141. const [startHour, startMinute] = item.horario_hora.split(":").map(Number);
  142. const startTimeInMinutes = startHour * 60 + startMinute;
  143. // Calculate end time using duracion
  144. const [durationHours, durationMinutes] = item.duracion.split(":").map(Number);
  145. const endTimeInMinutes = startTimeInMinutes + (durationHours * 60) + durationMinutes;
  146. if (currentTimeInMinutes >= startTimeInMinutes && currentTimeInMinutes < endTimeInMinutes) {
  147. return true; // The block is occupied
  148. }
  149. }
  150. return false; // The block is not occupied by any class
  151. }
  152. })
  153. const app = createApp({
  154. profesores,
  155. horarios,
  156. facultades,
  157. mounted: async function () {
  158. await profesores.fetch()
  159. await facultades.fetch()
  160. }
  161. }).mount('#app')