Files
RomhackPlaza/resources/js/notifications.js

127 lines
2.9 KiB
JavaScript
Raw Normal View History

/** @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<void>}
*/
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<void>}
*/
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<void>}
*/
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;
}
}
}