import { useEffect, useState } from 'react'; import { useOnlineStatus } from '@/hooks/useOnlineStatus'; import { offlineQueue } from '@/services/offlineQueue'; import { WifiOff, Loader2, List } from 'lucide-react'; import { hasRecentNetworkError } from '@/utils/networkErrorTracker'; import { OfflineQueueManager } from './OfflineQueueManager'; /** * Composant pour afficher un indicateur de mode hors ligne avec nombre de requêtes en attente */ export function OfflineIndicator() { const isOnline = useOnlineStatus(); const [queueSize, setQueueSize] = useState(0); const [isProcessing, setIsProcessing] = useState(false); const [hasNetworkError, setHasNetworkError] = useState(false); const [showQueueManager, setShowQueueManager] = useState(false); const [shouldShowSyncBar, setShouldShowSyncBar] = useState(false); // Mettre à jour la taille de la file d'attente useEffect(() => { const updateQueueSize = () => { const size = offlineQueue.getQueueSize(); // #region agent log // fetch('http://127.0.0.1:7242/ingest/09c5ea5e-2380-4cc3-92aa-d26f3b3d26f6',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'OfflineIndicator.tsx:updateQueueSize',message:'Queue size updated',data:{queueSize:size,isOnline},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'C'})}).catch(()=>{}); // #endregion setQueueSize(size); }; // Mettre à jour immédiatement updateQueueSize(); // Mettre à jour toutes les secondes const interval = setInterval(updateQueueSize, 1000); return () => clearInterval(interval); }, []); // Vérifier si la file est en cours de traitement useEffect(() => { if (isOnline && queueSize > 0) { setIsProcessing(true); // Vérifier périodiquement si le traitement est terminé const checkProcessing = setInterval(() => { const currentSize = offlineQueue.getQueueSize(); if (currentSize === 0) { setIsProcessing(false); clearInterval(checkProcessing); } }, 500); return () => clearInterval(checkProcessing); } else { setIsProcessing(false); return undefined; } }, [isOnline, queueSize]); // Check for recent network errors useEffect(() => { const checkNetworkError = () => { setHasNetworkError(hasRecentNetworkError()); }; // Check immediately checkNetworkError(); // Check periodically (every 2 seconds) to update when error expires const interval = setInterval(checkNetworkError, 2000); return () => clearInterval(interval); }, []); // FIX: Délai avant d'afficher la barre de synchronisation pour éviter les flashs useEffect(() => { // #region agent log // fetch('http://127.0.0.1:7242/ingest/09c5ea5e-2380-4cc3-92aa-d26f3b3d26f6',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'OfflineIndicator.tsx:useEffect',message:'Sync bar effect triggered',data:{isProcessing,queueSize,isOnline,shouldShowSyncBar},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'B'})}).catch(()=>{}); // #endregion if (isProcessing && queueSize > 0 && isOnline) { const timer = setTimeout(() => { // #region agent log // fetch('http://127.0.0.1:7242/ingest/09c5ea5e-2380-4cc3-92aa-d26f3b3d26f6',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'OfflineIndicator.tsx:setTimeout',message:'Setting shouldShowSyncBar to true',data:{queueSize,isProcessing},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'B'})}).catch(()=>{}); // #endregion setShouldShowSyncBar(true); }, 500); return () => { clearTimeout(timer); setShouldShowSyncBar(false); }; } else { setShouldShowSyncBar(false); return undefined; } }, [isProcessing, queueSize, isOnline]); // Ne rien afficher si en ligne, aucune requête en attente, et pas d'erreur réseau récente if (isOnline && queueSize === 0 && !isProcessing && !hasNetworkError) { return null; } // Mode hors ligne ou erreur réseau récente if (!isOnline || hasNetworkError) { return ( <>
Mode hors ligne {queueSize > 0 && ( - {queueSize} {queueSize === 1 ? 'requête' : 'requêtes'} en attente )} {queueSize > 0 && ( )}
setShowQueueManager(false)} /> ); } // En ligne mais traitement de la file en cours // FIX: Ne pas afficher la barre si les requêtes sont rapidement traitées (moins de 500ms) // Cela évite d'afficher la barre pour des requêtes qui sont déjà en cours de traitement // #region agent log if (isProcessing && queueSize > 0) { // fetch('http://127.0.0.1:7242/ingest/09c5ea5e-2380-4cc3-92aa-d26f3b3d26f6',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({location:'OfflineIndicator.tsx:123',message:'Checking sync bar display',data:{isProcessing,queueSize,shouldShowSyncBar,willShow:shouldShowSyncBar},timestamp:Date.now(),sessionId:'debug-session',runId:'run1',hypothesisId:'B'})}).catch(()=>{}); } // #endregion if (isProcessing && queueSize > 0 && shouldShowSyncBar) { return ( <>
Synchronisation en cours {queueSize > 0 && ( - {queueSize} {queueSize === 1 ? 'requête' : 'requêtes'} restante {queueSize > 1 ? 's' : ''} )} {queueSize > 0 && ( <> )}
setShowQueueManager(false)} /> ); } return null; }