All files / src/components/features/cart CartInitializer.tsx

95.29% Statements 81/85
80% Branches 12/15
100% Functions 1/1
95.29% Lines 81/85

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 861x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 9x 9x 9x 9x 9x 9x 9x 8x 8x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 8x 4x 4x 4x 4x 4x       4x 4x 4x 4x 4x 1x 1x 4x 3x 3x 3x 3x 4x 8x 2x 2x 2x 2x 2x 2x 2x   2x 2x 2x 2x 2x 2x 9x 9x 9x 9x 9x  
'use client';
 
import { useEffect, useRef } from 'react';
import { useSession } from 'next-auth/react';
import { useDispatch } from 'react-redux';
import { clientLogger } from '@/lib/logging/clientLogger';
import {
  initializeAnonymousCart,
  setCartLoaded,
  setIsAnonymous,
  fetchCart,
  clearCart } from '@/redux/features/cartSlice';
import { getCartCookie } from '@/lib/cart';
import { AppDispatch } from '@/redux/store';
 
/**
 * CartInitializer
 *
 * Initializes the cart on app load by:
 * - Loading anonymous cart from cookie if user is not authenticated
 * - Loading user cart from database if user is authenticated
 * - Reloads cart when authentication status changes
 */
export function CartInitializer() {
  const dispatch = useDispatch<AppDispatch>();
  const { status } = useSession();
  const previousStatus = useRef<string | null>(null);
  const isInitializing = useRef(false);
 
  useEffect(() => {
    // Wait for session to be determined
    if (status === 'loading') return;
 
    // Prevent duplicate initializations during the same status
    if (isInitializing.current) return;
 
    // Only run when status changes or on first load
    if (previousStatus.current === status) return;
 
    const wasAuthenticated = previousStatus.current === 'authenticated';
    isInitializing.current = true;
    previousStatus.current = status;
 
    if (status === 'unauthenticated') {
      // User is not logged in (either initial load or just logged out)
 
      // If user just logged out, clear the Redux cart state first
      // This prevents stale user cart data from persisting
      if (wasAuthenticated) {
        clientLogger.info('User logged out, clearing cart state');
        dispatch(clearCart());
      }
 
      // Load cart from cookie
      const anonymousCart = getCartCookie();
 
      if (anonymousCart && anonymousCart.length > 0) {
        clientLogger.info('Initializing anonymous cart from cookie', { itemCount: anonymousCart.length });
        dispatch(initializeAnonymousCart(anonymousCart));
      } else {
        // No cart in cookie - just mark as loaded with empty cart
        dispatch(setIsAnonymous(true));
        dispatch(setCartLoaded(true));
      }
      isInitializing.current = false;
    } else if (status === 'authenticated') {
      // User is authenticated - fetch cart from database
      // Clear any stale cart data first before fetching fresh data
      clientLogger.info('User authenticated, fetching cart from database');
      dispatch(clearCart());
      dispatch(setIsAnonymous(false));
      void dispatch(fetchCart())
        .catch((err) => {
          clientLogger.error('CartInitializer fetchCart error', err instanceof Error ? err : new Error(String(err)));
        })
        .finally(() => {
          dispatch(setCartLoaded(true));
          isInitializing.current = false;
        });
    }
  }, [status, dispatch]);
 
  // This component doesn't render anything
  return null;
}