import { useDispatch, useSelector, TypedUseSelectorHook } from 'react-redux'; import type { RootState, AppDispatch } from './store'; import { useCallback } from 'react'; // Use throughout your app instead of plain `useDispatch` and `useSelector` export const useAppDispatch = () => useDispatch(); export const useAppSelector: TypedUseSelectorHook = useSelector; // Custom hooks for common patterns /** * Hook to check if the app is online */ export const useIsOnline = () => { return useAppSelector((state) => state.network?.isOnline ?? true); }; /** * Hook to check if there are pending sync actions */ export const useHasPendingSync = () => { const pendingActions = useAppSelector((state) => state.offline?.pendingActions ?? []); return pendingActions.length > 0; }; /** * Hook to get sync status */ export const useSyncStatus = () => { const syncInProgress = useAppSelector((state) => state.offline?.syncInProgress ?? false); const lastSyncTime = useAppSelector((state) => state.offline?.lastSyncTime); const pendingCount = useAppSelector((state) => state.offline?.pendingActions?.length ?? 0); return { syncing: syncInProgress, lastSync: lastSyncTime, pendingCount, }; }; /** * Hook for optimistic updates * Provides a function that dispatches both optimistic and actual actions */ export const useOptimisticAction = ( optimisticAction: (...args: T) => any, actualAction: (...args: T) => any ) => { const dispatch = useAppDispatch(); const isOnline = useIsOnline(); return useCallback( async (...args: T) => { // Always dispatch optimistic action for immediate UI update dispatch(optimisticAction(...args)); // If online, dispatch actual action if (isOnline) { try { const result = await dispatch(actualAction(...args)); return result; } catch (error) { // Rollback will be handled by the rejected case in the slice throw error; } } // If offline, the action will be queued by the middleware return Promise.resolve(); }, [dispatch, optimisticAction, actualAction, isOnline] ); }; /** * Hook to get network quality information */ export const useNetworkQuality = () => { const quality = useAppSelector((state) => state.network?.connectionQuality ?? 'excellent'); const latency = useAppSelector((state) => state.network?.latency); return { quality, latency }; }; /** * Hook to check if a specific entity is being optimistically updated */ export const useIsOptimistic = (entityType: 'activities' | 'children', id: string) => { return useAppSelector((state) => { const entity = state[entityType]?.entities?.[id]; return entity?._optimistic ?? false; }); };