@riosst100/pwa-marketplace 1.3.0 → 1.3.2
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/componentOverrideMapping.js +6 -0
- package/src/components/OperatingHours/operatingHours.js +7 -9
- package/src/components/Pagination/index.js +27 -29
- package/src/components/SellerDetail/sellerDetail.js +2 -13
- package/src/components/SellerInformation/sellerInformation.js +2 -1
- package/src/components/SellerLocation/sellerLocation.js +1 -1
- package/src/components/SellerReview/sellerReview.js +18 -10
- package/src/components/SellerReviewItem/sellerReviewItem.js +105 -20
- package/src/components/ShopByCategory/index.js +2 -0
- package/src/components/ShopByCategory/shopByCategory.js +69 -0
- package/src/components/ShopByCategory/shopByCategory.module.css +58 -0
- package/src/components/ShopByCategory/shopByCategory.shimmer.js +24 -0
- package/src/components/SubCategory/subCategory.js +31 -0
- package/src/overwrites/peregrine/lib/talons/Breadcrumbs/useBreadcrumbs.js +100 -0
- package/src/overwrites/peregrine/lib/talons/MegaMenu/megaMenu.gql.js +70 -0
- package/src/overwrites/peregrine/lib/talons/MegaMenu/useMegaMenu.js +199 -0
- package/src/overwrites/peregrine/lib/talons/RootComponents/Category/categoryContent.gql.js +70 -0
- package/src/overwrites/peregrine/lib/talons/RootComponents/Category/useCategoryContent.js +141 -0
- package/src/overwrites/venia-ui/lib/RootComponents/Category/categoryContent.js +222 -0
- package/src/overwrites/venia-ui/lib/components/Adapter/adapter.js +5 -2
- package/src/overwrites/venia-ui/lib/components/FilterModal/FilterList/filterDefault.js +84 -0
- package/src/overwrites/venia-ui/lib/components/FilterSidebar/filterSidebar.js +157 -0
- package/src/overwrites/venia-ui/lib/components/MegaMenu/megaMenu.js +2 -1
- package/src/overwrites/venia-ui/lib/components/MegaMenu/megaMenuItem.js +1 -0
- package/src/overwrites/venia-ui/lib/components/MegaMenu/shopByColumn.js +75 -0
- package/src/overwrites/venia-ui/lib/components/MegaMenu/shopByColumn.module.css +28 -0
- package/src/overwrites/venia-ui/lib/components/MegaMenu/submenu.js +31 -0
- package/src/overwrites/venia-ui/lib/components/MegaMenu/submenuColumn.js +1 -0
- package/src/overwrites/venia-ui/lib/components/SearchBar/searchField.js +1 -1
- package/src/talons/MegaMenu/megaMenu.gql.js +70 -0
- package/src/talons/Seller/seller.gql.js +0 -36
- package/src/talons/SellerReview/sellerReview.gql.js +53 -0
- package/src/talons/SellerReview/useSellerReview.js +49 -0
- package/src/talons/ShopByCategory/index.js +1 -0
- package/src/talons/ShopByCategory/shopByCategory.gql.js +38 -0
- package/src/talons/ShopByCategory/useShopByCategory.js +69 -0
- package/src/talons/SubCategory/subCategory.gql.js +15 -0
- package/src/talons/SubCategory/useSubCategory.js +52 -0
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import React, { Fragment, Suspense, useMemo, useRef } from 'react';
|
|
2
|
+
import { FormattedMessage } from 'react-intl';
|
|
3
|
+
import { array, number, shape, string } from 'prop-types';
|
|
4
|
+
|
|
5
|
+
import { useIsInViewport } from '@magento/peregrine/lib/hooks/useIsInViewport';
|
|
6
|
+
import { useCategoryContent } from '@magento/peregrine/lib/talons/RootComponents/Category';
|
|
7
|
+
|
|
8
|
+
import { useStyle } from '@magento/venia-ui/lib/classify';
|
|
9
|
+
import Breadcrumbs from '@magento/venia-ui/lib/components/Breadcrumbs';
|
|
10
|
+
import FilterModalOpenButton, {
|
|
11
|
+
FilterModalOpenButtonShimmer
|
|
12
|
+
} from '@magento/venia-ui/lib/components/FilterModalOpenButton';
|
|
13
|
+
import { FilterSidebarShimmer } from '@magento/venia-ui/lib/components/FilterSidebar';
|
|
14
|
+
import Gallery, { GalleryShimmer } from '@magento/venia-ui/lib/components/Gallery';
|
|
15
|
+
import { StoreTitle } from '@magento/venia-ui/lib/components/Head';
|
|
16
|
+
import Pagination from '@magento/venia-ui/lib/components/Pagination';
|
|
17
|
+
import ProductSort, { ProductSortShimmer } from '@magento/venia-ui/lib/components/ProductSort';
|
|
18
|
+
import RichContent from '@magento/venia-ui/lib/components/RichContent';
|
|
19
|
+
import Shimmer from '@magento/venia-ui/lib/components/Shimmer';
|
|
20
|
+
import SortedByContainer, {
|
|
21
|
+
SortedByContainerShimmer
|
|
22
|
+
} from '@magento/venia-ui/lib/components/SortedByContainer';
|
|
23
|
+
import defaultClasses from '@magento/venia-ui/lib/RootComponents/Category/category.module.css';
|
|
24
|
+
import NoProductsFound from '@magento/venia-ui/lib/RootComponents/Category/NoProductsFound';
|
|
25
|
+
import SubCategory from '@riosst100/pwa-marketplace/src/components/SubCategory/subCategory';
|
|
26
|
+
|
|
27
|
+
const FilterModal = React.lazy(() => import('@magento/venia-ui/lib/components/FilterModal'));
|
|
28
|
+
const FilterSidebar = React.lazy(() =>
|
|
29
|
+
import('@magento/venia-ui/lib/components/FilterSidebar')
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
const CategoryContent = props => {
|
|
33
|
+
const {
|
|
34
|
+
categoryId,
|
|
35
|
+
data,
|
|
36
|
+
isLoading,
|
|
37
|
+
pageControl,
|
|
38
|
+
sortProps,
|
|
39
|
+
pageSize
|
|
40
|
+
} = props;
|
|
41
|
+
const [currentSort] = sortProps;
|
|
42
|
+
|
|
43
|
+
const talonProps = useCategoryContent({
|
|
44
|
+
categoryId,
|
|
45
|
+
data,
|
|
46
|
+
pageSize
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const {
|
|
50
|
+
availableSortMethods,
|
|
51
|
+
categoryName,
|
|
52
|
+
categoryDescription,
|
|
53
|
+
filters,
|
|
54
|
+
items,
|
|
55
|
+
totalCount,
|
|
56
|
+
totalPagesFromData,
|
|
57
|
+
children,
|
|
58
|
+
parent
|
|
59
|
+
} = talonProps;
|
|
60
|
+
|
|
61
|
+
const sidebarRef = useRef(null);
|
|
62
|
+
const classes = useStyle(defaultClasses, props.classes);
|
|
63
|
+
const shouldRenderSidebarContent = useIsInViewport({
|
|
64
|
+
elementRef: sidebarRef
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
const shouldShowFilterButtons = filters && filters.length;
|
|
68
|
+
const shouldShowFilterShimmer = filters === null;
|
|
69
|
+
|
|
70
|
+
// If there are no products we can hide the sort button.
|
|
71
|
+
const shouldShowSortButtons = totalPagesFromData && availableSortMethods;
|
|
72
|
+
const shouldShowSortShimmer = !totalPagesFromData && isLoading;
|
|
73
|
+
|
|
74
|
+
const maybeFilterButtons = shouldShowFilterButtons ? (
|
|
75
|
+
<FilterModalOpenButton filters={filters} />
|
|
76
|
+
) : shouldShowFilterShimmer ? (
|
|
77
|
+
<FilterModalOpenButtonShimmer />
|
|
78
|
+
) : null;
|
|
79
|
+
|
|
80
|
+
const filtersModal = shouldShowFilterButtons ? (
|
|
81
|
+
<FilterModal filters={filters} />
|
|
82
|
+
) : null;
|
|
83
|
+
|
|
84
|
+
const sidebar = shouldShowFilterButtons ? (
|
|
85
|
+
<FilterSidebar filters={filters} categoryName={categoryName} children={children} parent={parent} />
|
|
86
|
+
) : shouldShowFilterShimmer ? (
|
|
87
|
+
<FilterSidebarShimmer />
|
|
88
|
+
) : null;
|
|
89
|
+
|
|
90
|
+
const maybeSortButton = shouldShowSortButtons ? (
|
|
91
|
+
<ProductSort
|
|
92
|
+
sortProps={sortProps}
|
|
93
|
+
availableSortMethods={availableSortMethods}
|
|
94
|
+
/>
|
|
95
|
+
) : shouldShowSortShimmer ? (
|
|
96
|
+
<ProductSortShimmer />
|
|
97
|
+
) : null;
|
|
98
|
+
|
|
99
|
+
const maybeSortContainer = shouldShowSortButtons ? (
|
|
100
|
+
<SortedByContainer currentSort={currentSort} />
|
|
101
|
+
) : shouldShowSortShimmer ? (
|
|
102
|
+
<SortedByContainerShimmer />
|
|
103
|
+
) : null;
|
|
104
|
+
|
|
105
|
+
const categoryResultsHeading =
|
|
106
|
+
totalCount > 0 ? (
|
|
107
|
+
<FormattedMessage
|
|
108
|
+
id={'categoryContent.resultCount'}
|
|
109
|
+
values={{
|
|
110
|
+
count: totalCount
|
|
111
|
+
}}
|
|
112
|
+
defaultMessage={'{count} Results'}
|
|
113
|
+
/>
|
|
114
|
+
) : isLoading ? (
|
|
115
|
+
<Shimmer width={5} />
|
|
116
|
+
) : null;
|
|
117
|
+
|
|
118
|
+
const categoryDescriptionElement = categoryDescription ? (
|
|
119
|
+
<RichContent html={categoryDescription} />
|
|
120
|
+
) : null;
|
|
121
|
+
|
|
122
|
+
const content = useMemo(() => {
|
|
123
|
+
if (!totalPagesFromData && !isLoading) {
|
|
124
|
+
return <NoProductsFound categoryId={categoryId} />;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const gallery = totalPagesFromData ? (
|
|
128
|
+
<Gallery items={items} />
|
|
129
|
+
) : (
|
|
130
|
+
<GalleryShimmer items={items} />
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
const pagination = totalPagesFromData ? (
|
|
134
|
+
<Pagination pageControl={pageControl} />
|
|
135
|
+
) : null;
|
|
136
|
+
|
|
137
|
+
return (
|
|
138
|
+
<Fragment>
|
|
139
|
+
<section className={classes.gallery}>{gallery}</section>
|
|
140
|
+
<div className={classes.pagination}>{pagination}</div>
|
|
141
|
+
</Fragment>
|
|
142
|
+
);
|
|
143
|
+
}, [
|
|
144
|
+
categoryId,
|
|
145
|
+
classes.gallery,
|
|
146
|
+
classes.pagination,
|
|
147
|
+
isLoading,
|
|
148
|
+
items,
|
|
149
|
+
pageControl,
|
|
150
|
+
totalPagesFromData
|
|
151
|
+
]);
|
|
152
|
+
|
|
153
|
+
const categoryTitle = categoryName ? categoryName : <Shimmer width={5} />;
|
|
154
|
+
|
|
155
|
+
return (
|
|
156
|
+
<Fragment>
|
|
157
|
+
<Breadcrumbs categoryId={categoryId} />
|
|
158
|
+
<SubCategory children={children} />
|
|
159
|
+
<StoreTitle>{categoryName}</StoreTitle>
|
|
160
|
+
<article className={classes.root} data-cy="CategoryContent-root">
|
|
161
|
+
<div className={classes.categoryHeader}>
|
|
162
|
+
<h1 aria-live="polite" className={classes.title}>
|
|
163
|
+
<div
|
|
164
|
+
className={classes.categoryTitle}
|
|
165
|
+
data-cy="CategoryContent-categoryTitle"
|
|
166
|
+
>
|
|
167
|
+
{categoryTitle}
|
|
168
|
+
</div>
|
|
169
|
+
</h1>
|
|
170
|
+
{categoryDescriptionElement}
|
|
171
|
+
</div>
|
|
172
|
+
<div className={classes.contentWrapper}>
|
|
173
|
+
<div ref={sidebarRef} className={classes.sidebar}>
|
|
174
|
+
<Suspense fallback={<FilterSidebarShimmer />}>
|
|
175
|
+
{shouldRenderSidebarContent ? sidebar : null}
|
|
176
|
+
</Suspense>
|
|
177
|
+
</div>
|
|
178
|
+
<div className={classes.categoryContent}>
|
|
179
|
+
<div className={classes.heading}>
|
|
180
|
+
<div
|
|
181
|
+
data-cy="CategoryContent-categoryInfo"
|
|
182
|
+
className={classes.categoryInfo}
|
|
183
|
+
>
|
|
184
|
+
{categoryResultsHeading}
|
|
185
|
+
</div>
|
|
186
|
+
<div className={classes.headerButtons}>
|
|
187
|
+
{maybeFilterButtons}
|
|
188
|
+
{maybeSortButton}
|
|
189
|
+
</div>
|
|
190
|
+
{maybeSortContainer}
|
|
191
|
+
</div>
|
|
192
|
+
{content}
|
|
193
|
+
<Suspense fallback={null}>{filtersModal}</Suspense>
|
|
194
|
+
</div>
|
|
195
|
+
</div>
|
|
196
|
+
</article>
|
|
197
|
+
</Fragment>
|
|
198
|
+
);
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
export default CategoryContent;
|
|
202
|
+
|
|
203
|
+
CategoryContent.propTypes = {
|
|
204
|
+
classes: shape({
|
|
205
|
+
gallery: string,
|
|
206
|
+
pagination: string,
|
|
207
|
+
root: string,
|
|
208
|
+
categoryHeader: string,
|
|
209
|
+
title: string,
|
|
210
|
+
categoryTitle: string,
|
|
211
|
+
sidebar: string,
|
|
212
|
+
categoryContent: string,
|
|
213
|
+
heading: string,
|
|
214
|
+
categoryInfo: string,
|
|
215
|
+
headerButtons: string
|
|
216
|
+
}),
|
|
217
|
+
// sortProps contains the following structure:
|
|
218
|
+
// [{sortDirection: string, sortAttribute: string, sortText: string},
|
|
219
|
+
// React.Dispatch<React.SetStateAction<{sortDirection: string, sortAttribute: string, sortText: string}]
|
|
220
|
+
sortProps: array,
|
|
221
|
+
pageSize: number
|
|
222
|
+
};
|
|
@@ -40,7 +40,10 @@ const Adapter = props => {
|
|
|
40
40
|
const match = location && location.pathname.split("/")[1];
|
|
41
41
|
let websiteCodeInUrl = websiteCodes.find((str) => str === match);
|
|
42
42
|
|
|
43
|
-
const { getWebsiteByUserIp } = useWebsiteByIp(websiteCodeInUrl);
|
|
43
|
+
// const { getWebsiteByUserIp } = useWebsiteByIp(websiteCodeInUrl);
|
|
44
|
+
const getWebsiteByUserIp = {
|
|
45
|
+
countryCode: 'SG'
|
|
46
|
+
}
|
|
44
47
|
|
|
45
48
|
useEffect(() => {
|
|
46
49
|
if (websiteCodeInUrl) {
|
|
@@ -88,7 +91,7 @@ const Adapter = props => {
|
|
|
88
91
|
);
|
|
89
92
|
}
|
|
90
93
|
}
|
|
91
|
-
}, [websiteCodeInUrl
|
|
94
|
+
}, [websiteCodeInUrl])
|
|
92
95
|
|
|
93
96
|
// TODO: Replace with app skeleton. See PWA-547.
|
|
94
97
|
if (!initialized) {
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { useIntl } from 'react-intl';
|
|
3
|
+
import { bool, shape, string } from 'prop-types';
|
|
4
|
+
|
|
5
|
+
import Checkbox from '@magento/venia-ui/lib/components/Checkbox';
|
|
6
|
+
import { useStyle } from '@magento/venia-ui/lib/classify';
|
|
7
|
+
import defaultClasses from '@magento/venia-ui/lib/components/FilterModal/FilterList/filterDefault.module.css';
|
|
8
|
+
import { useCurrencySwitcher } from '@magento/peregrine/lib/talons/Header/useCurrencySwitcher';
|
|
9
|
+
|
|
10
|
+
const FilterDefault = props => {
|
|
11
|
+
const {
|
|
12
|
+
classes: propsClasses,
|
|
13
|
+
isSelected,
|
|
14
|
+
item,
|
|
15
|
+
onMouseDown,
|
|
16
|
+
group,
|
|
17
|
+
...restProps
|
|
18
|
+
} = props;
|
|
19
|
+
|
|
20
|
+
const { label, value_index } = item || {};
|
|
21
|
+
const classes = useStyle(defaultClasses, propsClasses);
|
|
22
|
+
const { currentCurrencyCode } = useCurrencySwitcher();
|
|
23
|
+
const currencySymbolMap = {
|
|
24
|
+
USD: '$',
|
|
25
|
+
EUR: '€'
|
|
26
|
+
};
|
|
27
|
+
const currencySymbol = currencySymbolMap[currentCurrencyCode] != undefined ? currencySymbolMap[currentCurrencyCode] : currentCurrencyCode;
|
|
28
|
+
const title =
|
|
29
|
+
group === 'price'
|
|
30
|
+
? currencySymbol + label.replace('-', ' - ' + currencySymbol)
|
|
31
|
+
: label;
|
|
32
|
+
const { formatMessage } = useIntl();
|
|
33
|
+
|
|
34
|
+
const ariaLabel = !isSelected
|
|
35
|
+
? formatMessage(
|
|
36
|
+
{
|
|
37
|
+
id: 'filterModal.item.applyFilter',
|
|
38
|
+
defaultMessage: 'Apply filter "{optionName}".'
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
optionName: label
|
|
42
|
+
}
|
|
43
|
+
)
|
|
44
|
+
: formatMessage(
|
|
45
|
+
{
|
|
46
|
+
id: 'filterModal.item.clearFilter',
|
|
47
|
+
defaultMessage: 'Remove filter "{optionName}".'
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
optionName: label
|
|
51
|
+
}
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<Checkbox
|
|
56
|
+
classes={classes}
|
|
57
|
+
field={`${label}-${value_index}`}
|
|
58
|
+
fieldValue={!!isSelected}
|
|
59
|
+
label={title}
|
|
60
|
+
ariaLabel={ariaLabel}
|
|
61
|
+
data-cy="FilterDefault-checkbox"
|
|
62
|
+
onClick={onMouseDown}
|
|
63
|
+
{...restProps}
|
|
64
|
+
/>
|
|
65
|
+
);
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export default FilterDefault;
|
|
69
|
+
|
|
70
|
+
FilterDefault.propTypes = {
|
|
71
|
+
classes: shape({
|
|
72
|
+
root: string,
|
|
73
|
+
icon: string,
|
|
74
|
+
label: string,
|
|
75
|
+
checked: string
|
|
76
|
+
}),
|
|
77
|
+
group: string,
|
|
78
|
+
isSelected: bool,
|
|
79
|
+
item: shape({
|
|
80
|
+
label: string.isRequired,
|
|
81
|
+
value_index: string.isRequired
|
|
82
|
+
}).isRequired,
|
|
83
|
+
label: string
|
|
84
|
+
};
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import React, { useMemo, useCallback, useRef } from 'react';
|
|
2
|
+
import { FormattedMessage } from 'react-intl';
|
|
3
|
+
import { array, arrayOf, shape, string, number } from 'prop-types';
|
|
4
|
+
import { useFilterSidebar } from '@magento/peregrine/lib/talons/FilterSidebar';
|
|
5
|
+
|
|
6
|
+
import { useStyle } from '../../classify';
|
|
7
|
+
import LinkButton from '../LinkButton';
|
|
8
|
+
import CurrentFilters from '../FilterModal/CurrentFilters';
|
|
9
|
+
import FilterBlock from '../FilterModal/filterBlock';
|
|
10
|
+
import defaultClasses from './filterSidebar.module.css';
|
|
11
|
+
import ShopByCategory from '@riosst100/pwa-marketplace/src/components/ShopByCategory';
|
|
12
|
+
|
|
13
|
+
const SCROLL_OFFSET = 150;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* A view that displays applicable and applied filters.
|
|
17
|
+
*
|
|
18
|
+
* @param {Object} props.filters - filters to display
|
|
19
|
+
*/
|
|
20
|
+
const FilterSidebar = props => {
|
|
21
|
+
const { categoryName, children, parent, filters, filterCountToOpen } = props;
|
|
22
|
+
|
|
23
|
+
const talonProps = useFilterSidebar({ filters });
|
|
24
|
+
const {
|
|
25
|
+
filterApi,
|
|
26
|
+
filterItems,
|
|
27
|
+
filterNames,
|
|
28
|
+
filterFrontendInput,
|
|
29
|
+
filterState,
|
|
30
|
+
handleApply,
|
|
31
|
+
handleReset
|
|
32
|
+
} = talonProps;
|
|
33
|
+
|
|
34
|
+
const filterRef = useRef();
|
|
35
|
+
const classes = useStyle(defaultClasses, props.classes);
|
|
36
|
+
|
|
37
|
+
const handleApplyFilter = useCallback(
|
|
38
|
+
(...args) => {
|
|
39
|
+
const filterElement = filterRef.current;
|
|
40
|
+
if (
|
|
41
|
+
filterElement &&
|
|
42
|
+
typeof filterElement.getBoundingClientRect === 'function'
|
|
43
|
+
) {
|
|
44
|
+
const filterTop = filterElement.getBoundingClientRect().top;
|
|
45
|
+
const windowScrollY =
|
|
46
|
+
window.scrollY + filterTop - SCROLL_OFFSET;
|
|
47
|
+
window.scrollTo(0, windowScrollY);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
handleApply(...args);
|
|
51
|
+
},
|
|
52
|
+
[handleApply, filterRef]
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
const filtersList = useMemo(
|
|
56
|
+
() =>
|
|
57
|
+
Array.from(filterItems, ([group, items], iteration) => {
|
|
58
|
+
const blockState = filterState.get(group);
|
|
59
|
+
const groupName = filterNames.get(group);
|
|
60
|
+
const frontendInput = filterFrontendInput.get(group);
|
|
61
|
+
return (
|
|
62
|
+
<FilterBlock
|
|
63
|
+
key={group}
|
|
64
|
+
filterApi={filterApi}
|
|
65
|
+
filterState={blockState}
|
|
66
|
+
filterFrontendInput={frontendInput}
|
|
67
|
+
group={group}
|
|
68
|
+
items={items}
|
|
69
|
+
name={groupName}
|
|
70
|
+
onApply={handleApplyFilter}
|
|
71
|
+
initialOpen={iteration < filterCountToOpen}
|
|
72
|
+
/>
|
|
73
|
+
);
|
|
74
|
+
}),
|
|
75
|
+
[
|
|
76
|
+
filterApi,
|
|
77
|
+
filterItems,
|
|
78
|
+
filterNames,
|
|
79
|
+
filterFrontendInput,
|
|
80
|
+
filterState,
|
|
81
|
+
filterCountToOpen,
|
|
82
|
+
handleApplyFilter
|
|
83
|
+
]
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
const clearAll = filterState.size ? (
|
|
87
|
+
<div className={classes.action}>
|
|
88
|
+
<LinkButton
|
|
89
|
+
type="button"
|
|
90
|
+
onClick={handleReset}
|
|
91
|
+
data-cy="FilterSidebar-clearButton"
|
|
92
|
+
>
|
|
93
|
+
<FormattedMessage
|
|
94
|
+
id={'filterModal.action'}
|
|
95
|
+
defaultMessage={'Clear all'}
|
|
96
|
+
/>
|
|
97
|
+
</LinkButton>
|
|
98
|
+
</div>
|
|
99
|
+
) : null;
|
|
100
|
+
|
|
101
|
+
return (
|
|
102
|
+
<aside
|
|
103
|
+
className={classes.root}
|
|
104
|
+
ref={filterRef}
|
|
105
|
+
data-cy="FilterSidebar-root"
|
|
106
|
+
aria-busy="false"
|
|
107
|
+
>
|
|
108
|
+
<div className={classes.body}>
|
|
109
|
+
<div className={classes.header}>
|
|
110
|
+
<h2
|
|
111
|
+
data-cy="FilterSidebar-headerTitle"
|
|
112
|
+
className={classes.headerTitle}
|
|
113
|
+
>
|
|
114
|
+
<FormattedMessage
|
|
115
|
+
id={'filterModal.headerTitle'}
|
|
116
|
+
defaultMessage={'Filters'}
|
|
117
|
+
/>
|
|
118
|
+
</h2>
|
|
119
|
+
</div>
|
|
120
|
+
<CurrentFilters
|
|
121
|
+
filterApi={filterApi}
|
|
122
|
+
filterNames={filterNames}
|
|
123
|
+
filterState={filterState}
|
|
124
|
+
onRemove={handleApplyFilter}
|
|
125
|
+
/>
|
|
126
|
+
{clearAll}
|
|
127
|
+
<ul className={classes.blocks}>{filtersList}</ul>
|
|
128
|
+
<ul className={classes.blocks}><ShopByCategory categoryName={categoryName} children={children} parent={parent} /></ul>
|
|
129
|
+
</div>
|
|
130
|
+
</aside>
|
|
131
|
+
);
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
FilterSidebar.defaultProps = {
|
|
135
|
+
filterCountToOpen: 3
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
FilterSidebar.propTypes = {
|
|
139
|
+
classes: shape({
|
|
140
|
+
action: string,
|
|
141
|
+
blocks: string,
|
|
142
|
+
body: string,
|
|
143
|
+
header: string,
|
|
144
|
+
headerTitle: string,
|
|
145
|
+
root: string,
|
|
146
|
+
root_open: string
|
|
147
|
+
}),
|
|
148
|
+
filters: arrayOf(
|
|
149
|
+
shape({
|
|
150
|
+
attribute_code: string,
|
|
151
|
+
items: array
|
|
152
|
+
})
|
|
153
|
+
),
|
|
154
|
+
filterCountToOpen: number
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
export default FilterSidebar;
|
|
@@ -2,6 +2,7 @@ import React, { useEffect, useRef, useState } from 'react';
|
|
|
2
2
|
|
|
3
3
|
import { useIsInViewport } from '@magento/peregrine/lib/hooks/useIsInViewport';
|
|
4
4
|
import { useMegaMenu } from '@magento/peregrine/lib/talons/MegaMenu/useMegaMenu';
|
|
5
|
+
// import { useMegaMenu } from '@riosst100/pwa-marketplace/src/overwrites/peregrine/lib/talons/MegaMenu/useMegaMenu';
|
|
5
6
|
import { useStyle } from '@magento/venia-ui/lib/classify';
|
|
6
7
|
|
|
7
8
|
import MegaMenuItem from './megaMenuItem';
|
|
@@ -51,7 +52,7 @@ const MegaMenu = (props) => {
|
|
|
51
52
|
return () => {
|
|
52
53
|
window.removeEventListener('resize', handleResize);
|
|
53
54
|
};
|
|
54
|
-
});
|
|
55
|
+
}, [setMainNavWidth]);
|
|
55
56
|
|
|
56
57
|
const items = megaMenuData.children
|
|
57
58
|
? megaMenuData.children.map(category => {
|
|
@@ -67,6 +67,7 @@ const MegaMenuItem = props => {
|
|
|
67
67
|
isFocused={isFocused}
|
|
68
68
|
subMenuState={subMenuState}
|
|
69
69
|
items={category.children}
|
|
70
|
+
shopByItems={category.shop_by}
|
|
70
71
|
mainNavWidth={mainNavWidth}
|
|
71
72
|
handleCloseSubMenu={handleCloseSubMenu}
|
|
72
73
|
categoryUrlSuffix={categoryUrlSuffix}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Link } from 'react-router-dom';
|
|
3
|
+
|
|
4
|
+
import resourceUrl from '@magento/peregrine/lib/util/makeUrl';
|
|
5
|
+
|
|
6
|
+
import { useStyle } from '@magento/venia-ui/lib/classify';
|
|
7
|
+
import defaultClasses from './shopByColumn.module.css';
|
|
8
|
+
import PropTypes from 'prop-types';
|
|
9
|
+
|
|
10
|
+
const ShopByColumn = props => {
|
|
11
|
+
const classes = useStyle(defaultClasses, props.classes);
|
|
12
|
+
|
|
13
|
+
const {
|
|
14
|
+
shopBy
|
|
15
|
+
} = props;
|
|
16
|
+
|
|
17
|
+
// const categoryUrl = resourceUrl(
|
|
18
|
+
// `/${category.url_path}${categoryUrlSuffix || ''}`
|
|
19
|
+
// );
|
|
20
|
+
let items = null;
|
|
21
|
+
|
|
22
|
+
if (shopBy.items.length) {
|
|
23
|
+
const childrenItems = shopBy.items.map((shopByItem, index) => {
|
|
24
|
+
// const { url_path, isActive, name } = shopByItem;
|
|
25
|
+
const { name } = shopByItem;
|
|
26
|
+
// const categoryUrl = resourceUrl(
|
|
27
|
+
// `/${url_path}${categoryUrlSuffix || ''}`
|
|
28
|
+
// );
|
|
29
|
+
|
|
30
|
+
// setting keyboardProps if it is last child of that shopBy
|
|
31
|
+
const keyboardProps =
|
|
32
|
+
index === shopBy.items.length - 1
|
|
33
|
+
? props.keyboardProps
|
|
34
|
+
: {};
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<li key={index} className={classes.submenuChildItem}>
|
|
38
|
+
<Link
|
|
39
|
+
{...keyboardProps}
|
|
40
|
+
// className={isActive ? classes.linkActive : classes.link}
|
|
41
|
+
className={classes.link}
|
|
42
|
+
data-cy="MegaMenu-ShopByColumn-link"
|
|
43
|
+
// to={categoryUrl}
|
|
44
|
+
// onClick={onNavigate}
|
|
45
|
+
>
|
|
46
|
+
{name}
|
|
47
|
+
</Link>
|
|
48
|
+
</li>
|
|
49
|
+
);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
items = <ul className={classes.submenuChild}>{childrenItems}</ul>;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<div className={classes.ShopByColumn}>
|
|
57
|
+
{/* <Link
|
|
58
|
+
{...keyboardProps}
|
|
59
|
+
className={classes.link}
|
|
60
|
+
data-cy="MegaMenu-ShopByColumn-link"
|
|
61
|
+
to={categoryUrl}
|
|
62
|
+
onClick={() => {
|
|
63
|
+
handleCloseSubMenu();
|
|
64
|
+
onNavigate();
|
|
65
|
+
}}
|
|
66
|
+
>
|
|
67
|
+
<span className={classes.heading}>{category.name}</span>
|
|
68
|
+
</Link> */}
|
|
69
|
+
<span className={classes.heading}>{shopBy.name}</span>
|
|
70
|
+
{items}
|
|
71
|
+
</div>
|
|
72
|
+
);
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
export default ShopByColumn;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
.shopByColumn {
|
|
2
|
+
composes: max-w-[235px] from global;
|
|
3
|
+
composes: p-5 from global;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.heading {
|
|
7
|
+
composes: font-semibold from global;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.link {
|
|
11
|
+
composes: whitespace-nowrap from global;
|
|
12
|
+
|
|
13
|
+
composes: focus_underline from global;
|
|
14
|
+
|
|
15
|
+
composes: hover_underline from global;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.linkActive {
|
|
19
|
+
composes: underline from global;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.submenuChild {
|
|
23
|
+
composes: mt-5 from global;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.submenuChildItem {
|
|
27
|
+
composes: mb-3 from global;
|
|
28
|
+
}
|
|
@@ -6,6 +6,7 @@ import { useSubMenu } from '@magento/peregrine/lib/talons/MegaMenu/useSubMenu';
|
|
|
6
6
|
import { useStyle } from '@magento/venia-ui/lib/classify';
|
|
7
7
|
import defaultClasses from './submenu.module.css';
|
|
8
8
|
import SubmenuColumn from './submenuColumn';
|
|
9
|
+
import ShopByColumn from '@riosst100/pwa-marketplace/src/overwrites/venia-ui/lib/components/MegaMenu/shopByColumn';
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* The Submenu component displays submenu in mega menu
|
|
@@ -17,6 +18,7 @@ import SubmenuColumn from './submenuColumn';
|
|
|
17
18
|
const Submenu = props => {
|
|
18
19
|
const {
|
|
19
20
|
items,
|
|
21
|
+
shopByItems,
|
|
20
22
|
mainNavWidth,
|
|
21
23
|
isFocused,
|
|
22
24
|
subMenuState,
|
|
@@ -55,6 +57,34 @@ const Submenu = props => {
|
|
|
55
57
|
);
|
|
56
58
|
});
|
|
57
59
|
|
|
60
|
+
// const shopByItems = [
|
|
61
|
+
// {
|
|
62
|
+
// name: 'Shop By Franchise',
|
|
63
|
+
// items: [
|
|
64
|
+
// {
|
|
65
|
+
// name: 'Hasbro',
|
|
66
|
+
// url: '/'
|
|
67
|
+
// }
|
|
68
|
+
// ]
|
|
69
|
+
// }
|
|
70
|
+
// ];
|
|
71
|
+
|
|
72
|
+
const shopBy = shopByItems.map((shopBy, index) => {
|
|
73
|
+
const keyboardProps =
|
|
74
|
+
index === shopByItems.length - 1 ? talonProps.keyboardProps : {};
|
|
75
|
+
return (
|
|
76
|
+
<ShopByColumn
|
|
77
|
+
index={index}
|
|
78
|
+
keyboardProps={keyboardProps}
|
|
79
|
+
// key={category.uid}
|
|
80
|
+
shopBy={shopBy}
|
|
81
|
+
// categoryUrlSuffix={categoryUrlSuffix}
|
|
82
|
+
onNavigate={onNavigate}
|
|
83
|
+
handleCloseSubMenu={handleCloseSubMenu}
|
|
84
|
+
/>
|
|
85
|
+
);
|
|
86
|
+
});
|
|
87
|
+
|
|
58
88
|
return (
|
|
59
89
|
<div className={subMenuClassname}>
|
|
60
90
|
<div
|
|
@@ -62,6 +92,7 @@ const Submenu = props => {
|
|
|
62
92
|
style={{ minWidth: mainNavWidth + PADDING_OFFSET }}
|
|
63
93
|
>
|
|
64
94
|
{subMenus}
|
|
95
|
+
{shopBy}
|
|
65
96
|
</div>
|
|
66
97
|
</div>
|
|
67
98
|
);
|