diff --git a/src/components/admin/OfflineBanner.tsx b/src/components/admin/OfflineBanner.tsx new file mode 100644 index 0000000..7a229de --- /dev/null +++ b/src/components/admin/OfflineBanner.tsx @@ -0,0 +1,52 @@ +"use client"; + +import { useEffect, useState } from "react"; +import { getQueuedActions } from "@/lib/offline/queue"; + +export function OfflineBanner() { + const [online, setOnline] = useState(true); + const [pendingCount, setPendingCount] = useState(0); + const [mounted, setMounted] = useState(false); + + useEffect(() => { + setMounted(true); + setOnline(navigator.onLine); + const onOnline = () => setOnline(true); + const onOffline = () => setOnline(false); + window.addEventListener("online", onOnline); + window.addEventListener("offline", onOffline); + + const interval = setInterval(async () => { + const actions = await getQueuedActions(); + setPendingCount(actions.filter((a) => a.status === "pending" || a.status === "in-flight").length); + }, 1000); + + return () => { + window.removeEventListener("online", onOnline); + window.removeEventListener("offline", onOffline); + clearInterval(interval); + }; + }, []); + + if (!mounted || (online && pendingCount === 0)) return null; + + return ( +