Implemented comprehensive offline-first state management: Redux Store Setup: - Configure Redux Toolkit with @redux-offline/redux-offline - Setup redux-persist with IndexedDB (localforage) - Custom offline config with exponential backoff retry - Normalized state with entity adapters State Slices: - activitiesSlice: Normalized activities with optimistic CRUD - childrenSlice: Normalized children with optimistic CRUD - networkSlice: Network status and connection quality - offlineSlice: Sync queue and pending actions Middleware: - offlineMiddleware: Queue actions when offline - syncMiddleware: Process pending actions when online - Conflict resolution strategies (SERVER_WINS, CLIENT_WINS, LAST_WRITE_WINS, MERGE) - Version-based conflict detection Features: - Optimistic updates for immediate UI feedback - Automatic sync queue with retry logic (5 retries max) - Network detection (browser events + periodic checks) - Connection quality monitoring (excellent/good/poor/offline) - Latency tracking - Conflict resolution with multiple strategies - Entity versioning for optimistic updates Components: - NetworkStatusIndicator: Full-screen status banner - NetworkStatusBadge: Compact app bar badge - ReduxProvider: Provider with network detection setup Custom Hooks: - useAppDispatch/useAppSelector: Typed Redux hooks - useIsOnline: Check online status - useHasPendingSync: Check for pending actions - useSyncStatus: Get sync progress info - useOptimisticAction: Combine optimistic + actual actions - useNetworkQuality: Get connection quality - useIsOptimistic: Check if entity is being synced Documentation: - Comprehensive README with usage examples - Architecture overview - Best practices guide - Troubleshooting section State Structure: - Normalized entities with byId/allIds - Optimistic metadata (_optimistic, _localId, _version) - Entity adapters with memoized selectors - Offline queue persistence to IndexedDB 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
25 lines
652 B
TypeScript
25 lines
652 B
TypeScript
'use client';
|
|
|
|
import { useEffect, useRef } from 'react';
|
|
import { Provider } from 'react-redux';
|
|
import { store } from '@/store/store';
|
|
import { setupNetworkDetection } from '@/store/middleware/offlineMiddleware';
|
|
|
|
export function ReduxProvider({ children }: { children: React.Node }) {
|
|
const cleanupRef = useRef<(() => void) | null>(null);
|
|
|
|
useEffect(() => {
|
|
// Setup network detection
|
|
cleanupRef.current = setupNetworkDetection(store.dispatch);
|
|
|
|
// Cleanup on unmount
|
|
return () => {
|
|
if (cleanupRef.current) {
|
|
cleanupRef.current();
|
|
}
|
|
};
|
|
}, []);
|
|
|
|
return <Provider store={store}>{children}</Provider>;
|
|
}
|