"use client"; import { useHocuspocusConnectionStatus, useHocuspocusEvent, useHocuspocusProvider, useHocuspocusSyncStatus, } from "@hocuspocus/provider-react"; import { useState } from "react"; const CollaborationStatus = () => { const provider = useHocuspocusProvider(); const connectionStatus = useHocuspocusConnectionStatus(); const syncStatus = useHocuspocusSyncStatus(); const [unsyncedChanges, setUnsyncedChanges] = useState(0); // Using the useHocuspocusEvent hook instead of manual provider.on/off useHocuspocusEvent("unsyncedChanges", (data) => { setUnsyncedChanges(data.number); }); const getStatusColor = (status: string) => { switch (status) { case "connected": return "bg-green-100 text-green-800 dark:bg-green-900/20 dark:text-green-400"; case "connecting": return "bg-yellow-100 text-yellow-800 dark:bg-yellow-900/20 dark:text-yellow-400"; case "disconnected": return "bg-red-100 text-red-800 dark:bg-red-900/20 dark:text-red-400"; default: return "bg-slate-100 text-slate-800 dark:bg-slate-800 dark:text-slate-400"; } }; const UNSYNCED_THRESHOLD = 10; return (
{/* Alert banner when unsynced changes grow — indicates connection issues */} {unsyncedChanges >= UNSYNCED_THRESHOLD && (

Connection issue detected

{unsyncedChanges} changes are waiting to sync. Your edits are saved locally but not yet on the server.

)} {/* Status indicators */}

Connection Status

{connectionStatus}
{syncStatus}
= UNSYNCED_THRESHOLD ? "bg-red-500 animate-pulse" : "bg-orange-500 animate-pulse"}`} /> = UNSYNCED_THRESHOLD ? "bg-red-100 text-red-800 dark:bg-red-900/20 dark:text-red-400" : "bg-orange-100 text-orange-800 dark:bg-orange-900/20 dark:text-orange-400"}`} > {unsyncedChanges} unsynced
{/* Control buttons */}

WebSocket Controls

Provider Controls

); }; export default CollaborationStatus;