75 lines
2.6 KiB
TypeScript
75 lines
2.6 KiB
TypeScript
import { useEffect, useRef } from 'react';
|
|
import { toast } from 'react-hot-toast'; // Assuming react-hot-toast for notifications
|
|
import { useCurrentUser } from './useAuth'; // To get current user and their tenant
|
|
|
|
/**
|
|
* Custom hook to manage WebSocket connection for real-time notifications.
|
|
*/
|
|
export const useNotificationWebSocket = () => {
|
|
const wsRef = useRef<WebSocket | null>(null);
|
|
const { data: user } = useCurrentUser(); // Get current user for authentication
|
|
|
|
useEffect(() => {
|
|
if (!user || !user.id) {
|
|
// If no user or not authenticated, ensure WebSocket is closed
|
|
if (wsRef.current && wsRef.current.readyState === WebSocket.OPEN) {
|
|
wsRef.current.close();
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Determine WebSocket URL dynamically
|
|
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
|
|
// The current host needs to be adjusted if the WebSocket server is on a different subdomain/port
|
|
// For local development, assuming it's on the same host/port as the frontend API
|
|
const wsHost = window.location.host;
|
|
const wsUrl = `${protocol}//${wsHost}/ws/notifications/`;
|
|
|
|
const connectWebSocket = () => {
|
|
wsRef.current = new WebSocket(wsUrl);
|
|
|
|
wsRef.current.onopen = () => {
|
|
console.log('Notification WebSocket connected');
|
|
};
|
|
|
|
wsRef.current.onmessage = (event) => {
|
|
const data = JSON.parse(event.data);
|
|
console.log('Notification received:', data);
|
|
// Display notification using a toast library
|
|
toast.success(data.message, {
|
|
duration: 5000,
|
|
position: 'top-right',
|
|
});
|
|
};
|
|
|
|
wsRef.current.onclose = (event) => {
|
|
console.log('Notification WebSocket disconnected:', event);
|
|
// Attempt to reconnect after a short delay
|
|
setTimeout(() => {
|
|
if (user && user.id) { // Only attempt reconnect if user is still authenticated
|
|
console.log('Attempting to reconnect Notification WebSocket...');
|
|
connectWebSocket();
|
|
}
|
|
}, 3000);
|
|
};
|
|
|
|
wsRef.current.onerror = (error) => {
|
|
console.error('Notification WebSocket error:', error);
|
|
wsRef.current?.close();
|
|
};
|
|
};
|
|
|
|
connectWebSocket();
|
|
|
|
// Clean up WebSocket connection on component unmount or user logout
|
|
return () => {
|
|
if (wsRef.current && wsRef.current.readyState === WebSocket.OPEN) {
|
|
wsRef.current.close();
|
|
}
|
|
};
|
|
}, [user]); // Reconnect if user changes (e.g., login/logout)
|
|
|
|
// You can expose functions here to manually send messages if needed
|
|
// For notifications, it's typically server-to-client only
|
|
};
|