@payloadcms/plugin-ecommerce 3.67.0-internal.87c53da → 3.67.0
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/collections/addresses/createAddressesCollection.d.ts +1 -5
- package/dist/collections/addresses/createAddressesCollection.d.ts.map +1 -1
- package/dist/collections/addresses/createAddressesCollection.js +7 -6
- package/dist/collections/addresses/createAddressesCollection.js.map +1 -1
- package/dist/collections/carts/beforeChange.d.ts.map +1 -1
- package/dist/collections/carts/beforeChange.js +13 -1
- package/dist/collections/carts/beforeChange.js.map +1 -1
- package/dist/collections/carts/createCartsCollection.d.ts +6 -4
- package/dist/collections/carts/createCartsCollection.d.ts.map +1 -1
- package/dist/collections/carts/createCartsCollection.js +36 -5
- package/dist/collections/carts/createCartsCollection.js.map +1 -1
- package/dist/collections/carts/hasCartSecretAccess.d.ts +10 -0
- package/dist/collections/carts/hasCartSecretAccess.d.ts.map +1 -0
- package/dist/collections/carts/hasCartSecretAccess.js +24 -0
- package/dist/collections/carts/hasCartSecretAccess.js.map +1 -0
- package/dist/collections/orders/createOrdersCollection.d.ts +1 -5
- package/dist/collections/orders/createOrdersCollection.d.ts.map +1 -1
- package/dist/collections/orders/createOrdersCollection.js +9 -8
- package/dist/collections/orders/createOrdersCollection.js.map +1 -1
- package/dist/collections/products/createProductsCollection.d.ts +1 -4
- package/dist/collections/products/createProductsCollection.d.ts.map +1 -1
- package/dist/collections/products/createProductsCollection.js +5 -5
- package/dist/collections/products/createProductsCollection.js.map +1 -1
- package/dist/collections/transactions/createTransactionsCollection.d.ts +1 -3
- package/dist/collections/transactions/createTransactionsCollection.d.ts.map +1 -1
- package/dist/collections/transactions/createTransactionsCollection.js +5 -5
- package/dist/collections/transactions/createTransactionsCollection.js.map +1 -1
- package/dist/collections/variants/createVariantOptionsCollection.d.ts +1 -4
- package/dist/collections/variants/createVariantOptionsCollection.d.ts.map +1 -1
- package/dist/collections/variants/createVariantOptionsCollection.js +5 -5
- package/dist/collections/variants/createVariantOptionsCollection.js.map +1 -1
- package/dist/collections/variants/createVariantTypesCollection.d.ts +1 -4
- package/dist/collections/variants/createVariantTypesCollection.d.ts.map +1 -1
- package/dist/collections/variants/createVariantTypesCollection.js +5 -5
- package/dist/collections/variants/createVariantTypesCollection.js.map +1 -1
- package/dist/collections/variants/createVariantsCollection/index.d.ts +1 -4
- package/dist/collections/variants/createVariantsCollection/index.d.ts.map +1 -1
- package/dist/collections/variants/createVariantsCollection/index.js +5 -5
- package/dist/collections/variants/createVariantsCollection/index.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -33
- package/dist/index.js.map +1 -1
- package/dist/react/provider/index.d.ts +3 -0
- package/dist/react/provider/index.d.ts.map +1 -1
- package/dist/react/provider/index.js +261 -156
- package/dist/react/provider/index.js.map +1 -1
- package/dist/translations/en.d.ts.map +1 -1
- package/dist/translations/en.js +1 -0
- package/dist/translations/en.js.map +1 -1
- package/dist/types/index.d.ts +43 -25
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/utilities/accessComposition.d.ts +55 -0
- package/dist/utilities/accessComposition.d.ts.map +1 -0
- package/dist/utilities/accessComposition.js +103 -0
- package/dist/utilities/accessComposition.js.map +1 -0
- package/dist/utilities/accessComposition.spec.js +803 -0
- package/dist/utilities/accessComposition.spec.js.map +1 -0
- package/dist/utilities/defaultProductsValidation.spec.js +383 -0
- package/dist/utilities/defaultProductsValidation.spec.js.map +1 -0
- package/dist/utilities/getCollectionSlugMap.spec.js +159 -0
- package/dist/utilities/getCollectionSlugMap.spec.js.map +1 -0
- package/dist/utilities/sanitizePluginConfig.d.ts.map +1 -1
- package/dist/utilities/sanitizePluginConfig.js +10 -2
- package/dist/utilities/sanitizePluginConfig.js.map +1 -1
- package/dist/utilities/sanitizePluginConfig.spec.js +515 -0
- package/dist/utilities/sanitizePluginConfig.spec.js.map +1 -0
- package/package.json +7 -7
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
3
|
import { deepMergeSimple } from 'payload/shared';
|
|
4
4
|
import * as qs from 'qs-esm';
|
|
5
|
-
import React, { createContext, use, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
5
|
+
import React, { createContext, use, useCallback, useEffect, useMemo, useRef, useState, useTransition } from 'react';
|
|
6
6
|
const defaultContext = {
|
|
7
7
|
addItem: async ()=>{},
|
|
8
8
|
clearCart: async ()=>{},
|
|
@@ -28,6 +28,7 @@ const defaultContext = {
|
|
|
28
28
|
decrementItem: async ()=>{},
|
|
29
29
|
incrementItem: async ()=>{},
|
|
30
30
|
initiatePayment: async ()=>{},
|
|
31
|
+
isLoading: false,
|
|
31
32
|
paymentMethods: [],
|
|
32
33
|
removeItem: async ()=>{},
|
|
33
34
|
setCurrency: ()=>{},
|
|
@@ -54,6 +55,7 @@ export const EcommerceProvider = ({ addressesSlug = 'addresses', api, cartsSlug
|
|
|
54
55
|
} : defaultLocalStorage;
|
|
55
56
|
const { apiRoute = '/api', cartsFetchQuery = {}, serverURL = '' } = api || {};
|
|
56
57
|
const baseAPIURL = `${serverURL}${apiRoute}`;
|
|
58
|
+
const [isLoading, startTransition] = useTransition();
|
|
57
59
|
const [user, setUser] = useState(null);
|
|
58
60
|
const [addresses, setAddresses] = useState();
|
|
59
61
|
const hasRendered = useRef(false);
|
|
@@ -62,6 +64,10 @@ export const EcommerceProvider = ({ addressesSlug = 'addresses', api, cartsSlug
|
|
|
62
64
|
* This is used to identify the cart in the database or local storage.
|
|
63
65
|
* It can be null if no cart has been created yet.
|
|
64
66
|
*/ const [cartID, setCartID] = useState();
|
|
67
|
+
/**
|
|
68
|
+
* The secret for accessing guest carts without authentication.
|
|
69
|
+
* This is generated when a guest user creates a cart.
|
|
70
|
+
*/ const [cartSecret, setCartSecret] = useState(undefined);
|
|
65
71
|
const [cart, setCart] = useState();
|
|
66
72
|
const [selectedCurrency, setSelectedCurrency] = useState(()=>currenciesConfig.supportedCurrencies.find((c)=>c.code === currenciesConfig.defaultCurrency));
|
|
67
73
|
const [selectedPaymentMethod, setSelectedPaymentMethod] = useState(null);
|
|
@@ -110,16 +116,28 @@ export const EcommerceProvider = ({ addressesSlug = 'addresses', api, cartsSlug
|
|
|
110
116
|
if (data.error) {
|
|
111
117
|
throw new Error(`Cart creation error: ${data.error}`);
|
|
112
118
|
}
|
|
119
|
+
// Store the secret for guest cart access
|
|
120
|
+
if (!user && data.doc?.secret) {
|
|
121
|
+
setCartSecret(data.doc.secret);
|
|
122
|
+
}
|
|
113
123
|
return data.doc;
|
|
114
124
|
}, [
|
|
115
125
|
baseAPIURL,
|
|
116
126
|
cartQuery,
|
|
117
127
|
cartsSlug,
|
|
118
128
|
selectedCurrency.code,
|
|
119
|
-
user
|
|
129
|
+
user
|
|
120
130
|
]);
|
|
121
|
-
const getCart = useCallback(async (cartID)=>{
|
|
122
|
-
const
|
|
131
|
+
const getCart = useCallback(async (cartID, options)=>{
|
|
132
|
+
const secret = options?.secret;
|
|
133
|
+
// Build query params with secret if provided
|
|
134
|
+
const queryParams = {
|
|
135
|
+
...cartQuery,
|
|
136
|
+
...secret ? {
|
|
137
|
+
secret
|
|
138
|
+
} : {}
|
|
139
|
+
};
|
|
140
|
+
const query = qs.stringify(queryParams);
|
|
123
141
|
const response = await fetch(`${baseAPIURL}/${cartsSlug}/${cartID}?${query}`, {
|
|
124
142
|
credentials: 'include',
|
|
125
143
|
headers: {
|
|
@@ -142,7 +160,14 @@ export const EcommerceProvider = ({ addressesSlug = 'addresses', api, cartsSlug
|
|
|
142
160
|
cartsSlug
|
|
143
161
|
]);
|
|
144
162
|
const updateCart = useCallback(async (cartID, data)=>{
|
|
145
|
-
|
|
163
|
+
// Build query params with secret if provided
|
|
164
|
+
const queryParams = {
|
|
165
|
+
...cartQuery,
|
|
166
|
+
...cartSecret ? {
|
|
167
|
+
secret: cartSecret
|
|
168
|
+
} : {}
|
|
169
|
+
};
|
|
170
|
+
const query = qs.stringify(queryParams);
|
|
146
171
|
const response = await fetch(`${baseAPIURL}/${cartsSlug}/${cartID}?${query}`, {
|
|
147
172
|
body: JSON.stringify(data),
|
|
148
173
|
credentials: 'include',
|
|
@@ -160,10 +185,17 @@ export const EcommerceProvider = ({ addressesSlug = 'addresses', api, cartsSlug
|
|
|
160
185
|
}, [
|
|
161
186
|
baseAPIURL,
|
|
162
187
|
cartQuery,
|
|
163
|
-
cartsSlug
|
|
188
|
+
cartsSlug,
|
|
189
|
+
cartSecret
|
|
164
190
|
]);
|
|
165
191
|
const deleteCart = useCallback(async (cartID)=>{
|
|
166
|
-
|
|
192
|
+
// Build query params with secret if provided
|
|
193
|
+
const queryParams = cartSecret ? {
|
|
194
|
+
secret: cartSecret
|
|
195
|
+
} : {};
|
|
196
|
+
const query = qs.stringify(queryParams);
|
|
197
|
+
const url = `${baseAPIURL}/${cartsSlug}/${cartID}${query ? `?${query}` : ''}`;
|
|
198
|
+
const response = await fetch(url, {
|
|
167
199
|
credentials: 'include',
|
|
168
200
|
headers: {
|
|
169
201
|
'Content-Type': 'application/json'
|
|
@@ -172,196 +204,257 @@ export const EcommerceProvider = ({ addressesSlug = 'addresses', api, cartsSlug
|
|
|
172
204
|
});
|
|
173
205
|
if (!response.ok) {
|
|
174
206
|
const errorText = await response.text();
|
|
175
|
-
throw new Error(`Failed to
|
|
207
|
+
throw new Error(`Failed to delete cart: ${errorText}`);
|
|
176
208
|
}
|
|
177
209
|
setCart(undefined);
|
|
178
210
|
setCartID(undefined);
|
|
211
|
+
setCartSecret(undefined);
|
|
179
212
|
}, [
|
|
180
213
|
baseAPIURL,
|
|
181
|
-
cartsSlug
|
|
214
|
+
cartsSlug,
|
|
215
|
+
cartSecret
|
|
182
216
|
]);
|
|
217
|
+
// Persist cart ID and secret to localStorage
|
|
183
218
|
useEffect(()=>{
|
|
184
219
|
if (hasRendered.current) {
|
|
185
|
-
if (syncLocalStorage
|
|
186
|
-
|
|
220
|
+
if (syncLocalStorage) {
|
|
221
|
+
if (cartID) {
|
|
222
|
+
localStorage.setItem(localStorageConfig.key, cartID);
|
|
223
|
+
} else {
|
|
224
|
+
localStorage.removeItem(localStorageConfig.key);
|
|
225
|
+
}
|
|
226
|
+
if (cartSecret) {
|
|
227
|
+
localStorage.setItem(`${localStorageConfig.key}_secret`, cartSecret);
|
|
228
|
+
} else {
|
|
229
|
+
localStorage.removeItem(`${localStorageConfig.key}_secret`);
|
|
230
|
+
}
|
|
187
231
|
}
|
|
188
232
|
}
|
|
189
233
|
}, [
|
|
190
234
|
cartID,
|
|
235
|
+
cartSecret,
|
|
191
236
|
localStorageConfig.key,
|
|
192
237
|
syncLocalStorage
|
|
193
238
|
]);
|
|
194
239
|
const addItem = useCallback(async (item, quantity = 1)=>{
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
const variantID = cartItem.variant && typeof cartItem.variant === 'object' ? cartItem.variant.id : item.variant;
|
|
207
|
-
return productID === item.product && (item.variant && variantID ? variantID === item.variant : true);
|
|
208
|
-
}) ?? -1;
|
|
209
|
-
let updatedItems = existingCart.items ? [
|
|
210
|
-
...existingCart.items
|
|
211
|
-
] : [];
|
|
212
|
-
if (existingItemIndex !== -1) {
|
|
213
|
-
// If the item exists, update its quantity
|
|
214
|
-
updatedItems[existingItemIndex].quantity = updatedItems[existingItemIndex].quantity + quantity;
|
|
215
|
-
// Update the cart with the new items
|
|
216
|
-
await updateCart(cartID, {
|
|
217
|
-
items: updatedItems
|
|
218
|
-
});
|
|
219
|
-
} else {
|
|
220
|
-
// If the item does not exist, add it to the cart
|
|
221
|
-
updatedItems = [
|
|
222
|
-
...existingCart.items ?? [],
|
|
223
|
-
{
|
|
224
|
-
...item,
|
|
225
|
-
quantity
|
|
240
|
+
return new Promise((resolve)=>{
|
|
241
|
+
startTransition(async ()=>{
|
|
242
|
+
if (cartID) {
|
|
243
|
+
const existingCart = await getCart(cartID, {
|
|
244
|
+
secret: cartSecret
|
|
245
|
+
});
|
|
246
|
+
if (!existingCart) {
|
|
247
|
+
// console.error(`Cart with ID "${cartID}" not found`)
|
|
248
|
+
setCartID(undefined);
|
|
249
|
+
setCart(undefined);
|
|
250
|
+
return;
|
|
226
251
|
}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
252
|
+
// Check if the item already exists in the cart
|
|
253
|
+
const existingItemIndex = existingCart.items?.findIndex((cartItem)=>{
|
|
254
|
+
const productID = typeof cartItem.product === 'object' ? cartItem.product.id : item.product;
|
|
255
|
+
const variantID = cartItem.variant && typeof cartItem.variant === 'object' ? cartItem.variant.id : item.variant;
|
|
256
|
+
return productID === item.product && (item.variant && variantID ? variantID === item.variant : true);
|
|
257
|
+
}) ?? -1;
|
|
258
|
+
let updatedItems = existingCart.items ? [
|
|
259
|
+
...existingCart.items
|
|
260
|
+
] : [];
|
|
261
|
+
if (existingItemIndex !== -1) {
|
|
262
|
+
// If the item exists, update its quantity
|
|
263
|
+
updatedItems[existingItemIndex].quantity = updatedItems[existingItemIndex].quantity + quantity;
|
|
264
|
+
// Update the cart with the new items
|
|
265
|
+
await updateCart(cartID, {
|
|
266
|
+
items: updatedItems
|
|
267
|
+
});
|
|
268
|
+
} else {
|
|
269
|
+
// If the item does not exist, add it to the cart
|
|
270
|
+
updatedItems = [
|
|
271
|
+
...existingCart.items ?? [],
|
|
272
|
+
{
|
|
273
|
+
...item,
|
|
274
|
+
quantity
|
|
275
|
+
}
|
|
276
|
+
];
|
|
240
277
|
}
|
|
241
|
-
|
|
278
|
+
// Update the cart with the new items
|
|
279
|
+
await updateCart(cartID, {
|
|
280
|
+
items: updatedItems
|
|
281
|
+
});
|
|
282
|
+
} else {
|
|
283
|
+
// If no cartID exists, create a new cart
|
|
284
|
+
const newCart = await createCart({
|
|
285
|
+
items: [
|
|
286
|
+
{
|
|
287
|
+
...item,
|
|
288
|
+
quantity
|
|
289
|
+
}
|
|
290
|
+
]
|
|
291
|
+
});
|
|
292
|
+
setCartID(newCart.id);
|
|
293
|
+
setCart(newCart);
|
|
294
|
+
}
|
|
295
|
+
resolve();
|
|
242
296
|
});
|
|
243
|
-
|
|
244
|
-
setCart(newCart);
|
|
245
|
-
}
|
|
297
|
+
});
|
|
246
298
|
}, [
|
|
247
299
|
cartID,
|
|
300
|
+
cartSecret,
|
|
248
301
|
createCart,
|
|
249
302
|
getCart,
|
|
303
|
+
startTransition,
|
|
250
304
|
updateCart
|
|
251
305
|
]);
|
|
252
306
|
const removeItem = useCallback(async (targetID)=>{
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
307
|
+
return new Promise((resolve)=>{
|
|
308
|
+
startTransition(async ()=>{
|
|
309
|
+
if (!cartID) {
|
|
310
|
+
resolve();
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
const existingCart = await getCart(cartID, {
|
|
314
|
+
secret: cartSecret
|
|
315
|
+
});
|
|
316
|
+
if (!existingCart) {
|
|
317
|
+
// console.error(`Cart with ID "${cartID}" not found`)
|
|
318
|
+
setCartID(undefined);
|
|
319
|
+
setCart(undefined);
|
|
320
|
+
resolve();
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
// Check if the item already exists in the cart
|
|
324
|
+
const existingItemIndex = existingCart.items?.findIndex((cartItem)=>cartItem.id === targetID) ?? -1;
|
|
325
|
+
if (existingItemIndex !== -1) {
|
|
326
|
+
// If the item exists, remove it from the cart
|
|
327
|
+
const updatedItems = existingCart.items ? [
|
|
328
|
+
...existingCart.items
|
|
329
|
+
] : [];
|
|
330
|
+
updatedItems.splice(existingItemIndex, 1);
|
|
331
|
+
// Update the cart with the new items
|
|
332
|
+
await updateCart(cartID, {
|
|
333
|
+
items: updatedItems
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
resolve();
|
|
274
337
|
});
|
|
275
|
-
}
|
|
338
|
+
});
|
|
276
339
|
}, [
|
|
277
340
|
cartID,
|
|
341
|
+
cartSecret,
|
|
278
342
|
getCart,
|
|
343
|
+
startTransition,
|
|
279
344
|
updateCart
|
|
280
345
|
]);
|
|
281
346
|
const incrementItem = useCallback(async (targetID)=>{
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
// console.error(`Cart with ID "${cartID}" not found`)
|
|
288
|
-
setCartID(undefined);
|
|
289
|
-
setCart(undefined);
|
|
290
|
-
return;
|
|
291
|
-
}
|
|
292
|
-
// Check if the item already exists in the cart
|
|
293
|
-
const existingItemIndex = existingCart.items?.findIndex((cartItem)=>cartItem.id === targetID) ?? -1;
|
|
294
|
-
let updatedItems = existingCart.items ? [
|
|
295
|
-
...existingCart.items
|
|
296
|
-
] : [];
|
|
297
|
-
if (existingItemIndex !== -1) {
|
|
298
|
-
// If the item exists, increment its quantity
|
|
299
|
-
updatedItems[existingItemIndex].quantity = updatedItems[existingItemIndex].quantity + 1 // Increment by 1
|
|
300
|
-
;
|
|
301
|
-
// Update the cart with the new items
|
|
302
|
-
await updateCart(cartID, {
|
|
303
|
-
items: updatedItems
|
|
304
|
-
});
|
|
305
|
-
} else {
|
|
306
|
-
// If the item does not exist, add it to the cart with quantity 1
|
|
307
|
-
updatedItems = [
|
|
308
|
-
...existingCart.items ?? [],
|
|
309
|
-
{
|
|
310
|
-
product: targetID,
|
|
311
|
-
quantity: 1
|
|
347
|
+
return new Promise((resolve)=>{
|
|
348
|
+
startTransition(async ()=>{
|
|
349
|
+
if (!cartID) {
|
|
350
|
+
resolve();
|
|
351
|
+
return;
|
|
312
352
|
}
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
353
|
+
const existingCart = await getCart(cartID, {
|
|
354
|
+
secret: cartSecret
|
|
355
|
+
});
|
|
356
|
+
if (!existingCart) {
|
|
357
|
+
// console.error(`Cart with ID "${cartID}" not found`)
|
|
358
|
+
setCartID(undefined);
|
|
359
|
+
setCart(undefined);
|
|
360
|
+
resolve();
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
// Check if the item already exists in the cart
|
|
364
|
+
const existingItemIndex = existingCart.items?.findIndex((cartItem)=>cartItem.id === targetID) ?? -1;
|
|
365
|
+
let updatedItems = existingCart.items ? [
|
|
366
|
+
...existingCart.items
|
|
367
|
+
] : [];
|
|
368
|
+
if (existingItemIndex !== -1) {
|
|
369
|
+
// If the item exists, increment its quantity
|
|
370
|
+
updatedItems[existingItemIndex].quantity = updatedItems[existingItemIndex].quantity + 1 // Increment by 1
|
|
371
|
+
;
|
|
372
|
+
// Update the cart with the new items
|
|
373
|
+
await updateCart(cartID, {
|
|
374
|
+
items: updatedItems
|
|
375
|
+
});
|
|
376
|
+
} else {
|
|
377
|
+
// If the item does not exist, add it to the cart with quantity 1
|
|
378
|
+
updatedItems = [
|
|
379
|
+
...existingCart.items ?? [],
|
|
380
|
+
{
|
|
381
|
+
product: targetID,
|
|
382
|
+
quantity: 1
|
|
383
|
+
}
|
|
384
|
+
];
|
|
385
|
+
// Update the cart with the new items
|
|
386
|
+
await updateCart(cartID, {
|
|
387
|
+
items: updatedItems
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
resolve();
|
|
317
391
|
});
|
|
318
|
-
}
|
|
392
|
+
});
|
|
319
393
|
}, [
|
|
320
394
|
cartID,
|
|
395
|
+
cartSecret,
|
|
321
396
|
getCart,
|
|
397
|
+
startTransition,
|
|
322
398
|
updateCart
|
|
323
399
|
]);
|
|
324
400
|
const decrementItem = useCallback(async (targetID)=>{
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
401
|
+
return new Promise((resolve)=>{
|
|
402
|
+
startTransition(async ()=>{
|
|
403
|
+
if (!cartID) {
|
|
404
|
+
resolve();
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
const existingCart = await getCart(cartID, {
|
|
408
|
+
secret: cartSecret
|
|
409
|
+
});
|
|
410
|
+
if (!existingCart) {
|
|
411
|
+
// console.error(`Cart with ID "${cartID}" not found`)
|
|
412
|
+
setCartID(undefined);
|
|
413
|
+
setCart(undefined);
|
|
414
|
+
resolve();
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
417
|
+
// Check if the item already exists in the cart
|
|
418
|
+
const existingItemIndex = existingCart.items?.findIndex((cartItem)=>cartItem.id === targetID) ?? -1;
|
|
419
|
+
const updatedItems = existingCart.items ? [
|
|
420
|
+
...existingCart.items
|
|
421
|
+
] : [];
|
|
422
|
+
if (existingItemIndex !== -1) {
|
|
423
|
+
// If the item exists, decrement its quantity
|
|
424
|
+
updatedItems[existingItemIndex].quantity = updatedItems[existingItemIndex].quantity - 1 // Decrement by 1
|
|
425
|
+
;
|
|
426
|
+
// If the quantity reaches 0, remove the item from the cart
|
|
427
|
+
if (updatedItems[existingItemIndex].quantity <= 0) {
|
|
428
|
+
updatedItems.splice(existingItemIndex, 1);
|
|
429
|
+
}
|
|
430
|
+
// Update the cart with the new items
|
|
431
|
+
await updateCart(cartID, {
|
|
432
|
+
items: updatedItems
|
|
433
|
+
});
|
|
434
|
+
}
|
|
435
|
+
resolve();
|
|
351
436
|
});
|
|
352
|
-
}
|
|
437
|
+
});
|
|
353
438
|
}, [
|
|
354
439
|
cartID,
|
|
440
|
+
cartSecret,
|
|
355
441
|
getCart,
|
|
442
|
+
startTransition,
|
|
356
443
|
updateCart
|
|
357
444
|
]);
|
|
358
445
|
const clearCart = useCallback(async ()=>{
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
446
|
+
return new Promise((resolve)=>{
|
|
447
|
+
startTransition(async ()=>{
|
|
448
|
+
if (cartID) {
|
|
449
|
+
await deleteCart(cartID);
|
|
450
|
+
}
|
|
451
|
+
resolve();
|
|
452
|
+
});
|
|
453
|
+
});
|
|
362
454
|
}, [
|
|
363
455
|
cartID,
|
|
364
|
-
deleteCart
|
|
456
|
+
deleteCart,
|
|
457
|
+
startTransition
|
|
365
458
|
]);
|
|
366
459
|
const setCurrency = useCallback((currency)=>{
|
|
367
460
|
if (selectedCurrency.code === currency) {
|
|
@@ -629,21 +722,29 @@ export const EcommerceProvider = ({ addressesSlug = 'addresses', api, cartsSlug
|
|
|
629
722
|
getAddresses,
|
|
630
723
|
debug
|
|
631
724
|
]);
|
|
632
|
-
// If localStorage is enabled,
|
|
725
|
+
// If localStorage is enabled, restore cart from storage
|
|
633
726
|
useEffect(()=>{
|
|
634
727
|
if (!hasRendered.current) {
|
|
635
728
|
if (syncLocalStorage) {
|
|
636
|
-
const
|
|
637
|
-
|
|
638
|
-
|
|
729
|
+
const storedCartID = localStorage.getItem(localStorageConfig.key);
|
|
730
|
+
const storedSecret = localStorage.getItem(`${localStorageConfig.key}_secret`);
|
|
731
|
+
if (storedCartID) {
|
|
732
|
+
getCart(storedCartID, {
|
|
733
|
+
secret: storedSecret || undefined
|
|
734
|
+
}).then((fetchedCart)=>{
|
|
639
735
|
setCart(fetchedCart);
|
|
640
|
-
setCartID(
|
|
736
|
+
setCartID(storedCartID);
|
|
737
|
+
if (storedSecret) {
|
|
738
|
+
setCartSecret(storedSecret);
|
|
739
|
+
}
|
|
641
740
|
}).catch((_)=>{
|
|
642
741
|
// console.error('Error fetching cart from localStorage:', error)
|
|
643
|
-
// If there's an error fetching the cart,
|
|
742
|
+
// If there's an error fetching the cart, clear it from localStorage
|
|
644
743
|
localStorage.removeItem(localStorageConfig.key);
|
|
744
|
+
localStorage.removeItem(`${localStorageConfig.key}_secret`);
|
|
645
745
|
setCartID(undefined);
|
|
646
746
|
setCart(undefined);
|
|
747
|
+
setCartSecret(undefined);
|
|
647
748
|
});
|
|
648
749
|
}
|
|
649
750
|
}
|
|
@@ -702,6 +803,7 @@ export const EcommerceProvider = ({ addressesSlug = 'addresses', api, cartsSlug
|
|
|
702
803
|
decrementItem,
|
|
703
804
|
incrementItem,
|
|
704
805
|
initiatePayment,
|
|
806
|
+
isLoading,
|
|
705
807
|
paymentMethods,
|
|
706
808
|
removeItem,
|
|
707
809
|
selectedPaymentMethod,
|
|
@@ -749,7 +851,7 @@ export const useCurrency = ()=>{
|
|
|
749
851
|
};
|
|
750
852
|
};
|
|
751
853
|
export function useCart() {
|
|
752
|
-
const { addItem, cart, clearCart, decrementItem, incrementItem, removeItem } = useEcommerce();
|
|
854
|
+
const { addItem, cart, clearCart, decrementItem, incrementItem, isLoading, removeItem } = useEcommerce();
|
|
753
855
|
if (!addItem) {
|
|
754
856
|
throw new Error('useCart must be used within an EcommerceProvider');
|
|
755
857
|
}
|
|
@@ -759,29 +861,32 @@ export function useCart() {
|
|
|
759
861
|
clearCart,
|
|
760
862
|
decrementItem,
|
|
761
863
|
incrementItem,
|
|
864
|
+
isLoading,
|
|
762
865
|
removeItem
|
|
763
866
|
};
|
|
764
867
|
}
|
|
765
868
|
export const usePayments = ()=>{
|
|
766
|
-
const { confirmOrder, initiatePayment, paymentMethods, selectedPaymentMethod } = useEcommerce();
|
|
869
|
+
const { confirmOrder, initiatePayment, isLoading, paymentMethods, selectedPaymentMethod } = useEcommerce();
|
|
767
870
|
if (!initiatePayment) {
|
|
768
871
|
throw new Error('usePayments must be used within an EcommerceProvider');
|
|
769
872
|
}
|
|
770
873
|
return {
|
|
771
874
|
confirmOrder,
|
|
772
875
|
initiatePayment,
|
|
876
|
+
isLoading,
|
|
773
877
|
paymentMethods,
|
|
774
878
|
selectedPaymentMethod
|
|
775
879
|
};
|
|
776
880
|
};
|
|
777
881
|
export function useAddresses() {
|
|
778
|
-
const { addresses, createAddress, updateAddress } = useEcommerce();
|
|
882
|
+
const { addresses, createAddress, isLoading, updateAddress } = useEcommerce();
|
|
779
883
|
if (!createAddress) {
|
|
780
884
|
throw new Error('usePayments must be used within an EcommerceProvider');
|
|
781
885
|
}
|
|
782
886
|
return {
|
|
783
887
|
addresses: addresses,
|
|
784
888
|
createAddress,
|
|
889
|
+
isLoading,
|
|
785
890
|
updateAddress
|
|
786
891
|
};
|
|
787
892
|
}
|