diff --git a/src/components/CartActionsButtons/CartActionsButtons.tsx b/src/components/CartActionsButtons/CartActionsButtons.tsx index 49c3a11..ee89b79 100644 --- a/src/components/CartActionsButtons/CartActionsButtons.tsx +++ b/src/components/CartActionsButtons/CartActionsButtons.tsx @@ -15,8 +15,8 @@ export default function CartActionsButtons({ item }: { item: CartItem }) { const isMobile = false; // Default to desktop const isRTL = false; // Default to LTR - const handleDeleteItem = (itemId: string) => { - dispatch(removeItem(Number(itemId))); + const handleDeleteItem = (uniqueId: string) => { + dispatch(removeItem(uniqueId)); }; const getPopconfirmOverlayStyle = () => ({ @@ -49,7 +49,7 @@ export default function CartActionsButtons({ item }: { item: CartItem }) { type="text" size="small" onClick={() => - dispatch(updateQuantity({ id: item.id, quantity: Math.max(1, item.quantity - 1) })) + dispatch(updateQuantity({ id: item.id, uniqueId: item.uniqueId || '', quantity: Math.max(1, item.quantity - 1) })) } className={styles.quantityButton} > @@ -59,7 +59,7 @@ export default function CartActionsButtons({ item }: { item: CartItem }) { handleDeleteItem(item.id.toString())} + onConfirm={() => handleDeleteItem(item.uniqueId || '')} okText={t("cart.deleteConfirmation.confirm")} cancelText={t("cart.deleteConfirmation.cancel")} okButtonProps={{ danger: true }} @@ -84,7 +84,7 @@ export default function CartActionsButtons({ item }: { item: CartItem }) { min={1} max={100} value={item.quantity || 1} - onChange={(value) => dispatch(updateQuantity({ id: item.id, quantity: value || 1 }))} + onChange={(value) => dispatch(updateQuantity({ id: item.id, uniqueId: item.uniqueId || '', quantity: value || 1 }))} size="small" controls={false} className={styles.quantityInput} @@ -94,7 +94,7 @@ export default function CartActionsButtons({ item }: { item: CartItem }) { type="text" size="small" onClick={() => - dispatch(updateQuantity({ id: item.id, quantity: Math.min(100, item.quantity + 1) })) + dispatch(updateQuantity({ id: item.id, uniqueId: item.uniqueId || '', quantity: Math.min(100, item.quantity + 1) })) } className={styles.quantityButton} > diff --git a/src/features/order/orderSlice.ts b/src/features/order/orderSlice.ts index 497b810..6fb7cff 100644 --- a/src/features/order/orderSlice.ts +++ b/src/features/order/orderSlice.ts @@ -96,6 +96,16 @@ const getFromLocalStorage = (key: string, defaultValue: T): T => { } }; +// Generate a unique identifier for cart items based on product ID, variant, extras, and comment +const generateUniqueId = (item: Omit): string => { + const variantStr = item.variant || ''; + const extrasStr = item.extras ? item.extras.sort().join(',') : ''; + const extrasGroupStr = item.extrasgroup ? item.extrasgroup.sort().join(',') : ''; + const commentStr = item.comment || ''; + + return `${item.id}-${variantStr}-${extrasStr}-${extrasGroupStr}-${commentStr}`; +}; + const initialState: CartState = { items: getFromLocalStorage(CART_STORAGE_KEYS.ITEMS, []), tmp: null, @@ -169,14 +179,21 @@ const orderSlice = createSlice({ }>, ) { const { item, quantity } = action.payload; - const existingItem = state.items.find((i) => i.id === item.id); + + // Generate a unique ID for this item configuration + const uniqueId = generateUniqueId(item); + + // Check if an item with the same configuration already exists + const existingItem = state.items.find((i) => i.uniqueId === uniqueId); if (existingItem) { + // Update quantity of existing item with same configuration state.items = state.items.map((i) => - i.id === item.id ? { ...i, quantity: i.quantity + quantity } : i, + i.uniqueId === uniqueId ? { ...i, quantity: i.quantity + quantity } : i, ); } else { - state.items = [...state.items, { ...item, quantity }]; + // Add new item with its unique identifier + state.items = [...state.items, { ...item, quantity, uniqueId }]; } // Validate loyalty points if enabled @@ -203,11 +220,11 @@ const orderSlice = createSlice({ }, updateQuantity( state, - action: PayloadAction<{ id: number | string; quantity: number }>, + action: PayloadAction<{ id: number | string; uniqueId: string; quantity: number }>, ) { - const { id, quantity } = action.payload; + const { uniqueId, quantity } = action.payload; state.items = state.items.map((item) => - item.id === id ? { ...item, quantity } : item, + item.uniqueId === uniqueId ? { ...item, quantity } : item, ); // Sync to localStorage @@ -218,8 +235,8 @@ const orderSlice = createSlice({ ); } }, - removeItem(state, action: PayloadAction) { - state.items = state.items.filter((item) => item.id !== action.payload); + removeItem(state, action: PayloadAction) { + state.items = state.items.filter((item) => item.uniqueId !== action.payload); // Validate loyalty points if enabled if (state.useLoyaltyPoints) { @@ -575,6 +592,13 @@ export const selectCartTotal = (state: RootState) => 0, ); export const selectCartItemsQuantity = + (uniqueId: string) => (state: RootState) => { + const item = state.order.items.find((i) => i.uniqueId === uniqueId); + return item ? item.quantity : 0; + }; + +// Keep backward compatibility for components that still use id +export const selectCartItemsQuantityById = (id: number | string) => (state: RootState) => { const item = state.order.items.find((i) => i.id === id); return item ? item.quantity : 0; diff --git a/src/utils/types/appTypes.ts b/src/utils/types/appTypes.ts index d99d9dc..6499227 100644 --- a/src/utils/types/appTypes.ts +++ b/src/utils/types/appTypes.ts @@ -328,6 +328,8 @@ export interface CartItem { isHasLoyalty?: boolean; no_of_stamps_give?: number; comment?: string; + // Unique identifier for cart items with the same product but different variants/extras/comments + uniqueId?: string; } export interface User {