/** @typedef { import('types/AlertsResponseItem.js').AlertsResponseItem} AlertsResponseItem */ export default function notifications() { return { /** * @type {boolean} */ start: false, /** * @type {AlertsResponseItem[]} */ data: null, /** * @type {boolean} */ loading: false, /** * @type {boolean} */ error: false, /** * @type {number} */ unviewed: 0, /** * Request for getting notifications. * * @return {Promise} */ async getNotifications() { if( this.loading ) return; this.loading = true; this.error = false; try { const RESPONSE = await fetch('/api/dynamic/notifications', { credentials: "include", headers: { 'X-Requested-With': 'XMLHttpRequest' } }); if( !RESPONSE.ok ) throw new Error(RESPONSE.status) let json = await RESPONSE.json() if( !json.alerts ) throw new Error(RESPONSE.status); this.data = json.alerts; } catch (error) { this.error = true; } finally { this.loading = false; } }, /** * * @param {HTMLElement} anchorEl * @return {Promise} */ async open( anchorEl ){ if( this.start ){ this.close(); return; } this.start = !this.start; if( this.start && !this.data ){ await this.getNotifications(); } if( this.start ){ Alpine.nextTick(() => window.refreshIcons(document.querySelector('.notifications'))) } }, /** * * @return {Promise} */ async markAllRead(){ await fetch('/api/dynamic/notifications/mark-all-read', { method: 'POST', credentials: "include", headers: { 'X-Requested-With': 'XMLHttpRequest', 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]')?.content ?? '' } }); if(this.data && this.data.length > 0){ this.data = this.data.map(a => ({ ...a, view_date: Math.floor(Date.now() / 1000) })); } }, /** * @return {number} */ get unread(){ if( !this.data ){ return this.unviewed; } return this.data.filter(a => a.view_date === 0 ).length; }, /** * */ close(){ if( this.start && this.unread > 0) this.markAllRead(); this.start = false; } } }