# Cart Initialization & Keep Alive Implementation ## Overview The cart is now initialized when the app starts (on HomePage mount) and kept alive throughout the entire app session. This ensures: - Cart data is loaded from API once on startup - Cart state persists across all navigation - No unnecessary re-fetching when navigating between pages - Real-time cart badge updates across all screens ## Implementation Details ### 1. Cart Provider with Keep Alive **File**: `lib/features/cart/presentation/providers/cart_provider.dart` ```dart @Riverpod(keepAlive: true) // ✅ Keep alive throughout app session class Cart extends _$Cart { @override CartState build() { return CartState.initial().copyWith( memberTier: 'Diamond', memberDiscountPercent: 15.0, ); } Future initialize() async { // Load cart from API with Hive fallback // ... } } // Dependent providers also need keepAlive @Riverpod(keepAlive: true) int cartItemCount(Ref ref) { final cartState = ref.watch(cartProvider); return cartState.items.length; } @Riverpod(keepAlive: true) double cartTotal(Ref ref) { final cartState = ref.watch(cartProvider); return cartState.total; } ``` ### 1.1 Cart Data Providers with Keep Alive **File**: `lib/features/cart/data/providers/cart_data_providers.dart` **CRITICAL**: All cart data layer providers must also use `keepAlive: true` to prevent disposal errors: ```dart @Riverpod(keepAlive: true) CartLocalDataSource cartLocalDataSource(Ref ref) { final hiveService = HiveService(); return CartLocalDataSourceImpl(hiveService); } @Riverpod(keepAlive: true) Future cartRemoteDataSource(Ref ref) async { final dioClient = await ref.watch(dioClientProvider.future); return CartRemoteDataSourceImpl(dioClient); } @Riverpod(keepAlive: true) Future cartRepository(Ref ref) async { final remoteDataSource = await ref.watch(cartRemoteDataSourceProvider.future); final localDataSource = ref.watch(cartLocalDataSourceProvider); return CartRepositoryImpl( remoteDataSource: remoteDataSource, localDataSource: localDataSource, ); } ``` **Why all providers need keepAlive:** - Cart provider depends on cartRepository - If repository is disposed, cart operations fail with "Ref disposed" error - All dependencies in the chain must persist together - Ensures consistent lifecycle management **Benefits of `keepAlive: true`:** - Provider state is never disposed - Cart data persists when navigating away and back - No re-initialization needed on subsequent visits - Consistent cart count across all app screens - No "Ref disposed" errors during async operations ### 2. HomePage Initialization **File**: `lib/features/home/presentation/pages/home_page.dart` ```dart class HomePage extends ConsumerStatefulWidget { const HomePage({super.key}); @override ConsumerState createState() => _HomePageState(); } class _HomePageState extends ConsumerState { @override void initState() { super.initState(); // Initialize cart from API on app startup WidgetsBinding.instance.addPostFrameCallback((_) { ref.read(cartProvider.notifier).initialize(); }); } @override Widget build(BuildContext context) { // Watch cart item count for badge final cartItemCount = ref.watch(cartItemCountProvider); // ... } } ``` **Why in HomePage?** - HomePage is the first screen after login - Ensures cart is loaded early in app lifecycle - Provides immediate cart count for navigation badge ### 3. Cart Badge Integration **Location**: All pages with cart icon/badge ```dart // Any page can watch cart count - it's always available final cartItemCount = ref.watch(cartItemCountProvider); // Display badge if (cartItemCount > 0) Badge( label: Text('$cartItemCount'), child: Icon(Icons.shopping_cart), ) ``` ## Data Flow ``` App Start ↓ HomePage mounts ↓ initState() calls cart.initialize() ↓ Cart loads from API → Syncs to Hive ↓ Cart state updates with items ↓ cartItemCountProvider updates ↓ All badges across app update reactively ↓ [keepAlive ensures state persists during navigation] ``` ## API & Local Storage Integration ### Initialize Flow 1. **API First**: Fetch cart items from ERPNext API 2. **Product Details**: For each cart item, fetch full product data 3. **Calculate Conversions**: Apply business rules (boxes, m², etc.) 4. **Update State**: Set cart items with full product info 5. **Local Sync**: Automatically synced to Hive by repository ### Offline Fallback - If API fails, cart loads from Hive cache - All mutations queue for sync when online - See `cart_repository_impl.dart` for sync logic ## Cart Operations All cart operations work seamlessly after initialization: ```dart // Add to cart (from any page) await ref.read(cartProvider.notifier).addToCart(product, quantity: 2.0); // Remove from cart await ref.read(cartProvider.notifier).removeFromCart(productId); // Update quantity await ref.read(cartProvider.notifier).updateQuantity(productId, 5.0); // Clear cart await ref.read(cartProvider.notifier).clearCart(); ``` All operations: - Sync to API first - Fallback to local on failure - Queue for sync when offline - Update UI reactively ## Testing Keep Alive To verify keepAlive works: 1. **Navigate to HomePage** → Cart initializes 2. **Add items to cart** → Badge shows count 3. **Navigate to Products page** → Badge still shows count 4. **Navigate back to HomePage** → Cart state preserved, no re-fetch 5. **Navigate to Cart page** → Same items, no loading 6. **Hot restart app** → Cart reloads from API ## Performance Benefits - **One-time API call**: Cart loads once on startup - **No re-fetching**: Navigation doesn't trigger reloads - **Instant updates**: All cart operations update state immediately - **Offline support**: Hive cache provides instant fallback - **Memory efficient**: Single provider instance for entire app ## Error Handling If cart initialization fails: - Error stored in `cartState.errorMessage` - Can retry via `ref.read(cartProvider.notifier).initialize()` - Cart page shows error state with retry button - Local Hive cache used if available ## Related Files - **Cart Provider**: `lib/features/cart/presentation/providers/cart_provider.dart` - **Cart State**: `lib/features/cart/presentation/providers/cart_state.dart` - **Data Providers**: `lib/features/cart/data/providers/cart_data_providers.dart` - **Repository**: `lib/features/cart/data/repositories/cart_repository_impl.dart` - **HomePage**: `lib/features/home/presentation/pages/home_page.dart` ## Future Enhancements Potential improvements: - Add periodic background sync (every 5 minutes) - Implement optimistic updates for faster UI - Add cart merge logic when switching accounts - Implement cart expiry (clear after 30 days) - Add analytics tracking for cart events