100 lines
3.0 KiB
TypeScript
100 lines
3.0 KiB
TypeScript
'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<string, { box: any; products: any[] }>());
|
|
const [standaloneProducts, setStandaloneProducts] = useState<any[]>([]);
|
|
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<string, { box: any; products: any[] }>();
|
|
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
|
|
};
|
|
}
|