@q2devel/q2-core 1.0.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/api/cart/Cart.service.d.ts +27 -0
- package/dist/api/cart/Cart.service.d.ts.map +1 -0
- package/dist/api/cart/Cart.service.js +205 -0
- package/dist/api/cart/CartService.types.d.ts +156 -0
- package/dist/api/cart/CartService.types.d.ts.map +1 -0
- package/dist/api/cart/CartService.types.js +1 -0
- package/dist/api/checkout/Checkout.service.d.ts +10 -0
- package/dist/api/checkout/Checkout.service.d.ts.map +1 -0
- package/dist/api/checkout/Checkout.service.js +31 -0
- package/dist/api/checkout/CheckoutService.types.d.ts +57 -0
- package/dist/api/checkout/CheckoutService.types.d.ts.map +1 -0
- package/dist/api/checkout/CheckoutService.types.js +1 -0
- package/dist/api/content/getBanners.d.ts +9 -0
- package/dist/api/content/getBanners.d.ts.map +1 -0
- package/dist/api/content/getBanners.js +32 -0
- package/dist/api/content/getBlog.d.ts +11 -0
- package/dist/api/content/getBlog.d.ts.map +1 -0
- package/dist/api/content/getBlog.js +43 -0
- package/dist/api/getTerms.d.ts +10 -0
- package/dist/api/getTerms.d.ts.map +1 -0
- package/dist/api/getTerms.js +38 -0
- package/dist/api/products/getProducts.d.ts +27 -0
- package/dist/api/products/getProducts.d.ts.map +1 -0
- package/dist/api/products/getProducts.js +125 -0
- package/dist/api/user/getUserCart.d.ts +1 -0
- package/dist/api/user/getUserCart.d.ts.map +1 -0
- package/dist/api/user/getUserCart.js +1 -0
- package/dist/api/user/resetPassword.d.ts +8 -0
- package/dist/api/user/resetPassword.d.ts.map +1 -0
- package/dist/api/user/resetPassword.js +4 -0
- package/dist/api/wishlist/Wishlist.service.d.ts +12 -0
- package/dist/api/wishlist/Wishlist.service.d.ts.map +1 -0
- package/dist/api/wishlist/Wishlist.service.js +73 -0
- package/dist/api/wishlist/WishlistService.types.d.ts +77 -0
- package/dist/api/wishlist/WishlistService.types.d.ts.map +1 -0
- package/dist/api/wishlist/WishlistService.types.js +1 -0
- package/dist/context/cart/BasketContext.d.ts +38 -0
- package/dist/context/cart/BasketContext.d.ts.map +1 -0
- package/dist/context/cart/BasketContext.js +408 -0
- package/dist/context.d.ts +14 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +1 -0
- package/dist/hooks/cart/api/useAddToCart.d.ts +4 -0
- package/dist/hooks/cart/api/useAddToCart.d.ts.map +1 -0
- package/dist/hooks/cart/api/useAddToCart.js +17 -0
- package/dist/hooks/cart/api/useClearCart.d.ts +5 -0
- package/dist/hooks/cart/api/useClearCart.d.ts.map +1 -0
- package/dist/hooks/cart/api/useClearCart.js +17 -0
- package/dist/hooks/cart/api/useDeleteCartItem.d.ts +7 -0
- package/dist/hooks/cart/api/useDeleteCartItem.d.ts.map +1 -0
- package/dist/hooks/cart/api/useDeleteCartItem.js +24 -0
- package/dist/hooks/cart/api/useGetCartToken.d.ts +177 -0
- package/dist/hooks/cart/api/useGetCartToken.d.ts.map +1 -0
- package/dist/hooks/cart/api/useGetCartToken.js +42 -0
- package/dist/hooks/cart/api/useGetCurrentCart.d.ts +9 -0
- package/dist/hooks/cart/api/useGetCurrentCart.d.ts.map +1 -0
- package/dist/hooks/cart/api/useGetCurrentCart.js +13 -0
- package/dist/hooks/cart/api/useGetUserCart.d.ts +4 -0
- package/dist/hooks/cart/api/useGetUserCart.d.ts.map +1 -0
- package/dist/hooks/cart/api/useGetUserCart.js +14 -0
- package/dist/hooks/cart/api/useUpdateCart.d.ts +10 -0
- package/dist/hooks/cart/api/useUpdateCart.d.ts.map +1 -0
- package/dist/hooks/cart/api/useUpdateCart.js +22 -0
- package/dist/hooks/checkout/useUpdateCheckout.d.ts +7 -0
- package/dist/hooks/checkout/useUpdateCheckout.d.ts.map +1 -0
- package/dist/hooks/checkout/useUpdateCheckout.js +15 -0
- package/dist/hooks/wishlist/api/useAddToWishlist.d.ts +4 -0
- package/dist/hooks/wishlist/api/useAddToWishlist.d.ts.map +1 -0
- package/dist/hooks/wishlist/api/useAddToWishlist.js +12 -0
- package/dist/hooks/wishlist/api/useCreateWishlist.d.ts +4 -0
- package/dist/hooks/wishlist/api/useCreateWishlist.d.ts.map +1 -0
- package/dist/hooks/wishlist/api/useCreateWishlist.js +15 -0
- package/dist/hooks/wishlist/api/useDeleteWishlist.d.ts +4 -0
- package/dist/hooks/wishlist/api/useDeleteWishlist.d.ts.map +1 -0
- package/dist/hooks/wishlist/api/useDeleteWishlist.js +16 -0
- package/dist/hooks/wishlist/api/useDeleteWishlistItem.d.ts +4 -0
- package/dist/hooks/wishlist/api/useDeleteWishlistItem.d.ts.map +1 -0
- package/dist/hooks/wishlist/api/useDeleteWishlistItem.js +11 -0
- package/dist/hooks/wishlist/api/useGetWishlistItems.d.ts +3 -0
- package/dist/hooks/wishlist/api/useGetWishlistItems.d.ts.map +1 -0
- package/dist/hooks/wishlist/api/useGetWishlistItems.js +9 -0
- package/dist/hooks/wishlist/api/useGetWishlistList.d.ts +4 -0
- package/dist/hooks/wishlist/api/useGetWishlistList.d.ts.map +1 -0
- package/dist/hooks/wishlist/api/useGetWishlistList.js +13 -0
- package/dist/hooks/wishlist/useWishlist.d.ts +22 -0
- package/dist/hooks/wishlist/useWishlist.d.ts.map +1 -0
- package/dist/hooks/wishlist/useWishlist.js +202 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/types/ResetPassword.d.ts +8 -0
- package/dist/types/ResetPassword.d.ts.map +1 -0
- package/dist/types/ResetPassword.js +1 -0
- package/dist/types/Term.d.ts +15 -0
- package/dist/types/Term.d.ts.map +1 -0
- package/dist/types/Term.js +1 -0
- package/dist/types/content/Banners.d.ts +14 -0
- package/dist/types/content/Banners.d.ts.map +1 -0
- package/dist/types/content/Banners.js +1 -0
- package/dist/types/content/Blog.d.ts +12 -0
- package/dist/types/content/Blog.d.ts.map +1 -0
- package/dist/types/content/Blog.js +1 -0
- package/dist/types/content/ResetPassword.d.ts +8 -0
- package/dist/types/content/ResetPassword.d.ts.map +1 -0
- package/dist/types/content/ResetPassword.js +1 -0
- package/dist/types/products/Product.d.ts +69 -0
- package/dist/types/products/Product.d.ts.map +1 -0
- package/dist/types/products/Product.js +1 -0
- package/dist/types/user/ResetPassword.d.ts +8 -0
- package/dist/types/user/ResetPassword.d.ts.map +1 -0
- package/dist/types/user/ResetPassword.js +1 -0
- package/dist/types/wishlist/Wishlist.d.ts +31 -0
- package/dist/types/wishlist/Wishlist.d.ts.map +1 -0
- package/dist/types/wishlist/Wishlist.js +1 -0
- package/dist/utils/generalHelper.d.ts +12 -0
- package/dist/utils/generalHelper.d.ts.map +1 -0
- package/dist/utils/generalHelper.js +37 -0
- package/dist/utils/mapIncludedResources.d.ts +21 -0
- package/dist/utils/mapIncludedResources.d.ts.map +1 -0
- package/dist/utils/mapIncludedResources.js +37 -0
- package/package.json +31 -0
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useAddToCart } from '../../hooks/cart/api/useAddToCart';
|
|
4
|
+
import { useClearCart } from '../../hooks/cart/api/useClearCart';
|
|
5
|
+
import { useDeleteCartItem } from '../../hooks/cart/api/useDeleteCartItem';
|
|
6
|
+
import { useGetCartToken } from '../../hooks/cart/api/useGetCartToken';
|
|
7
|
+
import { useGetCurrentCart } from '../../hooks/cart/api/useGetCurrentCart';
|
|
8
|
+
import { useGetUserCart } from '../../hooks/cart/api/useGetUserCart';
|
|
9
|
+
import { useUpdateCartItem } from '../../hooks/cart/api/useUpdateCart';
|
|
10
|
+
import { useUpdateCheckout } from '../../hooks/checkout/useUpdateCheckout';
|
|
11
|
+
import { formatPrice } from '../../utils/generalHelper';
|
|
12
|
+
import { createContext, useContext, useEffect, useRef, useState } from 'react';
|
|
13
|
+
const BasketContext = createContext(undefined);
|
|
14
|
+
export const BasketProvider = ({ children, ctx }) => {
|
|
15
|
+
const [basketProducts, setBasketProducts] = useState([]);
|
|
16
|
+
const [isBasketOpen, setIsBasketOpen] = useState(false);
|
|
17
|
+
const [orderId, setOrderId] = useState(null);
|
|
18
|
+
const [drupalOrderId, setDrupalOrderId] = useState(null);
|
|
19
|
+
const { getExistingCartToken, createCartToken, cartToken } = useGetCartToken(ctx);
|
|
20
|
+
const activeToken = cartToken;
|
|
21
|
+
console.log('Aktivní token:', activeToken);
|
|
22
|
+
const { data: userCartData, isLoading: isUserCartLoading, refetch: refetchUserCart, isFetching: isUserCartFetching, } = useGetUserCart(ctx);
|
|
23
|
+
const { data: guestCartData, isLoading: isGuestCartLoading, refetch: refetchGuestCart, isFetching: isGuestCartFetching, } = useGetCurrentCart({ activeToken: activeToken ?? undefined, ctx });
|
|
24
|
+
const cartData = ctx.userId ? userCartData : guestCartData;
|
|
25
|
+
const isLoading = ctx.userId ? isUserCartLoading : isGuestCartLoading;
|
|
26
|
+
const isFetching = ctx.userId ? isUserCartFetching : isGuestCartFetching;
|
|
27
|
+
const refetchCart = ctx.userId ? refetchUserCart : refetchGuestCart;
|
|
28
|
+
const { mutateAsync: addToCartMutation, isPending: isAddingToCart } = useAddToCart(ctx, activeToken ?? undefined);
|
|
29
|
+
const { mutateAsync: updateCartItemMutation } = useUpdateCartItem(ctx);
|
|
30
|
+
const { mutateAsync: deleteCartItemMutation } = useDeleteCartItem(ctx);
|
|
31
|
+
const { mutateAsync: clearCartMutation } = useClearCart(ctx);
|
|
32
|
+
const { mutateAsync: updateCheckoutMutation } = useUpdateCheckout(ctx);
|
|
33
|
+
const debounceTimersRef = useRef({});
|
|
34
|
+
const [pendingUpdates, setPendingUpdates] = useState({});
|
|
35
|
+
const DEBOUNCE_DELAY = 600;
|
|
36
|
+
const [processingItems, setProcessingItems] = useState({});
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
return () => {
|
|
39
|
+
const timers = debounceTimersRef.current;
|
|
40
|
+
Object.values(timers).forEach(clearTimeout);
|
|
41
|
+
};
|
|
42
|
+
}, []);
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
if (ctx.accessToken) {
|
|
45
|
+
// Přihlášený uživatel, token je v userToken
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
const existingToken = localStorage.getItem('cartToken');
|
|
49
|
+
if (existingToken) {
|
|
50
|
+
getExistingCartToken();
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
createCartToken();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}, [ctx.accessToken]);
|
|
57
|
+
// Synchronizace data z API
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
if (cartData?.data?.cartItems) {
|
|
60
|
+
const transformedProducts = cartData.data.cartItems.map((item) => {
|
|
61
|
+
const priceNumber = parseFloat(item.price.toString());
|
|
62
|
+
return {
|
|
63
|
+
variation_id: item.variation_id,
|
|
64
|
+
variation_uuid: item.variation_uuid,
|
|
65
|
+
type: 'product',
|
|
66
|
+
variation_name: item.variation_name,
|
|
67
|
+
description: '',
|
|
68
|
+
price: priceNumber,
|
|
69
|
+
formattedPrice: formatPrice(priceNumber, ctx.locale),
|
|
70
|
+
quantity: item.quantity,
|
|
71
|
+
images: item.images || [],
|
|
72
|
+
category: '',
|
|
73
|
+
field_news: item.field_news || false,
|
|
74
|
+
field_aftersale: item.field_aftersale || false,
|
|
75
|
+
field_care: [],
|
|
76
|
+
field_features: [],
|
|
77
|
+
field_returns: [],
|
|
78
|
+
field_shipping: [],
|
|
79
|
+
href: '/',
|
|
80
|
+
drupalOrderItemId: item.drupalOrderItemId?.toString(),
|
|
81
|
+
order_item_id: item.order_item_id,
|
|
82
|
+
};
|
|
83
|
+
});
|
|
84
|
+
setBasketProducts(transformedProducts);
|
|
85
|
+
if (cartData.data.drupalOrderId) {
|
|
86
|
+
setDrupalOrderId(cartData.data.drupalOrderId);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
else if (cartData &&
|
|
90
|
+
(!cartData.data?.cartItems || cartData.data.cartItems.length === 0)) {
|
|
91
|
+
setBasketProducts([]);
|
|
92
|
+
if (drupalOrderId === null) {
|
|
93
|
+
setDrupalOrderId(null);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}, [cartData, ctx.locale]);
|
|
97
|
+
const calculateSubtotal = () => {
|
|
98
|
+
const total = basketProducts.reduce((sum, product) => {
|
|
99
|
+
const priceValue = typeof product.price === 'string'
|
|
100
|
+
? parseFloat(product.price.replace(/[^\d,.-]/g, '').replace(',', '.'))
|
|
101
|
+
: Number(product.price);
|
|
102
|
+
return sum + priceValue * product.quantity;
|
|
103
|
+
}, 0);
|
|
104
|
+
return total;
|
|
105
|
+
};
|
|
106
|
+
const calculateTotalItems = () => {
|
|
107
|
+
return basketProducts.reduce((sum, product) => {
|
|
108
|
+
return sum + product.quantity;
|
|
109
|
+
}, 0);
|
|
110
|
+
};
|
|
111
|
+
const getProductQuantityInBasket = (productId) => {
|
|
112
|
+
const productInBasket = basketProducts.find((p) => p.variation_uuid === productId);
|
|
113
|
+
return productInBasket ? productInBasket.quantity : 0;
|
|
114
|
+
};
|
|
115
|
+
// Merged addToBasket function - directly calls API
|
|
116
|
+
const addToBasket = async (product, quantity = 1) => {
|
|
117
|
+
const productKey = product.variation_uuid;
|
|
118
|
+
setProcessingItems((prev) => ({
|
|
119
|
+
...prev,
|
|
120
|
+
[productKey]: true,
|
|
121
|
+
}));
|
|
122
|
+
const safetyTimeout = setTimeout(() => {
|
|
123
|
+
setProcessingItems((prev) => {
|
|
124
|
+
const newState = { ...prev };
|
|
125
|
+
delete newState[productKey];
|
|
126
|
+
return newState;
|
|
127
|
+
});
|
|
128
|
+
}, 4000);
|
|
129
|
+
try {
|
|
130
|
+
let token = ctx.accessToken || cartToken;
|
|
131
|
+
if (!token && !ctx.accessToken) {
|
|
132
|
+
const existingToken = localStorage.getItem('cartToken');
|
|
133
|
+
if (existingToken) {
|
|
134
|
+
token = existingToken;
|
|
135
|
+
getExistingCartToken();
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
token = createCartToken();
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
const request = {
|
|
142
|
+
data: [
|
|
143
|
+
{
|
|
144
|
+
type: 'commerce_product_variation--default',
|
|
145
|
+
id: product.variation_uuid,
|
|
146
|
+
meta: {
|
|
147
|
+
quantity,
|
|
148
|
+
combine: true,
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
],
|
|
152
|
+
};
|
|
153
|
+
const response = await addToCartMutation(request);
|
|
154
|
+
if (response?.[0]?.order_id) {
|
|
155
|
+
setOrderId(Number(response[0].order_id));
|
|
156
|
+
}
|
|
157
|
+
// Remove refetchCart() - hook should handle cache update
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
// Only refetch on error as fallback
|
|
161
|
+
await refetchCart();
|
|
162
|
+
throw error;
|
|
163
|
+
}
|
|
164
|
+
finally {
|
|
165
|
+
clearTimeout(safetyTimeout);
|
|
166
|
+
setProcessingItems((prev) => {
|
|
167
|
+
const newState = { ...prev };
|
|
168
|
+
delete newState[productKey];
|
|
169
|
+
return newState;
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
const addMultipleToBasket = async (products, quantity = 1) => {
|
|
174
|
+
if (!products.length || isAddingToCart)
|
|
175
|
+
return;
|
|
176
|
+
try {
|
|
177
|
+
const request = {
|
|
178
|
+
data: products.map((product) => ({
|
|
179
|
+
type: 'commerce_product_variation--default',
|
|
180
|
+
id: product.variation_uuid,
|
|
181
|
+
meta: {
|
|
182
|
+
quantity,
|
|
183
|
+
combine: true,
|
|
184
|
+
},
|
|
185
|
+
})),
|
|
186
|
+
};
|
|
187
|
+
const response = await addToCartMutation(request);
|
|
188
|
+
if (response?.[0]?.order_id) {
|
|
189
|
+
setOrderId(Number(response[0].order_id));
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
catch (error) {
|
|
193
|
+
console.error('Chyba pri hromadnom pridávaní produktov:', error);
|
|
194
|
+
await refetchCart(); // fallback
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
const removeFromBasket = async (productId) => {
|
|
198
|
+
const productToRemove = basketProducts.find((p) => p.variation_uuid === productId);
|
|
199
|
+
if (!productToRemove)
|
|
200
|
+
return;
|
|
201
|
+
const productKey = productToRemove.variation_uuid;
|
|
202
|
+
setProcessingItems((prev) => ({
|
|
203
|
+
...prev,
|
|
204
|
+
[productKey]: true,
|
|
205
|
+
}));
|
|
206
|
+
// Cancel any pending debounce for this product
|
|
207
|
+
if (debounceTimersRef.current[productKey]) {
|
|
208
|
+
clearTimeout(debounceTimersRef.current[productKey]);
|
|
209
|
+
delete debounceTimersRef.current[productKey];
|
|
210
|
+
}
|
|
211
|
+
// Clear pending updates
|
|
212
|
+
setPendingUpdates((prev) => {
|
|
213
|
+
const newState = { ...prev };
|
|
214
|
+
delete newState[productKey];
|
|
215
|
+
return newState;
|
|
216
|
+
});
|
|
217
|
+
try {
|
|
218
|
+
if (!activeToken || !drupalOrderId)
|
|
219
|
+
return;
|
|
220
|
+
const deleteId = productToRemove.order_item_id;
|
|
221
|
+
await deleteCartItemMutation({
|
|
222
|
+
orderId: drupalOrderId.toString(),
|
|
223
|
+
request: {
|
|
224
|
+
data: [
|
|
225
|
+
{
|
|
226
|
+
type: 'commerce_order_item--default',
|
|
227
|
+
id: deleteId,
|
|
228
|
+
},
|
|
229
|
+
],
|
|
230
|
+
},
|
|
231
|
+
});
|
|
232
|
+
await refetchCart();
|
|
233
|
+
}
|
|
234
|
+
catch (error) {
|
|
235
|
+
await refetchCart();
|
|
236
|
+
}
|
|
237
|
+
finally {
|
|
238
|
+
setProcessingItems((prev) => {
|
|
239
|
+
const newState = { ...prev };
|
|
240
|
+
delete newState[productKey];
|
|
241
|
+
return newState;
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
// Clear pending updates when cart stops fetching and data matches
|
|
246
|
+
useEffect(() => {
|
|
247
|
+
// Only clear when not fetching anymore
|
|
248
|
+
if (!isFetching) {
|
|
249
|
+
Object.keys(pendingUpdates).forEach((productKey) => {
|
|
250
|
+
const product = basketProducts.find((p) => p.variation_uuid === productKey);
|
|
251
|
+
const pendingQuantity = pendingUpdates[productKey];
|
|
252
|
+
if (product && product.quantity === pendingQuantity) {
|
|
253
|
+
setPendingUpdates((prev) => {
|
|
254
|
+
const newState = { ...prev };
|
|
255
|
+
delete newState[productKey];
|
|
256
|
+
return newState;
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
}, [basketProducts, pendingUpdates, isFetching]);
|
|
262
|
+
// Simplified updateQuantity function
|
|
263
|
+
const updateQuantity = async (productId, quantity) => {
|
|
264
|
+
const productInBasket = basketProducts.find((p) => p.variation_uuid === productId);
|
|
265
|
+
if (!productInBasket)
|
|
266
|
+
return;
|
|
267
|
+
// Handle removal
|
|
268
|
+
if (quantity <= 0) {
|
|
269
|
+
await removeFromBasket(productId);
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
const productKey = productId;
|
|
273
|
+
// Show pending quantity immediately in UI
|
|
274
|
+
setPendingUpdates((prev) => ({
|
|
275
|
+
...prev,
|
|
276
|
+
[productKey]: quantity,
|
|
277
|
+
}));
|
|
278
|
+
// Clear existing timer
|
|
279
|
+
if (debounceTimersRef.current[productKey]) {
|
|
280
|
+
clearTimeout(debounceTimersRef.current[productKey]);
|
|
281
|
+
}
|
|
282
|
+
// Set new debounced timer
|
|
283
|
+
debounceTimersRef.current[productKey] = setTimeout(async () => {
|
|
284
|
+
setProcessingItems((prev) => ({
|
|
285
|
+
...prev,
|
|
286
|
+
[productKey]: true,
|
|
287
|
+
}));
|
|
288
|
+
try {
|
|
289
|
+
if (!activeToken || !drupalOrderId)
|
|
290
|
+
return;
|
|
291
|
+
const itemId = getDrupalOrderItemId(productInBasket);
|
|
292
|
+
const request = {
|
|
293
|
+
data: {
|
|
294
|
+
type: 'order-items--default',
|
|
295
|
+
id: productInBasket.order_item_id,
|
|
296
|
+
attributes: { quantity },
|
|
297
|
+
},
|
|
298
|
+
};
|
|
299
|
+
await updateCartItemMutation({
|
|
300
|
+
orderId: drupalOrderId.toString(),
|
|
301
|
+
itemId: itemId,
|
|
302
|
+
request,
|
|
303
|
+
});
|
|
304
|
+
await refetchCart();
|
|
305
|
+
// Don't clear pending updates here - let the useEffect handle it
|
|
306
|
+
}
|
|
307
|
+
catch (error) {
|
|
308
|
+
await refetchCart();
|
|
309
|
+
// Clear pending updates on error
|
|
310
|
+
setPendingUpdates((prev) => {
|
|
311
|
+
const newState = { ...prev };
|
|
312
|
+
delete newState[productKey];
|
|
313
|
+
return newState;
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
finally {
|
|
317
|
+
setProcessingItems((prev) => {
|
|
318
|
+
const newState = { ...prev };
|
|
319
|
+
delete newState[productKey];
|
|
320
|
+
return newState;
|
|
321
|
+
});
|
|
322
|
+
delete debounceTimersRef.current[productKey];
|
|
323
|
+
}
|
|
324
|
+
}, DEBOUNCE_DELAY);
|
|
325
|
+
};
|
|
326
|
+
const getDrupalOrderItemId = (product) => {
|
|
327
|
+
return (product.drupalOrderItemId?.toString() ||
|
|
328
|
+
product.variation_uuid);
|
|
329
|
+
};
|
|
330
|
+
// Updated clearBasket without queue operations
|
|
331
|
+
const clearBasket = async () => {
|
|
332
|
+
try {
|
|
333
|
+
if (drupalOrderId) {
|
|
334
|
+
await clearCartMutation({
|
|
335
|
+
orderId: drupalOrderId.toString(),
|
|
336
|
+
});
|
|
337
|
+
await refetchCart();
|
|
338
|
+
}
|
|
339
|
+
// Clear all pending updates
|
|
340
|
+
setPendingUpdates({});
|
|
341
|
+
// Clear all debounce timers
|
|
342
|
+
const timers = debounceTimersRef.current;
|
|
343
|
+
Object.values(timers).forEach(clearTimeout);
|
|
344
|
+
debounceTimersRef.current = {};
|
|
345
|
+
}
|
|
346
|
+
catch (error) {
|
|
347
|
+
await refetchCart();
|
|
348
|
+
}
|
|
349
|
+
};
|
|
350
|
+
const openBasket = () => {
|
|
351
|
+
setIsBasketOpen(true);
|
|
352
|
+
};
|
|
353
|
+
const closeBasket = () => {
|
|
354
|
+
setIsBasketOpen(false);
|
|
355
|
+
};
|
|
356
|
+
const updateOrderForCheckout = async (request, callbacks) => {
|
|
357
|
+
if (!drupalOrderId) {
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
try {
|
|
361
|
+
await updateCheckoutMutation({
|
|
362
|
+
orderId: drupalOrderId.toString(),
|
|
363
|
+
request,
|
|
364
|
+
});
|
|
365
|
+
await refetchCart();
|
|
366
|
+
if (callbacks?.onSuccess) {
|
|
367
|
+
callbacks.onSuccess();
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
catch (error) {
|
|
371
|
+
if (callbacks?.onError) {
|
|
372
|
+
callbacks.onError(error);
|
|
373
|
+
}
|
|
374
|
+
throw error;
|
|
375
|
+
}
|
|
376
|
+
};
|
|
377
|
+
const getDrupalOrderId = () => {
|
|
378
|
+
return drupalOrderId;
|
|
379
|
+
};
|
|
380
|
+
const value = {
|
|
381
|
+
basketProducts,
|
|
382
|
+
subtotal: calculateSubtotal(),
|
|
383
|
+
totalItems: calculateTotalItems(),
|
|
384
|
+
addToBasket,
|
|
385
|
+
addMultipleToBasket,
|
|
386
|
+
removeFromBasket,
|
|
387
|
+
updateQuantity,
|
|
388
|
+
clearBasket,
|
|
389
|
+
isBasketOpen,
|
|
390
|
+
openBasket,
|
|
391
|
+
closeBasket,
|
|
392
|
+
isLoading,
|
|
393
|
+
getProductQuantityInBasket,
|
|
394
|
+
updateOrderForCheckout,
|
|
395
|
+
getDrupalOrderId,
|
|
396
|
+
pendingUpdates,
|
|
397
|
+
processingItems,
|
|
398
|
+
isAddingToCart,
|
|
399
|
+
};
|
|
400
|
+
return _jsx(BasketContext.Provider, { value: value, children: children });
|
|
401
|
+
};
|
|
402
|
+
export const useBasket = () => {
|
|
403
|
+
const context = useContext(BasketContext);
|
|
404
|
+
if (context === undefined) {
|
|
405
|
+
throw new Error('useBasket musí být použit uvnitř BasketProvider');
|
|
406
|
+
}
|
|
407
|
+
return context;
|
|
408
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { AxiosInstance } from 'axios';
|
|
2
|
+
export type CoreContext = {
|
|
3
|
+
axios: AxiosInstance;
|
|
4
|
+
defaultLocale: string;
|
|
5
|
+
locale: string;
|
|
6
|
+
accessToken?: string;
|
|
7
|
+
baseUrl?: string;
|
|
8
|
+
userId?: string;
|
|
9
|
+
cartToken?: string;
|
|
10
|
+
makeAbsoluteUrl: (path: string) => string;
|
|
11
|
+
getCache?: <T = any>(key: string) => Promise<T | null>;
|
|
12
|
+
setCache?: <T = any>(key: string, value: T) => Promise<void>;
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAEtC,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,aAAa,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAC1C,QAAQ,CAAC,EAAE,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IACvD,QAAQ,CAAC,EAAE,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9D,CAAC"}
|
package/dist/context.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { AddToCartRequest, AddToCartResponse } from '../../../api/cart/CartService.types';
|
|
2
|
+
import { CoreContext } from '../../../context';
|
|
3
|
+
export declare const useAddToCart: (ctx: CoreContext, activeToken?: string) => import("@tanstack/react-query").UseMutationResult<AddToCartResponse, Error, AddToCartRequest, unknown>;
|
|
4
|
+
//# sourceMappingURL=useAddToCart.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAddToCart.d.ts","sourceRoot":"","sources":["../../../../hooks/cart/api/useAddToCart.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AAC1F,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,eAAO,MAAM,YAAY,GAAI,KAAK,WAAW,EAAE,cAAa,MAAM,2GAcjE,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// src/hooks/api/cart/useAddToCart.ts
|
|
2
|
+
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
|
3
|
+
import { addToCart } from '../../../api/cart/Cart.service';
|
|
4
|
+
export const useAddToCart = (ctx, activeToken) => {
|
|
5
|
+
const queryClient = useQueryClient();
|
|
6
|
+
return useMutation({
|
|
7
|
+
mutationFn: (request) => addToCart(ctx, activeToken, request),
|
|
8
|
+
onSuccess: () => {
|
|
9
|
+
if (ctx.userId) {
|
|
10
|
+
queryClient.invalidateQueries({ queryKey: ['userCart'] });
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
queryClient.invalidateQueries({ queryKey: ['cart'] });
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useClearCart.d.ts","sourceRoot":"","sources":["../../../../hooks/cart/api/useClearCart.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,eAAO,MAAM,YAAY,GAAI,KAAK,WAAW;aAGA,MAAM;WAWlD,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// src/hooks/api/cart/useClearCart.ts
|
|
2
|
+
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
|
3
|
+
import { clearCart } from '../../../api/cart/Cart.service';
|
|
4
|
+
export const useClearCart = (ctx) => {
|
|
5
|
+
const queryClient = useQueryClient();
|
|
6
|
+
return useMutation({
|
|
7
|
+
mutationFn: ({ orderId }) => clearCart(ctx, orderId),
|
|
8
|
+
onSuccess: () => {
|
|
9
|
+
if (ctx.userId) {
|
|
10
|
+
queryClient.invalidateQueries({ queryKey: ['userCart'] });
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
queryClient.invalidateQueries({ queryKey: ['cart'] });
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { DeleteCartItemRequest } from '../../../api/cart/CartService.types';
|
|
2
|
+
import { CoreContext } from '../../../context';
|
|
3
|
+
export declare const useDeleteCartItem: (ctx: CoreContext) => import("@tanstack/react-query").UseMutationResult<void, Error, {
|
|
4
|
+
request: DeleteCartItemRequest;
|
|
5
|
+
orderId: string;
|
|
6
|
+
}, unknown>;
|
|
7
|
+
//# sourceMappingURL=useDeleteCartItem.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDeleteCartItem.d.ts","sourceRoot":"","sources":["../../../../hooks/cart/api/useDeleteCartItem.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAC5E,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,eAAO,MAAM,iBAAiB,GAAI,KAAK,WAAW;aAGL,qBAAqB;aAAW,MAAM;WAuBlF,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// src/hooks/api/cart/useDeleteCartItem.ts
|
|
2
|
+
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
|
3
|
+
import { deleteCartItem } from '../../../api/cart/Cart.service';
|
|
4
|
+
export const useDeleteCartItem = (ctx) => {
|
|
5
|
+
const queryClient = useQueryClient();
|
|
6
|
+
return useMutation({
|
|
7
|
+
mutationFn: ({ request, orderId }) => deleteCartItem(ctx, orderId, request),
|
|
8
|
+
onSuccess: (_, variables) => {
|
|
9
|
+
const queryKey = ctx.userId ? ['userCart', ctx.userId] : ['cart'];
|
|
10
|
+
queryClient.setQueryData(queryKey, (oldData) => {
|
|
11
|
+
if (!oldData?.data?.cartItems)
|
|
12
|
+
return oldData;
|
|
13
|
+
const itemIdToRemove = variables.request.data[0].id;
|
|
14
|
+
return {
|
|
15
|
+
...oldData,
|
|
16
|
+
data: {
|
|
17
|
+
...oldData.data,
|
|
18
|
+
cartItems: oldData.data.cartItems.filter((item) => item.id !== itemIdToRemove),
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
});
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
};
|