@riosst100/pwa-marketplace 1.6.3 → 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/CustomSubCategory/subCategory.js +0 -1
- package/src/components/CustomSubCategoryPage/subCategoryPage.js +132 -0
- package/src/components/CustomSubCategoryPage/subCategoryPage.module.css +46 -0
- package/src/components/SubCategory/subCategory.js +1 -1
- package/src/overwrites/venia-ui/lib/RootComponents/Category/category.js +23 -12
- package/src/overwrites/venia-ui/lib/RootComponents/Category/categoryContent.js +7 -5
- package/src/overwrites/venia-ui/lib/components/Gallery/gallery.js +0 -4
- package/src/talons/SubCategoryPage/subCategoryPage.gql.js +36 -0
- package/src/talons/SubCategoryPage/useSubCategoryPage.js +111 -0
package/package.json
CHANGED
|
@@ -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
|
+
}
|
|
@@ -10,6 +10,7 @@ import { GET_PAGE_SIZE } from './category.gql';
|
|
|
10
10
|
import ErrorView from '@magento/venia-ui/lib/components/ErrorView';
|
|
11
11
|
import { useIntl } from 'react-intl';
|
|
12
12
|
import ShopBy from '@riosst100/pwa-marketplace/src/components/ShopBy/shopBy';
|
|
13
|
+
import SubCategoryPage from '@riosst100/pwa-marketplace/src/components/CustomSubCategoryPage/subCategoryPage';
|
|
13
14
|
|
|
14
15
|
const MESSAGES = new Map().set(
|
|
15
16
|
'NOT_FOUND',
|
|
@@ -24,7 +25,7 @@ const Category = props => {
|
|
|
24
25
|
|
|
25
26
|
const query = new URLSearchParams(location.search);
|
|
26
27
|
const shopby = query.get('shopby') || null;
|
|
27
|
-
|
|
28
|
+
const showSubcategory = query.get('show_subcategory') || null;
|
|
28
29
|
|
|
29
30
|
const talonProps = useCategory({
|
|
30
31
|
id: uid,
|
|
@@ -70,18 +71,28 @@ const Category = props => {
|
|
|
70
71
|
return (
|
|
71
72
|
<Fragment>
|
|
72
73
|
<Meta name="description" content={metaDescription} />
|
|
73
|
-
{
|
|
74
|
+
{showSubcategory ? (
|
|
75
|
+
<SubCategoryPage
|
|
74
76
|
categoryId={uid}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
77
|
+
isLoading={loading} />
|
|
78
|
+
) : (
|
|
79
|
+
shopby ? (
|
|
80
|
+
<ShopBy
|
|
81
|
+
categoryId={uid}
|
|
82
|
+
shopby={shopby}
|
|
83
|
+
isLoading={loading} />
|
|
84
|
+
) : (
|
|
85
|
+
<CategoryContent
|
|
86
|
+
categoryId={uid}
|
|
87
|
+
classes={classes}
|
|
88
|
+
data={categoryData}
|
|
89
|
+
isLoading={loading}
|
|
90
|
+
pageControl={pageControl}
|
|
91
|
+
sortProps={sortProps}
|
|
92
|
+
pageSize={pageSize}
|
|
93
|
+
/>
|
|
94
|
+
)
|
|
95
|
+
)}
|
|
85
96
|
</Fragment>
|
|
86
97
|
);
|
|
87
98
|
};
|
|
@@ -85,6 +85,8 @@ const CategoryContent = props => {
|
|
|
85
85
|
useMemo(() => {
|
|
86
86
|
items && items.map((item, index) => {
|
|
87
87
|
if (item) {
|
|
88
|
+
let firstLetter = null;
|
|
89
|
+
|
|
88
90
|
const { custom_attributes } = item;
|
|
89
91
|
if (custom_attributes) {
|
|
90
92
|
let cardName = '';
|
|
@@ -100,13 +102,13 @@ const CategoryContent = props => {
|
|
|
100
102
|
});
|
|
101
103
|
|
|
102
104
|
if (cardName) {
|
|
103
|
-
|
|
104
|
-
console.log(firstLetter + " dan " + activeLetter)
|
|
105
|
-
if (activeLetter == "all" || activeLetter != "all" && firstLetter == activeLetter) {
|
|
106
|
-
return galleryItems.push(item);
|
|
107
|
-
}
|
|
105
|
+
firstLetter = cardName.charAt(0).toUpperCase();
|
|
108
106
|
}
|
|
109
107
|
}
|
|
108
|
+
|
|
109
|
+
if (activeLetter == "all" || activeLetter != "all" && firstLetter == activeLetter) {
|
|
110
|
+
return galleryItems.push(item);
|
|
111
|
+
}
|
|
110
112
|
}
|
|
111
113
|
}),
|
|
112
114
|
[items, activeLetter]
|
|
@@ -26,9 +26,6 @@ const Gallery = props => {
|
|
|
26
26
|
return <GalleryItemShimmer key={index} />;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
// const firstLetter = item.name.charAt(0).toUpperCase();
|
|
30
|
-
|
|
31
|
-
// if (activeLetter == "all" || activeLetter != "all" && firstLetter == activeLetter) {
|
|
32
29
|
return (
|
|
33
30
|
<GalleryItem
|
|
34
31
|
key={item.id}
|
|
@@ -36,7 +33,6 @@ const Gallery = props => {
|
|
|
36
33
|
storeConfig={storeConfig}
|
|
37
34
|
/>
|
|
38
35
|
);
|
|
39
|
-
// }
|
|
40
36
|
}),
|
|
41
37
|
[items, storeConfig, activeLetter]
|
|
42
38
|
);
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { gql } from '@apollo/client';
|
|
2
|
+
|
|
3
|
+
export const GET_STORE_CONFIG_DATA = gql`
|
|
4
|
+
query getStoreConfigData {
|
|
5
|
+
# eslint-disable-next-line @graphql-eslint/require-id-when-available
|
|
6
|
+
storeConfig {
|
|
7
|
+
store_code
|
|
8
|
+
product_url_suffix
|
|
9
|
+
category_url_suffix
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
`;
|
|
13
|
+
|
|
14
|
+
export const GET_CATEGORY_CONTENT = gql`
|
|
15
|
+
query getCategoryData($id: String!) {
|
|
16
|
+
categories(filters: { category_uid: { in: [$id] } }) {
|
|
17
|
+
# eslint-disable-next-line @graphql-eslint/require-id-when-available
|
|
18
|
+
items {
|
|
19
|
+
uid
|
|
20
|
+
name
|
|
21
|
+
url_key
|
|
22
|
+
url_path
|
|
23
|
+
children {
|
|
24
|
+
uid
|
|
25
|
+
name
|
|
26
|
+
url_path
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
`;
|
|
32
|
+
|
|
33
|
+
export default {
|
|
34
|
+
getStoreConfigData: GET_STORE_CONFIG_DATA,
|
|
35
|
+
getCategoryContentQuery: GET_CATEGORY_CONTENT
|
|
36
|
+
};
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { useQuery } from '@apollo/client';
|
|
2
|
+
import { useEffect, useMemo } from 'react';
|
|
3
|
+
import { useLocation } from 'react-router-dom';
|
|
4
|
+
import { useAppContext } from '@magento/peregrine/lib/context/app';
|
|
5
|
+
|
|
6
|
+
import mergeOperations from '@magento/peregrine/lib/util/shallowMerge';
|
|
7
|
+
import DEFAULT_OPERATIONS from './subCategoryPage.gql';
|
|
8
|
+
|
|
9
|
+
export const useSubCategoryPage = props => {
|
|
10
|
+
|
|
11
|
+
const { searchQuery, setActive, categoryId } = props
|
|
12
|
+
|
|
13
|
+
const operations = mergeOperations(DEFAULT_OPERATIONS, null);
|
|
14
|
+
const { getStoreConfigData, getCategoryContentQuery } = operations;
|
|
15
|
+
|
|
16
|
+
const { data: storeConfigData } = useQuery(getStoreConfigData, {
|
|
17
|
+
fetchPolicy: 'cache-and-network',
|
|
18
|
+
nextFetchPolicy: 'cache-first'
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const { data: categoryData, loading, error } = useQuery(
|
|
22
|
+
getCategoryContentQuery,
|
|
23
|
+
{
|
|
24
|
+
fetchPolicy: 'cache-and-network',
|
|
25
|
+
nextFetchPolicy: 'cache-first',
|
|
26
|
+
skip: !categoryId,
|
|
27
|
+
variables: {
|
|
28
|
+
id: categoryId
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
const category =
|
|
34
|
+
categoryData && categoryData.categories.items.length
|
|
35
|
+
? categoryData.categories.items[0]
|
|
36
|
+
: null;
|
|
37
|
+
const children =
|
|
38
|
+
categoryData && categoryData.categories.items.length
|
|
39
|
+
? categoryData.categories.items[0].children
|
|
40
|
+
: null;
|
|
41
|
+
|
|
42
|
+
const categoryUrlSuffix = storeConfigData?.storeConfig?.category_url_suffix;
|
|
43
|
+
|
|
44
|
+
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'];
|
|
45
|
+
|
|
46
|
+
const originalDataResult = useMemo(() => {
|
|
47
|
+
if (!children) {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const mappingData = children.reduce((acc, item) => {
|
|
52
|
+
let firstLetter = item.name.charAt(0).toUpperCase();
|
|
53
|
+
if (!alpha.includes(firstLetter)) {
|
|
54
|
+
firstLetter = '#';
|
|
55
|
+
}
|
|
56
|
+
acc[firstLetter] = acc[firstLetter] || [];
|
|
57
|
+
acc[firstLetter].push(item);
|
|
58
|
+
return acc;
|
|
59
|
+
}, {});
|
|
60
|
+
|
|
61
|
+
return mappingData;
|
|
62
|
+
}, [children, searchQuery]);
|
|
63
|
+
|
|
64
|
+
const dataResult = useMemo(() => {
|
|
65
|
+
if (!children) {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (!children) {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
let options = children;
|
|
74
|
+
|
|
75
|
+
if (searchQuery) {
|
|
76
|
+
setActive('all')
|
|
77
|
+
options = options.filter(function(option) {
|
|
78
|
+
return option.name.search(new RegExp(searchQuery, "i")) != -1;
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const mappingData = options.reduce((acc, item) => {
|
|
83
|
+
console.log(item)
|
|
84
|
+
let firstLetter = item.name.charAt(0).toUpperCase();
|
|
85
|
+
if (!alpha.includes(firstLetter)) {
|
|
86
|
+
firstLetter = '#';
|
|
87
|
+
}
|
|
88
|
+
acc[firstLetter] = acc[firstLetter] || [];
|
|
89
|
+
acc[firstLetter].push(item);
|
|
90
|
+
return acc;
|
|
91
|
+
}, {});
|
|
92
|
+
|
|
93
|
+
return mappingData;
|
|
94
|
+
}, [children, searchQuery]);
|
|
95
|
+
|
|
96
|
+
console.log(dataResult)
|
|
97
|
+
|
|
98
|
+
const availableGroups = originalDataResult ? Object.keys(originalDataResult).sort() : [];
|
|
99
|
+
const filteredAvailableGroups = dataResult ? Object.keys(dataResult).sort() : [];
|
|
100
|
+
|
|
101
|
+
return {
|
|
102
|
+
error,
|
|
103
|
+
loading,
|
|
104
|
+
dataResult,
|
|
105
|
+
filteredAvailableGroups,
|
|
106
|
+
categoryUrlSuffix,
|
|
107
|
+
availableGroups,
|
|
108
|
+
alpha,
|
|
109
|
+
category
|
|
110
|
+
};
|
|
111
|
+
};
|