@riosst100/pwa-marketplace 3.1.8 → 3.2.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.
Files changed (39) hide show
  1. package/i18n/en_US.json +30 -1
  2. package/i18n/id_ID.json +30 -1
  3. package/package.json +1 -1
  4. package/src/components/AboutUs/aboutUs.js +9 -0
  5. package/src/components/AboutUs/index.js +1 -0
  6. package/src/components/AgeVerification/ageVerificationModal.js +163 -0
  7. package/src/components/AgeVerification/ageVerificationModal.module.css +85 -0
  8. package/src/components/AgeVerification/ageVerificationModal.shimmer.js +21 -0
  9. package/src/components/AgeVerification/index.js +2 -0
  10. package/src/components/AgeVerification/sellerCoupon.js +119 -0
  11. package/src/components/AgeVerification/sellerCouponCheckout.js +164 -0
  12. package/src/components/HelpCenter/helpCenter.js +95 -23
  13. package/src/components/HelpCenter/helpcenter.module.css +15 -2
  14. package/src/components/HelpCenter/questionDetail.js +1 -1
  15. package/src/components/LiveChat/MessagesModal.js +345 -0
  16. package/src/components/LiveChat/chatContent.js +3 -2
  17. package/src/components/MaintenancePage/maintenancePage.js +2 -2
  18. package/src/components/SellerCoupon/sellerCouponCheckout.js +2 -2
  19. package/src/components/SellerDetail/sellerDetail.js +38 -36
  20. package/src/components/SellerMegaMenu/sellerMegaMenu.js +2 -3
  21. package/src/components/SellerMegaMenu/sellerMegaMenuItem.js +1 -19
  22. package/src/components/SellerProducts/productContent.js +1 -6
  23. package/src/components/WebsiteSwitcher/websiteSwitcherItem.js +17 -7
  24. package/src/intercept.js +21 -0
  25. package/src/overwrites/venia-ui/lib/components/Adapter/adapter.js +23 -3
  26. package/src/overwrites/venia-ui/lib/components/FilterModal/CurrentFilters/currentFilters.js +1 -1
  27. package/src/overwrites/venia-ui/lib/components/Footer/footer.js +21 -22
  28. package/src/overwrites/venia-ui/lib/components/Footer/sampleData.js +35 -31
  29. package/src/overwrites/venia-ui/lib/components/Header/header.js +2 -2
  30. package/src/overwrites/venia-ui/lib/components/ProductFullDetail/productFullDetail.js +105 -3
  31. package/src/overwrites/venia-ui/lib/components/StoreCodeRoute/storeCodeRoute.js +55 -53
  32. package/src/talons/HelpCenter/helpCenter.gql.js +50 -39
  33. package/src/talons/HelpCenter/useHelpCenter.js +67 -7
  34. package/src/talons/Seller/seller.gql.js +90 -0
  35. package/src/talons/Seller/useSeller.js +102 -4
  36. package/src/talons/SellerMegaMenu/megaMenu.gql.js +11 -18
  37. package/src/talons/SellerMegaMenu/useSellerMegaMenu.js +59 -2
  38. package/src/talons/SellerProducts/productContent.gql.js +5 -0
  39. package/src/talons/SellerProducts/useProductContent.js +61 -2
@@ -1,5 +1,6 @@
1
- import { useQuery } from '@apollo/client';
2
- import { useEffect, useMemo } from 'react';
1
+ import { useQuery, useMutation } from '@apollo/client';
2
+ import { useEffect, useMemo, useCallback, useState } from 'react';
3
+ import { useToasts } from '@magento/peregrine/lib/Toasts/useToasts';
3
4
  import { useLocation } from 'react-router-dom';
4
5
  import { useAppContext } from '@magento/peregrine/lib/context/app';
5
6
  import { useIntl } from 'react-intl';
