Files
social-media/frontend/src/features/notifications/stores/notificationsStore.js

104 lines
3.0 KiB
JavaScript

import { computed, ref, watch } from 'vue';
import { defineStore } from 'pinia';
import { useAuthStore } from '@/features/auth/stores/authStore.js';
import { useWorkspaceStore } from '@/features/workspaces/stores/workspaceStore.js';
import { useClient } from '@/plugins/api.js';
import { isFeedbackNotification } from '@/features/notifications/notificationRoutes.js';
export const useNotificationsStore = defineStore('notifications', () => {
const authStore = useAuthStore();
const workspaceStore = useWorkspaceStore();
const client = useClient();
const items = ref([]);
const isLoading = ref(false);
const error = ref(null);
const unreadCount = computed(() =>
items.value.filter(item => !item.readAt).length
);
const recentItems = computed(() => items.value.slice(0, 6));
const unreadFeedbackReportIds = computed(() =>
new Set(
items.value
.filter(item => !item.readAt && isFeedbackNotification(item) && item.entityId)
.map(item => item.entityId)
)
);
function reset() {
items.value = [];
error.value = null;
}
async function fetchNotifications() {
if (!authStore.isAuthenticated) {
reset();
return;
}
isLoading.value = true;
error.value = null;
try {
const response = await client.get('/api/notifications');
items.value = response.data ?? [];
} catch (fetchError) {
console.error('Failed to fetch notifications:', fetchError);
items.value = [];
error.value = 'Failed to load notifications.';
} finally {
isLoading.value = false;
}
}
async function markAsRead(notificationId) {
try {
await client.post(`/api/notifications/${notificationId}/read`);
items.value = items.value.map(item =>
item.id === notificationId
? { ...item, readAt: item.readAt ?? new Date().toISOString() }
: item
);
} catch (markError) {
console.error('Failed to mark notification as read:', markError);
}
}
async function markFeedbackReportAsRead(reportId) {
const unreadNotifications = items.value.filter(item =>
!item.readAt && isFeedbackNotification(item) && item.entityId === reportId
);
await Promise.all(unreadNotifications.map(item => markAsRead(item.id)));
}
watch(
() => [authStore.isAuthenticated, workspaceStore.activeWorkspaceId],
async ([isAuthenticated, workspaceId]) => {
if (!isAuthenticated) {
reset();
return;
}
await fetchNotifications();
},
{ immediate: true }
);
return {
items,
recentItems,
unreadFeedbackReportIds,
unreadCount,
isLoading,
error,
reset,
fetchNotifications,
markAsRead,
markFeedbackReportAsRead,
};
});