auditoría.ts 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. import { createApp, reactive } from 'https://unpkg.com/petite-vue?module'
  2. import { text } from 'stream/consumers';
  3. type Registro = {
  4. carrera: string;
  5. carrera_id: number;
  6. comentario: null;
  7. dia: string;
  8. duracion: string;
  9. duracion_id: number;
  10. estado_supervisor_id: number;
  11. facultad: string;
  12. facultad_id: number;
  13. horario_dia: number;
  14. horario_fin: string;
  15. horario_grupo: string;
  16. horario_hora: string;
  17. horario_id: number;
  18. materia: string;
  19. materia_id: number;
  20. nombre: string;
  21. periodo: string;
  22. periodo_id: number;
  23. profesor_clave: string;
  24. profesor_correo: string;
  25. profesor_grado: null;
  26. profesor_id: number;
  27. profesor_nombre: string;
  28. registro_fecha: null;
  29. registro_fecha_ideal: Date;
  30. registro_fecha_supervisor: Date;
  31. registro_id: number;
  32. registro_justificada: null;
  33. registro_retardo: null;
  34. salon: string;
  35. salon_id: number;
  36. supervisor_id: number;
  37. }
  38. type Estado = {
  39. color: string;
  40. icon: string;
  41. estado_supervisor_id: number;
  42. }
  43. type Facultad = {
  44. clave_dependencia: string;
  45. facultad_id: number;
  46. facultad_nombre: string;
  47. }
  48. type Filter = {
  49. type: string;
  50. value: string;
  51. icon: string;
  52. field: string;
  53. label: string;
  54. }
  55. const store = reactive({
  56. loading: false,
  57. current: {
  58. comentario: '',
  59. clase_vista: null,
  60. empty: '',
  61. },
  62. facultades: {
  63. data: [] as Facultad[],
  64. async fetch() {
  65. this.data = [] as Facultad[]
  66. const res = await fetch('action/action_facultad.php')
  67. this.data = await res.json()
  68. },
  69. },
  70. filters: {
  71. facultad_id: null,
  72. fecha: null,
  73. fecha_inicio: null,
  74. fecha_fin: null,
  75. profesor: null,
  76. estados: [],
  77. switchFecha: false,
  78. switchFechas() {
  79. $(function () {
  80. store.filters.fecha_inicio = store.filters.fecha_fin = store.filters.fecha = null
  81. $("#fecha, #fecha_inicio, #fecha_fin").datepicker({
  82. minDate: -3,
  83. maxDate: new Date(),
  84. dateFormat: "yy-mm-dd",
  85. showAnim: "slide",
  86. });
  87. const fecha = $("#fecha"), inicio = $("#fecha_inicio"), fin = $("#fecha_fin")
  88. inicio.on("change", function () {
  89. store.filters.fecha_inicio = inicio.val()
  90. fin.datepicker("option", "minDate", inicio.val());
  91. });
  92. fin.on("change", function () {
  93. store.filters.fecha_fin = fin.val()
  94. inicio.datepicker("option", "maxDate", fin.val());
  95. });
  96. fecha.on("change", function () {
  97. store.filters.fecha = fecha.val()
  98. });
  99. });
  100. }
  101. },
  102. estados: {
  103. data: [] as Estado[],
  104. async fetch() {
  105. this.data = [] as Estado[]
  106. const res = await fetch('action/action_estado_supervisor.php')
  107. this.data = await res.json()
  108. },
  109. getEstado(id: number): Estado {
  110. return this.data.find((estado: Estado) => estado.estado_supervisor_id === id)
  111. },
  112. printEstados() {
  113. if (store.filters.estados.length > 0)
  114. document.querySelector('#estados')!.innerHTML = store.filters.estados.map((estado: number) =>
  115. `<span class="mx-2 badge badge-${store.estados.getEstado(estado).estado_color}">
  116. <i class="${store.estados.getEstado(estado).estado_icon}"></i> ${store.estados.getEstado(estado).nombre}
  117. </span>`
  118. ).join('')
  119. else
  120. document.querySelector('#estados')!.innerHTML = `Todos los registros`
  121. }
  122. },
  123. toggle(arr: any, element: any) {
  124. const newArray = arr.includes(element) ? arr.filter((item: any) => item !== element) : [...arr, element]
  125. // if all are selected, then unselect all
  126. if (newArray.length === this.estados.data.length) return []
  127. return newArray
  128. },
  129. })
  130. declare var $: any
  131. type Profesor = {
  132. profesor_id: number;
  133. profesor_nombre: string;
  134. profesor_correo: string;
  135. profesor_clave: string;
  136. profesor_grado: string;
  137. }
  138. createApp({
  139. store,
  140. get clase_vista() {
  141. return store.current.clase_vista
  142. },
  143. registros: {
  144. data: [] as Registro[],
  145. async fetch() {
  146. this.loading = true
  147. this.data = [] as Registro[]
  148. const res = await fetch('action/action_auditoria.php')
  149. this.data = await res.json()
  150. this.loading = false
  151. },
  152. invertir() {
  153. this.data = this.data.reverse()
  154. },
  155. mostrarComentario(registro_id: number) {
  156. const registro = this.data.find((registro: Registro) => registro.registro_id === registro_id)
  157. store.current.comentario = registro.comentario
  158. $('#ver-comentario').modal('show')
  159. },
  160. get relevant() {
  161. /*
  162. facultad_id: null,
  163. fecha: null,
  164. fecha_inicio: null,
  165. fecha_fin: null,
  166. profesor: null,
  167. asistencia: null,
  168. estado_id: null,
  169. if one of the filters is null, then it is not relevant
  170. */
  171. const filters = Object.keys(store.filters).filter((filtro) => store.filters[filtro] || store.filters[filtro]?.length > 0)
  172. return this.data.filter((registro: Registro) => {
  173. return filters.every((filtro) => {
  174. switch (filtro) {
  175. case 'fecha':
  176. return registro.registro_fecha_ideal === store.filters[filtro];
  177. case 'fecha_inicio':
  178. return registro.registro_fecha_ideal >= store.filters[filtro];
  179. case 'fecha_fin':
  180. return registro.registro_fecha_ideal <= store.filters[filtro];
  181. case 'profesor':
  182. const textoFiltro = store.filters[filtro].toLowerCase();
  183. if (/^\([^)]+\)\s[\s\S]+$/.test(textoFiltro)) {
  184. const clave = registro.profesor_clave.toLowerCase();
  185. const filtroClave = textoFiltro.match(/\((.*?)\)/)?.[1];
  186. console.log(clave, filtroClave);
  187. return clave.includes(filtroClave);
  188. } else {
  189. const nombre = registro.profesor_nombre.toLowerCase();
  190. return nombre.includes(textoFiltro);
  191. }
  192. case 'facultad_id':
  193. return registro.facultad_id === store.filters[filtro];
  194. case 'estados':
  195. if (store.filters[filtro].length === 0) return true;
  196. return store.filters[filtro].includes(registro.estado_supervisor_id);
  197. default:
  198. return true;
  199. }
  200. })
  201. })
  202. },
  203. },
  204. get profesores() {
  205. return this.registros.data.map((registro: Registro) => (
  206. {
  207. profesor_id: registro.profesor_id,
  208. profesor_nombre: registro.profesor_nombre,
  209. profesor_correo: registro.profesor_correo,
  210. profesor_clave: registro.profesor_clave,
  211. profesor_grado: registro.profesor_grado,
  212. }
  213. )).sort((a: Profesor, b: Profesor) =>
  214. a.profesor_nombre.localeCompare(b.profesor_nombre)
  215. )
  216. },
  217. async mounted() {
  218. await this.registros.fetch()
  219. await store.facultades.fetch()
  220. await store.estados.fetch()
  221. store.filters.switchFechas()
  222. }
  223. }).mount('#app')