import { createContext, useContext, ReactNode, useState, useEffect } from 'react'; import { logger } from '@/lib/logger'; interface APIConnectivityContextType { isAPIReachable: boolean; isBannerDismissed: boolean; dismissBanner: () => void; } const APIConnectivityContext = createContext(undefined); const DISMISSAL_DURATION = 15 * 60 * 1000; // 15 minutes const DISMISSAL_KEY = 'api-connectivity-dismissed-until'; const REACHABILITY_KEY = 'api-reachable'; export function APIConnectivityProvider({ children }: { children: ReactNode }) { const [isAPIReachable, setIsAPIReachable] = useState(() => { const stored = sessionStorage.getItem(REACHABILITY_KEY); return stored !== 'false'; // Default to true, only false if explicitly set }); const [dismissedUntil, setDismissedUntil] = useState(() => { const stored = localStorage.getItem(DISMISSAL_KEY); return stored ? parseInt(stored) : null; }); const dismissBanner = () => { const until = Date.now() + DISMISSAL_DURATION; localStorage.setItem(DISMISSAL_KEY, until.toString()); setDismissedUntil(until); logger.info('API status banner dismissed', { until: new Date(until).toISOString() }); }; const isBannerDismissed = dismissedUntil ? Date.now() < dismissedUntil : false; // Auto-clear dismissal when API is healthy again useEffect(() => { if (isAPIReachable && dismissedUntil) { localStorage.removeItem(DISMISSAL_KEY); setDismissedUntil(null); logger.info('API status banner dismissal cleared (API recovered)'); } }, [isAPIReachable, dismissedUntil]); // Listen for custom events from error handler useEffect(() => { const handleAPIDown = () => { logger.warn('API connectivity lost'); setIsAPIReachable(false); sessionStorage.setItem(REACHABILITY_KEY, 'false'); }; const handleAPIUp = () => { logger.info('API connectivity restored'); setIsAPIReachable(true); sessionStorage.setItem(REACHABILITY_KEY, 'true'); }; window.addEventListener('api-connectivity-down', handleAPIDown); window.addEventListener('api-connectivity-up', handleAPIUp); return () => { window.removeEventListener('api-connectivity-down', handleAPIDown); window.removeEventListener('api-connectivity-up', handleAPIUp); }; }, []); return ( {children} ); } export function useAPIConnectivity() { const context = useContext(APIConnectivityContext); if (context === undefined) { throw new Error('useAPIConnectivity must be used within APIConnectivityProvider'); } return context; }