"use client"; import { WifiOff, CloudUpload, RefreshCw, AlertTriangle } from "lucide-react"; import { useQueryClient } from "@tanstack/react-query"; import { useLocale } from "next-intl"; import { cn } from "@/lib/utils"; import { useSyncQueueStore } from "@/lib/stores/sync-queue.store"; import { getQueueCount } from "@/lib/offline/offline-db"; import { drainOutbox, getActiveOutboxCount, getFailedOutboxCount, discardFailedOps, } from "@/lib/offline/outbox"; export function SyncStatusIndicator() { const { queueCount, failedCount, isSyncing, isOnline, setSyncing, setQueueCount, setFailedCount, } = useSyncQueueStore(); const queryClient = useQueryClient(); const locale = useLocale(); const isFa = locale !== "en"; const recount = async () => { setQueueCount((await getActiveOutboxCount()) + (await getQueueCount())); setFailedCount(await getFailedOutboxCount()); }; // Manual retry — drains the REAL outbox (the engine the app actually uses), // then refreshes server data and the counts. const retry = async () => { if (typeof navigator !== "undefined" && !navigator.onLine) return; if (isSyncing) return; setSyncing(true); try { const res = await drainOutbox(); if (res.sent > 0) await queryClient.invalidateQueries(); } finally { setSyncing(false); await recount(); } }; // Poisoned ops can never sync (permanent 4xx) — let the user clear them so the // badge doesn't sit stuck forever. const clearFailed = async () => { await discardFailedOps(); await recount(); }; const showPending = !isOnline || queueCount > 0 || isSyncing; const showFailed = !showPending && failedCount > 0; if (!showPending && !showFailed) return null; if (showFailed) { return ( ); } const label = isFa ? !isOnline ? "آفلاین" : isSyncing ? "همگام‌سازی..." : `${queueCount} مورد در صف` : !isOnline ? "Offline" : isSyncing ? "Syncing..." : `${queueCount} pending`; return ( ); }