@riosst100/pwa-marketplace 2.4.7 → 2.4.9

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.
Files changed (32) hide show
  1. package/package.json +1 -1
  2. package/src/componentOverrideMapping.js +3 -0
  3. package/src/components/Seller/seller.js +8 -0
  4. package/src/components/SellerDetail/sellerDetail.js +4 -3
  5. package/src/components/SellerMegaMenu/index.js +1 -0
  6. package/src/components/SellerMegaMenu/sellerMegaMenu.js +92 -0
  7. package/src/components/SellerMegaMenu/sellerMegaMenu.module.css +12 -0
  8. package/src/components/SellerMegaMenu/sellerMegaMenuItem.js +164 -0
  9. package/src/components/SellerMegaMenu/sellerMegaMenuItem.module.css +31 -0
  10. package/src/components/SellerMegaMenu/sellerSubmenu.js +106 -0
  11. package/src/components/SellerMegaMenu/sellerSubmenu.module.css +57 -0
  12. package/src/components/SellerMegaMenu/sellerSubmenuColumn.js +173 -0
  13. package/src/components/SellerMegaMenu/sellerSubmenuColumn.module.css +33 -0
  14. package/src/components/SellerProducts/productContent.js +70 -11
  15. package/src/components/SellerProducts/sellerProducts.js +51 -12
  16. package/src/intercept.js +14 -0
  17. package/src/overwrites/peregrine/lib/context/cart.js +136 -0
  18. package/src/overwrites/peregrine/lib/store/actions/cart/asyncActions.js +589 -0
  19. package/src/overwrites/peregrine/lib/talons/CartPage/PriceSummary/usePriceSummary.js +4 -1
  20. package/src/overwrites/peregrine/lib/talons/CheckoutPage/useCheckoutPage.js +434 -0
  21. package/src/overwrites/venia-ui/lib/components/Adapter/adapter.js +0 -9
  22. package/src/overwrites/venia-ui/lib/components/CartPage/ProductListing/product.js +2 -2
  23. package/src/overwrites/venia-ui/lib/components/CartPage/ProductListing/productListing.js +8 -8
  24. package/src/overwrites/venia-ui/lib/components/Header/header.js +1 -1
  25. package/src/talons/Seller/useSeller.js +1 -1
  26. package/src/talons/SellerMegaMenu/megaMenu.gql.js +96 -0
  27. package/src/talons/SellerMegaMenu/useSellerMegaMenu.js +199 -0
  28. package/src/talons/SellerMegaMenu/useSellerMegaMenuItem.js +66 -0
  29. package/src/talons/SellerMegaMenu/useSellerSubMenu.js +21 -0
  30. package/src/talons/SellerProducts/sellerProducts.gql.js +24 -1
  31. package/src/talons/SellerProducts/useProductContent.js +17 -23
  32. package/src/talons/SellerProducts/useSellerProducts.js +44 -28
