import { BOOKING_WINDOW_WS_EVENTS, BOOKING_WINDOW_WS_NAMESPACE, type BookingWindowPhaseEvent, } from "@edr/types"; import { useQueryClient } from "@tanstack/react-query"; import { useEffect } from "react"; import { io } from "socket.io-client"; import { API_BASE_URL } from "@/constants/apiConfig"; function getAuthToken(): string | undefined { return document.cookie .split("; ") .find((row) => row.startsWith("auth-token=")) ?.split("=")[1]; } // The socket namespace lives at the server root, not under the `/api` REST // prefix — strip a trailing `/api` if the base URL carries one. const SOCKET_ORIGIN = String(API_BASE_URL ?? "").replace(/\/api\/?$/, ""); /** * Subscribes to live booking-window pushes. Every phase transition the window * engine applies (open, doc review, payment, reopen, done) invalidates the * cached window lists, so the home-page "Booking Windows" card flips the * moment the backend does — the 60s poll remains only as a fallback. */ export function useBookingWindowSocket(enabled: boolean) { const qc = useQueryClient(); useEffect(() => { if (!enabled) return; const token = getAuthToken(); if (!token) return; const socket = io(`${SOCKET_ORIGIN}/${BOOKING_WINDOW_WS_NAMESPACE}`, { auth: { token }, transports: ["websocket"], withCredentials: true, }); // Deliberate console breadcrumbs: "live updates not arriving" is only // diagnosable from the browser when connect/reject outcomes are visible. socket.on("connect", () => console.debug("[booking-windows] socket connected", socket.id), ); socket.on("connect_error", (err) => console.warn("[booking-windows] socket connect failed:", err.message), ); socket.on("disconnect", (reason) => console.debug("[booking-windows] socket disconnected:", reason), ); socket.on( BOOKING_WINDOW_WS_EVENTS.PHASE, (_event: BookingWindowPhaseEvent) => { qc.invalidateQueries({ queryKey: ["train-scheduling", "myBookingWindows"], }); qc.invalidateQueries({ queryKey: ["train-scheduling", "contractBookingWindows"], }); }, ); return () => { socket.off(); socket.disconnect(); }; }, [enabled, qc]); }