@payloadcms/plugin-ecommerce 3.71.0-internal.e36f916 → 3.71.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 -1
- package/dist/collections/addresses/createAddressesCollection.d.ts.map +1 -1
- package/dist/collections/addresses/createAddressesCollection.js +1 -1
- package/dist/collections/addresses/createAddressesCollection.js.map +1 -1
- package/dist/collections/addresses/hooks/beforeChange.d.ts +2 -3
- package/dist/collections/addresses/hooks/beforeChange.d.ts.map +1 -1
- package/dist/collections/addresses/hooks/beforeChange.js +7 -3
- package/dist/collections/addresses/hooks/beforeChange.js.map +1 -1
- package/dist/collections/carts/beforeChange.d.ts.map +1 -1
- package/dist/collections/carts/beforeChange.js.map +1 -1
- package/dist/collections/carts/createCartsCollection.d.ts +21 -0
- package/dist/collections/carts/createCartsCollection.d.ts.map +1 -1
- package/dist/collections/carts/createCartsCollection.js +27 -2
- package/dist/collections/carts/createCartsCollection.js.map +1 -1
- package/dist/collections/carts/endpoints/addItem.d.ts +19 -0
- package/dist/collections/carts/endpoints/addItem.d.ts.map +1 -0
- package/dist/collections/carts/endpoints/addItem.js +54 -0
- package/dist/collections/carts/endpoints/addItem.js.map +1 -0
- package/dist/collections/carts/endpoints/clearCart.d.ts +15 -0
- package/dist/collections/carts/endpoints/clearCart.d.ts.map +1 -0
- package/dist/collections/carts/endpoints/clearCart.js +41 -0
- package/dist/collections/carts/endpoints/clearCart.js.map +1 -0
- package/dist/collections/carts/endpoints/mergeCart.d.ts +21 -0
- package/dist/collections/carts/endpoints/mergeCart.d.ts.map +1 -0
- package/dist/collections/carts/endpoints/mergeCart.js +72 -0
- package/dist/collections/carts/endpoints/mergeCart.js.map +1 -0
- package/dist/collections/carts/endpoints/removeItem.d.ts +16 -0
- package/dist/collections/carts/endpoints/removeItem.d.ts.map +1 -0
- package/dist/collections/carts/endpoints/removeItem.js +51 -0
- package/dist/collections/carts/endpoints/removeItem.js.map +1 -0
- package/dist/collections/carts/endpoints/updateItem.d.ts +40 -0
- package/dist/collections/carts/endpoints/updateItem.d.ts.map +1 -0
- package/dist/collections/carts/endpoints/updateItem.js +95 -0
- package/dist/collections/carts/endpoints/updateItem.js.map +1 -0
- package/dist/collections/carts/hasCartSecretAccess.d.ts +2 -2
- package/dist/collections/carts/hasCartSecretAccess.js +3 -3
- package/dist/collections/carts/hasCartSecretAccess.js.map +1 -1
- package/dist/collections/carts/operations/addItem.d.ts +24 -0
- package/dist/collections/carts/operations/addItem.d.ts.map +1 -0
- package/dist/collections/carts/operations/addItem.js +95 -0
- package/dist/collections/carts/operations/addItem.js.map +1 -0
- package/dist/collections/carts/operations/clearCart.d.ts +20 -0
- package/dist/collections/carts/operations/clearCart.d.ts.map +1 -0
- package/dist/collections/carts/operations/clearCart.js +53 -0
- package/dist/collections/carts/operations/clearCart.js.map +1 -0
- package/dist/collections/carts/operations/createRequestWithSecret.d.ts +11 -0
- package/dist/collections/carts/operations/createRequestWithSecret.d.ts.map +1 -0
- package/dist/collections/carts/operations/createRequestWithSecret.js +21 -0
- package/dist/collections/carts/operations/createRequestWithSecret.js.map +1 -0
- package/dist/collections/carts/operations/defaultCartItemMatcher.d.ts +19 -0
- package/dist/collections/carts/operations/defaultCartItemMatcher.d.ts.map +1 -0
- package/dist/collections/carts/operations/defaultCartItemMatcher.js +25 -0
- package/dist/collections/carts/operations/defaultCartItemMatcher.js.map +1 -0
- package/dist/collections/carts/operations/defaultCartItemMatcher.spec.js +358 -0
- package/dist/collections/carts/operations/defaultCartItemMatcher.spec.js.map +1 -0
- package/dist/collections/carts/operations/mergeCart.d.ts +54 -0
- package/dist/collections/carts/operations/mergeCart.d.ts.map +1 -0
- package/dist/collections/carts/operations/mergeCart.js +144 -0
- package/dist/collections/carts/operations/mergeCart.js.map +1 -0
- package/dist/collections/carts/operations/removeItem.d.ts +21 -0
- package/dist/collections/carts/operations/removeItem.d.ts.map +1 -0
- package/dist/collections/carts/operations/removeItem.js +69 -0
- package/dist/collections/carts/operations/removeItem.js.map +1 -0
- package/dist/collections/carts/operations/types.d.ts +152 -0
- package/dist/collections/carts/operations/types.d.ts.map +1 -0
- package/dist/collections/carts/operations/types.js +7 -0
- package/dist/collections/carts/operations/types.js.map +1 -0
- package/dist/collections/carts/operations/updateItem.d.ts +41 -0
- package/dist/collections/carts/operations/updateItem.d.ts.map +1 -0
- package/dist/collections/carts/operations/updateItem.js +110 -0
- package/dist/collections/carts/operations/updateItem.js.map +1 -0
- package/dist/collections/variants/createVariantsCollection/index.d.ts +4 -0
- package/dist/collections/variants/createVariantsCollection/index.d.ts.map +1 -1
- package/dist/collections/variants/createVariantsCollection/index.js +8 -2
- package/dist/collections/variants/createVariantsCollection/index.js.map +1 -1
- package/dist/endpoints/confirmOrder.d.ts.map +1 -1
- package/dist/endpoints/confirmOrder.js +9 -2
- package/dist/endpoints/confirmOrder.js.map +1 -1
- package/dist/endpoints/initiatePayment.d.ts.map +1 -1
- package/dist/endpoints/initiatePayment.js +8 -2
- package/dist/endpoints/initiatePayment.js.map +1 -1
- package/dist/exports/client/react.d.ts +1 -1
- package/dist/exports/client/react.d.ts.map +1 -1
- package/dist/exports/client/react.js +1 -1
- package/dist/exports/client/react.js.map +1 -1
- package/dist/exports/types.d.ts +1 -1
- package/dist/exports/types.d.ts.map +1 -1
- package/dist/exports/types.js.map +1 -1
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -1
- package/dist/index.js.map +1 -1
- package/dist/payments/adapters/stripe/confirmOrder.d.ts.map +1 -1
- package/dist/payments/adapters/stripe/confirmOrder.js +2 -2
- package/dist/payments/adapters/stripe/confirmOrder.js.map +1 -1
- package/dist/react/provider/index.d.ts +5 -4
- package/dist/react/provider/index.d.ts.map +1 -1
- package/dist/react/provider/index.js +449 -265
- package/dist/react/provider/index.js.map +1 -1
- package/dist/translations/index.d.ts +3 -4
- package/dist/translations/index.d.ts.map +1 -1
- package/dist/translations/index.js +80 -2
- package/dist/translations/index.js.map +1 -1
- package/dist/translations/languages/ar.d.ts +89 -0
- package/dist/translations/languages/ar.d.ts.map +1 -0
- package/dist/translations/languages/ar.js +92 -0
- package/dist/translations/languages/ar.js.map +1 -0
- package/dist/translations/languages/az.d.ts +89 -0
- package/dist/translations/languages/az.d.ts.map +1 -0
- package/dist/translations/languages/az.js +92 -0
- package/dist/translations/languages/az.js.map +1 -0
- package/dist/translations/languages/bg.d.ts +89 -0
- package/dist/translations/languages/bg.d.ts.map +1 -0
- package/dist/translations/languages/bg.js +92 -0
- package/dist/translations/languages/bg.js.map +1 -0
- package/dist/translations/languages/ca.d.ts +89 -0
- package/dist/translations/languages/ca.d.ts.map +1 -0
- package/dist/translations/languages/ca.js +92 -0
- package/dist/translations/languages/ca.js.map +1 -0
- package/dist/translations/languages/cs.d.ts +89 -0
- package/dist/translations/languages/cs.d.ts.map +1 -0
- package/dist/translations/languages/cs.js +92 -0
- package/dist/translations/languages/cs.js.map +1 -0
- package/dist/translations/languages/da.d.ts +89 -0
- package/dist/translations/languages/da.d.ts.map +1 -0
- package/dist/translations/languages/da.js +92 -0
- package/dist/translations/languages/da.js.map +1 -0
- package/dist/translations/languages/de.d.ts +89 -0
- package/dist/translations/languages/de.d.ts.map +1 -0
- package/dist/translations/languages/de.js +92 -0
- package/dist/translations/languages/de.js.map +1 -0
- package/dist/translations/languages/en.d.ts +89 -0
- package/dist/translations/languages/en.d.ts.map +1 -0
- package/dist/translations/languages/en.js +92 -0
- package/dist/translations/languages/en.js.map +1 -0
- package/dist/translations/languages/es.d.ts +89 -0
- package/dist/translations/languages/es.d.ts.map +1 -0
- package/dist/translations/languages/es.js +92 -0
- package/dist/translations/languages/es.js.map +1 -0
- package/dist/translations/languages/et.d.ts +89 -0
- package/dist/translations/languages/et.d.ts.map +1 -0
- package/dist/translations/languages/et.js +92 -0
- package/dist/translations/languages/et.js.map +1 -0
- package/dist/translations/languages/fa.d.ts +89 -0
- package/dist/translations/languages/fa.d.ts.map +1 -0
- package/dist/translations/languages/fa.js +92 -0
- package/dist/translations/languages/fa.js.map +1 -0
- package/dist/translations/languages/fr.d.ts +89 -0
- package/dist/translations/languages/fr.d.ts.map +1 -0
- package/dist/translations/languages/fr.js +92 -0
- package/dist/translations/languages/fr.js.map +1 -0
- package/dist/translations/languages/he.d.ts +89 -0
- package/dist/translations/languages/he.d.ts.map +1 -0
- package/dist/translations/languages/he.js +92 -0
- package/dist/translations/languages/he.js.map +1 -0
- package/dist/translations/languages/hr.d.ts +89 -0
- package/dist/translations/languages/hr.d.ts.map +1 -0
- package/dist/translations/languages/hr.js +92 -0
- package/dist/translations/languages/hr.js.map +1 -0
- package/dist/translations/languages/hu.d.ts +89 -0
- package/dist/translations/languages/hu.d.ts.map +1 -0
- package/dist/translations/languages/hu.js +92 -0
- package/dist/translations/languages/hu.js.map +1 -0
- package/dist/translations/languages/hy.d.ts +89 -0
- package/dist/translations/languages/hy.d.ts.map +1 -0
- package/dist/translations/languages/hy.js +92 -0
- package/dist/translations/languages/hy.js.map +1 -0
- package/dist/translations/languages/is.d.ts +89 -0
- package/dist/translations/languages/is.d.ts.map +1 -0
- package/dist/translations/languages/is.js +92 -0
- package/dist/translations/languages/is.js.map +1 -0
- package/dist/translations/languages/it.d.ts +89 -0
- package/dist/translations/languages/it.d.ts.map +1 -0
- package/dist/translations/languages/it.js +92 -0
- package/dist/translations/languages/it.js.map +1 -0
- package/dist/translations/languages/ja.d.ts +89 -0
- package/dist/translations/languages/ja.d.ts.map +1 -0
- package/dist/translations/languages/ja.js +92 -0
- package/dist/translations/languages/ja.js.map +1 -0
- package/dist/translations/languages/ko.d.ts +89 -0
- package/dist/translations/languages/ko.d.ts.map +1 -0
- package/dist/translations/languages/ko.js +92 -0
- package/dist/translations/languages/ko.js.map +1 -0
- package/dist/translations/languages/lt.d.ts +89 -0
- package/dist/translations/languages/lt.d.ts.map +1 -0
- package/dist/translations/languages/lt.js +92 -0
- package/dist/translations/languages/lt.js.map +1 -0
- package/dist/translations/languages/my.d.ts +89 -0
- package/dist/translations/languages/my.d.ts.map +1 -0
- package/dist/translations/languages/my.js +92 -0
- package/dist/translations/languages/my.js.map +1 -0
- package/dist/translations/languages/nb.d.ts +89 -0
- package/dist/translations/languages/nb.d.ts.map +1 -0
- package/dist/translations/languages/nb.js +92 -0
- package/dist/translations/languages/nb.js.map +1 -0
- package/dist/translations/languages/nl.d.ts +89 -0
- package/dist/translations/languages/nl.d.ts.map +1 -0
- package/dist/translations/languages/nl.js +92 -0
- package/dist/translations/languages/nl.js.map +1 -0
- package/dist/translations/languages/pl.d.ts +89 -0
- package/dist/translations/languages/pl.d.ts.map +1 -0
- package/dist/translations/languages/pl.js +92 -0
- package/dist/translations/languages/pl.js.map +1 -0
- package/dist/translations/languages/pt.d.ts +89 -0
- package/dist/translations/languages/pt.d.ts.map +1 -0
- package/dist/translations/languages/pt.js +92 -0
- package/dist/translations/languages/pt.js.map +1 -0
- package/dist/translations/languages/ro.d.ts +89 -0
- package/dist/translations/languages/ro.d.ts.map +1 -0
- package/dist/translations/languages/ro.js +92 -0
- package/dist/translations/languages/ro.js.map +1 -0
- package/dist/translations/languages/rs.d.ts +89 -0
- package/dist/translations/languages/rs.d.ts.map +1 -0
- package/dist/translations/languages/rs.js +92 -0
- package/dist/translations/languages/rs.js.map +1 -0
- package/dist/translations/languages/rsLatin.d.ts +89 -0
- package/dist/translations/languages/rsLatin.d.ts.map +1 -0
- package/dist/translations/languages/rsLatin.js +92 -0
- package/dist/translations/languages/rsLatin.js.map +1 -0
- package/dist/translations/languages/ru.d.ts +89 -0
- package/dist/translations/languages/ru.d.ts.map +1 -0
- package/dist/translations/languages/ru.js +92 -0
- package/dist/translations/languages/ru.js.map +1 -0
- package/dist/translations/languages/sk.d.ts +89 -0
- package/dist/translations/languages/sk.d.ts.map +1 -0
- package/dist/translations/languages/sk.js +92 -0
- package/dist/translations/languages/sk.js.map +1 -0
- package/dist/translations/languages/sl.d.ts +89 -0
- package/dist/translations/languages/sl.d.ts.map +1 -0
- package/dist/translations/languages/sl.js +92 -0
- package/dist/translations/languages/sl.js.map +1 -0
- package/dist/translations/languages/sv.d.ts +89 -0
- package/dist/translations/languages/sv.d.ts.map +1 -0
- package/dist/translations/languages/sv.js +92 -0
- package/dist/translations/languages/sv.js.map +1 -0
- package/dist/translations/languages/ta.d.ts +89 -0
- package/dist/translations/languages/ta.d.ts.map +1 -0
- package/dist/translations/languages/ta.js +92 -0
- package/dist/translations/languages/ta.js.map +1 -0
- package/dist/translations/languages/th.d.ts +89 -0
- package/dist/translations/languages/th.d.ts.map +1 -0
- package/dist/translations/languages/th.js +92 -0
- package/dist/translations/languages/th.js.map +1 -0
- package/dist/translations/languages/tr.d.ts +89 -0
- package/dist/translations/languages/tr.d.ts.map +1 -0
- package/dist/translations/languages/tr.js +92 -0
- package/dist/translations/languages/tr.js.map +1 -0
- package/dist/translations/languages/uk.d.ts +89 -0
- package/dist/translations/languages/uk.d.ts.map +1 -0
- package/dist/translations/languages/uk.js +92 -0
- package/dist/translations/languages/uk.js.map +1 -0
- package/dist/translations/languages/vi.d.ts +89 -0
- package/dist/translations/languages/vi.d.ts.map +1 -0
- package/dist/translations/languages/vi.js +92 -0
- package/dist/translations/languages/vi.js.map +1 -0
- package/dist/translations/languages/zh.d.ts +89 -0
- package/dist/translations/languages/zh.d.ts.map +1 -0
- package/dist/translations/languages/zh.js +92 -0
- package/dist/translations/languages/zh.js.map +1 -0
- package/dist/translations/languages/zhTw.d.ts +89 -0
- package/dist/translations/languages/zhTw.d.ts.map +1 -0
- package/dist/translations/languages/zhTw.js +92 -0
- package/dist/translations/languages/zhTw.js.map +1 -0
- package/dist/translations/translation-schema.json +313 -5
- package/dist/translations/types.d.ts +89 -0
- package/dist/translations/types.d.ts.map +1 -0
- package/dist/translations/types.js +3 -0
- package/dist/translations/types.js.map +1 -0
- package/dist/types/index.d.ts +154 -14
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/ui/VariantOptionsSelector/index.d.ts.map +1 -1
- package/dist/ui/VariantOptionsSelector/index.js +6 -3
- package/dist/ui/VariantOptionsSelector/index.js.map +1 -1
- package/package.json +16 -10
|
@@ -2,10 +2,19 @@
|
|
|
2
2
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
3
|
import { deepMergeSimple, formatAdminURL } from 'payload/shared';
|
|
4
4
|
import * as qs from 'qs-esm';
|
|
5
|
-
import React, { createContext, use, useCallback, useEffect, useMemo, useRef, useState
|
|
5
|
+
import React, { createContext, use, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
6
6
|
const defaultContext = {
|
|
7
7
|
addItem: async ()=>{},
|
|
8
8
|
clearCart: async ()=>{},
|
|
9
|
+
clearSession: ()=>{},
|
|
10
|
+
config: {
|
|
11
|
+
addressesSlug: 'addresses',
|
|
12
|
+
api: {
|
|
13
|
+
apiRoute: '/api'
|
|
14
|
+
},
|
|
15
|
+
cartsSlug: 'carts',
|
|
16
|
+
customersSlug: 'users'
|
|
17
|
+
},
|
|
9
18
|
confirmOrder: async ()=>{},
|
|
10
19
|
createAddress: async ()=>{},
|
|
11
20
|
currenciesConfig: {
|
|
@@ -29,11 +38,15 @@ const defaultContext = {
|
|
|
29
38
|
incrementItem: async ()=>{},
|
|
30
39
|
initiatePayment: async ()=>{},
|
|
31
40
|
isLoading: false,
|
|
41
|
+
mergeCart: async ()=>{},
|
|
42
|
+
onLogin: async ()=>{},
|
|
43
|
+
onLogout: ()=>{},
|
|
32
44
|
paymentMethods: [],
|
|
33
45
|
refreshCart: async ()=>{},
|
|
34
46
|
removeItem: async ()=>{},
|
|
35
47
|
setCurrency: ()=>{},
|
|
36
|
-
updateAddress: async ()=>{}
|
|
48
|
+
updateAddress: async ()=>{},
|
|
49
|
+
user: null
|
|
37
50
|
};
|
|
38
51
|
const EcommerceContext = /*#__PURE__*/ createContext(defaultContext);
|
|
39
52
|
const defaultLocalStorage = {
|
|
@@ -59,7 +72,20 @@ export const EcommerceProvider = ({ addressesSlug = 'addresses', api, cartsSlug
|
|
|
59
72
|
apiRoute,
|
|
60
73
|
path: ''
|
|
61
74
|
});
|
|
62
|
-
const
|
|
75
|
+
const config = useMemo(()=>({
|
|
76
|
+
addressesSlug,
|
|
77
|
+
api: {
|
|
78
|
+
apiRoute
|
|
79
|
+
},
|
|
80
|
+
cartsSlug,
|
|
81
|
+
customersSlug
|
|
82
|
+
}), [
|
|
83
|
+
addressesSlug,
|
|
84
|
+
apiRoute,
|
|
85
|
+
cartsSlug,
|
|
86
|
+
customersSlug
|
|
87
|
+
]);
|
|
88
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
63
89
|
const [user, setUser] = useState(null);
|
|
64
90
|
const [addresses, setAddresses] = useState();
|
|
65
91
|
const hasRendered = useRef(false);
|
|
@@ -133,15 +159,12 @@ export const EcommerceProvider = ({ addressesSlug = 'addresses', api, cartsSlug
|
|
|
133
159
|
user
|
|
134
160
|
]);
|
|
135
161
|
const getCart = useCallback(async (cartID, options)=>{
|
|
136
|
-
const
|
|
137
|
-
// Build query params with secret if provided
|
|
138
|
-
const queryParams = {
|
|
162
|
+
const query = qs.stringify({
|
|
139
163
|
...cartQuery,
|
|
140
|
-
...secret ? {
|
|
141
|
-
secret
|
|
164
|
+
...options?.secret ? {
|
|
165
|
+
secret: options.secret
|
|
142
166
|
} : {}
|
|
143
|
-
};
|
|
144
|
-
const query = qs.stringify(queryParams);
|
|
167
|
+
});
|
|
145
168
|
const response = await fetch(`${baseAPIURL}/${cartsSlug}/${cartID}?${query}`, {
|
|
146
169
|
credentials: 'include',
|
|
147
170
|
headers: {
|
|
@@ -163,35 +186,6 @@ export const EcommerceProvider = ({ addressesSlug = 'addresses', api, cartsSlug
|
|
|
163
186
|
cartQuery,
|
|
164
187
|
cartsSlug
|
|
165
188
|
]);
|
|
166
|
-
const updateCart = useCallback(async (cartID, data)=>{
|
|
167
|
-
// Build query params with secret if provided
|
|
168
|
-
const queryParams = {
|
|
169
|
-
...cartQuery,
|
|
170
|
-
...cartSecret ? {
|
|
171
|
-
secret: cartSecret
|
|
172
|
-
} : {}
|
|
173
|
-
};
|
|
174
|
-
const query = qs.stringify(queryParams);
|
|
175
|
-
const response = await fetch(`${baseAPIURL}/${cartsSlug}/${cartID}?${query}`, {
|
|
176
|
-
body: JSON.stringify(data),
|
|
177
|
-
credentials: 'include',
|
|
178
|
-
headers: {
|
|
179
|
-
'Content-Type': 'application/json'
|
|
180
|
-
},
|
|
181
|
-
method: 'PATCH'
|
|
182
|
-
});
|
|
183
|
-
if (!response.ok) {
|
|
184
|
-
const errorText = await response.text();
|
|
185
|
-
throw new Error(`Failed to update cart: ${errorText}`);
|
|
186
|
-
}
|
|
187
|
-
const updatedCart = await response.json();
|
|
188
|
-
setCart(updatedCart.doc);
|
|
189
|
-
}, [
|
|
190
|
-
baseAPIURL,
|
|
191
|
-
cartQuery,
|
|
192
|
-
cartsSlug,
|
|
193
|
-
cartSecret
|
|
194
|
-
]);
|
|
195
189
|
const refreshCart = useCallback(async ()=>{
|
|
196
190
|
if (!cartID) {
|
|
197
191
|
return;
|
|
@@ -202,32 +196,6 @@ export const EcommerceProvider = ({ addressesSlug = 'addresses', api, cartsSlug
|
|
|
202
196
|
cartID,
|
|
203
197
|
getCart
|
|
204
198
|
]);
|
|
205
|
-
const deleteCart = useCallback(async (cartID)=>{
|
|
206
|
-
// Build query params with secret if provided
|
|
207
|
-
const queryParams = cartSecret ? {
|
|
208
|
-
secret: cartSecret
|
|
209
|
-
} : {};
|
|
210
|
-
const query = qs.stringify(queryParams);
|
|
211
|
-
const url = `${baseAPIURL}/${cartsSlug}/${cartID}${query ? `?${query}` : ''}`;
|
|
212
|
-
const response = await fetch(url, {
|
|
213
|
-
credentials: 'include',
|
|
214
|
-
headers: {
|
|
215
|
-
'Content-Type': 'application/json'
|
|
216
|
-
},
|
|
217
|
-
method: 'DELETE'
|
|
218
|
-
});
|
|
219
|
-
if (!response.ok) {
|
|
220
|
-
const errorText = await response.text();
|
|
221
|
-
throw new Error(`Failed to delete cart: ${errorText}`);
|
|
222
|
-
}
|
|
223
|
-
setCart(undefined);
|
|
224
|
-
setCartID(undefined);
|
|
225
|
-
setCartSecret(undefined);
|
|
226
|
-
}, [
|
|
227
|
-
baseAPIURL,
|
|
228
|
-
cartsSlug,
|
|
229
|
-
cartSecret
|
|
230
|
-
]);
|
|
231
199
|
// Persist cart ID and secret to localStorage
|
|
232
200
|
useEffect(()=>{
|
|
233
201
|
if (hasRendered.current) {
|
|
@@ -251,222 +219,273 @@ export const EcommerceProvider = ({ addressesSlug = 'addresses', api, cartsSlug
|
|
|
251
219
|
syncLocalStorage
|
|
252
220
|
]);
|
|
253
221
|
const addItem = useCallback(async (item, quantity = 1)=>{
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
222
|
+
setIsLoading(true);
|
|
223
|
+
try {
|
|
224
|
+
if (cartID) {
|
|
225
|
+
// Use server-side endpoint for adding items
|
|
226
|
+
const response = await fetch(`${baseAPIURL}/${cartsSlug}/${cartID}/add-item`, {
|
|
227
|
+
body: JSON.stringify({
|
|
228
|
+
item,
|
|
229
|
+
quantity,
|
|
258
230
|
secret: cartSecret
|
|
259
|
-
})
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
const
|
|
268
|
-
|
|
269
|
-
const variantID = cartItem.variant && typeof cartItem.variant === 'object' ? cartItem.variant.id : item.variant;
|
|
270
|
-
return productID === item.product && (item.variant && variantID ? variantID === item.variant : true);
|
|
271
|
-
}) ?? -1;
|
|
272
|
-
let updatedItems = existingCart.items ? [
|
|
273
|
-
...existingCart.items
|
|
274
|
-
] : [];
|
|
275
|
-
if (existingItemIndex !== -1) {
|
|
276
|
-
// If the item exists, update its quantity
|
|
277
|
-
updatedItems[existingItemIndex].quantity = updatedItems[existingItemIndex].quantity + quantity;
|
|
278
|
-
// Update the cart with the new items
|
|
279
|
-
await updateCart(cartID, {
|
|
280
|
-
items: updatedItems
|
|
281
|
-
});
|
|
282
|
-
} else {
|
|
283
|
-
// If the item does not exist, add it to the cart
|
|
284
|
-
updatedItems = [
|
|
285
|
-
...existingCart.items ?? [],
|
|
286
|
-
{
|
|
287
|
-
...item,
|
|
288
|
-
quantity
|
|
289
|
-
}
|
|
290
|
-
];
|
|
291
|
-
}
|
|
292
|
-
// Update the cart with the new items
|
|
293
|
-
await updateCart(cartID, {
|
|
294
|
-
items: updatedItems
|
|
295
|
-
});
|
|
296
|
-
} else {
|
|
297
|
-
// If no cartID exists, create a new cart
|
|
298
|
-
const newCart = await createCart({
|
|
299
|
-
items: [
|
|
300
|
-
{
|
|
301
|
-
...item,
|
|
302
|
-
quantity
|
|
303
|
-
}
|
|
304
|
-
]
|
|
305
|
-
});
|
|
306
|
-
setCartID(newCart.id);
|
|
307
|
-
setCart(newCart);
|
|
231
|
+
}),
|
|
232
|
+
credentials: 'include',
|
|
233
|
+
headers: {
|
|
234
|
+
'Content-Type': 'application/json'
|
|
235
|
+
},
|
|
236
|
+
method: 'POST'
|
|
237
|
+
});
|
|
238
|
+
if (!response.ok) {
|
|
239
|
+
const errorText = await response.text();
|
|
240
|
+
throw new Error(`Failed to add item: ${errorText}`);
|
|
308
241
|
}
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
242
|
+
const result = await response.json();
|
|
243
|
+
if (!result.success) {
|
|
244
|
+
// Cart not found - reset state
|
|
245
|
+
setCartID(undefined);
|
|
246
|
+
setCart(undefined);
|
|
247
|
+
setCartSecret(undefined);
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
// Refresh cart with proper depth/populate settings for UI
|
|
251
|
+
const refreshedCart = await getCart(cartID, {
|
|
252
|
+
secret: cartSecret
|
|
253
|
+
});
|
|
254
|
+
setCart(refreshedCart);
|
|
255
|
+
} else {
|
|
256
|
+
// If no cartID exists, create a new cart with the item
|
|
257
|
+
const newCart = await createCart({
|
|
258
|
+
items: [
|
|
259
|
+
{
|
|
260
|
+
...item,
|
|
261
|
+
quantity
|
|
262
|
+
}
|
|
263
|
+
]
|
|
264
|
+
});
|
|
265
|
+
setCartID(newCart.id);
|
|
266
|
+
setCart(newCart);
|
|
267
|
+
}
|
|
268
|
+
} catch (error) {
|
|
269
|
+
if (debug) {
|
|
270
|
+
// eslint-disable-next-line no-console
|
|
271
|
+
console.error('Error adding item to cart:', error);
|
|
272
|
+
}
|
|
273
|
+
} finally{
|
|
274
|
+
setIsLoading(false);
|
|
275
|
+
}
|
|
312
276
|
}, [
|
|
277
|
+
baseAPIURL,
|
|
313
278
|
cartID,
|
|
314
279
|
cartSecret,
|
|
280
|
+
cartsSlug,
|
|
315
281
|
createCart,
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
updateCart
|
|
282
|
+
debug,
|
|
283
|
+
getCart
|
|
319
284
|
]);
|
|
320
285
|
const removeItem = useCallback(async (targetID)=>{
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
286
|
+
if (!cartID) {
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
setIsLoading(true);
|
|
290
|
+
try {
|
|
291
|
+
const response = await fetch(`${baseAPIURL}/${cartsSlug}/${cartID}/remove-item`, {
|
|
292
|
+
body: JSON.stringify({
|
|
293
|
+
itemID: targetID,
|
|
328
294
|
secret: cartSecret
|
|
329
|
-
})
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
return;
|
|
336
|
-
}
|
|
337
|
-
// Check if the item already exists in the cart
|
|
338
|
-
const existingItemIndex = existingCart.items?.findIndex((cartItem)=>cartItem.id === targetID) ?? -1;
|
|
339
|
-
if (existingItemIndex !== -1) {
|
|
340
|
-
// If the item exists, remove it from the cart
|
|
341
|
-
const updatedItems = existingCart.items ? [
|
|
342
|
-
...existingCart.items
|
|
343
|
-
] : [];
|
|
344
|
-
updatedItems.splice(existingItemIndex, 1);
|
|
345
|
-
// Update the cart with the new items
|
|
346
|
-
await updateCart(cartID, {
|
|
347
|
-
items: updatedItems
|
|
348
|
-
});
|
|
349
|
-
}
|
|
350
|
-
resolve();
|
|
295
|
+
}),
|
|
296
|
+
credentials: 'include',
|
|
297
|
+
headers: {
|
|
298
|
+
'Content-Type': 'application/json'
|
|
299
|
+
},
|
|
300
|
+
method: 'POST'
|
|
351
301
|
});
|
|
352
|
-
|
|
302
|
+
if (!response.ok) {
|
|
303
|
+
const errorText = await response.text();
|
|
304
|
+
throw new Error(`Failed to remove item: ${errorText}`);
|
|
305
|
+
}
|
|
306
|
+
const result = await response.json();
|
|
307
|
+
if (!result.success) {
|
|
308
|
+
// Cart not found - reset state
|
|
309
|
+
setCartID(undefined);
|
|
310
|
+
setCart(undefined);
|
|
311
|
+
setCartSecret(undefined);
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
// Refresh cart with proper depth/populate settings for UI
|
|
315
|
+
const refreshedCart = await getCart(cartID, {
|
|
316
|
+
secret: cartSecret
|
|
317
|
+
});
|
|
318
|
+
setCart(refreshedCart);
|
|
319
|
+
} catch (error) {
|
|
320
|
+
if (debug) {
|
|
321
|
+
// eslint-disable-next-line no-console
|
|
322
|
+
console.error('Error removing item from cart:', error);
|
|
323
|
+
}
|
|
324
|
+
} finally{
|
|
325
|
+
setIsLoading(false);
|
|
326
|
+
}
|
|
353
327
|
}, [
|
|
328
|
+
baseAPIURL,
|
|
354
329
|
cartID,
|
|
355
330
|
cartSecret,
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
331
|
+
cartsSlug,
|
|
332
|
+
debug,
|
|
333
|
+
getCart
|
|
359
334
|
]);
|
|
360
335
|
const incrementItem = useCallback(async (targetID)=>{
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
336
|
+
if (!cartID) {
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
setIsLoading(true);
|
|
340
|
+
try {
|
|
341
|
+
const response = await fetch(`${baseAPIURL}/${cartsSlug}/${cartID}/update-item`, {
|
|
342
|
+
body: JSON.stringify({
|
|
343
|
+
itemID: targetID,
|
|
344
|
+
quantity: {
|
|
345
|
+
$inc: 1
|
|
346
|
+
},
|
|
368
347
|
secret: cartSecret
|
|
369
|
-
})
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
return;
|
|
376
|
-
}
|
|
377
|
-
// Check if the item already exists in the cart
|
|
378
|
-
const existingItemIndex = existingCart.items?.findIndex((cartItem)=>cartItem.id === targetID) ?? -1;
|
|
379
|
-
let updatedItems = existingCart.items ? [
|
|
380
|
-
...existingCart.items
|
|
381
|
-
] : [];
|
|
382
|
-
if (existingItemIndex !== -1) {
|
|
383
|
-
// If the item exists, increment its quantity
|
|
384
|
-
updatedItems[existingItemIndex].quantity = updatedItems[existingItemIndex].quantity + 1; // Increment by 1
|
|
385
|
-
// Update the cart with the new items
|
|
386
|
-
await updateCart(cartID, {
|
|
387
|
-
items: updatedItems
|
|
388
|
-
});
|
|
389
|
-
} else {
|
|
390
|
-
// If the item does not exist, add it to the cart with quantity 1
|
|
391
|
-
updatedItems = [
|
|
392
|
-
...existingCart.items ?? [],
|
|
393
|
-
{
|
|
394
|
-
product: targetID,
|
|
395
|
-
quantity: 1
|
|
396
|
-
}
|
|
397
|
-
];
|
|
398
|
-
// Update the cart with the new items
|
|
399
|
-
await updateCart(cartID, {
|
|
400
|
-
items: updatedItems
|
|
401
|
-
});
|
|
402
|
-
}
|
|
403
|
-
resolve();
|
|
348
|
+
}),
|
|
349
|
+
credentials: 'include',
|
|
350
|
+
headers: {
|
|
351
|
+
'Content-Type': 'application/json'
|
|
352
|
+
},
|
|
353
|
+
method: 'POST'
|
|
404
354
|
});
|
|
405
|
-
|
|
355
|
+
if (!response.ok) {
|
|
356
|
+
const errorText = await response.text();
|
|
357
|
+
throw new Error(`Failed to increment item: ${errorText}`);
|
|
358
|
+
}
|
|
359
|
+
const result = await response.json();
|
|
360
|
+
if (!result.success) {
|
|
361
|
+
// Cart not found - reset state
|
|
362
|
+
setCartID(undefined);
|
|
363
|
+
setCart(undefined);
|
|
364
|
+
setCartSecret(undefined);
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
// Refresh cart with proper depth/populate settings for UI
|
|
368
|
+
const refreshedCart = await getCart(cartID, {
|
|
369
|
+
secret: cartSecret
|
|
370
|
+
});
|
|
371
|
+
setCart(refreshedCart);
|
|
372
|
+
} catch (error) {
|
|
373
|
+
if (debug) {
|
|
374
|
+
// eslint-disable-next-line no-console
|
|
375
|
+
console.error('Error incrementing item quantity:', error);
|
|
376
|
+
}
|
|
377
|
+
} finally{
|
|
378
|
+
setIsLoading(false);
|
|
379
|
+
}
|
|
406
380
|
}, [
|
|
381
|
+
baseAPIURL,
|
|
407
382
|
cartID,
|
|
408
383
|
cartSecret,
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
384
|
+
cartsSlug,
|
|
385
|
+
debug,
|
|
386
|
+
getCart
|
|
412
387
|
]);
|
|
413
388
|
const decrementItem = useCallback(async (targetID)=>{
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
389
|
+
if (!cartID) {
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
setIsLoading(true);
|
|
393
|
+
try {
|
|
394
|
+
const response = await fetch(`${baseAPIURL}/${cartsSlug}/${cartID}/update-item`, {
|
|
395
|
+
body: JSON.stringify({
|
|
396
|
+
itemID: targetID,
|
|
397
|
+
quantity: {
|
|
398
|
+
$inc: -1
|
|
399
|
+
},
|
|
421
400
|
secret: cartSecret
|
|
422
|
-
})
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
return;
|
|
429
|
-
}
|
|
430
|
-
// Check if the item already exists in the cart
|
|
431
|
-
const existingItemIndex = existingCart.items?.findIndex((cartItem)=>cartItem.id === targetID) ?? -1;
|
|
432
|
-
const updatedItems = existingCart.items ? [
|
|
433
|
-
...existingCart.items
|
|
434
|
-
] : [];
|
|
435
|
-
if (existingItemIndex !== -1) {
|
|
436
|
-
// If the item exists, decrement its quantity
|
|
437
|
-
updatedItems[existingItemIndex].quantity = updatedItems[existingItemIndex].quantity - 1; // Decrement by 1
|
|
438
|
-
// If the quantity reaches 0, remove the item from the cart
|
|
439
|
-
if (updatedItems[existingItemIndex].quantity <= 0) {
|
|
440
|
-
updatedItems.splice(existingItemIndex, 1);
|
|
441
|
-
}
|
|
442
|
-
// Update the cart with the new items
|
|
443
|
-
await updateCart(cartID, {
|
|
444
|
-
items: updatedItems
|
|
445
|
-
});
|
|
446
|
-
}
|
|
447
|
-
resolve();
|
|
401
|
+
}),
|
|
402
|
+
credentials: 'include',
|
|
403
|
+
headers: {
|
|
404
|
+
'Content-Type': 'application/json'
|
|
405
|
+
},
|
|
406
|
+
method: 'POST'
|
|
448
407
|
});
|
|
449
|
-
|
|
408
|
+
if (!response.ok) {
|
|
409
|
+
const errorText = await response.text();
|
|
410
|
+
throw new Error(`Failed to decrement item: ${errorText}`);
|
|
411
|
+
}
|
|
412
|
+
const result = await response.json();
|
|
413
|
+
if (!result.success) {
|
|
414
|
+
// Cart not found - reset state
|
|
415
|
+
setCartID(undefined);
|
|
416
|
+
setCart(undefined);
|
|
417
|
+
setCartSecret(undefined);
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
// Refresh cart with proper depth/populate settings for UI
|
|
421
|
+
const refreshedCart = await getCart(cartID, {
|
|
422
|
+
secret: cartSecret
|
|
423
|
+
});
|
|
424
|
+
setCart(refreshedCart);
|
|
425
|
+
} catch (error) {
|
|
426
|
+
if (debug) {
|
|
427
|
+
// eslint-disable-next-line no-console
|
|
428
|
+
console.error('Error decrementing item quantity:', error);
|
|
429
|
+
}
|
|
430
|
+
} finally{
|
|
431
|
+
setIsLoading(false);
|
|
432
|
+
}
|
|
450
433
|
}, [
|
|
434
|
+
baseAPIURL,
|
|
451
435
|
cartID,
|
|
452
436
|
cartSecret,
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
437
|
+
cartsSlug,
|
|
438
|
+
debug,
|
|
439
|
+
getCart
|
|
456
440
|
]);
|
|
457
441
|
const clearCart = useCallback(async ()=>{
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
442
|
+
if (!cartID) {
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
setIsLoading(true);
|
|
446
|
+
try {
|
|
447
|
+
const response = await fetch(`${baseAPIURL}/${cartsSlug}/${cartID}/clear`, {
|
|
448
|
+
body: JSON.stringify({
|
|
449
|
+
secret: cartSecret
|
|
450
|
+
}),
|
|
451
|
+
credentials: 'include',
|
|
452
|
+
headers: {
|
|
453
|
+
'Content-Type': 'application/json'
|
|
454
|
+
},
|
|
455
|
+
method: 'POST'
|
|
464
456
|
});
|
|
465
|
-
|
|
457
|
+
if (!response.ok) {
|
|
458
|
+
const errorText = await response.text();
|
|
459
|
+
throw new Error(`Failed to clear cart: ${errorText}`);
|
|
460
|
+
}
|
|
461
|
+
const result = await response.json();
|
|
462
|
+
if (!result.success) {
|
|
463
|
+
// Cart not found - reset state
|
|
464
|
+
setCartID(undefined);
|
|
465
|
+
setCart(undefined);
|
|
466
|
+
setCartSecret(undefined);
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
// Refresh cart with proper depth/populate settings for UI
|
|
470
|
+
const refreshedCart = await getCart(cartID, {
|
|
471
|
+
secret: cartSecret
|
|
472
|
+
});
|
|
473
|
+
setCart(refreshedCart);
|
|
474
|
+
} catch (error) {
|
|
475
|
+
if (debug) {
|
|
476
|
+
// eslint-disable-next-line no-console
|
|
477
|
+
console.error('Error clearing cart:', error);
|
|
478
|
+
}
|
|
479
|
+
} finally{
|
|
480
|
+
setIsLoading(false);
|
|
481
|
+
}
|
|
466
482
|
}, [
|
|
483
|
+
baseAPIURL,
|
|
467
484
|
cartID,
|
|
468
|
-
|
|
469
|
-
|
|
485
|
+
cartSecret,
|
|
486
|
+
cartsSlug,
|
|
487
|
+
debug,
|
|
488
|
+
getCart
|
|
470
489
|
]);
|
|
471
490
|
const setCurrency = useCallback((currency)=>{
|
|
472
491
|
if (selectedCurrency.code === currency) {
|
|
@@ -491,15 +510,12 @@ export const EcommerceProvider = ({ addressesSlug = 'addresses', api, cartsSlug
|
|
|
491
510
|
}
|
|
492
511
|
setSelectedPaymentMethod(paymentMethodID);
|
|
493
512
|
if (paymentMethod.initiatePayment) {
|
|
494
|
-
const fetchURL = `${baseAPIURL}/payments/${paymentMethodID}/initiate`;
|
|
495
|
-
const data = {
|
|
496
|
-
cartID,
|
|
497
|
-
currency: selectedCurrency.code
|
|
498
|
-
};
|
|
499
513
|
try {
|
|
500
|
-
const response = await fetch(
|
|
514
|
+
const response = await fetch(`${baseAPIURL}/payments/${paymentMethodID}/initiate`, {
|
|
501
515
|
body: JSON.stringify({
|
|
502
|
-
|
|
516
|
+
cartID,
|
|
517
|
+
currency: selectedCurrency.code,
|
|
518
|
+
secret: cartSecret,
|
|
503
519
|
...options?.additionalData || {}
|
|
504
520
|
}),
|
|
505
521
|
credentials: 'include',
|
|
@@ -530,6 +546,7 @@ export const EcommerceProvider = ({ addressesSlug = 'addresses', api, cartsSlug
|
|
|
530
546
|
}, [
|
|
531
547
|
baseAPIURL,
|
|
532
548
|
cartID,
|
|
549
|
+
cartSecret,
|
|
533
550
|
debug,
|
|
534
551
|
paymentMethods,
|
|
535
552
|
selectedCurrency.code
|
|
@@ -543,14 +560,11 @@ export const EcommerceProvider = ({ addressesSlug = 'addresses', api, cartsSlug
|
|
|
543
560
|
throw new Error(`Payment method with ID "${paymentMethodID}" not found`);
|
|
544
561
|
}
|
|
545
562
|
if (paymentMethod.confirmOrder) {
|
|
546
|
-
const
|
|
547
|
-
const data = {
|
|
548
|
-
cartID,
|
|
549
|
-
currency: selectedCurrency.code
|
|
550
|
-
};
|
|
551
|
-
const response = await fetch(fetchURL, {
|
|
563
|
+
const response = await fetch(`${baseAPIURL}/payments/${paymentMethodID}/confirm-order`, {
|
|
552
564
|
body: JSON.stringify({
|
|
553
|
-
|
|
565
|
+
cartID,
|
|
566
|
+
currency: selectedCurrency.code,
|
|
567
|
+
secret: cartSecret,
|
|
554
568
|
...options?.additionalData || {}
|
|
555
569
|
}),
|
|
556
570
|
credentials: 'include',
|
|
@@ -574,6 +588,7 @@ export const EcommerceProvider = ({ addressesSlug = 'addresses', api, cartsSlug
|
|
|
574
588
|
}, [
|
|
575
589
|
baseAPIURL,
|
|
576
590
|
cartID,
|
|
591
|
+
cartSecret,
|
|
577
592
|
paymentMethods,
|
|
578
593
|
selectedCurrency.code
|
|
579
594
|
]);
|
|
@@ -583,7 +598,7 @@ export const EcommerceProvider = ({ addressesSlug = 'addresses', api, cartsSlug
|
|
|
583
598
|
depth: 0,
|
|
584
599
|
select: {
|
|
585
600
|
id: true,
|
|
586
|
-
|
|
601
|
+
cart: true
|
|
587
602
|
}
|
|
588
603
|
});
|
|
589
604
|
const response = await fetch(`${baseAPIURL}/${customersSlug}/me?${query}`, {
|
|
@@ -734,6 +749,165 @@ export const EcommerceProvider = ({ addressesSlug = 'addresses', api, cartsSlug
|
|
|
734
749
|
getAddresses,
|
|
735
750
|
debug
|
|
736
751
|
]);
|
|
752
|
+
/**
|
|
753
|
+
* Clears all ecommerce session data from state and localStorage.
|
|
754
|
+
* Used during logout to ensure no user data persists.
|
|
755
|
+
*/ const clearSession = useCallback(()=>{
|
|
756
|
+
setCart(undefined);
|
|
757
|
+
setCartID(undefined);
|
|
758
|
+
setCartSecret(undefined);
|
|
759
|
+
setAddresses(undefined);
|
|
760
|
+
setUser(null);
|
|
761
|
+
if (syncLocalStorage) {
|
|
762
|
+
localStorage.removeItem(localStorageConfig.key);
|
|
763
|
+
localStorage.removeItem(`${localStorageConfig.key}_secret`);
|
|
764
|
+
}
|
|
765
|
+
}, [
|
|
766
|
+
localStorageConfig.key,
|
|
767
|
+
syncLocalStorage
|
|
768
|
+
]);
|
|
769
|
+
/**
|
|
770
|
+
* Called during logout. Clears all session data.
|
|
771
|
+
*/ const onLogout = useCallback(()=>{
|
|
772
|
+
clearSession();
|
|
773
|
+
}, [
|
|
774
|
+
clearSession
|
|
775
|
+
]);
|
|
776
|
+
/**
|
|
777
|
+
* Merges items from a source cart into a target cart.
|
|
778
|
+
* Useful for merging a guest cart into a user's existing cart after login.
|
|
779
|
+
*
|
|
780
|
+
* @param targetCartID - The ID of the cart to merge items into
|
|
781
|
+
* @param sourceCartID - The ID of the cart to merge items from
|
|
782
|
+
* @param sourceSecret - The secret for the source cart (required for guest carts)
|
|
783
|
+
* @returns The merged cart
|
|
784
|
+
*/ const mergeCart = useCallback(async (targetCartID, sourceCartID, sourceSecret)=>{
|
|
785
|
+
setIsLoading(true);
|
|
786
|
+
try {
|
|
787
|
+
const response = await fetch(`${baseAPIURL}/${cartsSlug}/${targetCartID}/merge`, {
|
|
788
|
+
body: JSON.stringify({
|
|
789
|
+
sourceCartID,
|
|
790
|
+
sourceSecret
|
|
791
|
+
}),
|
|
792
|
+
credentials: 'include',
|
|
793
|
+
headers: {
|
|
794
|
+
'Content-Type': 'application/json'
|
|
795
|
+
},
|
|
796
|
+
method: 'POST'
|
|
797
|
+
});
|
|
798
|
+
if (!response.ok) {
|
|
799
|
+
const errorText = await response.text();
|
|
800
|
+
throw new Error(`Failed to merge carts: ${errorText}`);
|
|
801
|
+
}
|
|
802
|
+
const result = await response.json();
|
|
803
|
+
if (!result.success) {
|
|
804
|
+
throw new Error(result.message || 'Failed to merge carts');
|
|
805
|
+
}
|
|
806
|
+
// Refresh cart with proper depth/populate settings for UI
|
|
807
|
+
const refreshedCart = await getCart(targetCartID);
|
|
808
|
+
setCart(refreshedCart);
|
|
809
|
+
setCartID(targetCartID);
|
|
810
|
+
return refreshedCart;
|
|
811
|
+
} catch (error) {
|
|
812
|
+
if (debug) {
|
|
813
|
+
// eslint-disable-next-line no-console
|
|
814
|
+
console.error('Error merging carts:', error);
|
|
815
|
+
}
|
|
816
|
+
throw error;
|
|
817
|
+
} finally{
|
|
818
|
+
setIsLoading(false);
|
|
819
|
+
}
|
|
820
|
+
}, [
|
|
821
|
+
baseAPIURL,
|
|
822
|
+
cartsSlug,
|
|
823
|
+
debug,
|
|
824
|
+
getCart
|
|
825
|
+
]);
|
|
826
|
+
/**
|
|
827
|
+
* Called after login to properly set up cart state.
|
|
828
|
+
* Handles merging guest cart with user's existing cart if applicable.
|
|
829
|
+
*/ const onLogin = useCallback(async ()=>{
|
|
830
|
+
// Store reference to any existing guest cart before fetching user
|
|
831
|
+
const guestCartID = cartID;
|
|
832
|
+
const guestSecret = cartSecret;
|
|
833
|
+
// Fetch fresh user data
|
|
834
|
+
const fetchedUser = await getUser();
|
|
835
|
+
if (!fetchedUser) {
|
|
836
|
+
// No user means login failed, keep current state
|
|
837
|
+
return;
|
|
838
|
+
}
|
|
839
|
+
// Clear the guest cart secret - authenticated users don't need it
|
|
840
|
+
setCartSecret(undefined);
|
|
841
|
+
if (syncLocalStorage) {
|
|
842
|
+
localStorage.removeItem(`${localStorageConfig.key}_secret`);
|
|
843
|
+
}
|
|
844
|
+
// Check if user has an existing cart
|
|
845
|
+
const userCartID = fetchedUser.cart?.docs && fetchedUser.cart.docs.length > 0 ? typeof fetchedUser.cart.docs[0] === 'object' ? fetchedUser.cart.docs[0].id : fetchedUser.cart.docs[0] : undefined;
|
|
846
|
+
if (guestCartID && guestSecret) {
|
|
847
|
+
// Guest had a cart - need to handle merge/transfer
|
|
848
|
+
if (userCartID) {
|
|
849
|
+
// User has existing cart - merge guest cart into user's cart
|
|
850
|
+
try {
|
|
851
|
+
await mergeCart(userCartID, guestCartID, guestSecret);
|
|
852
|
+
} catch (error) {
|
|
853
|
+
if (debug) {
|
|
854
|
+
// eslint-disable-next-line no-console
|
|
855
|
+
console.error('Error merging carts:', error);
|
|
856
|
+
}
|
|
857
|
+
// Fall back to user's cart
|
|
858
|
+
const userCart = await getCart(userCartID);
|
|
859
|
+
setCart(userCart);
|
|
860
|
+
setCartID(userCartID);
|
|
861
|
+
}
|
|
862
|
+
} else {
|
|
863
|
+
// User has no existing cart - transfer guest cart to user
|
|
864
|
+
try {
|
|
865
|
+
const response = await fetch(`${baseAPIURL}/${cartsSlug}/${guestCartID}?secret=${guestSecret}`, {
|
|
866
|
+
body: JSON.stringify({
|
|
867
|
+
customer: fetchedUser.id,
|
|
868
|
+
secret: null
|
|
869
|
+
}),
|
|
870
|
+
credentials: 'include',
|
|
871
|
+
headers: {
|
|
872
|
+
'Content-Type': 'application/json'
|
|
873
|
+
},
|
|
874
|
+
method: 'PATCH'
|
|
875
|
+
});
|
|
876
|
+
if (response.ok) {
|
|
877
|
+
// Fetch updated cart
|
|
878
|
+
const updatedCart = await getCart(guestCartID);
|
|
879
|
+
setCart(updatedCart);
|
|
880
|
+
setCartID(guestCartID);
|
|
881
|
+
}
|
|
882
|
+
} catch (error) {
|
|
883
|
+
if (debug) {
|
|
884
|
+
// eslint-disable-next-line no-console
|
|
885
|
+
console.error('Error transferring cart to user:', error);
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
} else if (userCartID) {
|
|
890
|
+
// No guest cart, but user has a cart - fetch it
|
|
891
|
+
const userCart = await getCart(userCartID);
|
|
892
|
+
setCart(userCart);
|
|
893
|
+
setCartID(userCartID);
|
|
894
|
+
}
|
|
895
|
+
// Update localStorage with user's cart ID (no secret needed)
|
|
896
|
+
if (syncLocalStorage && cartID) {
|
|
897
|
+
localStorage.setItem(localStorageConfig.key, cartID);
|
|
898
|
+
}
|
|
899
|
+
}, [
|
|
900
|
+
baseAPIURL,
|
|
901
|
+
cartID,
|
|
902
|
+
cartSecret,
|
|
903
|
+
cartsSlug,
|
|
904
|
+
debug,
|
|
905
|
+
getCart,
|
|
906
|
+
getUser,
|
|
907
|
+
localStorageConfig.key,
|
|
908
|
+
mergeCart,
|
|
909
|
+
syncLocalStorage
|
|
910
|
+
]);
|
|
737
911
|
// If localStorage is enabled, restore cart from storage
|
|
738
912
|
useEffect(()=>{
|
|
739
913
|
if (!hasRendered.current) {
|
|
@@ -808,6 +982,8 @@ export const EcommerceProvider = ({ addressesSlug = 'addresses', api, cartsSlug
|
|
|
808
982
|
addresses,
|
|
809
983
|
cart,
|
|
810
984
|
clearCart,
|
|
985
|
+
clearSession,
|
|
986
|
+
config,
|
|
811
987
|
confirmOrder,
|
|
812
988
|
createAddress,
|
|
813
989
|
currenciesConfig,
|
|
@@ -816,12 +992,16 @@ export const EcommerceProvider = ({ addressesSlug = 'addresses', api, cartsSlug
|
|
|
816
992
|
incrementItem,
|
|
817
993
|
initiatePayment,
|
|
818
994
|
isLoading,
|
|
995
|
+
mergeCart,
|
|
996
|
+
onLogin,
|
|
997
|
+
onLogout,
|
|
819
998
|
paymentMethods,
|
|
820
999
|
refreshCart,
|
|
821
1000
|
removeItem,
|
|
822
1001
|
selectedPaymentMethod,
|
|
823
1002
|
setCurrency,
|
|
824
|
-
updateAddress
|
|
1003
|
+
updateAddress,
|
|
1004
|
+
user
|
|
825
1005
|
},
|
|
826
1006
|
children: children
|
|
827
1007
|
});
|
|
@@ -833,6 +1013,10 @@ export const useEcommerce = ()=>{
|
|
|
833
1013
|
}
|
|
834
1014
|
return context;
|
|
835
1015
|
};
|
|
1016
|
+
export const useEcommerceConfig = ()=>{
|
|
1017
|
+
const { config } = useEcommerce();
|
|
1018
|
+
return config;
|
|
1019
|
+
};
|
|
836
1020
|
export const useCurrency = ()=>{
|
|
837
1021
|
const { currenciesConfig, currency, setCurrency } = useEcommerce();
|
|
838
1022
|
const formatCurrency = useCallback((value, options)=>{
|