@@ -0,0 +1,434 @@
1
+ import { useCallback, useEffect, useMemo, useState, useRef } from 'react';
2
+ import {
3
+ useApolloClient,
4
+ useLazyQuery,
5
+ useMutation,
6
+ useQuery
7
+ } from '@apollo/client';
8
+ import { useEventingContext } from '@magento/peregrine/lib/context/eventing';
9
+
10
+ import { useUserContext } from '@magento/peregrine/lib/context/user';
11
+ import { useCartContext } from '@magento/peregrine/lib/context/cart';
12
+ import { setCheckoutState} from '@magento/peregrine/lib/store/actions/cart';
13
+
14
+ import mergeOperations from '@magento/peregrine/lib/util/shallowMerge';
15
+
16
+ import DEFAULT_OPERATIONS from '@magento/peregrine/lib/talons/CheckoutPage/checkoutPage.gql.js';
17
+
18
+ import CheckoutError from '@magento/peregrine/lib/talons/CheckoutPage/CheckoutError';
19
+ import { useGoogleReCaptcha } from '@magento/peregrine/lib/hooks/useGoogleReCaptcha';
20
+
21
+ export const CHECKOUT_STEP = {
22
+ SHIPPING_ADDRESS: 1,
23
+ SHIPPING_METHOD: 2,
24
+ PAYMENT: 3,
25
+ REVIEW: 4
26
+ };
27
+
28
+ /**
29
+ *
30
+ * @param {DocumentNode} props.operations.getCheckoutDetailsQuery query to fetch checkout details
31
+ * @param {DocumentNode} props.operations.getCustomerQuery query to fetch customer details
32
+ * @param {DocumentNode} props.operations.getOrderDetailsQuery query to fetch order details
33
+ * @param {DocumentNode} props.operations.createCartMutation mutation to create a new cart
34
+ * @param {DocumentNode} props.operations.placeOrderMutation mutation to place order
35
+ *
36
+ * @returns {
37
+ * activeContent: String,
38
+ * availablePaymentMethods: Array,
39
+ * cartItems: Array,
40
+ * checkoutStep: Number,
41
+ * customer: Object,
42
+ * error: ApolloError,
43
+ * handlePlaceOrder: Function,
44
+ * handlePlaceOrderEnterKeyPress: Function,
45
+ * hasError: Boolean,
46
+ * isCartEmpty: Boolean,
47
+ * isGuestCheckout: Boolean,
48
+ * isLoading: Boolean,
49
+ * isUpdating: Boolean,
50
+ * orderDetailsData: Object,
51
+ * orderDetailsLoading: Boolean,
52
+ * orderNumber: String,
53
+ * placeOrderLoading: Boolean,
54
+ * setCheckoutStep: Function,
55
+ * setIsUpdating: Function,
56
+ * setShippingInformationDone: Function,
57
+ * setShippingMethodDone: Function,
58
+ * setPaymentInformationDone: Function,
59
+ * scrollShippingInformationIntoView: Function,
60
+ * shippingInformationRef: ReactRef,
61
+ * shippingMethodRef: ReactRef,
62
+ * scrollShippingMethodIntoView: Function,
63
+ * resetReviewOrderButtonClicked: Function,
64
+ * handleReviewOrder: Function,
65
+ * handleReviewOrderEnterKeyPress: Function,
66
+ * reviewOrderButtonClicked: Boolean,
67
+ * toggleAddressBookContent: Function,
68
+ * toggleSignInContent: Function,
69
+ * }
70
+ */
71
+ export const useCheckoutPage = (props = {}) => {
72
+ const operations = mergeOperations(DEFAULT_OPERATIONS, props.operations);
73
+
74
+ const {
75
+ createCartMutation,
76
+ getCheckoutDetailsQuery,
77
+ getCustomerQuery,
78
+ getOrderDetailsQuery,
79
+ placeOrderMutation
80
+ } = operations;
81
+
82
+ const { generateReCaptchaData, recaptchaWidgetProps } = useGoogleReCaptcha({
83
+ currentForm: 'PLACE_ORDER',
84
+ formAction: 'placeOrder'
85
+ });
86
+
87
+ const [reviewOrderButtonClicked, setReviewOrderButtonClicked] = useState(
88
+ false
89
+ );
90
+
91
+ const shippingInformationRef = useRef();
92
+ const shippingMethodRef = useRef();
93
+
94
+ const apolloClient = useApolloClient();
95
+ const [isUpdating, setIsUpdating] = useState(false);
96
+ const [placeOrderButtonClicked, setPlaceOrderButtonClicked] = useState(
97
+ false
98
+ );
99
+ const [activeContent, setActiveContent] = useState('checkout');
100
+ const [checkoutStep, setCheckoutStep] = useState(
101
+ CHECKOUT_STEP.SHIPPING_ADDRESS
102
+ );
103
+ const [guestSignInUsername, setGuestSignInUsername] = useState('');
104
+
105
+ const [{ isSignedIn }] = useUserContext();
106
+ const [{ cartId }, { createCart, removeCart }] = useCartContext();
107
+
108
+ const [fetchCartId] = useMutation(createCartMutation);
109
+ const [
110
+ placeOrder,
111
+ {
112
+ data: placeOrderData,
113
+ error: placeOrderError,
114
+ loading: placeOrderLoading
115
+ }
116
+ ] = useMutation(placeOrderMutation);
117
+
118
+ const [
119
+ getOrderDetails,
120
+ { data: orderDetailsData, loading: orderDetailsLoading }
121
+ ] = useLazyQuery(getOrderDetailsQuery, {
122
+ // We use this query to fetch details _just_ before submission, so we
123
+ // want to make sure it is fresh. We also don't want to cache this data
124
+ // because it may contain PII.
125
+ fetchPolicy: 'no-cache'
126
+ });
127
+
128
+ const { data: customerData, loading: customerLoading } = useQuery(
129
+ getCustomerQuery,
130
+ { skip: !isSignedIn }
131
+ );
132
+
133
+ const {
134
+ data: checkoutData,
135
+ networkStatus: checkoutQueryNetworkStatus
136
+ } = useQuery(getCheckoutDetailsQuery, {
137
+ /**
138
+ * Skip fetching checkout details if the `cartId`
139
+ * is a falsy value.
140
+ */
141
+ skip: !cartId,
142
+ notifyOnNetworkStatusChange: true,
143
+ variables: {
144
+ cartId
145
+ }
146
+ });
147
+
148
+ const cartItems = useMemo(() => {
149
+ return (checkoutData && checkoutData?.cart?.items) || [];
150
+ }, [checkoutData]);
151
+
152
+ /**
153
+ * For more info about network statues check this out
154
+ *
155
+ * https://www.apollographql.com/docs/react/data/queries/#inspecting-loading-states
156
+ */
157
+ const isLoading = useMemo(() => {
158
+ const checkoutQueryInFlight = checkoutQueryNetworkStatus
159
+ ? checkoutQueryNetworkStatus < 7
160
+ : true;
161
+
162
+ return checkoutQueryInFlight || customerLoading;
163
+ }, [checkoutQueryNetworkStatus, customerLoading]);
164
+
165
+ const customer = customerData && customerData.customer;
166
+
167
+ const toggleAddressBookContent = useCallback(() => {
168
+ setActiveContent(currentlyActive =>
169
+ currentlyActive === 'checkout' ? 'addressBook' : 'checkout'
170
+ );
171
+ }, []);
172
+ const toggleSignInContent = useCallback(() => {
173
+ setActiveContent(currentlyActive =>
174
+ currentlyActive === 'checkout' ? 'signIn' : 'checkout'
175
+ );
176
+ }, []);
177
+
178
+ const checkoutError = useMemo(() => {
179
+ if (placeOrderError) {
180
+ return new CheckoutError(placeOrderError);
181
+ }
182
+ }, [placeOrderError]);
183
+
184
+ const handleReviewOrder = useCallback(() => {
185
+ setReviewOrderButtonClicked(true);
186
+ }, []);
187
+
188
+ const handleReviewOrderEnterKeyPress = useCallback(() => {
189
+ event => {
190
+ if (event.key === 'Enter') {
191
+ handleReviewOrder();
192
+ }
193
+ };
194
+ }, [handleReviewOrder]);
195
+
196
+ const resetReviewOrderButtonClicked = useCallback(() => {
197
+ setReviewOrderButtonClicked(false);
198
+ }, []);
199
+
200
+ const scrollShippingInformationIntoView = useCallback(() => {
201
+ if (shippingInformationRef.current) {
202
+ shippingInformationRef.current.scrollIntoView({
203
+ behavior: 'smooth'
204
+ });
205
+ }
206
+ }, [shippingInformationRef]);
207
+
208
+ const setShippingInformationDone = useCallback(() => {
209
+ if (checkoutStep === CHECKOUT_STEP.SHIPPING_ADDRESS) {
210
+ setCheckoutStep(CHECKOUT_STEP.SHIPPING_METHOD);
211
+ }
212
+ }, [checkoutStep]);
213
+
214
+ const scrollShippingMethodIntoView = useCallback(() => {
215
+ if (shippingMethodRef.current) {
216
+ shippingMethodRef.current.scrollIntoView({
217
+ behavior: 'smooth'
218
+ });
219
+ }
220
+ }, [shippingMethodRef]);
221
+
222
+ const setShippingMethodDone = useCallback(() => {
223
+ if (checkoutStep === CHECKOUT_STEP.SHIPPING_METHOD) {
224
+ setCheckoutStep(CHECKOUT_STEP.PAYMENT);
225
+ }
226
+ }, [checkoutStep]);
227
+
228
+ const setPaymentInformationDone = useCallback(() => {
229
+ if (checkoutStep === CHECKOUT_STEP.PAYMENT) {
230
+ globalThis.scrollTo({
231
+ left: 0,
232
+ top: 0,
233
+ behavior: 'smooth'
234
+ });
235
+ setCheckoutStep(CHECKOUT_STEP.REVIEW);
236
+ }
237
+ }, [checkoutStep]);
238
+
239
+ const [isPlacingOrder, setIsPlacingOrder] = useState(false);
240
+
241
+ const handlePlaceOrder = useCallback(async () => {
242
+ // Fetch order details and then use an effect to actually place the
243
+ // order. If/when Apollo returns promises for invokers from useLazyQuery
244
+ // we can just await this function and then perform the rest of order
245
+ // placement.
246
+ await getOrderDetails({
247
+ variables: {
248
+ cartId
249
+ }
250
+ });
251
+ setPlaceOrderButtonClicked(true);
252
+ setIsPlacingOrder(true);
253
+ }, [cartId, getOrderDetails]);
254
+
255
+ const handlePlaceOrderEnterKeyPress = useCallback(() => {
256
+ event => {
257
+ if (event.key === 'Enter') {
258
+ handlePlaceOrder();
259
+ }
260
+ };
261
+ }, [handlePlaceOrder]);
262
+
263
+ const [, { dispatch }] = useEventingContext();
264
+
265
+ // Go back to checkout if shopper logs in
266
+ useEffect(() => {
267
+ if (isSignedIn) {
268
+ setActiveContent('checkout');
269
+ }
270
+ }, [isSignedIn]);
271
+
272
+ useEffect(() => {
273
+ async function placeOrderAndCleanup() {
274
+ try {
275
+ const reCaptchaData = await generateReCaptchaData();
276
+
277
+ await placeOrder({
278
+ variables: {
279
+ cartId
280
+ },
281
+ ...reCaptchaData
282
+ });
283
+ // Cleanup stale cart and customer info.
284
+ await removeCart();
285
+ await apolloClient.clearCacheData(apolloClient, 'cart');
286
+
287
+ await createCart({
288
+ fetchCartId
289
+ });
290
+ } catch (err) {
291
+ console.error(
292
+ 'An error occurred during when placing the order',
293
+ err
294
+ );
295
+ setPlaceOrderButtonClicked(false);
296
+ }
297
+ }
298
+
299
+ if (orderDetailsData && isPlacingOrder) {
300
+ setIsPlacingOrder(false);
301
+ placeOrderAndCleanup();
302
+ }
303
+ }, [
304
+ apolloClient,
305
+ cartId,
306
+ createCart,
307
+ fetchCartId,
308
+ generateReCaptchaData,
309
+ orderDetailsData,
310
+ placeOrder,
311
+ removeCart,
312
+ isPlacingOrder
313
+ ]);
314
+
315
+ useEffect(async () => {
316
+ await setCheckoutState(false);
317
+ }, [setCheckoutState]);
318
+
319
+ useEffect(() => {
320
+ if (
321
+ checkoutStep === CHECKOUT_STEP.SHIPPING_ADDRESS &&
322
+ cartItems.length
323
+ ) {
324
+ dispatch({
325
+ type: 'CHECKOUT_PAGE_VIEW',
326
+ payload: {
327
+ cart_id: cartId,
328
+ products: cartItems
329
+ }
330
+ });
331
+ } else if (reviewOrderButtonClicked) {
332
+ dispatch({
333
+ type: 'CHECKOUT_REVIEW_BUTTON_CLICKED',
334
+ payload: {
335
+ cart_id: cartId
336
+ }
337
+ });
338
+ } else if (
339
+ placeOrderButtonClicked &&
340
+ orderDetailsData &&
341
+ orderDetailsData.cart
342
+ ) {
343
+ const shipping =
344
+ orderDetailsData.cart?.shipping_addresses &&
345
+ orderDetailsData.cart.shipping_addresses.reduce(
346
+ (result, item) => {
347
+ return [
348
+ ...result,
349
+ {
350
+ ...item.selected_shipping_method
351
+ }
352
+ ];
353
+ },
354
+ []
355
+ );
356
+ const eventPayload = {
357
+ cart_id: cartId,
358
+ amount: orderDetailsData.cart.prices,
359
+ shipping: shipping,
360
+ payment: orderDetailsData.cart.selected_payment_method,
361
+ products: orderDetailsData.cart.items
362
+ };
363
+ if (isPlacingOrder) {
364
+ dispatch({
365
+ type: 'CHECKOUT_PLACE_ORDER_BUTTON_CLICKED',
366
+ payload: eventPayload
367
+ });
368
+ } else if (placeOrderData && orderDetailsData?.cart.id === cartId) {
369
+ dispatch({
370
+ type: 'ORDER_CONFIRMATION_PAGE_VIEW',
371
+ payload: {
372
+ order_number:
373
+ placeOrderData.placeOrder.order.order_number,
374
+ ...eventPayload
375
+ }
376
+ });
377
+ }
378
+ }
379
+ }, [
380
+ placeOrderButtonClicked,
381
+ cartId,
382
+ checkoutStep,
383
+ orderDetailsData,
384
+ cartItems,
385
+ isLoading,
386
+ dispatch,
387
+ placeOrderData,
388
+ isPlacingOrder,
389
+ reviewOrderButtonClicked
390
+ ]);
391
+
392
+ return {
393
+ activeContent,
394
+ availablePaymentMethods: checkoutData
395
+ ? checkoutData?.cart?.available_payment_methods
396
+ : null,
397
+ cartItems,
398
+ checkoutStep,
399
+ customer,
400
+ error: checkoutError,
401
+ guestSignInUsername,
402
+ handlePlaceOrder,
403
+ handlePlaceOrderEnterKeyPress,
404
+ hasError: !!checkoutError,
405
+ isCartEmpty: !(checkoutData && checkoutData?.cart?.total_quantity),
406
+ isGuestCheckout: !isSignedIn,
407
+ isLoading,
408
+ isUpdating,
409
+ orderDetailsData,
410
+ orderDetailsLoading,
411
+ orderNumber:
412
+ (placeOrderData && placeOrderData.placeOrder.order.order_number) ||
413
+ null,
414
+ placeOrderLoading,
415
+ placeOrderButtonClicked,
416
+ setCheckoutStep,
417
+ setGuestSignInUsername,
418
+ setIsUpdating,
419
+ setShippingInformationDone,
420
+ setShippingMethodDone,
421
+ setPaymentInformationDone,
422
+ scrollShippingInformationIntoView,
423
+ shippingInformationRef,
424
+ shippingMethodRef,
425
+ scrollShippingMethodIntoView,
426
+ resetReviewOrderButtonClicked,
427
+ handleReviewOrder,
428
+ handleReviewOrderEnterKeyPress,
429
+ reviewOrderButtonClicked,
430
+ recaptchaWidgetProps,
431
+ toggleAddressBookContent,
432
+ toggleSignInContent
433
+ };
434
+ };
@@ -45,15 +45,6 @@ const Adapter = props => {
45
45
  // const getWebsiteByUserIp = {
46
46
  // countryCode: 'SG'
47
47
  // }
48
-
49
- // Check split cart
50
- useEffect(() => {
51
- if (pathname && pathname.includes('cart')) {
52
- console.log('INI CART PAGE')
53
- } else {
54
- console.log('INI BUKAN CART PAGE')
55
- }
56
- }, [pathname]);
57
48
 
58
49
  useEffect(() => {
59
50
  if (websiteCodeInUrl) {
@@ -195,7 +195,7 @@ const Product = props => {
195
195
  />
196
196
  </div>
197
197
  {editItemSection}
198
- <li>
198
+ <span>
199
199
  <AddToListButton
200
200
  // {...addToWishlistProps}
201
201
  afterAdd={afterAdd}
@@ -210,7 +210,7 @@ const Product = props => {
210
210
  }}
211
211
  icon={HeartIcon}
212
212
  />
213
- </li>
213
+ </span>
214
214
  {/* <Section
215
215
  // text={formatMessage({
216
216
  // id: 'product.removeFromCart',
@@ -67,14 +67,14 @@ const ProductListing = props => {
67
67
  const { seller_id, seller_name, seller_url } = item.seller;
68
68
 
69
69
  if (!acc[seller_id]) {
70
- acc[seller_id] = {
71
- seller: {
72
- seller_id,
73
- seller_name,
74
- seller_url
75
- },
76
- items: []
77
- };
70
+ acc[seller_id] = {
71
+ seller: {
72
+ seller_id,
73
+ seller_name,
74
+ seller_url
75
+ },
76
+ items: []
77
+ };
78
78
  }
79
79
 
80
80
  acc[seller_id].items.push(item);
@@ -147,7 +147,7 @@ const Header = props => {
147
147
  hasBeenOffline={hasBeenOffline}
148
148
  isOnline={isOnline}
149
149
  />
150
- <style jsx>
150
+ <style jsx="true">
151
151
  {`
152
152
  .logo-wrapper>img:first-child {
153
153
  height: ${IMAGE_HEIGHT}px;
@@ -27,7 +27,7 @@ export const useSeller = props => {
27
27
  nextFetchPolicy: 'cache-first'
28
28
  });
29
29
 
30
- const slug = pathname.split('/').pop();
30
+ const slug = pathname.split('/')[2];
31
31
  const productUrlSuffix = storeConfigData?.storeConfig?.product_url_suffix;
32
32
  const urlKey = productUrlSuffix ? slug.replace(productUrlSuffix, '') : slug;
33
33
 
@@ -0,0 +1,96 @@
1
+ import { gql } from '@apollo/client';
2
+ export const GET_STORE_CONFIG_DATA = gql`
3
+ query GetStoreConfigForMegaMenu {
4
+ # eslint-disable-next-line @graphql-eslint/require-id-when-available
5
+ storeConfig {
6
+ store_code
7
+ category_url_suffix
8
+ }
9
+ }
10
+ `;
11
+
12
+ export const GET_MEGA_MENU = gql`
13
+ query getMegaMenu {
14
+ # eslint-disable-next-line @graphql-eslint/require-id-when-available
15
+ categoryList {
16
+ uid
17
+ name
18
+ # eslint-disable-next-line @graphql-eslint/require-id-when-available
19
+ children {
20
+ uid
21
+ include_in_menu
22
+ name
23
+ position
24
+ url_path
25
+ custom_submenu {
26
+ name
27
+ attribute {
28
+ code
29
+ value
30
+ }
31
+ path
32
+ }
33
+ shop_by {
34
+ name
35
+ code
36
+ items {
37
+ name
38
+ option_id
39
+ url_path
40
+ }
41
+ }
42
+ # eslint-disable-next-line @graphql-eslint/require-id-when-available
43
+ children {
44
+ uid
45
+ include_in_menu
46
+ name
47
+ position
48
+ url_path
49
+ custom_submenu {
50
+ name
51
+ attribute {
52
+ code
53
+ value
54
+ }
55
+ path
56
+ }
57
+ shop_by {
58
+ name
59
+ items {
60
+ name
61
+ url_path
62
+ }
63
+ }
64
+ # eslint-disable-next-line @graphql-eslint/require-id-when-available
65
+ children {
66
+ uid
67
+ include_in_menu
68
+ name
69
+ position
70
+ url_path
71
+ custom_submenu {
72
+ name
73
+ attribute {
74
+ code
75
+ value
76
+ }
77
+ path
78
+ }
79
+ shop_by {
80
+ name
81
+ items {
82
+ name
83
+ url_path
84
+ }
85
+ }
86
+ }
87
+ }
88
+ }
89
+ }
90
+ }
91
+ `;
92
+
93
+ export default {
94
+ getMegaMenuQuery: GET_MEGA_MENU,
95
+ getStoreConfigQuery: GET_STORE_CONFIG_DATA
96
+ };