Refactor Notification

This commit is contained in:
alma 2026-01-06 16:31:39 +01:00
parent 7bb9649b6b
commit 77ffdefba4

View File

@ -51,9 +51,15 @@ export function useNotifications() {
setError(null); setError(null);
lastFetchTimeRef.current = now; lastFetchTimeRef.current = now;
console.log('[useNotifications] Fetching notification count'); console.log('[useNotifications] Fetching notification count', { force });
const response = await fetch('/api/notifications/count', { // Add cache-busting parameter when force is true to ensure fresh data
credentials: 'include' // Ensure cookies are sent with the request const url = force
? `/api/notifications/count?_t=${Date.now()}`
: '/api/notifications/count';
const response = await fetch(url, {
credentials: 'include', // Ensure cookies are sent with the request
cache: force ? 'no-store' : 'default', // Disable cache when forcing refresh
}); });
if (!response.ok) { if (!response.ok) {
@ -68,6 +74,7 @@ export function useNotifications() {
const data = await response.json(); const data = await response.json();
if (isMountedRef.current) { if (isMountedRef.current) {
console.log('[useNotifications] Received notification count:', data);
setNotificationCount(data); setNotificationCount(data);
} }
} catch (err) { } catch (err) {
@ -149,7 +156,7 @@ export function useNotifications() {
return false; return false;
} }
// Update local state // Update local state optimistically
setNotifications(prev => setNotifications(prev =>
prev.map(notification => prev.map(notification =>
notification.id === notificationId notification.id === notificationId
@ -158,15 +165,25 @@ export function useNotifications() {
) )
); );
// Refresh notification count // Update count optimistically (decrement unread count)
debouncedFetchCount(true); setNotificationCount(prev => ({
...prev,
unread: Math.max(0, prev.unread - 1), // Ensure it doesn't go below 0
total: prev.total, // Keep total the same
}));
// Immediately refresh notification count (not debounced) to get accurate data
// Use a small delay to ensure server cache is invalidated
setTimeout(() => {
fetchNotificationCount(true);
}, 100);
return true; return true;
} catch (err) { } catch (err) {
console.error('Error marking notification as read:', err); console.error('Error marking notification as read:', err);
return false; return false;
} }
}, [session?.user, debouncedFetchCount]); }, [session?.user, fetchNotificationCount]);
// Mark all notifications as read // Mark all notifications as read
const markAllAsRead = useCallback(async () => { const markAllAsRead = useCallback(async () => {
@ -191,20 +208,36 @@ export function useNotifications() {
return false; return false;
} }
// Update local state // Update local state optimistically
setNotifications(prev => setNotifications(prev =>
prev.map(notification => ({ ...notification, isRead: true })) prev.map(notification => ({ ...notification, isRead: true }))
); );
// Refresh notification count // Update count optimistically (set unread to 0 immediately for instant UI feedback)
debouncedFetchCount(true); setNotificationCount(prev => ({
...prev,
unread: 0,
total: prev.total, // Keep total the same
sources: Object.fromEntries(
Object.entries(prev.sources).map(([key, value]) => [
key,
{ ...value, unread: 0 }
])
),
}));
// Immediately refresh notification count (not debounced) to get accurate data from server
// Use a small delay to ensure server cache is invalidated
setTimeout(() => {
fetchNotificationCount(true);
}, 200);
return true; return true;
} catch (err) { } catch (err) {
console.error('Error marking all notifications as read:', err); console.error('Error marking all notifications as read:', err);
return false; return false;
} }
}, [session?.user, debouncedFetchCount]); }, [session?.user, fetchNotificationCount]);
// Start polling for notification count // Start polling for notification count
const startPolling = useCallback(() => { const startPolling = useCallback(() => {