'use client'; import { Cart } from 'lib/shopify/types'; import { useEffect, useState } from 'react'; export function useCartProcessing(cart: Cart | undefined) { const [boxGroups, setBoxGroups] = useState(new Map()); const [standaloneProducts, setStandaloneProducts] = useState([]); const [isGroupingComplete, setIsGroupingComplete] = useState(false); const [didInitialProcess, setDidInitialProcess] = useState(false); // First-time cart load processing with delay useEffect(() => { if (!cart?.lines?.length) { setIsGroupingComplete(true); return; } // Use a small timeout to ensure cart data is fully loaded const timeoutId = setTimeout(() => { processCartItems(); }, 100); // 100ms delay return () => clearTimeout(timeoutId); }, []); // Process cart items whenever the cart changes after initial load useEffect(() => { if (!didInitialProcess && cart?.lines?.length) { // Skip first update - handled by the first effect return; } if (!cart?.lines?.length) { setIsGroupingComplete(true); return; } processCartItems(); }, [cart, didInitialProcess]); // Process cart items function const processCartItems = () => { if (!cart) return; // Set grouping as incomplete at the start setIsGroupingComplete(false); const newBoxGroups = new Map(); const newStandaloneProducts: any[] = []; // First, sort all items into boxes or standalone products cart.lines.forEach(item => { // Skip items without attributes (avoid runtime errors) if (!item.attributes || item.attributes.length === 0) { newStandaloneProducts.push(item); return; } const boxType = item.attributes.find(attr => attr.key === '_box_type')?.value; const boxGroupId = item.attributes.find(attr => attr.key === '_box_group_id')?.value; if (boxType === 'container' && boxGroupId) { // This is a box container if (!newBoxGroups.has(boxGroupId)) { newBoxGroups.set(boxGroupId, { box: item, products: [] }); } else { newBoxGroups.get(boxGroupId)!.box = item; } } else if (boxType === 'item' && boxGroupId) { // This is an item that belongs in a box if (!newBoxGroups.has(boxGroupId)) { newBoxGroups.set(boxGroupId, { box: null, products: [item] }); } else { newBoxGroups.get(boxGroupId)!.products.push(item); } } else { // This is a standalone product newStandaloneProducts.push(item); } }); setBoxGroups(newBoxGroups); setStandaloneProducts(newStandaloneProducts); setDidInitialProcess(true); // Mark grouping as complete setIsGroupingComplete(true); }; // Get boxes array from the map for rendering const boxes = Array.from(boxGroups.values()).filter(group => group.box); return { boxes, standaloneProducts, isGroupingComplete, didInitialProcess }; }