import { useEffect, useRef } from "react"; import { Button } from "~/components/ui/button"; import { Card } from "~/components/ui/card"; interface ConnectionOverlayProps { isConnected: boolean; isReconnecting: boolean; connectionError: string | null; isSyncing: boolean; } export function ConnectionOverlay({ isConnected, isReconnecting, connectionError, isSyncing, }: ConnectionOverlayProps) { const dialogRef = useRef(null); const titleId = "connection-overlay-title"; useEffect(() => { if (isConnected && !isSyncing) return; const el = dialogRef.current; if (!el) return; const focusable = el.querySelector( 'button:not([disabled]), [href], input:not([disabled]), [tabindex]:not([tabindex="-1"])' ); focusable?.focus(); function trapFocus(e: KeyboardEvent) { if (e.key !== "Tab") return; const focusables = el?.querySelectorAll( 'button:not([disabled]), [href], input:not([disabled]), [tabindex]:not([tabindex="-1"])' ); if (!focusables || focusables.length === 0) return; const first = focusables[0]; const last = focusables[focusables.length - 1]; if (e.shiftKey) { if (document.activeElement === first) { e.preventDefault(); last.focus(); } } else { if (document.activeElement === last) { e.preventDefault(); first.focus(); } } } document.addEventListener("keydown", trapFocus); return () => document.removeEventListener("keydown", trapFocus); }, [isConnected, isSyncing]); if (isConnected && !isSyncing) { return null; } const statusMessage = connectionError ? connectionError : isSyncing ? "Reconnected. Syncing the latest draft state..." : isReconnecting ? "Lost connection to the draft server. Attempting to reconnect..." : "Please wait while we connect you to the live draft room."; return (
{/* Spinner or Error Icon */} {connectionError ? (
) : (
)} {/* Title */}

{connectionError ? "Connection Error" : isSyncing ? "Syncing Draft State..." : isReconnecting ? "Reconnecting..." : "Connecting to Draft"}

{statusMessage}

{/* Action Button (only on persistent error) */} {connectionError && ( )} {/* Loading Dots */} {!connectionError && (
); }