avisos.ts 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. import { createApp, reactive } from 'https://unpkg.com/petite-vue?module'
  2. type Profesor = {
  3. profesor_clave: string;
  4. profesor_correo: null | string;
  5. profesor_grado: null | string;
  6. profesor_id: number;
  7. profesor_nombre: string;
  8. }
  9. type Carrera = {
  10. carrera_activa: boolean;
  11. carrera_comun: boolean;
  12. carrera_id: number;
  13. carrera_nombre: string;
  14. clave_carrera: string;
  15. facultad_id: number | null;
  16. nivel_id: number;
  17. }
  18. type Periodo = {
  19. created_at: Date;
  20. estado_id: number;
  21. fecha_final: Date;
  22. id_periodo_sgu: number;
  23. nivel_id: number;
  24. periodo_clave: string;
  25. periodo_fecha_fin: Date;
  26. periodo_fecha_inicio: Date;
  27. periodo_id: number;
  28. periodo_nombre: string;
  29. }
  30. type Aviso = {
  31. aviso_estado: boolean;
  32. aviso_titulo: string;
  33. aviso_fecha_final: Date;
  34. aviso_fecha_inicial: Date;
  35. aviso_id: number;
  36. aviso_texto: string;
  37. carreras: Carrera[];
  38. facultad_id: null;
  39. profesores: Profesor[];
  40. }
  41. const new_aviso = reactive({
  42. titulo: '',
  43. descripcion: '',
  44. fechaInicio: '',
  45. fechaFin: '',
  46. profesores: [] as Array<Profesor>,
  47. carreras: [] as Array<Carrera>,
  48. reset() {
  49. this.titulo = ''
  50. this.descripcion = ''
  51. this.fechaInicio = ''
  52. this.fechaFin = ''
  53. this.profesores = []
  54. this.carreras = []
  55. },
  56. get isValid() {
  57. return this.titulo !== '' && this.descripcion !== '' && this.fechaInicio !== '' && this.fechaFin !== '' && (this.profesores.length > 0 || this.carreras.length > 0) && this.facultad_id !== null
  58. },
  59. })
  60. // define datepicker method
  61. const app = createApp({
  62. new_aviso,
  63. profesores: [] as Array<Profesor>,
  64. carreras: [] as Array<Carrera>,
  65. avisos: [] as Array<Aviso>,
  66. profesor: null as String | null,
  67. formatProfesor(profesor: Profesor) {
  68. return `(${profesor.profesor_clave}) ${profesor.profesor_nombre}`
  69. },
  70. addProfesor() {
  71. const profesorObj = this.profesores.find((profesor: Profesor) => this.profesor === this.formatProfesor(profesor))
  72. if (profesorObj) {
  73. this.new_aviso.profesores.push(profesorObj)
  74. this.profesor = null
  75. }
  76. },
  77. aviso_shown: null as Aviso | null,
  78. // int?
  79. aviso_suspendido: null as number | null,
  80. suspenderAviso() {
  81. if (this.aviso_suspendido) {
  82. const aviso = this.avisos.find((aviso: Aviso) => aviso.aviso_id === this.aviso_suspendido)
  83. if (aviso) {
  84. this.deleteAviso(aviso)
  85. }
  86. }
  87. },
  88. get relevant_profesores() {
  89. // not in array new_aviso.profesores
  90. const relevant = this.profesores.filter((profesor: Profesor) => !this.new_aviso.profesores.map((profesor: Profesor) => profesor.profesor_id).includes(profesor.profesor_id))
  91. // console.log('profesores:', this.profesores.map((profesor: Profesor) => profesor.profesor_nombre), 'relevant:', relevant.map((profesor: Profesor) => profesor.profesor_nombre), 'new_aviso:', this.new_aviso.profesores.map((profesor: Profesor) => profesor.profesor_nombre))
  92. return relevant
  93. },
  94. get relevant_carreras() {
  95. // not in array new_aviso.carreras
  96. return this.carreras.filter((carrera: Carrera) => !this.new_aviso.carreras.includes(carrera))
  97. },
  98. createAviso() {
  99. const data = {
  100. aviso_titulo: this.new_aviso.titulo,
  101. aviso_texto: this.new_aviso.descripcion,
  102. aviso_fecha_inicial: this.new_aviso.fechaInicio,
  103. aviso_fecha_final: this.new_aviso.fechaFin,
  104. profesores: this.new_aviso.profesores.map((profesor: Profesor) => profesor.profesor_id),
  105. carreras: this.new_aviso.carreras.map((carrera: Carrera) => carrera.carrera_id),
  106. }
  107. fetch('/action/avisos.php', {
  108. method: 'POST',
  109. body: JSON.stringify(data)
  110. }).then(res => res.json()).then(res => {
  111. if (res.success) {
  112. // hydrate with carreras and profesores
  113. this.avisos.push({
  114. ...data,
  115. carreras: this.carreras.filter((carrera: Carrera) => data.carreras.includes(carrera.carrera_id)),
  116. profesores: this.profesores.filter((profesor: Profesor) => data.profesores.includes(profesor.profesor_id)),
  117. aviso_estado: true,
  118. aviso_id: res.aviso_id,
  119. })
  120. this.new_aviso.reset()
  121. }
  122. else {
  123. alert(res.error)
  124. console.log(res.errors)
  125. }
  126. })
  127. },
  128. deleteAviso(aviso: Aviso) {
  129. fetch(`/action/avisos.php`, {
  130. method: 'DELETE',
  131. body: JSON.stringify({ aviso_id: aviso.aviso_id })
  132. }).then(res => res.json()).then(res => {
  133. if (res.success) {
  134. this.avisos = this.avisos.filter((aviso: Aviso) => aviso.aviso_id !== this.aviso_suspendido)
  135. this.aviso_suspendido = null
  136. }
  137. else {
  138. alert(res.error)
  139. console.log(res.errors)
  140. }
  141. })
  142. },
  143. updateAviso() {
  144. fetch(`/action/avisos.php`, {
  145. method: 'PUT',
  146. body: JSON.stringify({
  147. aviso_id: this.aviso_shown.aviso_id,
  148. aviso_fecha_final: this.aviso_shown.aviso_fecha_final,
  149. })
  150. }).then(res => res.json()).then(res => {
  151. if (res.success) {
  152. }
  153. else {
  154. alert(res.error)
  155. console.log(res.errors)
  156. }
  157. })
  158. },
  159. async initializeDatepickers($el: HTMLElement) {
  160. const periodo = await fetch('action/periodo_datos.php');
  161. const periodo_data = await periodo.json() as Periodo;
  162. $('.date-picker').datepicker({
  163. dateFormat: 'yy-mm-dd',
  164. maxDate: periodo_data.periodo_fecha_fin,
  165. minDate: 0,
  166. });
  167. $($el).on('change', () => {
  168. this.aviso_shown.aviso_fecha_final = $($el).val() as string;
  169. });
  170. },
  171. async mounted() {
  172. this.avisos = await fetch("/action/avisos.php").then(res => res.json()) as Array<Aviso>
  173. this.profesores = await fetch('/action/action_profesor.php').then(res => res.json()) as Array<Profesor>
  174. this.carreras = await fetch('/action/action_carreras.php').then(res => res.json()) as Array<Carrera>
  175. await this.initializeDatepickers()
  176. const fechaInicio = $('#fechaInicio.date-picker')
  177. const fechaFin = $('#fechaFin.date-picker')
  178. fechaInicio.on("change", function () {
  179. new_aviso.fechaInicio = fechaInicio.val() as string
  180. fechaFin.datepicker("option", "minDate", fechaInicio.val());
  181. });
  182. fechaFin.on("change", function () {
  183. new_aviso.fechaFin = fechaFin.val() as string
  184. fechaInicio.datepicker("option", "maxDate", fechaFin.val());
  185. });
  186. }
  187. }).mount('#app')