All files / src/hooks useNotificationWebSocket.ts

3.12% Statements 1/32
0% Branches 0/18
0% Functions 0/9
3.12% Lines 1/32

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75              1x                                                                                                                                      
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
};