@@ -13,7 +14,15 @@ export const useSeller = props => {
13
14
  const { formatMessage } = useIntl();
14
15
 
15
16
  const operations = mergeOperations(DEFAULT_OPERATIONS, props.operations);
16
- const { getStoreConfigData, getSellerDetailQuery, getCouponCodeQuery } = operations;
17
+ const {
18
+ getStoreConfigData,
19
+ getSellerDetailQuery,
20
+ getCouponCodeQuery,
21
+ getCustomerSellerMessages,
22
+ customerSendMessageMutation,
23
+ customerReplyMessageMutation,
24
+ customerDeleteMessageMutation
25
+ } = operations;
17
26
  const { pathname } = useLocation();
18
27
  const [
19
28
  ,
@@ -27,6 +36,8 @@ export const useSeller = props => {
27
36
  nextFetchPolicy: 'cache-first'
28
37
  });
29
38
 
39
+ const [, { addToast }] = useToasts();
40
+
30
41
  const slug = pathname.split('/')[2];
31
42
  const productUrlSuffix = storeConfigData?.storeConfig?.product_url_suffix;
32
43
  const urlKey = productUrlSuffix ? slug.replace(productUrlSuffix, '') : slug;
@@ -100,6 +111,82 @@ export const useSeller = props => {
100
111
  storeConfig: storeConfigData ? storeConfigData.storeConfig : {}
101
112
  };
102
113
 
114
+ // Messages state
115
+ const [messageListVars, setMessageListVars] = useState({
116
+ pageSize: 500,
117
+ currentPage: 1,
118
+ filter: undefined,
119
+ sort: undefined
120
+ });
121
+
122
+ const {
123
+ data: messagesData,
124
+ loading: messagesLoading,
125
+ error: messagesError,
126
+ refetch: refetchMessages
127
+ } = useQuery(getCustomerSellerMessages, {
128
+ fetchPolicy: 'network-only',
129
+ nextFetchPolicy: 'network-only',
130
+ skip: !storeConfigData,
131
+ variables: messageListVars,
132
+ pollInterval: 10000,
133
+ notifyOnNetworkStatusChange: true
134
+ });
135
+
136
+ const [sendMessage, { loading: sendLoading }] = useMutation(customerSendMessageMutation);
137
+ const [replyMessage, { loading: replyLoading }] = useMutation(customerReplyMessageMutation);
138
+ const [deleteMessage, { loading: deleteLoading }] = useMutation(customerDeleteMessageMutation);
139
+
140
+ const handleSendMessage = useCallback(async ({ subject, content, seller_url }) => {
141
+ const input = {
142
+ subject,
143
+ content,
144
+ seller_url
145
+ };
146
+ const result = await sendMessage({ variables: { input }, refetchQueries: [{ query: getCustomerSellerMessages, variables: messageListVars }] });
147
+ addToast({
148
+ type: 'success',
149
+ message: formatMessage({
150
+ id: 'messages.messageSent',
151
+ defaultMessage: 'Message sent successfully.'
152
+ }),
153
+ timeout: 3000
154
+ });
155
+ await refetchMessages({ fetchPolicy: 'network-only' });
156
+ return result?.data?.customerSendMessage;
157
+ }, [sendMessage, refetchMessages, addToast, formatMessage]);
158
+
159
+ const handleReplyMessage = useCallback(async ({ message_id, content }) => {
160
+ const input = {
161
+ message_id,
162
+ content
163
+ };
164
+ const result = await replyMessage({ variables: { input }, refetchQueries: [{ query: getCustomerSellerMessages, variables: messageListVars }] });
165
+ addToast({
166
+ type: 'success',
167
+ message: formatMessage({
168
+ id: 'messages.replySent',
169
+ defaultMessage: 'Reply sent successfully.'
170
+ }),
171
+ timeout: 3000
172
+ });
173
+ await refetchMessages({ fetchPolicy: 'network-only' });
174
+ return result?.data?.customerReplyMessage;
175
+ }, [replyMessage, refetchMessages, addToast, formatMessage]);
176
+
177
+ const handleDeleteMessage = useCallback(async ({ id }) => {
178
+ await deleteMessage({ variables: { id }, refetchQueries: [{ query: getCustomerSellerMessages, variables: messageListVars }] });
179
+ addToast({
180
+ type: 'success',
181
+ message: formatMessage({
182
+ id: 'messages.messageDeleted',
183
+ defaultMessage: 'Message deleted successfully.'
184
+ }),
185
+ timeout: 3000
186
+ });
187
+ await refetchMessages({ fetchPolicy: 'network-only' });
188
+ }, [deleteMessage, refetchMessages, addToast, formatMessage]);
189
+
103
190
  return {
104
191
  error,
105
192
  loading,
@@ -107,6 +194,17 @@ export const useSeller = props => {
107
194
  favoriteSellerButtonProps,
108
195
  couponData,
109
196
  couponError,
110
- couponLoading
197
+ couponLoading,
198
+ // messages
199
+ messages: messagesData?.customer?.sellerMessages,
200
+ messagesLoading,
201
+ messagesError,
202
+ setMessageListVars,
203
+ sendLoading,
204
+ replyLoading,
205
+ deleteLoading,
206
+ handleSendMessage,
207
+ handleReplyMessage,
208
+ handleDeleteMessage
111
209
  };
112
210
  };
@@ -10,9 +10,9 @@ export const GET_STORE_CONFIG_DATA = gql`
10
10
  `;
11
11
 
12
12
  export const GET_MEGA_MENU = gql`
13
- query getMegaMenu {
13
+ query getSellerMegaMenu {
14
14
  # eslint-disable-next-line @graphql-eslint/require-id-when-available
15
- categoryList {
15
+ sellerCategories {
16
16
  uid
17
17
  name
18
18
  # eslint-disable-next-line @graphql-eslint/require-id-when-available
@@ -22,22 +22,10 @@ export const GET_MEGA_MENU = gql`
22
22
  name
23
23
  position
24
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
- }
25
+ default_top_filter {
26
+ attribute_code
27
+ label
28
+ value
41
29
  }
