@riosst100/pwa-marketplace 1.6.2 → 1.6.4
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 +1 -1
- package/src/components/AlphaFilter/alphaFilter.js +23 -6
- package/src/components/ArraySearchInput/arraySearchInput.js +100 -0
- package/src/components/ArraySearchInput/arraySearchInput.module.css +48 -0
- package/src/components/ArraySearchInput/index.js +1 -0
- package/src/components/CollectibleGameSets/collectibleGameSets.js +53 -25
- package/src/components/CollectibleGameSets/collectibleGameSets.module.css +8 -0
- package/src/components/CustomSortBy/customSortBy.js +9 -11
- package/src/components/CustomSubCategory/subCategory.js +1 -1
- package/src/components/CustomSubCategoryPage/subCategoryPage.js +132 -0
- package/src/components/CustomSubCategoryPage/subCategoryPage.module.css +46 -0
- package/src/components/FilterTop/FilterBlockList/filterTopItemGroup.module.css +1 -1
- package/src/components/FilterTop/filterTop.js +1 -1
- package/src/components/ShopBy/index.js +2 -0
- package/src/components/ShopBy/shopBy.js +237 -0
- package/src/components/ShopBy/shopBy.module.css +46 -0
- package/src/components/ShopBy/shopBy.shimmer.js +50 -0
- package/src/components/ShopByPage/index.js +1 -0
- package/src/components/ShopByPage/shopByPage.js +12 -0
- package/src/components/SubCategory/subCategory.js +1 -1
- package/src/hooks/useCustomSort.js +21 -0
- package/src/intercept.js +1 -8
- package/src/overwrites/peregrine/lib/talons/FilterSidebar/useFilterSidebar.js +2 -2
- package/src/overwrites/peregrine/lib/talons/RootComponents/Category/categoryContent.gql.js +1 -0
- package/src/overwrites/peregrine/lib/talons/RootComponents/Category/categoryFragments.gql.js +31 -0
- package/src/overwrites/venia-ui/lib/RootComponents/Category/category.js +30 -8
- package/src/overwrites/venia-ui/lib/RootComponents/Category/categoryContent.js +30 -3
- package/src/overwrites/venia-ui/lib/components/FilterSidebar/filterSidebar.js +5 -5
- package/src/overwrites/venia-ui/lib/components/Gallery/gallery.js +0 -4
- package/src/talons/ArraySearchInput/useArraySearchInput.js +58 -0
- package/src/talons/CollectibleGameSets/useCollectibleGameSets.js +75 -2
- package/src/talons/ShopBy/shopBy.gql.js +47 -0
- package/src/talons/ShopBy/useShopBy.js +171 -0
- package/src/talons/SubCategoryPage/subCategoryPage.gql.js +36 -0
- package/src/talons/SubCategoryPage/useSubCategoryPage.js +111 -0
package/package.json
CHANGED
|
@@ -15,14 +15,31 @@ import ProductSort from '@riosst100/pwa-marketplace/src/overwrites/venia-ui/lib/
|
|
|
15
15
|
import CustomSortBy from '@riosst100/pwa-marketplace/src/components/CustomSortBy';
|
|
16
16
|
|
|
17
17
|
const AlphaFilter = props => {
|
|
18
|
-
const {items, handleActiveLetter, activeLetter} = props;
|
|
18
|
+
const {items, handleActiveLetter, activeLetter, isSingles } = props;
|
|
19
19
|
|
|
20
20
|
const groupSinglesFirstLetter = (data) => {
|
|
21
21
|
return data.reduce((acc, item) => {
|
|
22
|
-
if (item
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
if (item) {
|
|
23
|
+
const { custom_attributes } = item;
|
|
24
|
+
if (custom_attributes) {
|
|
25
|
+
let cardName = '';
|
|
26
|
+
custom_attributes.some((attribute, index) => {
|
|
27
|
+
const { attribute_metadata, entered_attribute_value, selected_attribute_options } = attribute
|
|
28
|
+
if (attribute_metadata.code == "card_name") {
|
|
29
|
+
cardName = selected_attribute_options.attribute_option[0].label;
|
|
30
|
+
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return false;
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
if (cardName) {
|
|
38
|
+
const firstLetter = cardName.charAt(0).toUpperCase();
|
|
39
|
+
acc[firstLetter] = acc[firstLetter] || [];
|
|
40
|
+
acc[firstLetter].push(item);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
26
43
|
}
|
|
27
44
|
|
|
28
45
|
return acc;
|
|
@@ -34,7 +51,7 @@ const AlphaFilter = props => {
|
|
|
34
51
|
|
|
35
52
|
const alpha = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'];
|
|
36
53
|
|
|
37
|
-
return <>
|
|
54
|
+
return isSingles && <>
|
|
38
55
|
<section className='single_list-indexing-container relative m-auto py-1'>
|
|
39
56
|
<ul className='flex gap-2 justify-center flex-wrap'>
|
|
40
57
|
{alpha.map((letter, index) => (
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import React, { useCallback } from 'react';
|
|
2
|
+
import { bool, shape, string } from 'prop-types';
|
|
3
|
+
import { Form } from 'informed';
|
|
4
|
+
import { useIntl } from 'react-intl';
|
|
5
|
+
import { useSearchBar } from '@magento/peregrine/lib/talons/SearchBar';
|
|
6
|
+
|
|
7
|
+
import { useStyle } from '@magento/venia-ui/lib/classify';
|
|
8
|
+
import Autocomplete from '@magento/venia-ui/lib/components/SearchBar/autocomplete';
|
|
9
|
+
import defaultClasses from './arraySearchInput.module.css';
|
|
10
|
+
import Dropdown from '@riosst100/pwa-marketplace/src/components/Dropdown';
|
|
11
|
+
import cn from 'classnames';
|
|
12
|
+
import SearchField from '@riosst100/pwa-marketplace/src/overwrites/venia-ui/lib/components/SearchBar/searchField';
|
|
13
|
+
import useFieldState from '@magento/peregrine/lib/hooks/hook-wrappers/useInformedFieldStateWrapper';
|
|
14
|
+
import { useArraySearchInput } from '@riosst100/pwa-marketplace/src/talons/ArraySearchInput/useArraySearchInput';
|
|
15
|
+
|
|
16
|
+
const ArraySearchInput = React.forwardRef((props, ref) => {
|
|
17
|
+
const { isOpen, placeholder, setSearchQuery, active, setActive } = props;
|
|
18
|
+
const talonProps = useArraySearchInput({ active });
|
|
19
|
+
// const fieldState = useFieldState('search_query');
|
|
20
|
+
const {
|
|
21
|
+
containerRef,
|
|
22
|
+
// handleChange,
|
|
23
|
+
handleFocus,
|
|
24
|
+
// handleSubmit,
|
|
25
|
+
initialValues,
|
|
26
|
+
isAutoCompleteOpen,
|
|
27
|
+
setIsAutoCompleteOpen,
|
|
28
|
+
valid
|
|
29
|
+
} = talonProps;
|
|
30
|
+
|
|
31
|
+
const handleSubmit = useCallback(
|
|
32
|
+
({ search_query }) => {
|
|
33
|
+
return false;
|
|
34
|
+
},
|
|
35
|
+
[]
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
const handleChange = useCallback(
|
|
39
|
+
value => {
|
|
40
|
+
// const hasValue = !!value;
|
|
41
|
+
// const isValid = hasValue && value.length > 2;
|
|
42
|
+
|
|
43
|
+
setSearchQuery(value)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
// setValid(isValid);
|
|
48
|
+
// setIsAutoCompleteOpen(hasValue);
|
|
49
|
+
},
|
|
50
|
+
[setSearchQuery]
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
const classes = useStyle(defaultClasses, props.classes);
|
|
54
|
+
const rootClassName = isOpen ? classes.root_open : classes.root;
|
|
55
|
+
const { formatMessage } = useIntl();
|
|
56
|
+
|
|
57
|
+
return (
|
|
58
|
+
<div className={rootClassName} data-cy="ArraySearchInput-root" ref={ref}>
|
|
59
|
+
<div ref={containerRef} className={classes.container}>
|
|
60
|
+
<Form
|
|
61
|
+
autoComplete="off"
|
|
62
|
+
className={classes.form}
|
|
63
|
+
initialValues={initialValues}
|
|
64
|
+
onSubmit={handleSubmit}
|
|
65
|
+
>
|
|
66
|
+
<div
|
|
67
|
+
className={cn(
|
|
68
|
+
classes.search,
|
|
69
|
+
'flex flex-row relative border border-gray-100 rounded-full'
|
|
70
|
+
)}
|
|
71
|
+
>
|
|
72
|
+
<SearchField
|
|
73
|
+
addLabel={formatMessage({
|
|
74
|
+
id: 'global.clearText',
|
|
75
|
+
defaultMessage: 'Clear Text'
|
|
76
|
+
})}
|
|
77
|
+
isSearchOpen={isAutoCompleteOpen}
|
|
78
|
+
onChange={handleChange}
|
|
79
|
+
onFocus={handleFocus}
|
|
80
|
+
/>
|
|
81
|
+
</div>
|
|
82
|
+
</Form>
|
|
83
|
+
</div>
|
|
84
|
+
</div>
|
|
85
|
+
);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
export default ArraySearchInput;
|
|
89
|
+
|
|
90
|
+
ArraySearchInput.propTypes = {
|
|
91
|
+
classes: shape({
|
|
92
|
+
autocomplete: string,
|
|
93
|
+
container: string,
|
|
94
|
+
form: string,
|
|
95
|
+
root: string,
|
|
96
|
+
root_open: string,
|
|
97
|
+
search: string
|
|
98
|
+
}),
|
|
99
|
+
isOpen: bool
|
|
100
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
.root {
|
|
2
|
+
composes: items-center from global;
|
|
3
|
+
composes: justify-items-center from global;
|
|
4
|
+
composes: justify-self-center from global;
|
|
5
|
+
composes: py-0 from global;
|
|
6
|
+
composes: w-full from global;
|
|
7
|
+
|
|
8
|
+
/* TODO @TW: review (B6) */
|
|
9
|
+
/* composes: hidden from global; */
|
|
10
|
+
display: none;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.root_open {
|
|
14
|
+
composes: root;
|
|
15
|
+
|
|
16
|
+
composes: z-dropdown from global;
|
|
17
|
+
|
|
18
|
+
/* TODO @TW: review (B6) */
|
|
19
|
+
/* composes: grid from global; */
|
|
20
|
+
display: grid;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.form {
|
|
24
|
+
composes: grid from global;
|
|
25
|
+
composes: items-center from global;
|
|
26
|
+
composes: justify-items-stretch from global;
|
|
27
|
+
composes: w-full from global;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.container {
|
|
31
|
+
composes: inline-flex from global;
|
|
32
|
+
composes: items-center from global;
|
|
33
|
+
composes: justify-center from global;
|
|
34
|
+
composes: max-w-full from global;
|
|
35
|
+
composes: relative from global;
|
|
36
|
+
composes: w-full from global;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.search {
|
|
40
|
+
composes: relative from global;
|
|
41
|
+
padding-left: 20px;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.autocomplete {
|
|
45
|
+
composes: grid from global;
|
|
46
|
+
/* composes: relative from global; */
|
|
47
|
+
composes: z-menu from global;
|
|
48
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './arraySearchInput';
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import React, { Fragment, useState } from 'react';
|
|
2
|
-
import { FormattedMessage } from 'react-intl';
|
|
3
|
-
import { useSeller } from '@riosst100/pwa-marketplace/src/talons/Seller/useSeller';
|
|
1
|
+
import React, { Fragment, useEffect, useMemo, useState } from 'react';
|
|
4
2
|
import ErrorView from '@magento/venia-ui/lib/components/ErrorView';
|
|
5
3
|
import { StoreTitle, Meta } from '@magento/venia-ui/lib/components/Head';
|
|
6
4
|
import { useCollectibleGameSets } from '@riosst100/pwa-marketplace/src/talons/CollectibleGameSets/useCollectibleGameSets';
|
|
@@ -11,22 +9,35 @@ import { useStyle } from '@magento/venia-ui/lib/classify';
|
|
|
11
9
|
import cn from 'classnames';
|
|
12
10
|
import Divider from '@riosst100/pwa-marketplace/src/components/Divider';
|
|
13
11
|
import { CollectibleGameSetsShimmer } from '@riosst100/pwa-marketplace/src/components/CollectibleGameSets';
|
|
14
|
-
import ProductSort from '@riosst100/pwa-marketplace/src/overwrites/venia-ui/lib/components/ProductSort';
|
|
15
12
|
import CustomSortBy from '@riosst100/pwa-marketplace/src/components/CustomSortBy';
|
|
13
|
+
import ArraySearchInput from '@riosst100/pwa-marketplace/src/components/ArraySearchInput';
|
|
14
|
+
import { useCustomSort } from '@riosst100/pwa-marketplace/src/hooks/useCustomSort';
|
|
16
15
|
|
|
17
16
|
const CollectibleGameSets = props => {
|
|
18
17
|
const [active, setActive] = useState('all');
|
|
19
18
|
|
|
20
|
-
const [
|
|
19
|
+
const [searchQuery, setSearchQuery] = useState('');
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
const sortProps = useCustomSort({ sortFromSearch: false, defaultSort: {
|
|
21
23
|
sortText: 'All (A-Z)',
|
|
22
24
|
value: 'all'
|
|
23
|
-
});
|
|
25
|
+
}});
|
|
26
|
+
|
|
27
|
+
const [currentSort] = sortProps;
|
|
28
|
+
|
|
29
|
+
// const [sortBy, setSortBy] = useState({
|
|
30
|
+
// sortText: 'All (A-Z)',
|
|
31
|
+
// value: 'all'
|
|
32
|
+
// });
|
|
33
|
+
|
|
34
|
+
// console.log(currentSort)
|
|
24
35
|
|
|
25
36
|
const classes = useStyle(defaultClasses);
|
|
26
37
|
|
|
27
|
-
const talonProps = useCollectibleGameSets();
|
|
38
|
+
const talonProps = useCollectibleGameSets({ searchQuery, setActive, currentSort });
|
|
28
39
|
|
|
29
|
-
const { error, loading, collectibleGameSets, categoryUrlSuffix, categoryUrlKey, productType } = talonProps;
|
|
40
|
+
const { error, loading, collectibleGameSets, categoryUrlSuffix, categoryUrlKey, productType, filteredCollectibleGameSets } = talonProps;
|
|
30
41
|
|
|
31
42
|
if (loading && !collectibleGameSets)
|
|
32
43
|
return <CollectibleGameSetsShimmer />;
|
|
@@ -37,12 +48,21 @@ const CollectibleGameSets = props => {
|
|
|
37
48
|
}
|
|
38
49
|
|
|
39
50
|
const setsLengthArr = [];
|
|
40
|
-
const groupByYear = [];
|
|
41
51
|
|
|
42
|
-
const
|
|
43
|
-
|
|
52
|
+
const newCollectibleGameSets = searchQuery ? filteredCollectibleGameSets : collectibleGameSets;
|
|
53
|
+
|
|
54
|
+
// useEffect(() => {
|
|
55
|
+
if (collectibleGameSets) {
|
|
56
|
+
collectibleGameSets.map((setRelease, index) => {
|
|
57
|
+
const { release_type, sets } = setRelease;
|
|
58
|
+
|
|
59
|
+
setsLengthArr[release_type] = sets.length
|
|
60
|
+
})
|
|
61
|
+
}
|
|
62
|
+
// }, [collectibleGameSets])
|
|
44
63
|
|
|
45
|
-
|
|
64
|
+
const setRelases = newCollectibleGameSets.map((setRelease, index) => {
|
|
65
|
+
const { release_type, sets } = setRelease;
|
|
46
66
|
|
|
47
67
|
const setsResult = [];
|
|
48
68
|
|
|
@@ -50,8 +70,6 @@ const CollectibleGameSets = props => {
|
|
|
50
70
|
sets.map((set, index) => {
|
|
51
71
|
const { set_name, option_id, set_abbreviation, release_year } = set;
|
|
52
72
|
|
|
53
|
-
groupByYear[release_year] = set;
|
|
54
|
-
|
|
55
73
|
const categoryUrl = resourceUrl(
|
|
56
74
|
`/games/collectible-game/${categoryUrlKey}${categoryUrlSuffix || ''}?card_set[filter]=${set_name},${option_id}`
|
|
57
75
|
);
|
|
@@ -67,7 +85,7 @@ const CollectibleGameSets = props => {
|
|
|
67
85
|
return (
|
|
68
86
|
<>
|
|
69
87
|
{active == "all" || active == release_type ?
|
|
70
|
-
<div
|
|
88
|
+
<div className='singles_group-wrapper mb-4 px-2 inline-block w-full'>
|
|
71
89
|
<div className='singles_item_group_letter text-xl font-semibold border-b border-gray-100 pb-1 mb-2' >
|
|
72
90
|
{release_type}
|
|
73
91
|
</div>
|
|
@@ -77,10 +95,13 @@ const CollectibleGameSets = props => {
|
|
|
77
95
|
);
|
|
78
96
|
});
|
|
79
97
|
|
|
80
|
-
// console.log(groupByYear)
|
|
81
|
-
|
|
82
98
|
const handleActive = (val) => {
|
|
83
99
|
setActive(val);
|
|
100
|
+
|
|
101
|
+
//
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
setSearchQuery('')
|
|
84
105
|
}
|
|
85
106
|
|
|
86
107
|
const alpha = ['#', 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'];
|
|
@@ -91,12 +112,12 @@ const CollectibleGameSets = props => {
|
|
|
91
112
|
'value': 'all'
|
|
92
113
|
},
|
|
93
114
|
{
|
|
94
|
-
'label': '
|
|
115
|
+
'label': 'Latest Sets',
|
|
95
116
|
'value': 'newest'
|
|
96
117
|
},
|
|
97
118
|
{
|
|
98
|
-
'label': '
|
|
99
|
-
'value': '
|
|
119
|
+
'label': 'By Date',
|
|
120
|
+
'value': 'date'
|
|
100
121
|
}
|
|
101
122
|
];
|
|
102
123
|
|
|
@@ -114,9 +135,16 @@ const CollectibleGameSets = props => {
|
|
|
114
135
|
{title}
|
|
115
136
|
</h1>
|
|
116
137
|
<div className='border border-gray-100 px-6'>
|
|
138
|
+
{collectibleGameSets ? (
|
|
139
|
+
<div
|
|
140
|
+
className={classes.toolbar}
|
|
141
|
+
>
|
|
142
|
+
<div style={{"width":"35%"}}><ArraySearchInput active={active} searchQuery={searchQuery} placeholder="Search sets..." isOpen={true} setSearchQuery={setSearchQuery} /></div>
|
|
143
|
+
<CustomSortBy sortProps={sortProps} availableSortMethods={availableSortBy} />
|
|
144
|
+
</div>
|
|
145
|
+
) : ''}
|
|
117
146
|
{productType != "expansion-sets" ? (
|
|
118
147
|
<>
|
|
119
|
-
<CustomSortBy sortProps={[sortBy, setSortBy]} availableSortMethods={availableSortBy} />
|
|
120
148
|
<section className='single_list-indexing-container relative m-auto py-10'>
|
|
121
149
|
<ul className='flex gap-2 justify-center flex-wrap'>
|
|
122
150
|
<li>
|
|
@@ -129,7 +157,7 @@ const CollectibleGameSets = props => {
|
|
|
129
157
|
handleActive('all')
|
|
130
158
|
}}
|
|
131
159
|
>
|
|
132
|
-
All
|
|
160
|
+
{active == 'all' ? <b>All</b> : 'All'}
|
|
133
161
|
</button>
|
|
134
162
|
</li>
|
|
135
163
|
{alpha.map((letter, index) => (
|
|
@@ -145,7 +173,7 @@ const CollectibleGameSets = props => {
|
|
|
145
173
|
}}
|
|
146
174
|
disabled={setsLengthArr[letter] > 0 ? false : true}
|
|
147
175
|
>
|
|
148
|
-
{letter}
|
|
176
|
+
{active == letter ? <b>{letter}</b> : letter}
|
|
149
177
|
</button>
|
|
150
178
|
</li>
|
|
151
179
|
))}
|
|
@@ -153,10 +181,10 @@ const CollectibleGameSets = props => {
|
|
|
153
181
|
</section>
|
|
154
182
|
</>
|
|
155
183
|
) : ''}
|
|
156
|
-
<Divider className="mb-5 px-4" />
|
|
184
|
+
<Divider className="mb-5 px-4 mt-5" />
|
|
157
185
|
<section className='singles-container'>
|
|
158
186
|
<div className={cn('singles-wrapper block -mx-4', classes.singlesWrapper)}>
|
|
159
|
-
{setRelases}
|
|
187
|
+
{newCollectibleGameSets && newCollectibleGameSets.length ? setRelases : (searchQuery ? <div className='singles_group-wrapper mb-4 px-2 inline-block w-full'>No sets found for <b>{searchQuery}</b> search query.</div> : <div className='singles_group-wrapper mb-4 px-2 inline-block w-full'>No sets found.</div>)}
|
|
160
188
|
</div>
|
|
161
189
|
</section>
|
|
162
190
|
</div>
|
|
@@ -156,12 +156,13 @@ const CustomSortBy = props => {
|
|
|
156
156
|
});
|
|
157
157
|
|
|
158
158
|
return (
|
|
159
|
-
<div
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
>
|
|
159
|
+
// <div
|
|
160
|
+
// ref={elementRef}
|
|
161
|
+
// className={classes.root}
|
|
162
|
+
// data-cy="CustomSortBy-root"
|
|
163
|
+
// aria-busy="false"
|
|
164
|
+
// >
|
|
165
|
+
<>
|
|
165
166
|
<Button
|
|
166
167
|
priority={'low'}
|
|
167
168
|
classes={{
|
|
@@ -181,17 +182,14 @@ const CustomSortBy = props => {
|
|
|
181
182
|
</span>
|
|
182
183
|
<span className={cn(classes.desktopText, 'flex items-center gap-[15px]')}>
|
|
183
184
|
<span className={classes.sortText}>
|
|
184
|
-
<FormattedMessage
|
|
185
|
-
id={'productSort.sortByButton'}
|
|
186
|
-
defaultMessage={'Sort by'}
|
|
187
|
-
/>
|
|
188
185
|
{currentSort.sortText}
|
|
189
186
|
</span>
|
|
190
187
|
<ArrowUp2 size={15} className={cn('text-gray-900 transition-all stroke-[#292D32]', expanded ? 'rotate-0' : 'rotate-180')} />
|
|
191
188
|
</span>
|
|
192
189
|
</Button>
|
|
193
190
|
{sortElements}
|
|
194
|
-
|
|
191
|
+
</>
|
|
192
|
+
// </div>
|
|
195
193
|
);
|
|
196
194
|
};
|
|
197
195
|
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import React, { Fragment, Suspense, useMemo, useRef, useState } from 'react';
|
|
2
|
+
import { useStyle } from '@magento/venia-ui/lib/classify';
|
|
3
|
+
import cn from 'classnames';
|
|
4
|
+
import ErrorView from '@magento/venia-ui/lib/components/ErrorView';
|
|
5
|
+
import { StoreTitle, Meta } from '@magento/venia-ui/lib/components/Head';
|
|
6
|
+
import { Link } from 'react-router-dom';
|
|
7
|
+
import resourceUrl from '@magento/peregrine/lib/util/makeUrl';
|
|
8
|
+
import defaultClasses from './subCategoryPage.module.css';
|
|
9
|
+
import Divider from '@riosst100/pwa-marketplace/src/components/Divider';
|
|
10
|
+
import { ShopByShimmer } from '@riosst100/pwa-marketplace/src/components/ShopBy';
|
|
11
|
+
import CustomSortBy from '@riosst100/pwa-marketplace/src/components/CustomSortBy';
|
|
12
|
+
import ArraySearchInput from '@riosst100/pwa-marketplace/src/components/ArraySearchInput';
|
|
13
|
+
import { useSubCategoryPage } from '@riosst100/pwa-marketplace/src/talons/SubCategoryPage/useSubCategoryPage';
|
|
14
|
+
|
|
15
|
+
const SubCategoryPage = props => {
|
|
16
|
+
const { categoryId } = props;
|
|
17
|
+
const [active, setActive] = useState('all');
|
|
18
|
+
const [searchQuery, setSearchQuery] = useState('');
|
|
19
|
+
|
|
20
|
+
const classes = useStyle(defaultClasses);
|
|
21
|
+
|
|
22
|
+
const talonProps = useSubCategoryPage({ searchQuery, setActive, categoryId });
|
|
23
|
+
|
|
24
|
+
const { error, loading, dataResult, categoryUrlSuffix, filteredAvailableGroups, availableGroups, alpha, category } = talonProps;
|
|
25
|
+
|
|
26
|
+
if (loading && !dataResult)
|
|
27
|
+
return <ShopByShimmer />;
|
|
28
|
+
if (error && !dataResult) return <ErrorView />;
|
|
29
|
+
|
|
30
|
+
if (!dataResult && !loading && !error) {
|
|
31
|
+
return <ShopByShimmer />;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const newAvailableGroups = searchQuery ? filteredAvailableGroups : availableGroups;
|
|
35
|
+
|
|
36
|
+
const setRelases = newAvailableGroups.map((group, index) => {
|
|
37
|
+
const optionsResult = [];
|
|
38
|
+
|
|
39
|
+
if (active === 'all' || active === group) {
|
|
40
|
+
dataResult[group].map((option, index) => {
|
|
41
|
+
const { name, url_path } = option;
|
|
42
|
+
|
|
43
|
+
optionsResult.push(<li className='list-none'>
|
|
44
|
+
<Link to={'/' + url_path + categoryUrlSuffix} className="hover_bg-darkblue-900 hover_text-white w-full block text-[14px] py-[2px] px-2">
|
|
45
|
+
{name}
|
|
46
|
+
</Link>
|
|
47
|
+
</li>)
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<>
|
|
52
|
+
{optionsResult ?
|
|
53
|
+
<div className='singles_group-wrapper mb-4 px-2 inline-block w-full'>
|
|
54
|
+
<div className='singles_item_group_letter text-xl font-semibold border-b border-gray-100 pb-1 mb-2' >
|
|
55
|
+
{group}
|
|
56
|
+
</div>
|
|
57
|
+
<div className={cn('singles_item-list flex flex-col')}>{optionsResult}</div>
|
|
58
|
+
</div> : ''}
|
|
59
|
+
</>
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return null;
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
const handleActive = (val) => {
|
|
67
|
+
setActive(val);
|
|
68
|
+
setSearchQuery('')
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return (
|
|
72
|
+
<Fragment>
|
|
73
|
+
<StoreTitle>{category ? category.name : 'Shop By'}</StoreTitle>
|
|
74
|
+
<h1 className='mx-auto relative block text-xl font-bold text-center pt-10 pb-4'>
|
|
75
|
+
{category ? category.name : 'Shop By'}
|
|
76
|
+
</h1>
|
|
77
|
+
<div className='border border-gray-100 px-6'>
|
|
78
|
+
{dataResult ? (
|
|
79
|
+
<div
|
|
80
|
+
className={classes.toolbar}
|
|
81
|
+
>
|
|
82
|
+
<div style={{"width":"35%"}}><ArraySearchInput active={active} searchQuery={searchQuery} placeholder="Search sets..." isOpen={true} setSearchQuery={setSearchQuery} /></div>
|
|
83
|
+
</div>
|
|
84
|
+
) : ''}
|
|
85
|
+
<>
|
|
86
|
+
<section className='single_list-indexing-container relative m-auto py-10'>
|
|
87
|
+
<ul className='flex gap-2 justify-center flex-wrap'>
|
|
88
|
+
<li>
|
|
89
|
+
<button
|
|
90
|
+
className={cn(
|
|
91
|
+
'rounded-md border border-solid border-gray-100 p-2 min-w-[28px]',
|
|
92
|
+
'leading-4 font-medium text-base hover_bg-gray-50'
|
|
93
|
+
)}
|
|
94
|
+
onClick={() => {
|
|
95
|
+
handleActive('all')
|
|
96
|
+
}}
|
|
97
|
+
>
|
|
98
|
+
{active == 'all' ? <b>All</b> : 'All'}
|
|
99
|
+
</button>
|
|
100
|
+
</li>
|
|
101
|
+
{alpha.map((letter, index) => (
|
|
102
|
+
<li key={index}>
|
|
103
|
+
<button
|
|
104
|
+
className={cn(
|
|
105
|
+
'rounded-md border border-solid border-gray-100 p-2 min-w-[28px]',
|
|
106
|
+
'leading-4 font-medium text-base ',
|
|
107
|
+
availableGroups.includes(letter) > 0 ? 'hover_bg-gray-50' : 'bg-gray-100 text-gray-400',
|
|
108
|
+
)}
|
|
109
|
+
onClick={() => {
|
|
110
|
+
handleActive(letter)
|
|
111
|
+
}}
|
|
112
|
+
disabled={availableGroups.includes(letter) > 0 ? false : true}
|
|
113
|
+
>
|
|
114
|
+
{active == letter ? <b>{letter}</b> : letter}
|
|
115
|
+
</button>
|
|
116
|
+
</li>
|
|
117
|
+
))}
|
|
118
|
+
</ul>
|
|
119
|
+
</section>
|
|
120
|
+
</>
|
|
121
|
+
<Divider className="mb-5 px-4 mt-5" />
|
|
122
|
+
<section className='singles-container'>
|
|
123
|
+
<div className={cn('singles-wrapper block -mx-4', classes.singlesWrapper)}>
|
|
124
|
+
{Object.keys(dataResult).length != 0 ? setRelases : (searchQuery ? <div className='singles_group-wrapper mb-4 px-2 inline-block w-full'>No data found for <b>{searchQuery}</b> search query.</div> : <div className='singles_group-wrapper mb-4 px-2 inline-block w-full'>No data found.</div>)}
|
|
125
|
+
</div>
|
|
126
|
+
</section>
|
|
127
|
+
</div>
|
|
128
|
+
</Fragment>
|
|
129
|
+
);
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
export default SubCategoryPage;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
.toolbar {
|
|
2
|
+
composes: relative from global;
|
|
3
|
+
composes: ml-2xs from global;
|
|
4
|
+
display: flex;
|
|
5
|
+
justify-content: space-between;
|
|
6
|
+
margin-top: 20px;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.tabs {
|
|
10
|
+
composes: flex from global;
|
|
11
|
+
composes: flex-wrap from global;
|
|
12
|
+
composes: mt-3 from global;
|
|
13
|
+
composes: gap-[15px] from global;
|
|
14
|
+
margin-bottom: 30px;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.tabs_item {
|
|
18
|
+
composes: px-4 from global;
|
|
19
|
+
composes: py-2 from global;
|
|
20
|
+
composes: transition-colors from global;
|
|
21
|
+
composes: duration-150 from global;
|
|
22
|
+
composes: border from global;
|
|
23
|
+
composes: border-solid from global;
|
|
24
|
+
composes: leading-normal from global;
|
|
25
|
+
composes: text-base from global;
|
|
26
|
+
composes: text-colorDefault from global;
|
|
27
|
+
composes: bg-white from global;
|
|
28
|
+
composes: border-gray-100 from global;
|
|
29
|
+
border-radius: 5px;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.singlesWrapper {
|
|
33
|
+
column-count: 1;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@media screen and (min-width: 768px) {
|
|
37
|
+
.singlesWrapper {
|
|
38
|
+
column-count: 2;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@media screen and (min-width: 1023px) {
|
|
43
|
+
.singlesWrapper {
|
|
44
|
+
column-count: 3;
|
|
45
|
+
}
|
|
46
|
+
}
|