auditoría.js 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. import { createApp, reactive } from 'https://unpkg.com/petite-vue?module';
  2. const store = reactive({
  3. loading: false,
  4. current: {
  5. comentario: '',
  6. clase_vista: null,
  7. empty: '',
  8. },
  9. facultades: {
  10. data: [],
  11. async fetch() {
  12. this.data = [];
  13. const res = await fetch('action/action_facultad.php');
  14. this.data = await res.json();
  15. },
  16. },
  17. filters: {
  18. facultad_id: null,
  19. fecha: null,
  20. fecha_inicio: null,
  21. fecha_fin: null,
  22. profesor: null,
  23. bloque_horario: null,
  24. estados: [],
  25. switchFecha: false,
  26. switchFechas() {
  27. $(function () {
  28. store.filters.fecha_inicio = store.filters.fecha_fin = store.filters.fecha = null;
  29. $("#fecha, #fecha_inicio, #fecha_fin").datepicker({
  30. minDate: -3,
  31. maxDate: new Date(),
  32. dateFormat: "yy-mm-dd",
  33. showAnim: "slide",
  34. });
  35. const fecha = $("#fecha"), inicio = $("#fecha_inicio"), fin = $("#fecha_fin");
  36. inicio.on("change", function () {
  37. store.filters.fecha_inicio = inicio.val();
  38. fin.datepicker("option", "minDate", inicio.val());
  39. });
  40. fin.on("change", function () {
  41. store.filters.fecha_fin = fin.val();
  42. inicio.datepicker("option", "maxDate", fin.val());
  43. });
  44. fecha.on("change", function () {
  45. store.filters.fecha = fecha.val();
  46. });
  47. });
  48. }
  49. },
  50. estados: {
  51. data: [],
  52. async fetch() {
  53. this.data = [];
  54. const res = await fetch('action/action_estado_supervisor.php');
  55. this.data = await res.json();
  56. },
  57. getEstado(id) {
  58. return this.data.find((estado) => estado.estado_supervisor_id === id);
  59. },
  60. printEstados() {
  61. if (store.filters.estados.length > 0)
  62. document.querySelector('#estados').innerHTML = store.filters.estados.map((estado) => `<span class="mx-2 badge badge-${store.estados.getEstado(estado).estado_color}">
  63. <i class="${store.estados.getEstado(estado).estado_icon}"></i> ${store.estados.getEstado(estado).nombre}
  64. </span>`).join('');
  65. else
  66. document.querySelector('#estados').innerHTML = `Todos los registros`;
  67. }
  68. },
  69. bloques_horario: {
  70. data: [],
  71. async fetch() {
  72. this.data = [];
  73. const res = await fetch('action/action_grupo_horario.php');
  74. this.data = await res.json();
  75. if (this.data.every((bloque) => !bloque.selected))
  76. this.data[0].selected = true;
  77. },
  78. },
  79. toggle(arr, element) {
  80. const newArray = arr.includes(element) ? arr.filter((item) => item !== element) : [...arr, element];
  81. // if all are selected, then unselect all
  82. if (newArray.length === this.estados.data.length)
  83. return [];
  84. return newArray;
  85. },
  86. });
  87. createApp({
  88. store,
  89. get clase_vista() {
  90. return store.current.clase_vista;
  91. },
  92. registros: {
  93. data: [],
  94. async fetch() {
  95. this.loading = true;
  96. this.data = [];
  97. const res = await fetch('action/action_auditoria.php');
  98. this.data = await res.json();
  99. this.loading = false;
  100. },
  101. invertir() {
  102. this.data = this.data.reverse();
  103. },
  104. mostrarComentario(registro_id) {
  105. const registro = this.data.find((registro) => registro.registro_id === registro_id);
  106. store.current.comentario = registro.comentario;
  107. $('#ver-comentario').modal('show');
  108. },
  109. get relevant() {
  110. /*
  111. facultad_id: null,
  112. fecha: null,
  113. fecha_inicio: null,
  114. fecha_fin: null,
  115. profesor: null,
  116. asistencia: null,
  117. estado_id: null,
  118. if one of the filters is null, then it is not relevant
  119. */
  120. const filters = Object.keys(store.filters).filter((filtro) => store.filters[filtro] || store.filters[filtro]?.length > 0);
  121. return this.data.filter((registro) => {
  122. return filters.every((filtro) => {
  123. switch (filtro) {
  124. case 'fecha':
  125. return registro.registro_fecha_ideal === store.filters[filtro];
  126. case 'fecha_inicio':
  127. return registro.registro_fecha_ideal >= store.filters[filtro];
  128. case 'fecha_fin':
  129. return registro.registro_fecha_ideal <= store.filters[filtro];
  130. case 'profesor':
  131. const textoFiltro = store.filters[filtro].toLowerCase();
  132. if (/^\([^)]+\)\s[\s\S]+$/.test(textoFiltro)) {
  133. const clave = registro.profesor_clave.toLowerCase();
  134. const filtroClave = textoFiltro.match(/\((.*?)\)/)?.[1];
  135. console.log(clave, filtroClave);
  136. return clave.includes(filtroClave);
  137. }
  138. else {
  139. const nombre = registro.profesor_nombre.toLowerCase();
  140. return nombre.includes(textoFiltro);
  141. }
  142. case 'facultad_id':
  143. return registro.facultad_id === store.filters[filtro];
  144. case 'estados':
  145. if (store.filters[filtro].length === 0)
  146. return true;
  147. return store.filters[filtro].includes(registro.estado_supervisor_id);
  148. case 'bloque_horario':
  149. const bloque = store.bloques_horario.data.find((bloque) => bloque.id === store.filters[filtro]);
  150. return registro.horario_hora <= bloque.hora_fin && registro.horario_fin >= bloque.hora_inicio;
  151. default:
  152. return true;
  153. }
  154. });
  155. });
  156. },
  157. async descargar() {
  158. if (this.relevant.length === 0)
  159. return;
  160. const res = await fetch('export/supervisor_excel.php', {
  161. method: 'POST',
  162. headers: {
  163. 'Content-Type': 'application/json'
  164. },
  165. body: JSON.stringify(this.relevant)
  166. });
  167. const blob = await res.blob();
  168. window.saveAs(blob, `auditoria_${new Date().toISOString().slice(0, 10)}.xlsx`);
  169. }
  170. },
  171. get profesores() {
  172. return this.registros.data.map((registro) => ({
  173. profesor_id: registro.profesor_id,
  174. profesor_nombre: registro.profesor_nombre,
  175. profesor_correo: registro.profesor_correo,
  176. profesor_clave: registro.profesor_clave,
  177. profesor_grado: registro.profesor_grado,
  178. })).sort((a, b) => a.profesor_nombre.localeCompare(b.profesor_nombre));
  179. },
  180. async mounted() {
  181. await this.registros.fetch();
  182. await store.facultades.fetch();
  183. await store.estados.fetch();
  184. await store.bloques_horario.fetch();
  185. store.filters.bloque_horario = store.bloques_horario.data.find((bloque) => bloque.selected)?.id;
  186. store.filters.switchFechas();
  187. }
  188. }).mount('#app');