added changes ready to ship
This commit is contained in:
80
src/NotificationContext.tsx
Normal file
80
src/NotificationContext.tsx
Normal file
@@ -0,0 +1,80 @@
|
||||
import React, { createContext, useContext, useEffect, useState } from 'react';
|
||||
import { io } from 'socket.io-client';
|
||||
|
||||
export interface Notification {
|
||||
id: string;
|
||||
type: 'assignment' | 'mention' | 'update';
|
||||
title: string;
|
||||
message: string;
|
||||
link?: string;
|
||||
is_read: boolean;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
interface NotificationContextType {
|
||||
notifications: Notification[];
|
||||
unreadCount: number;
|
||||
markAsRead: (id: string) => Promise<void>;
|
||||
}
|
||||
|
||||
const NotificationContext = createContext<NotificationContextType | undefined>(undefined);
|
||||
|
||||
export const NotificationProvider: React.FC<{ children: React.ReactNode, userId: string }> = ({ children, userId }) => {
|
||||
const [notifications, setNotifications] = useState<Notification[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!userId) return;
|
||||
|
||||
const newSocket = io(window.location.protocol + '//' + window.location.hostname + ':3001');
|
||||
|
||||
newSocket.emit('join', userId);
|
||||
|
||||
newSocket.on('notification', (notif: Notification) => {
|
||||
setNotifications(prev => [notif, ...prev]);
|
||||
// Optional: Show browser toast here
|
||||
});
|
||||
|
||||
fetchNotifications();
|
||||
|
||||
return () => {
|
||||
newSocket.close();
|
||||
};
|
||||
}, [userId]);
|
||||
|
||||
const fetchNotifications = async () => {
|
||||
try {
|
||||
const res = await fetch(`/api/notifications/${userId}`);
|
||||
if (res.ok) {
|
||||
const data = await res.json();
|
||||
setNotifications(data);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Fetch notifications failed', err);
|
||||
}
|
||||
};
|
||||
|
||||
const markAsRead = async (id: string) => {
|
||||
try {
|
||||
const res = await fetch(`/api/notifications/${id}/read`, { method: 'PUT' });
|
||||
if (res.ok) {
|
||||
setNotifications(prev => prev.map(n => n.id === id ? { ...n, is_read: true } : n));
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Mark read failed', err);
|
||||
}
|
||||
};
|
||||
|
||||
const unreadCount = notifications.filter(n => !n.is_read).length;
|
||||
|
||||
return (
|
||||
<NotificationContext.Provider value={{ notifications, unreadCount, markAsRead }}>
|
||||
{children}
|
||||
</NotificationContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const useNotifications = () => {
|
||||
const context = useContext(NotificationContext);
|
||||
if (!context) throw new Error('useNotifications must be used within NotificationProvider');
|
||||
return context;
|
||||
};
|
||||
Reference in New Issue
Block a user