42
30
  # eslint-disable-next-line @graphql-eslint/require-id-when-available
43
31
  children {
@@ -46,6 +34,11 @@ export const GET_MEGA_MENU = gql`
46
34
  name
47
35
  position
48
36
  url_path
37
+ default_top_filter {
38
+ attribute_code
39
+ label
40
+ value
41
+ }
49
42
  custom_submenu {
50
43
  name
51
44
  attribute {
@@ -1,5 +1,5 @@
1
1
  import { useMemo, useState, useCallback, useEffect } from 'react';
2
- import { useLocation } from 'react-router-dom';
2
+ import { useLocation, useHistory } from 'react-router-dom';
3
3
  import { useInternalLink } from '@magento/peregrine/lib/hooks/useInternalLink';
4
4
 
5
5
  import { useQuery } from '@apollo/client';
@@ -8,6 +8,7 @@ import { useEventListener } from '@magento/peregrine/lib/hooks/useEventListener'
8
8
  import mergeOperations from '@magento/peregrine/lib/util/shallowMerge';
9
9
  import DEFAULT_OPERATIONS from './megaMenu.gql';
10
10
 
11
+
11
12
  /**
12
13
  * The useSellerMegaMenu talon complements the SellerMegaMenu component.
13
14
  *
@@ -107,9 +108,65 @@ export const useSellerMegaMenu = (props = {}) => {
107
108
  );
108
109
 
109
110
  const megaMenuData = useMemo(() => {
110
- return data ? processData(data.categoryList[0]) : {};
111
+ return data ? processData(data.sellerCategories[0]) : {};
111
112
  }, [data, processData]);
112
113
 
114
+ const category = useMemo(() => {
115
+ return Array.isArray(megaMenuData?.children)
116
+ ? megaMenuData.children[0]
117
+ : [];
118
+ }, [megaMenuData]);
119
+
120
+ const history = useHistory();
121
+
122
+ const setQueryParam = ({ history, location, parameter, replace, value }) => {
123
+ const { search } = location;
124
+ const queryParams = new URLSearchParams(search);
125
+
126
+ queryParams.set(parameter, value);
127
+ const destination = { search: queryParams.toString() };
128
+
129
+ if (replace) {
130
+ history.replace(destination);
131
+ } else {
132
+ history.push(destination);
133
+ }
134
+ };
135
+
136
+ const setDefaultSubcategoryAndTopFilter = useCallback(
137
+ (value, searchParam, replace = false) => {
138
+ // Update the query parameter.
139
+ setQueryParam({
140
+ history,
141
+ location,
142
+ parameter: searchParam,
143
+ replace,
144
+ value: value
145
+ });
146
+ },
147
+ [history, location]
148
+ );
149
+
150
+ useEffect(() => {
151
+ const { search } = location;
152
+
153
+ // if (category && category.default_top_filter) {
154
+ // const defaultTopFilter = category.default_top_filter;
155
+
156
+ // const attrCode = defaultTopFilter.attribute_code;
157
+ // const label = defaultTopFilter.label;
158
+ // const value = defaultTopFilter.value;
159
+
160
+ // if (!search.includes(attrCode)) {
161
+ // setDefaultSubcategoryAndTopFilter(
162
+ // label + ',' + value,
163
+ // attrCode + '[filter]',
164
+ // true
165
+ // );
166
+ // }
167
+ // }
168
+ }, [category, location, setDefaultSubcategoryAndTopFilter]);
169
+
113
170
  const findActiveCategory = useCallback(
114
171
  (pathname, category) => {
115
172
  if (isActive(category)) {
@@ -35,6 +35,11 @@ export const GET_CATEGORY_CONTENT = gql`
35
35
  url_key
36
36
  url_path
37
37
  prefixes
38
+ default_top_filter {
39
+ attribute_code
40
+ label
41
+ value
42
+ }
38
43
  parent {
39
44
  uid
40
45
  name
@@ -1,6 +1,6 @@
1
- import React, { useEffect, useMemo } from 'react';
1
+ import React, { useCallback, useEffect, useMemo } from 'react';
2
2
  import { useLazyQuery, useQuery } from '@apollo/client';
3
-
3
+ import { useLocation, useHistory } from 'react-router-dom';
4
4
  import mergeOperations from '@magento/peregrine/lib/util/shallowMerge';
5
5
  import { useEventingContext } from '@magento/peregrine/lib/context/eventing';
6
6
 
@@ -48,6 +48,8 @@ export const useProductContent = props => {
48
48
  }
49
49
  );
50
50
 
51
+
52
+
51
53
  const { data: categoryData, loading: categoryLoading } = useQuery(
52
54
  getCategoryContentQuery,
53
55
  {
@@ -60,6 +62,9 @@ export const useProductContent = props => {
60
62
  }
61
63
  );
62
64
 
65
+ // console.log('categoryData',categoryData)
66
+ // console.log('categoryId',categoryId)
67
+
63
68
  const [, { dispatch }] = useEventingContext();
64
69
 
65
70
  useEffect(() => {
@@ -94,6 +99,7 @@ export const useProductContent = props => {
94
99
  categoryData && categoryData.categories.items.length
95
100
  ? categoryData.categories.items[0]
96
101
  : null;
102
+ // console.log('categorycategory',category)
97
103
  const children =
98
104
  categoryData && categoryData.categories.items.length
99
105
  ? categoryData.categories.items[0].children
@@ -101,6 +107,59 @@ export const useProductContent = props => {
101
107
 
102
108
  const filters = [];
103
109
 
110
+ const history = useHistory();
111
+ const location = useLocation();
112
+
113
+ const setQueryParam = ({ history, location, parameter, replace, value }) => {
114
+ const { search } = location;
115
+ const queryParams = new URLSearchParams(search);
116
+
117
+ queryParams.set(parameter, value);
118
+ const destination = { search: queryParams.toString() };
119
+
120
+ if (replace) {
121
+ history.replace(destination);
122
+ } else {
123
+ history.push(destination);
124
+ }
125
+ };
126
+
127
+ const setDefaultSubcategoryAndTopFilter = useCallback(
128
+ (value, searchParam, replace = false) => {
129
+ // Update the query parameter.
130
+ setQueryParam({
131
+ history,
132
+ location,
133
+ parameter: searchParam,
134
+ replace,
135
+ value: value
136
+ });
137
+ },
138
+ [history, location]
139
+ );
140
+
141
+ // console.log('category category',category)
142
+
143
+ useEffect(() => {
144
+ const { search } = location;
145
+
146
+ if (category && category.default_top_filter) {
147
+ const defaultTopFilter = category.default_top_filter;
148
+
149
+ const attrCode = defaultTopFilter.attribute_code;
150
+ const label = defaultTopFilter.label;
151
+ const value = defaultTopFilter.value;
152
+
153
+ if (!search.includes(attrCode)) {
154
+ setDefaultSubcategoryAndTopFilter(
155
+ label + ',' + value,
156
+ attrCode + '[filter]',
157
+ true
158
+ );
159
+ }
160
+ }
161
+ }, [category, location, setDefaultSubcategoryAndTopFilter]);
162
+
104
163
  rawFilters && rawFilters.map((filter, index) => {
105
164
 
106
165
  const filterOptions = [];