import { createApp, reactive } from 'https://unpkg.com/petite-vue?module' type Profesor = { profesor_clave: string; profesor_correo: null | string; profesor_grado: null | string; profesor_id: number; profesor_nombre: string; } type Carrera = { carrera_activa: boolean; carrera_comun: boolean; carrera_id: number; carrera_nombre: string; clave_carrera: string; facultad_id: number | null; nivel_id: number; } type Periodo = { created_at: Date; estado_id: number; fecha_final: Date; id_periodo_sgu: number; nivel_id: number; periodo_clave: string; periodo_fecha_fin: Date; periodo_fecha_inicio: Date; periodo_id: number; periodo_nombre: string; } type Aviso = { aviso_estado: boolean; aviso_titulo: string; aviso_fecha_final: Date; aviso_fecha_inicial: Date; aviso_id: number; aviso_texto: string; carreras: Carrera[]; facultad_id: null; profesores: Profesor[]; } const new_aviso = reactive({ titulo: '', descripcion: '', fechaInicio: '', fechaFin: '', profesores: [] as Array, carreras: [] as Array, reset() { this.titulo = '' this.descripcion = '' this.fechaInicio = '' this.fechaFin = '' this.profesores = [] this.carreras = [] }, get isValid() { return this.titulo !== '' && this.descripcion !== '' && this.fechaInicio !== '' && this.fechaFin !== '' && (this.profesores.length > 0 || this.carreras.length > 0) && this.facultad_id !== null }, }) // define datepicker method const app = createApp({ new_aviso, profesores: [] as Array, carreras: [] as Array, avisos: [] as Array, profesor: null as String | null, formatProfesor(profesor: Profesor) { return `(${profesor.profesor_clave}) ${profesor.profesor_nombre}` }, addProfesor() { const profesorObj = this.profesores.find((profesor: Profesor) => this.profesor === this.formatProfesor(profesor)) if (profesorObj) { this.new_aviso.profesores.push(profesorObj) this.profesor = null } }, aviso_shown: null as Aviso | null, // int? aviso_suspendido: null as number | null, suspenderAviso() { if (this.aviso_suspendido) { const aviso = this.avisos.find((aviso: Aviso) => aviso.aviso_id === this.aviso_suspendido) if (aviso) { this.deleteAviso(aviso) } } }, get relevant_profesores() { // not in array new_aviso.profesores const relevant = this.profesores.filter((profesor: Profesor) => !this.new_aviso.profesores.map((profesor: Profesor) => profesor.profesor_id).includes(profesor.profesor_id)) // 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)) return relevant }, get relevant_carreras() { // not in array new_aviso.carreras return this.carreras.filter((carrera: Carrera) => !this.new_aviso.carreras.includes(carrera)) }, createAviso() { const data = { aviso_titulo: this.new_aviso.titulo, aviso_texto: this.new_aviso.descripcion, aviso_fecha_inicial: this.new_aviso.fechaInicio, aviso_fecha_final: this.new_aviso.fechaFin, profesores: this.new_aviso.profesores.map((profesor: Profesor) => profesor.profesor_id), carreras: this.new_aviso.carreras.map((carrera: Carrera) => carrera.carrera_id), } fetch('/action/avisos.php', { method: 'POST', body: JSON.stringify(data) }).then(res => res.json()).then(res => { if (res.success) { // hydrate with carreras and profesores this.avisos.push({ ...data, carreras: this.carreras.filter((carrera: Carrera) => data.carreras.includes(carrera.carrera_id)), profesores: this.profesores.filter((profesor: Profesor) => data.profesores.includes(profesor.profesor_id)), aviso_estado: true, aviso_id: res.aviso_id, }) this.new_aviso.reset() } else { alert(res.error) console.log(res.errors) } }) }, deleteAviso(aviso: Aviso) { fetch(`/action/avisos.php`, { method: 'DELETE', body: JSON.stringify({ aviso_id: aviso.aviso_id }) }).then(res => res.json()).then(res => { if (res.success) { this.avisos = this.avisos.filter((aviso: Aviso) => aviso.aviso_id !== this.aviso_suspendido) this.aviso_suspendido = null } else { alert(res.error) console.log(res.errors) } }) }, updateAviso() { fetch(`/action/avisos.php`, { method: 'PUT', body: JSON.stringify({ aviso_id: this.aviso_shown.aviso_id, aviso_fecha_final: this.aviso_shown.aviso_fecha_final, }) }).then(res => res.json()).then(res => { if (res.success) { } else { alert(res.error) console.log(res.errors) } }) }, async initializeDatepickers($el: HTMLElement) { const periodo = await fetch('action/periodo_datos.php'); const periodo_data = await periodo.json() as Periodo; $('.date-picker').datepicker({ dateFormat: 'yy-mm-dd', maxDate: periodo_data.periodo_fecha_fin, minDate: 0, }); $($el).on('change', () => { this.aviso_shown.aviso_fecha_final = $($el).val() as string; }); }, async mounted() { this.avisos = await fetch("/action/avisos.php").then(res => res.json()) as Array this.profesores = await fetch('/action/action_profesor.php').then(res => res.json()) as Array this.carreras = await fetch('/action/action_carreras.php').then(res => res.json()) as Array await this.initializeDatepickers() const fechaInicio = $('#fechaInicio.date-picker') const fechaFin = $('#fechaFin.date-picker') fechaInicio.on("change", function () { new_aviso.fechaInicio = fechaInicio.val() as string fechaFin.datepicker("option", "minDate", fechaInicio.val()); }); fechaFin.on("change", function () { new_aviso.fechaFin = fechaFin.val() as string fechaInicio.datepicker("option", "maxDate", fechaFin.val()); }); } }).mount('#app')