@instockng/storefront-ui 1.0.11 → 1.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/Checkout.d.ts.map +1 -1
- package/dist/components/ShoppingCart.d.ts.map +1 -1
- package/dist/contexts/CartContext.d.ts +2 -0
- package/dist/contexts/CartContext.d.ts.map +1 -1
- package/dist/index10.mjs +70 -70
- package/dist/index101.mjs +1 -1
- package/dist/index102.mjs +3 -3
- package/dist/index103.mjs +3 -3
- package/dist/index105.mjs +1 -1
- package/dist/index111.mjs +1 -1
- package/dist/index29.mjs +1 -1
- package/dist/index3.mjs +83 -78
- package/dist/index30.mjs +1 -1
- package/dist/index31.mjs +1 -1
- package/dist/index32.mjs +1 -1
- package/dist/index42.mjs +17 -17
- package/dist/index43.mjs +2 -2
- package/dist/index44.mjs +1 -1
- package/dist/index45.mjs +1 -1
- package/dist/index46.mjs +1 -1
- package/dist/index47.mjs +1 -1
- package/dist/index48.mjs +1 -1
- package/dist/index49.mjs +1 -1
- package/dist/index50.mjs +1 -1
- package/dist/index51.mjs +1 -1
- package/dist/index52.mjs +1 -1
- package/dist/index53.mjs +1 -1
- package/dist/index54.mjs +1 -1
- package/dist/index58.mjs +2 -2
- package/dist/index59.mjs +3 -4
- package/dist/index60.mjs +2 -4
- package/dist/index61.mjs +5 -2
- package/dist/index62.mjs +231 -30
- package/dist/index63.mjs +5 -42
- package/dist/index64.mjs +127 -228
- package/dist/index65.mjs +66 -4
- package/dist/index66.mjs +77 -124
- package/dist/index67.mjs +26 -65
- package/dist/index68.mjs +6 -84
- package/dist/index69.mjs +72 -26
- package/dist/index70.mjs +3 -8
- package/dist/index71.mjs +2 -75
- package/dist/index72.mjs +82 -3
- package/dist/index73.mjs +54 -2
- package/dist/index74.mjs +5 -82
- package/dist/index75.mjs +4 -53
- package/dist/index76.mjs +178 -5
- package/dist/index77.mjs +53 -5
- package/dist/index78.mjs +68 -178
- package/dist/index79.mjs +31 -50
- package/dist/index8.mjs +8 -7
- package/dist/index80.mjs +43 -69
- package/dist/index81.mjs +2 -2
- package/dist/index82.mjs +1 -1
- package/dist/index83.mjs +6 -6
- package/dist/index84.mjs +2 -2
- package/dist/index85.mjs +2 -2
- package/dist/index87.mjs +2 -2
- package/dist/index88.mjs +2 -2
- package/dist/index89.mjs +1 -1
- package/dist/index91.mjs +4 -4
- package/dist/index92.mjs +3 -3
- package/dist/index93.mjs +12 -30
- package/dist/index94.mjs +7 -11
- package/dist/index95.mjs +30 -3
- package/dist/index96.mjs +10 -3
- package/dist/index97.mjs +4 -13
- package/dist/index98.mjs +4 -7
- package/dist/index99.mjs +1 -1
- package/dist/test-utils/MockCartProvider.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/Checkout.tsx +9 -1
- package/src/components/ShoppingCart.tsx +1 -0
- package/src/contexts/CartContext.tsx +51 -24
- package/src/test-utils/MockCartProvider.tsx +8 -0
|
@@ -50,6 +50,8 @@ interface CartContextValue {
|
|
|
50
50
|
removeDiscount: () => Promise<void>;
|
|
51
51
|
/** Clear cart (removes from localStorage) */
|
|
52
52
|
clearCart: () => void;
|
|
53
|
+
/** Clear cart and create a new one immediately */
|
|
54
|
+
clearAndCreateNewCart: () => void;
|
|
53
55
|
/** Refresh cart data */
|
|
54
56
|
refetch: () => void;
|
|
55
57
|
/** Whether the cart modal is open */
|
|
@@ -84,7 +86,8 @@ export function CartProvider({ children, brandSlug, initialCartId, shoppingCartP
|
|
|
84
86
|
const [isMounted, setIsMounted] = useState(false);
|
|
85
87
|
|
|
86
88
|
// Use refs to prevent infinite loops
|
|
87
|
-
const
|
|
89
|
+
const hasLoadedFromStorageRef = useRef(false);
|
|
90
|
+
const hasAutoCreatedRef = useRef(false);
|
|
88
91
|
const isHandlingErrorRef = useRef(false);
|
|
89
92
|
|
|
90
93
|
// Set mounted flag on client
|
|
@@ -95,7 +98,9 @@ export function CartProvider({ children, brandSlug, initialCartId, shoppingCartP
|
|
|
95
98
|
// Load cartId from URL/localStorage after mount (client-side only)
|
|
96
99
|
// This avoids hydration mismatch between server and client
|
|
97
100
|
useEffect(() => {
|
|
98
|
-
if (initialCartId ||
|
|
101
|
+
if (initialCartId || hasLoadedFromStorageRef.current) return;
|
|
102
|
+
|
|
103
|
+
hasLoadedFromStorageRef.current = true;
|
|
99
104
|
|
|
100
105
|
// Check URL query params first
|
|
101
106
|
const urlParams = new URLSearchParams(window.location.search);
|
|
@@ -132,41 +137,53 @@ export function CartProvider({ children, brandSlug, initialCartId, shoppingCartP
|
|
|
132
137
|
onError: (error) => {
|
|
133
138
|
console.error('Failed to create cart:', error);
|
|
134
139
|
},
|
|
140
|
+
retry: 10,
|
|
135
141
|
});
|
|
136
142
|
|
|
137
|
-
// Auto-create cart on mount if no cartId
|
|
138
|
-
//
|
|
143
|
+
// Auto-create cart ONLY on initial mount if no cartId in localStorage
|
|
144
|
+
// After the first mount, we don't auto-create (user must explicitly add items)
|
|
139
145
|
useEffect(() => {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
146
|
+
// Only run on initial mount
|
|
147
|
+
if (hasAutoCreatedRef.current) return;
|
|
148
|
+
|
|
149
|
+
hasAutoCreatedRef.current = true;
|
|
150
|
+
|
|
151
|
+
// Defer cart creation to allow localStorage to load first
|
|
152
|
+
const timeoutId = setTimeout(() => {
|
|
153
|
+
// Check localStorage directly (don't rely on state due to closure)
|
|
154
|
+
const storedCartId = typeof window !== 'undefined' ? localStorage.getItem(CART_ID_KEY) : null;
|
|
155
|
+
|
|
156
|
+
// Only create if we still don't have a cartId after localStorage loaded
|
|
157
|
+
if (!storedCartId && !initialCartId) {
|
|
145
158
|
createCartMutation.mutate(brandSlug);
|
|
146
|
-
}
|
|
159
|
+
}
|
|
160
|
+
}, 150); // Delay to ensure localStorage effect has run
|
|
147
161
|
|
|
148
|
-
|
|
149
|
-
}
|
|
162
|
+
return () => clearTimeout(timeoutId);
|
|
150
163
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
151
|
-
}, []);
|
|
164
|
+
}, []); // Empty deps - truly only run once on mount
|
|
152
165
|
|
|
153
166
|
// Handle cart fetch error (invalid/expired cart from URL or localStorage)
|
|
154
|
-
//
|
|
167
|
+
// Clear the invalid cart and create a new one
|
|
155
168
|
useEffect(() => {
|
|
156
169
|
if (error && cartId && !isHandlingErrorRef.current) {
|
|
157
170
|
isHandlingErrorRef.current = true;
|
|
158
|
-
console.warn('Cart fetch failed,
|
|
159
|
-
|
|
160
|
-
//
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
171
|
+
console.warn('Cart fetch failed, creating new cart:', error);
|
|
172
|
+
|
|
173
|
+
// Clear invalid cart
|
|
174
|
+
setCartId(null);
|
|
175
|
+
if (typeof window !== 'undefined') {
|
|
176
|
+
localStorage.removeItem(CART_ID_KEY);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Create a new cart after clearing the invalid one
|
|
180
|
+
setTimeout(() => {
|
|
181
|
+
createCartMutation.mutate(brandSlug);
|
|
166
182
|
isHandlingErrorRef.current = false;
|
|
167
|
-
});
|
|
183
|
+
}, 100);
|
|
168
184
|
}
|
|
169
|
-
|
|
185
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
186
|
+
}, [error, cartId, brandSlug]); // Don't include createCartMutation to avoid infinite loop
|
|
170
187
|
|
|
171
188
|
// Mutations
|
|
172
189
|
const addItemMutation = useAddCartItem(cartId || '', {
|
|
@@ -191,6 +208,7 @@ export function CartProvider({ children, brandSlug, initialCartId, shoppingCartP
|
|
|
191
208
|
|
|
192
209
|
const updateCartMutation = useUpdateCart(cartId || '', {
|
|
193
210
|
onSuccess: () => refetch(),
|
|
211
|
+
retry: 3
|
|
194
212
|
});
|
|
195
213
|
|
|
196
214
|
const checkoutMutation = useCheckoutCart(cartId || '');
|
|
@@ -251,6 +269,14 @@ export function CartProvider({ children, brandSlug, initialCartId, shoppingCartP
|
|
|
251
269
|
}
|
|
252
270
|
}, []);
|
|
253
271
|
|
|
272
|
+
const clearAndCreateNewCart = useCallback(() => {
|
|
273
|
+
clearCart();
|
|
274
|
+
|
|
275
|
+
// Create a new cart immediately
|
|
276
|
+
createCartMutation.mutate(brandSlug);
|
|
277
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
278
|
+
}, [brandSlug]);
|
|
279
|
+
|
|
254
280
|
const open = useCallback(() => {
|
|
255
281
|
setIsOpen(true);
|
|
256
282
|
}, []);
|
|
@@ -272,6 +298,7 @@ export function CartProvider({ children, brandSlug, initialCartId, shoppingCartP
|
|
|
272
298
|
applyDiscount,
|
|
273
299
|
removeDiscount,
|
|
274
300
|
clearCart,
|
|
301
|
+
clearAndCreateNewCart,
|
|
275
302
|
refetch,
|
|
276
303
|
isOpen,
|
|
277
304
|
open,
|
|
@@ -400,6 +400,14 @@ export function MockCartProvider({
|
|
|
400
400
|
}));
|
|
401
401
|
},
|
|
402
402
|
|
|
403
|
+
clearAndCreateNewCart: () => {
|
|
404
|
+
console.log('Mock clearAndCreateNewCart');
|
|
405
|
+
setCart(prev => ({
|
|
406
|
+
...prev,
|
|
407
|
+
items: [],
|
|
408
|
+
}));
|
|
409
|
+
},
|
|
410
|
+
|
|
403
411
|
refetch: () => {
|
|
404
412
|
console.log('Mock refetch');
|
|
405
413
|
},
|