Files
smoothschedule/frontend/src/hooks/useNotificationWebSocket.ts

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
};