@riosst100/pwa-marketplace 2.3.7 → 2.3.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.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@riosst100/pwa-marketplace",
3
3
  "author": "riosst100@gmail.com",
4
- "version": "2.3.7",
4
+ "version": "2.3.9",
5
5
  "main": "src/index.js",
6
6
  "pwa-studio": {
7
7
  "targets": {
@@ -43,6 +43,7 @@ module.exports = componentOverrideMapping = {
43
43
  [`@magento/venia-ui/lib/components/QuantityStepper/index.js`]: '@riosst100/pwa-marketplace/src/overwrites/venia-ui/lib/components/QuantityStepper/index.js',
44
44
  // [`@magento/venia-ui/lib/components/RichContent/index.js`]: '@riosst100/pwa-marketplace/src/overwrites/venia-ui/lib/components/RichContent/index.js',
45
45
  [`@magento/venia-ui/lib/components/RadioGroup/radio.js`]: '@riosst100/pwa-marketplace/src/overwrites/venia-ui/lib/components/RadioGroup/radio.js',
46
+ [`@magento/venia-ui/lib/components/RadioGroup/radioGroup.js`]: '@riosst100/pwa-marketplace/src/overwrites/venia-ui/lib/components/RadioGroup/radioGroup.js',
46
47
  [`@magento/venia-ui/lib/components/Button/index.js`]: '@riosst100/pwa-marketplace/src/overwrites/venia-ui/lib/components/Button/index.js',
47
48
  [`@magento/venia-ui/lib/components/RichText/index.js`]: '@riosst100/pwa-marketplace/src/overwrites/venia-ui/lib/components/RichText/index.js',
48
49
  [`@magento/venia-ui/lib/components/Main/index.js`]: '@riosst100/pwa-marketplace/src/overwrites/venia-ui/lib/components/Main/index.js',
@@ -14,6 +14,7 @@ import ArraySearchInput from '@riosst100/pwa-marketplace/src/components/ArraySea
14
14
  import { useCustomSort } from '@riosst100/pwa-marketplace/src/hooks/useCustomSort';
15
15
  import Breadcrumbs from '@magento/venia-ui/lib/components/Breadcrumbs';
16
16
  import { useLocation } from 'react-router-dom';
17
+ import { getFiltersFromSearch } from '@magento/peregrine/lib/talons/FilterModal/helpers';
17
18
 
18
19
  const SetsData = props => {
19
20
  const { categoryId } = props
@@ -232,10 +233,37 @@ const SetsData = props => {
232
233
  setSearchQuery('')
233
234
  }
234
235
 
236
+ const activeFilters = [];
237
+
238
+ const allActiveFilters = getFiltersFromSearch(search);
239
+
240
+ if (allActiveFilters && allActiveFilters.size > 0) {
241
+ allActiveFilters.forEach((value, key) => {
242
+ value.forEach((value) => {
243
+ const filterArr = value.split(',');
244
+
245
+ const label = filterArr[0];
246
+ const optionId = filterArr[1];
247
+ if (label == "Singles") {
248
+ isSingles = true;
249
+ }
250
+ if (key == "card_game" || key == "product_line" && urlKey == "brands" || key == "product_line" && urlKey == "franchise" || key == "franchise" && urlKey == "brands" || key == "franchise" && urlKey == "franchise" || key == "brands" && urlKey == "franchise" || key == "brands" && urlKey == "brands" || virtualCategoryFilters && virtualCategoryFilters.includes(key)) {
251
+ activeFilters.push(
252
+ {
253
+ 'label': label,
254
+ 'code': key,
255
+ 'option_id': optionId
256
+ }
257
+ )
258
+ }
259
+ })
260
+ });
261
+ }
262
+
235
263
  return (
236
264
  <Fragment>
237
265
  <StoreTitle>{title}</StoreTitle>
238
- <Breadcrumbs categoryId={categoryId} customPage={shopby == "singles" ? "Mini-Figures" : title} />
266
+ <Breadcrumbs categoryId={categoryId} currentFilter={activeFilters} customPage={shopby == "singles" ? "Mini-Figures" : title} />
239
267
  {/* <ul className={classes.nav}>
240
268
  <li className={classes.nav_item}>
241
269
  <button
@@ -199,14 +199,19 @@ const CategoryContent = props => {
199
199
  <ProductListTabShimmer />
200
200
  ) : null;
201
201
 
202
+ const formatNumber = (num) => {
203
+ return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
204
+ }
205
+
202
206
  const categoryResultsHeading =
203
207
  galleryItems.length > 0 ? (
204
208
  <FormattedMessage
205
- id={'categoryContent.resultCount'}
209
+ id={'categoryContent.resultAndTotalCount'}
206
210
  values={{
207
- count: galleryItems.length
211
+ count: galleryItems.length,
212
+ total_count: formatNumber(totalCount)
208
213
  }}
209
- defaultMessage={'{count} Results'}
214
+ defaultMessage={"Showing {count} of {total_count} products"}
210
215
  />
211
216
  ) : isLoading ? (
212
217
  <Shimmer width={5} />
@@ -1,4 +1,4 @@
1
- import React, { Fragment, useMemo } from 'react';
1
+ import React, { Fragment, useMemo, useRef } from 'react';
2
2
  import { FormattedMessage } from 'react-intl';
3
3
  import { string } from 'prop-types';
4
4
  import { Link } from 'react-router-dom';
@@ -78,6 +78,35 @@ const Breadcrumbs = props => {
78
78
 
79
79
  const lastIndex = currentFilter ? currentFilter.length - 1 : 0;
80
80
  // const filterpath = ;
81
+
82
+ const { search } = useLocation();
83
+
84
+ // const previousSearch = useRef(search);
85
+
86
+ console.log('search')
87
+ console.log(search)
88
+
89
+ const removeShopbyParam = (url) => {
90
+ const urlParts = url.split("?"); // Pisahkan URL sebelum dan sesudah tanda tanya
91
+ if (urlParts.length < 2) return url; // Jika tidak ada query string, kembalikan URL asli
92
+
93
+ const baseUrl = urlParts[0]; // Bagian URL sebelum query string
94
+ const queryString = urlParts[1]; // Bagian query string
95
+
96
+ // Pisahkan parameter menjadi array
97
+ const params = queryString.split("&").filter(param => !param.startsWith("shopby="));
98
+
99
+ // Gabungkan kembali parameter tanpa "shopby"
100
+ const newQueryString = params.join("&");
101
+
102
+ // Gabungkan URL dasar dengan query string yang telah dimodifikasi
103
+ return newQueryString ? `${baseUrl}?${newQueryString}` : baseUrl;
104
+ }
105
+
106
+ const params = removeShopbyParam(search);
107
+
108
+ console.log("paramsparamsparams")
109
+ console.log(params)
81
110
 
82
111
  currentFilter && currentFilter.length && currentFilter.map((filter, index) => {
83
112
  currentProduct ? (
@@ -102,7 +131,7 @@ const Breadcrumbs = props => {
102
131
  <Link
103
132
  key={index}
104
133
  className={classes.link}
105
- to={resourceUrl('/'+currentCategoryPath)}
134
+ to={resourceUrl('/'+currentCategoryPath+params)}
106
135
  onClick={handleClick}
107
136
  >
108
137
  {filter.label}
@@ -119,7 +148,7 @@ const Breadcrumbs = props => {
119
148
  <Link
120
149
  key={index}
121
150
  className={classes.link}
122
- to={resourceUrl('/'+currentCategoryPath+'?' + filter.code + '[filter]=' + filter.label + ',' + filter.option_id)}
151
+ to={resourceUrl('/'+currentCategoryPath+params)}
123
152
  onClick={handleClick}
124
153
  >
125
154
  {filter.label}
@@ -6,7 +6,7 @@ import { useStyle } from '@magento/venia-ui/lib/classify';
6
6
  import { useIntl } from 'react-intl';
7
7
 
8
8
  const FilterItemRadio = props => {
9
- const { filterApi, group, item, onApply, labels } = props;
9
+ const { filterApi, group, item, isSubFilter, onApply, labels } = props;
10
10
  const { removeGroup, toggleItem } = filterApi;
11
11
  const { title, value } = item;
12
12
  const classes = useStyle(defaultClasses);
@@ -44,6 +44,7 @@ const FilterItemRadio = props => {
44
44
  classes={classes}
45
45
  id={`item-${group}-${value}`}
46
46
  label={title}
47
+ isSubFilter={isSubFilter}
47
48
  value={value}
48
49
  onChange={handleOnchange}
49
50
  data-cy="FilterDefault-radio"
@@ -15,7 +15,7 @@ import { useFieldApi } from 'informed';
15
15
  import useFieldState from '@magento/peregrine/lib/hooks/hook-wrappers/useInformedFieldStateWrapper';
16
16
 
17
17
  const FilterItemRadioGroup = props => {
18
- const { filterApi, filterState, group, items, onApply, labels,isListExpanded = true, itemCountToShow = 5 } = props;
18
+ const { filterApi, filterState, group, isSubFilter, items, onApply, labels,isListExpanded = true, itemCountToShow = 5 } = props;
19
19
 
20
20
  const radioItems = useMemo(() => {
21
21
  return items.map((item,index) => {
@@ -61,7 +61,7 @@ const FilterItemRadioGroup = props => {
61
61
  }, [field, fieldApi, fieldState.value, fieldValue]);
62
62
 
63
63
  return (
64
- <RadioGroup field={field} data-cy="FilterDefault-radioGroup">
64
+ <RadioGroup isSubFilter={isSubFilter} field={field} data-cy="FilterDefault-radioGroup">
65
65
  {radioItems}
66
66
  </RadioGroup>
67
67
  );
@@ -8,6 +8,7 @@ import { useStyle } from '@magento/venia-ui/lib/classify';
8
8
  import FilterItem from './filterItem';
9
9
  import defaultClasses from './filterList.module.css';
10
10
  import FilterItemRadioGroup from './filterItemRadioGroup';
11
+ import SubFilterItemRadioGroup from './subFilterItemRadioGroup';
11
12
 
12
13
  const labels = new WeakMap();
13
14
  const labels2 = new WeakMap();
@@ -19,6 +20,9 @@ const FilterList = props => {
19
20
  filterApi,
20
21
  filterState,
21
22
  filterFrontendInput,
23
+ isSubFilter,
24
+ filterItems,
25
+ subFilterBlock,
22
26
  name,
23
27
  group,
24
28
  itemCountToShow,
@@ -99,12 +103,56 @@ const FilterList = props => {
99
103
  onApply
100
104
  ]);
101
105
 
106
+ // const subFilter = useMemo(
107
+ // () =>
108
+ // Array.from(filterItems, ([group, items], iteration) => {
109
+ // // const blockState = filterState.get(group);
110
+ // // const groupName = filterNames.get(group);
111
+ // // const frontendInput = filterFrontendInput.get(group);
112
+
113
+ // if (group.includes('card_set')) {
114
+ // return (
115
+ // // <FilterBlock
116
+ // // key={group}
117
+ // // filterApi={filterApi}
118
+ // // filterState={blockState}
119
+ // // filterFrontendInput={frontendInput}
120
+ // // group={group}
121
+ // // filterItems={filterItems}
122
+ // // items={items}
123
+ // // name={groupName}
124
+ // // onApply={group == "category_uid" ? handleCategoryApplyFilter : handleApplyFilter}
125
+ // // initialOpen={true}
126
+ // // />
127
+ // <SubFilterItemRadioGroup
128
+ // filterApi={filterApi}
129
+ // filterState={filterState}
130
+ // group={group}
131
+ // name={'Set Name'}
132
+ // items={items}
133
+ // onApply={onApply}
134
+ // labels={labels}
135
+ // isListExpanded={isListExpanded}
136
+ // itemCountToShow={itemCountToShow}
137
+ // />
138
+ // );
139
+ // }
140
+ // }),
141
+ // [
142
+ // filterApi,
143
+ // filterItems
144
+ // ]
145
+ // );
146
+
102
147
  // memoize item creation
103
148
  // search value is not referenced, so this array is stable
104
149
  const itemElements = useMemo(() => {
105
150
  // if (filterFrontendInput === 'boolean') {
106
151
 
107
152
  const key = `item-${group}`;
153
+
154
+ const cardSetGroup = group.replace('card_release', 'card_set');
155
+
108
156
  return (
109
157
  <li
110
158
  key={key}
@@ -116,12 +164,14 @@ const FilterList = props => {
116
164
  filterState={filterState}
117
165
  group={group}
118
166
  name={name}
167
+ isSubFilter={isSubFilter}
119
168
  items={items}
120
169
  onApply={onApply}
121
170
  labels={labels}
122
171
  isListExpanded={isListExpanded}
123
172
  itemCountToShow={itemCountToShow}
124
173
  />
174
+ {group.includes('card_release') && subFilterBlock}
125
175
  </li>
126
176
  );
127
177
  // }
@@ -235,7 +285,7 @@ const FilterList = props => {
235
285
 
236
286
  return (
237
287
  <Fragment>
238
- <ul className={classes.items}>
288
+ <ul className={isSubFilter ? classes.sub_items : classes.items}>
239
289
  {itemElements}
240
290
  {showMoreItem}
241
291
  </ul>
@@ -8,6 +8,15 @@
8
8
  composes: border-gray-100 from global;
9
9
  }
10
10
 
11
+ .sub_items {
12
+ composes: gap-[15px] from global;
13
+ composes: grid from global;
14
+ /* composes: -ml-1.5 from global; */
15
+ composes: py-2.5 from global;
16
+ grid-template-columns: 100%;
17
+ composes: border-gray-100 from global;
18
+ }
19
+
11
20
  .showMoreLessItem {
12
21
  composes: pl-1 from global;
13
22
  }
@@ -0,0 +1,91 @@
1
+ import React, { useMemo, useEffect } from 'react';
2
+ import {
3
+ arrayOf,
4
+ func,
5
+ number,
6
+ oneOfType,
7
+ shape,
8
+ string,
9
+ instanceOf
10
+ } from 'prop-types';
11
+ import setValidator from '@magento/peregrine/lib/validators/set';
12
+ import RadioGroup from '@magento/venia-ui/lib/components/RadioGroup';
13
+ import FilterItemRadio from './filterItemRadio';
14
+ import { useFieldApi } from 'informed';
15
+ import useFieldState from '@magento/peregrine/lib/hooks/hook-wrappers/useInformedFieldStateWrapper';
16
+
17
+ const SubFilterItemRadioGroup = props => {
18
+ const { filterApi, filterState, group, items, onApply, labels,isListExpanded = true, itemCountToShow = 5 } = props;
19
+
20
+ const radioItems = useMemo(() => {
21
+ return items.map((item,index) => {
22
+ if (!isListExpanded && index >= itemCountToShow) {
23
+ return null;
24
+ }
25
+
26
+ const code = `item-${group}-${item.value}`;
27
+ return (
28
+ <FilterItemRadio
29
+ key={code}
30
+ filterApi={filterApi}
31
+ filterState={filterState}
32
+ group={group}
33
+ item={item}
34
+ onApply={onApply}
35
+ labels={labels}
36
+ />
37
+ );
38
+ });
39
+ }, [filterApi, filterState, group, items, labels, onApply,isListExpanded,itemCountToShow]);
40
+
41
+ const fieldValue = useMemo(() => {
42
+ if (filterState) {
43
+ for (const item of items) {
44
+ if (filterState.has(item)) {
45
+ return item.value;
46
+ }
47
+ }
48
+ }
49
+
50
+ return null;
51
+ }, [filterState, items]);
52
+ const field = `item-${group}`;
53
+ const fieldApi = useFieldApi(field);
54
+ const fieldState = useFieldState(field);
55
+ useEffect(() => {
56
+ if (field && fieldValue === null) {
57
+ fieldApi.reset();
58
+ } else if (field && fieldValue !== fieldState.value) {
59
+ fieldApi.setValue(fieldValue);
60
+ }
61
+ }, [field, fieldApi, fieldState.value, fieldValue]);
62
+
63
+ return (
64
+ <RadioGroup isSubFilter={true} field={field} data-cy="FilterDefault-radioGroup">
65
+ {radioItems}
66
+ </RadioGroup>
67
+ );
68
+ };
69
+
70
+ SubFilterItemRadioGroup.defaultProps = {
71
+ onApply: null
72
+ };
73
+
74
+ SubFilterItemRadioGroup.propTypes = {
75
+ filterApi: shape({
76
+ toggleItem: func.isRequired
77
+ }).isRequired,
78
+ filterState: setValidator,
79
+ group: string.isRequired,
80
+ items: arrayOf(
81
+ shape({
82
+ title: string.isRequired,
83
+ value: oneOfType([number, string]).isRequired,
84
+ path: string
85
+ })
86
+ ).isRequired,
87
+ onApply: func,
88
+ labels: instanceOf(Map).isRequired
89
+ };
90
+
91
+ export default SubFilterItemRadioGroup;
@@ -19,6 +19,9 @@ const FilterBlock = props => {
19
19
  filterApi,
20
20
  filterState,
21
21
  filterFrontendInput,
22
+ filterItems,
23
+ subFilterBlock,
24
+ isSubFilter,
22
25
  group,
23
26
  items,
24
27
  name,
@@ -72,6 +75,9 @@ const FilterBlock = props => {
72
75
  filterApi={filterApi}
73
76
  filterState={filterState}
74
77
  name={name}
78
+ isSubFilter={isSubFilter}
79
+ subFilterBlock={subFilterBlock}
80
+ filterItems={filterItems}
75
81
  filterFrontendInput={filterFrontendInput}
76
82
  group={group}
77
83
  items={items}
@@ -86,7 +92,7 @@ const FilterBlock = props => {
86
92
  aria-label={itemAriaLabel}
87
93
  data-cy="FilterBlock-root"
88
94
  >
89
- <button
95
+ {name && <button
90
96
  className={classes.trigger}
91
97
  onClick={handleClick}
92
98
  data-cy="FilterBlock-triggerButton"
@@ -103,7 +109,7 @@ const FilterBlock = props => {
103
109
  variant="Outline"
104
110
  />
105
111
  </span>
106
- </button>
112
+ </button>}
107
113
  {list}
108
114
  </li>
109
115
  );
@@ -102,7 +102,26 @@ const FilterSidebar = props => {
102
102
  if (!hideFilters.includes(group) && groupName) {
103
103
 
104
104
  // if (!allowedFiltersArr?.length && group != "category_uid" || allowedFiltersArr?.length && allowedFiltersArr.includes(group)) {
105
-
105
+ let subFilterBlock = '';
106
+ if (group.includes('card_release')) {
107
+ const subGroup = group.replace('card_release', 'card_set');
108
+ const subBlockState = filterState.get(subGroup);
109
+ const subFrontendInput = filterFrontendInput.get(subGroup);
110
+ const subFilterItems = filterItems.get(subGroup);
111
+
112
+ subFilterBlock = <FilterBlock
113
+ key={subGroup}
114
+ filterApi={filterApi}
115
+ filterState={subBlockState}
116
+ filterFrontendInput={subFrontendInput}
117
+ group={subGroup}
118
+ isSubFilter={true}
119
+ items={subFilterItems}
120
+ name={''}
121
+ onApply={handleApplyFilter}
122
+ initialOpen={true}
123
+ />;
124
+ }
106
125
 
107
126
  return (
108
127
  <FilterBlock
@@ -111,6 +130,8 @@ const FilterSidebar = props => {
111
130
  filterState={blockState}
112
131
  filterFrontendInput={frontendInput}
113
132
  group={group}
133
+ filterItems={filterItems}
134
+ subFilterBlock={subFilterBlock}
114
135
  items={items}
115
136
  name={groupName}
116
137
  onApply={group == "category_uid" ? handleCategoryApplyFilter : handleApplyFilter}
@@ -0,0 +1,77 @@
1
+ import React, { Fragment } from 'react';
2
+ import { arrayOf, number, node, oneOfType, shape, string } from 'prop-types';
3
+ import { RadioGroup as InformedRadioGroup } from 'informed';
4
+ import useFieldState from '@magento/peregrine/lib/hooks/hook-wrappers/useInformedFieldStateWrapper';
5
+
6
+ import { useStyle } from '@magento/venia-ui/lib/classify';
7
+ import { Message } from '@magento/venia-ui/lib/components/Field';
8
+ import Radio from './radio';
9
+ import defaultClasses from './radioGroup.module.css';
10
+
11
+ const RadioGroup = props => {
12
+ const {
13
+ children,
14
+ classes: propClasses,
15
+ disabled,
16
+ field,
17
+ id,
18
+ items,
19
+ message,
20
+ isSubFilter,
21
+ ...rest
22
+ } = props;
23
+ const fieldState = useFieldState(field);
24
+ const classes = useStyle(defaultClasses, propClasses);
25
+
26
+ const options =
27
+ children ||
28
+ items.map(({ value, ...item }) => (
29
+ <Radio
30
+ data-cy=""
31
+ key={value}
32
+ disabled={disabled}
33
+ {...item}
34
+ classes={{
35
+ label: classes.radioLabel,
36
+ root: classes.radioContainer
37
+ }}
38
+ id={`${field}--${value}`}
39
+ value={value}
40
+ />
41
+ ));
42
+
43
+ return (
44
+ <Fragment>
45
+ <div data-cy="RadioGroup-root" className={isSubFilter ? classes.sub_root : classes.root}>
46
+ <InformedRadioGroup {...rest} field={field} id={id}>
47
+ {options}
48
+ </InformedRadioGroup>
49
+ </div>
50
+ <Message className={classes.message} fieldState={fieldState}>
51
+ {message}
52
+ </Message>
53
+ </Fragment>
54
+ );
55
+ };
56
+
57
+ export default RadioGroup;
58
+
59
+ RadioGroup.propTypes = {
60
+ children: node,
61
+ classes: shape({
62
+ message: string,
63
+ radioContainer: string,
64
+ radioLabel: string,
65
+ root: string
66
+ }),
67
+ field: string.isRequired,
68
+ id: string,
69
+ items: arrayOf(
70
+ shape({
71
+ key: oneOfType([number, string]),
72
+ label: node,
73
+ value: oneOfType([number, string])
74
+ })
75
+ ),
76
+ message: node
77
+ };
@@ -0,0 +1,30 @@
1
+ .root {
2
+ composes: gap-2xs from global;
3
+ composes: grid from global;
4
+ }
5
+
6
+ .sub_root {
7
+ composes: gap-2xs from global;
8
+ composes: grid from global;
9
+ composes: pl-5 from global;
10
+ }
11
+
12
+ .radioContainer {
13
+ composes: gap-3 from global;
14
+ composes: grid from global;
15
+ composes: grid-flow-col from global;
16
+ composes: justify-center from global;
17
+ composes: leading-normal from global;
18
+ grid-template-areas: 'input label';
19
+ grid-template-columns: min-content 1fr;
20
+ }
21
+
22
+ .message {
23
+ composes: mt-xs from global;
24
+ composes: text-colorDefault from global;
25
+ }
26
+
27
+ /* TODO @TW: cannot compose */
28
+ .message:empty {
29
+ display: none;
30
+ }