Upload source code
This commit is contained in:
103
src/client/contexts/NotificationContext.tsx
Normal file
103
src/client/contexts/NotificationContext.tsx
Normal file
@@ -0,0 +1,103 @@
|
||||
import React, { useState, useEffect, useCallback } from 'react';
|
||||
import { useAuth } from '@clerk/clerk-react';
|
||||
import api from '../services/api';
|
||||
import type { INotification } from '../types';
|
||||
import { NotificationContext } from './NotificationContextState';
|
||||
|
||||
export const NotificationProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
||||
const { orgId, isSignedIn } = useAuth();
|
||||
const [notifications, setNotifications] = useState<INotification[]>([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const fetchNotifications = useCallback(async () => {
|
||||
if (!orgId || !isSignedIn) return;
|
||||
|
||||
try {
|
||||
if (notifications.length === 0) setLoading(true);
|
||||
const response = await api.get('/notifications');
|
||||
setNotifications(response.data);
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch notifications', error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [orgId, isSignedIn, notifications.length]);
|
||||
|
||||
const markAsRead = async (id: string) => {
|
||||
try {
|
||||
await api.put(`/notifications/${id}/read`);
|
||||
setNotifications(prev => prev.map(n => n._id === id ? { ...n, isRead: true } : n));
|
||||
} catch (error) {
|
||||
console.error('Failed to mark as read', error);
|
||||
}
|
||||
};
|
||||
|
||||
const markAllAsRead = async () => {
|
||||
try {
|
||||
await api.put('/notifications/read-all');
|
||||
setNotifications(prev => prev.map(n => ({ ...n, isRead: true })));
|
||||
} catch (error) {
|
||||
console.error('Failed to mark all as read', error);
|
||||
}
|
||||
}
|
||||
|
||||
const clearAll = async () => {
|
||||
try {
|
||||
await api.delete('/notifications/clear-all');
|
||||
setNotifications([]);
|
||||
} catch (error) {
|
||||
console.error('Failed to clear all notifications', error);
|
||||
}
|
||||
};
|
||||
|
||||
const archiveNotification = async (id: string) => {
|
||||
try {
|
||||
await api.patch(`/notifications/${id}/archive`);
|
||||
setNotifications(prev => prev.filter(n => n._id !== id));
|
||||
} catch (error) {
|
||||
console.error('Failed to archive notification', error);
|
||||
}
|
||||
};
|
||||
|
||||
const deleteNotification = async (id: string) => {
|
||||
try {
|
||||
await api.delete(`/notifications/${id}`);
|
||||
setNotifications(prev => prev.filter(n => n._id !== id));
|
||||
} catch (error) {
|
||||
console.error('Failed to delete notification', error);
|
||||
}
|
||||
};
|
||||
|
||||
// Polling effect
|
||||
useEffect(() => {
|
||||
if (isSignedIn && orgId) {
|
||||
fetchNotifications(); // Initial fetch
|
||||
|
||||
const interval = setInterval(() => {
|
||||
fetchNotifications();
|
||||
}, 30000); // Poll every 30 seconds
|
||||
|
||||
return () => clearInterval(interval);
|
||||
} else {
|
||||
setNotifications([]);
|
||||
}
|
||||
}, [isSignedIn, orgId, fetchNotifications]);
|
||||
|
||||
const unreadCount = notifications.filter(n => !n.isRead).length;
|
||||
|
||||
return (
|
||||
<NotificationContext.Provider value={{
|
||||
notifications,
|
||||
unreadCount,
|
||||
loading,
|
||||
markAsRead,
|
||||
markAllAsRead,
|
||||
clearAll,
|
||||
archiveNotification,
|
||||
deleteNotification,
|
||||
fetchNotifications
|
||||
}}>
|
||||
{children}
|
||||
</NotificationContext.Provider>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user