@riosst100/pwa-marketplace 2.0.8 → 2.1.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.
- package/.github/workflows/dependabot.yml +28 -28
- package/i18n/en_US.json +508 -509
- package/i18n/id_ID.json +508 -509
- package/package.json +18 -22
- package/src/componentOverrideMapping.js +1 -0
- package/src/components/AccountLayout/index.js +15 -0
- package/src/components/OrderDetail/components/itemsOrdered.js +128 -0
- package/src/components/OrderDetail/components/rmaList.js +114 -0
- package/src/components/OrderDetail/orderDetail.js +204 -0
- package/src/components/OrderDetail/orderDetailPage.js +14 -0
- package/src/components/RMAPage/RMACreate.js +238 -0
- package/src/components/RMAPage/RMACreatePage.js +14 -0
- package/src/components/RMAPage/RMADetail.js +318 -0
- package/src/components/RMAPage/RMADetailPage.js +14 -0
- package/src/components/RMAPage/RMAList.js +241 -0
- package/src/components/RMAPage/RMASelect.js +36 -0
- package/src/components/RMAPage/RMASelectPage.js +13 -0
- package/src/components/RMAPage/components/productItem.js +114 -0
- package/src/components/RMAPage/components/rmaList.js +250 -0
- package/src/components/RMAPage/index.js +14 -0
- package/src/components/RMAPage/orderRow.js +318 -0
- package/src/components/commons/Checkbox/index.js +57 -0
- package/src/components/commons/Collapsible/index.js +51 -0
- package/src/components/commons/Select/index.js +29 -0
- package/src/components/commons/Textfield/index.js +20 -0
- package/src/intercept.js +35 -0
- package/src/overwrites/venia-ui/lib/components/AccountMenu/accountMenu.js +2 -1
- package/src/overwrites/venia-ui/lib/components/Breadcrumbs/breadcrumbs.module.css +38 -0
- package/src/overwrites/venia-ui/lib/components/CartPage/ProductListing/product.js +9 -2
- package/src/overwrites/venia-ui/lib/components/Footer/footer.js +1 -1
- package/src/overwrites/venia-ui/lib/components/Header/header.js +12 -1
- package/src/overwrites/venia-ui/lib/components/Newsletter/newsletter.js +1 -1
- package/src/overwrites/venia-ui/lib/components/OrderHistoryPage/orderRow.js +11 -3
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/productFullDetail.js +34 -3
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/productFullDetail.module.css +9 -0
- package/src/overwrites/venia-ui/lib/components/ProductImageCarousel/carousel.module.css +1 -1
- package/src/overwrites/venia-ui/lib/components/WishlistPage/actionMenu.ee.js +54 -0
- package/src/overwrites/venia-ui/lib/components/WishlistPage/actionMenu.js +7 -0
- package/src/overwrites/venia-ui/lib/components/WishlistPage/createWishlist.ee.js +129 -0
- package/src/overwrites/venia-ui/lib/components/WishlistPage/createWishlist.js +3 -0
- package/src/overwrites/venia-ui/lib/components/WishlistPage/createWishlist.module.css +63 -0
- package/src/overwrites/venia-ui/lib/components/WishlistPage/index.js +14 -0
- package/src/overwrites/venia-ui/lib/components/WishlistPage/wishlist.js +193 -0
- package/src/overwrites/venia-ui/lib/components/WishlistPage/wishlist.module.css +78 -0
- package/src/overwrites/venia-ui/lib/components/WishlistPage/wishlistConfirmRemoveProductDialog.js +84 -0
- package/src/overwrites/venia-ui/lib/components/WishlistPage/wishlistConfirmRemoveProductDialog.module.css +20 -0
- package/src/overwrites/venia-ui/lib/components/WishlistPage/wishlistEditFavoritesListDialog.js +96 -0
- package/src/overwrites/venia-ui/lib/components/WishlistPage/wishlistEditFavoritesListDialog.module.css +22 -0
- package/src/overwrites/venia-ui/lib/components/WishlistPage/wishlistItem.js +138 -0
- package/src/overwrites/venia-ui/lib/components/WishlistPage/wishlistItem.module.css +78 -0
- package/src/overwrites/venia-ui/lib/components/WishlistPage/wishlistItems.js +45 -0
- package/src/overwrites/venia-ui/lib/components/WishlistPage/wishlistItems.module.css +9 -0
- package/src/overwrites/venia-ui/lib/components/WishlistPage/wishlistListActionsDialog.js +61 -0
- package/src/overwrites/venia-ui/lib/components/WishlistPage/wishlistMoreActionsDialog.js +84 -0
- package/src/overwrites/venia-ui/lib/components/WishlistPage/wishlistMoreActionsDialog.module.css +19 -0
- package/src/overwrites/venia-ui/lib/components/WishlistPage/wishlistPage.js +120 -0
- package/src/overwrites/venia-ui/lib/components/WishlistPage/wishlistPage.module.css +31 -0
|
@@ -14,6 +14,7 @@ import defaultClasses from './orderRow.module.css';
|
|
|
14
14
|
import cn from 'classnames';
|
|
15
15
|
import { Verify } from 'iconsax-react';
|
|
16
16
|
import PlaceholderImage from '@magento/venia-ui/lib/components/Image/placeholderImage';
|
|
17
|
+
import { Link } from 'react-router-dom';
|
|
17
18
|
|
|
18
19
|
const OrderRow = props => {
|
|
19
20
|
const { order } = props;
|
|
@@ -162,20 +163,27 @@ const OrderRow = props => {
|
|
|
162
163
|
</div>
|
|
163
164
|
</div>
|
|
164
165
|
<div className='flex flex-row justify-end py-[5px]'>
|
|
165
|
-
<button
|
|
166
|
+
{/* <button
|
|
166
167
|
className={cn(classes.contentToggleContainer, '!p-0 !border-0')}
|
|
167
168
|
onClick={handleContentToggle}
|
|
168
169
|
type="button"
|
|
169
170
|
aria-expanded={isOpen}
|
|
170
171
|
>
|
|
171
|
-
{/* {contentToggleIcon} */}
|
|
172
172
|
<span className="text-[13px] font-medium text-blue-700 underline">
|
|
173
173
|
<FormattedMessage
|
|
174
174
|
id={'orderRow.ViewTransactionDetail'}
|
|
175
175
|
defaultMessage={'View Transaction Detail'}
|
|
176
176
|
/>
|
|
177
177
|
</span>
|
|
178
|
-
</button>
|
|
178
|
+
</button> */}
|
|
179
|
+
<Link to="/order-history/view/123213">
|
|
180
|
+
<span className="text-[13px] font-medium text-blue-700 underline">
|
|
181
|
+
<FormattedMessage
|
|
182
|
+
id={'orderRow.ViewTransactionDetail'}
|
|
183
|
+
defaultMessage={'View Transaction Detail'}
|
|
184
|
+
/>
|
|
185
|
+
</span>
|
|
186
|
+
</Link>
|
|
179
187
|
</div>
|
|
180
188
|
|
|
181
189
|
{/* <div className={classes.orderDateContainer}>
|
|
@@ -36,6 +36,7 @@ import CrossSeller from '@riosst100/pwa-marketplace/src/components/CrossSeller';
|
|
|
36
36
|
import RelatedProduct from '@riosst100/pwa-marketplace/src/components/RelatedProduct';
|
|
37
37
|
import ProductLabel from '@riosst100/pwa-marketplace/src/components/ProductLabel';
|
|
38
38
|
import RFQ from '@riosst100/pwa-marketplace/src/components/RFQ';
|
|
39
|
+
import Collapsible from '@riosst100/pwa-marketplace/src/components/commons/Collapsible';
|
|
39
40
|
|
|
40
41
|
// Correlate a GQL error message to a field. GQL could return a longer error
|
|
41
42
|
// string but it may contain contextual info such as product id. We can use
|
|
@@ -51,6 +52,25 @@ const ERROR_FIELD_TO_MESSAGE_MAPPING = {
|
|
|
51
52
|
quantity: 'The requested quantity is not available.'
|
|
52
53
|
};
|
|
53
54
|
|
|
55
|
+
const ProductDetailsCollapsible = (props) => {
|
|
56
|
+
const { data } = props;
|
|
57
|
+
|
|
58
|
+
return (
|
|
59
|
+
<>
|
|
60
|
+
{data.map((_data) => (
|
|
61
|
+
<Collapsible
|
|
62
|
+
title={_data.title}
|
|
63
|
+
contentWrapperClassName="!mt-0"
|
|
64
|
+
rootClassName="first-of-type_!border-0 last-of-type_border-b last-of-type_border-gray-100"
|
|
65
|
+
className="last-of-type_border-b last-of-type_border-gray-100"
|
|
66
|
+
>
|
|
67
|
+
{_data.content}
|
|
68
|
+
</Collapsible>
|
|
69
|
+
))}
|
|
70
|
+
</>
|
|
71
|
+
)
|
|
72
|
+
}
|
|
73
|
+
|
|
54
74
|
const ProductFullDetail = props => {
|
|
55
75
|
const { product } = props;
|
|
56
76
|
|
|
@@ -283,7 +303,7 @@ const ProductFullDetail = props => {
|
|
|
283
303
|
|
|
284
304
|
const tokopedia_logo = './tokopedia_logo.png';
|
|
285
305
|
|
|
286
|
-
const contentContainerClass = 'content-container max-w-[1040px] p-2.5 m-auto relative mt-[34px]'
|
|
306
|
+
const contentContainerClass = 'content-container max-w-[1040px] p-2.5 m-auto relative mt-0 lg_mt-[34px] pb-6 lg_pb-0'
|
|
287
307
|
const ProductDescription = () => (
|
|
288
308
|
<div className={cn(contentContainerClass)}>
|
|
289
309
|
{/* <span
|
|
@@ -428,7 +448,7 @@ const ProductFullDetail = props => {
|
|
|
428
448
|
<section className={cn(classes.leftContainer, 'relative')}>
|
|
429
449
|
<ProductLabel item={productDetails} />
|
|
430
450
|
<Carousel images={mediaGalleryEntries} />
|
|
431
|
-
<div className='product_group-actions flex gap-x-[18px] gap-y-4 justify-center items-center mt-5'>
|
|
451
|
+
<div className='product_group-actions flex gap-x-[18px] gap-y-4 justify-center items-center mt-2 lg_mt-5 mb-6 lg_mb-0'>
|
|
432
452
|
<Suspense fallback={null}>
|
|
433
453
|
<WishlistButton
|
|
434
454
|
classes={{
|
|
@@ -660,6 +680,17 @@ const ProductFullDetail = props => {
|
|
|
660
680
|
</section>
|
|
661
681
|
</Form>
|
|
662
682
|
<section className='section_product-details-container mt-8 mb-10'>
|
|
683
|
+
<div className='hidden lg_block'>
|
|
684
|
+
<Tabs
|
|
685
|
+
data={dataTabs}
|
|
686
|
+
tabContentWrapperClassName='!p-0'
|
|
687
|
+
hasContent
|
|
688
|
+
tabWrapperClassName='xl_gap-x-[60px] justify-center'
|
|
689
|
+
/>
|
|
690
|
+
</div>
|
|
691
|
+
<div className='block lg_hidden'>
|
|
692
|
+
<ProductDetailsCollapsible data={dataTabs} />
|
|
693
|
+
</div>
|
|
663
694
|
<Tabs
|
|
664
695
|
data={dataTabs}
|
|
665
696
|
tabContentWrapperClassName='!p-0'
|
|
@@ -673,7 +704,7 @@ const ProductFullDetail = props => {
|
|
|
673
704
|
</section>
|
|
674
705
|
|
|
675
706
|
<section className='w-[calc(100vw-9px)] relative left-1/2 right-1/2 ml-[-50vw] mr-[-50vw] bg-gray-50 py-[30px] px-0 mb-10'>
|
|
676
|
-
<div className='
|
|
707
|
+
<div className='lg_max-w-[1200px] px-2.5 mx-auto relative max-w-screen-md'>
|
|
677
708
|
<CrossSeller />
|
|
678
709
|
</div>
|
|
679
710
|
</section>
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import Icon from '../Icon';
|
|
3
|
+
import { MoreHorizontal } from 'react-feather';
|
|
4
|
+
import { useActionMenu } from '@magento/peregrine/lib/talons/WishlistPage/useActionMenu';
|
|
5
|
+
import WishlistListActionsDialog from './wishlistListActionsDialog';
|
|
6
|
+
import WishlistEditFavoritesListDialog from './wishlistEditFavoritesListDialog';
|
|
7
|
+
|
|
8
|
+
const ActionMenu = props => {
|
|
9
|
+
const { id, name, visibility } = props;
|
|
10
|
+
const talonProps = useActionMenu({ id });
|
|
11
|
+
const {
|
|
12
|
+
editFavoritesListIsOpen,
|
|
13
|
+
formErrors,
|
|
14
|
+
handleActionMenuClick,
|
|
15
|
+
handleEditWishlist,
|
|
16
|
+
handleHideDialogs,
|
|
17
|
+
handleShowEditFavorites,
|
|
18
|
+
isEditInProgress,
|
|
19
|
+
listActionsIsOpen,
|
|
20
|
+
shouldRender
|
|
21
|
+
} = talonProps;
|
|
22
|
+
|
|
23
|
+
if (!shouldRender) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<div>
|
|
29
|
+
<button onClick={handleActionMenuClick} type="button">
|
|
30
|
+
<Icon src={MoreHorizontal} size={24} />
|
|
31
|
+
</button>
|
|
32
|
+
<WishlistListActionsDialog
|
|
33
|
+
isOpen={listActionsIsOpen}
|
|
34
|
+
onCancel={handleHideDialogs}
|
|
35
|
+
onEdit={handleShowEditFavorites}
|
|
36
|
+
/>
|
|
37
|
+
<WishlistEditFavoritesListDialog
|
|
38
|
+
formErrors={formErrors}
|
|
39
|
+
formProps={{
|
|
40
|
+
initialValues: {
|
|
41
|
+
name: name,
|
|
42
|
+
visibility: visibility
|
|
43
|
+
}
|
|
44
|
+
}}
|
|
45
|
+
isOpen={editFavoritesListIsOpen}
|
|
46
|
+
isEditInProgress={isEditInProgress}
|
|
47
|
+
onCancel={handleHideDialogs}
|
|
48
|
+
onConfirm={handleEditWishlist}
|
|
49
|
+
/>
|
|
50
|
+
</div>
|
|
51
|
+
);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export default ActionMenu;
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { shape, string } from 'prop-types';
|
|
3
|
+
import { FormattedMessage, useIntl } from 'react-intl';
|
|
4
|
+
import { PlusSquare } from 'react-feather';
|
|
5
|
+
|
|
6
|
+
import { useCreateWishlist } from '@magento/peregrine/lib/talons/WishlistPage/useCreateWishlist';
|
|
7
|
+
|
|
8
|
+
import Dialog from '@magento/venia-ui/lib/components/Dialog';
|
|
9
|
+
import Field from '@magento/venia-ui/lib/components/Field';
|
|
10
|
+
import Icon from '@magento/venia-ui/lib/components/Icon';
|
|
11
|
+
import { isRequired } from '@magento/venia-ui/lib/util/formValidators';
|
|
12
|
+
import { useStyle } from '@magento/venia-ui/lib/classify';
|
|
13
|
+
|
|
14
|
+
import TextInput from '@magento/venia-ui/lib/components/TextInput';
|
|
15
|
+
import FormError from '@magento/venia-ui/lib/components/FormError/formError';
|
|
16
|
+
|
|
17
|
+
import defaultClasses from './createWishlist.module.css';
|
|
18
|
+
|
|
19
|
+
const CreateWishlist = props => {
|
|
20
|
+
const { numberOfWishlists } = props;
|
|
21
|
+
|
|
22
|
+
const classes = useStyle(defaultClasses, props.classes);
|
|
23
|
+
|
|
24
|
+
const talonProps = useCreateWishlist({ numberOfWishlists });
|
|
25
|
+
const {
|
|
26
|
+
handleCreateList,
|
|
27
|
+
handleHideModal,
|
|
28
|
+
handleShowModal,
|
|
29
|
+
isModalOpen,
|
|
30
|
+
formErrors,
|
|
31
|
+
loading,
|
|
32
|
+
shouldRender
|
|
33
|
+
} = talonProps;
|
|
34
|
+
|
|
35
|
+
const { formatMessage } = useIntl();
|
|
36
|
+
|
|
37
|
+
const createIcon = (
|
|
38
|
+
<Icon
|
|
39
|
+
classes={{
|
|
40
|
+
icon: classes.icon
|
|
41
|
+
}}
|
|
42
|
+
src={PlusSquare}
|
|
43
|
+
/>
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
return shouldRender ? (
|
|
47
|
+
<div className={classes.root}>
|
|
48
|
+
<button
|
|
49
|
+
className={classes.createButton}
|
|
50
|
+
onClick={handleShowModal}
|
|
51
|
+
type="button"
|
|
52
|
+
data-cy="createWishlist-createButton"
|
|
53
|
+
>
|
|
54
|
+
<div className={classes.labelContainer}>
|
|
55
|
+
{createIcon}
|
|
56
|
+
<span>
|
|
57
|
+
<FormattedMessage
|
|
58
|
+
id={'createWishlist.handleCreateListText'}
|
|
59
|
+
defaultMessage={'Create a list'}
|
|
60
|
+
/>
|
|
61
|
+
</span>
|
|
62
|
+
</div>
|
|
63
|
+
</button>
|
|
64
|
+
<Dialog
|
|
65
|
+
classes={{
|
|
66
|
+
body: classes.body,
|
|
67
|
+
buttons: classes.buttons,
|
|
68
|
+
cancelButton: classes.cancelButton,
|
|
69
|
+
confirmButton: classes.confirmButton,
|
|
70
|
+
contents: classes.contents
|
|
71
|
+
}}
|
|
72
|
+
cancelText={formatMessage({
|
|
73
|
+
id: 'global.cancelButton',
|
|
74
|
+
defaultMessage: 'Cancel'
|
|
75
|
+
})}
|
|
76
|
+
confirmText={formatMessage({
|
|
77
|
+
id: 'global.save',
|
|
78
|
+
defaultMessage: 'Save'
|
|
79
|
+
})}
|
|
80
|
+
formProps={{ initialValues: { visibility: 'PRIVATE' } }}
|
|
81
|
+
isModal={true}
|
|
82
|
+
isOpen={isModalOpen}
|
|
83
|
+
onCancel={handleHideModal}
|
|
84
|
+
onConfirm={handleCreateList}
|
|
85
|
+
shouldUnmountOnHide={true}
|
|
86
|
+
title={formatMessage({
|
|
87
|
+
id: 'createWishlist.dialogTitle',
|
|
88
|
+
defaultMessage: 'New Favorites List'
|
|
89
|
+
})}
|
|
90
|
+
shouldDisableConfirmButton={loading}
|
|
91
|
+
>
|
|
92
|
+
<div className={classes.form}>
|
|
93
|
+
<FormError errors={Array.from(formErrors.values())} />
|
|
94
|
+
<Field
|
|
95
|
+
classes={{ root: classes.listName }}
|
|
96
|
+
label={formatMessage({
|
|
97
|
+
id: 'createWishlist.listName',
|
|
98
|
+
defaultMessage: 'List Name'
|
|
99
|
+
})}
|
|
100
|
+
>
|
|
101
|
+
<TextInput
|
|
102
|
+
field="name"
|
|
103
|
+
validate={isRequired}
|
|
104
|
+
validateOnBlur
|
|
105
|
+
data-cy="createWishlist-name"
|
|
106
|
+
/>
|
|
107
|
+
</Field>
|
|
108
|
+
</div>
|
|
109
|
+
</Dialog>
|
|
110
|
+
</div>
|
|
111
|
+
) : null;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
export default CreateWishlist;
|
|
115
|
+
|
|
116
|
+
CreateWishlist.propTypes = {
|
|
117
|
+
classes: shape({
|
|
118
|
+
body: string,
|
|
119
|
+
buttons: string,
|
|
120
|
+
createButton: string,
|
|
121
|
+
icon: string,
|
|
122
|
+
labelContainer: string,
|
|
123
|
+
listName: string,
|
|
124
|
+
radioLabel: string,
|
|
125
|
+
radioMessage: string,
|
|
126
|
+
radioRoot: string,
|
|
127
|
+
root: string
|
|
128
|
+
})
|
|
129
|
+
};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
.root {}
|
|
2
|
+
|
|
3
|
+
.body {
|
|
4
|
+
composes: overflow-auto from global;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.buttons {
|
|
8
|
+
composes: gap-xs from global;
|
|
9
|
+
composes: grid from global;
|
|
10
|
+
composes: grid-flow-col from global;
|
|
11
|
+
composes: justify-center from global;
|
|
12
|
+
composes: pb-md from global;
|
|
13
|
+
composes: pt-xs from global;
|
|
14
|
+
composes: px-xs from global;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.cancelButton {
|
|
18
|
+
composes: root_lowPriority from '@magento/venia-ui/lib/components/Button/button.module.css';
|
|
19
|
+
|
|
20
|
+
composes: min-w-[9rem] from global;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.confirmButton {
|
|
24
|
+
composes: root_highPriority from '@magento/venia-ui/lib/components/Button/button.module.css';
|
|
25
|
+
|
|
26
|
+
composes: min-w-[9rem] from global;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.contents {
|
|
30
|
+
composes: h-fitContent from global;
|
|
31
|
+
composes: p-xs from global;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.createButton {
|
|
35
|
+
composes: w-full from global;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.form {
|
|
39
|
+
composes: gap-md from global;
|
|
40
|
+
composes: grid from global;
|
|
41
|
+
composes: m-auto from global;
|
|
42
|
+
composes: px-xs from global;
|
|
43
|
+
composes: py-2xs from global;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.icon {
|
|
47
|
+
composes: stroke-brand-base from global;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.labelContainer {
|
|
51
|
+
composes: border-2 from global;
|
|
52
|
+
composes: border-solid from global;
|
|
53
|
+
composes: border-subtle from global;
|
|
54
|
+
composes: font-semibold from global;
|
|
55
|
+
composes: gap-x-2xs from global;
|
|
56
|
+
composes: grid from global;
|
|
57
|
+
composes: grid-flow-col from global;
|
|
58
|
+
composes: h-[6rem] from global;
|
|
59
|
+
composes: items-center from global;
|
|
60
|
+
composes: justify-center from global;
|
|
61
|
+
composes: rounded-md from global;
|
|
62
|
+
composes: text-brand-dark from global;
|
|
63
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import WishlistPage from './wishlistPage'
|
|
2
|
+
import AccountLayout from '@riosst100/pwa-marketplace/src/components/AccountLayout';
|
|
3
|
+
|
|
4
|
+
import React from 'react';
|
|
5
|
+
|
|
6
|
+
const index = () => {
|
|
7
|
+
return (
|
|
8
|
+
<AccountLayout>
|
|
9
|
+
<WishlistPage />
|
|
10
|
+
</AccountLayout>
|
|
11
|
+
)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export default index;
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import React, { Fragment } from 'react';
|
|
2
|
+
import { FormattedMessage, useIntl } from 'react-intl';
|
|
3
|
+
import { ChevronDown, ChevronUp } from 'react-feather';
|
|
4
|
+
import { useWishlist } from '@magento/peregrine/lib/talons/WishlistPage/useWishlist';
|
|
5
|
+
import { bool, shape, string, int } from 'prop-types';
|
|
6
|
+
|
|
7
|
+
import { useStyle } from '@magento/venia-ui/lib/classify';
|
|
8
|
+
import LoadingIndicator from '@magento/venia-ui/lib/components/LoadingIndicator';
|
|
9
|
+
import Icon from '@magento/venia-ui/lib/components/Icon';
|
|
10
|
+
import WishlistItems from './wishlistItems';
|
|
11
|
+
import Button from '@magento/venia-ui/lib/components/Button';
|
|
12
|
+
import defaultClasses from './wishlist.module.css';
|
|
13
|
+
import ActionMenu from './actionMenu';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* A single wishlist container.
|
|
17
|
+
*
|
|
18
|
+
* @param {Object} props.data the data for this wishlist
|
|
19
|
+
* @param {boolean} props.shouldRenderVisibilityToggle whether or not to render the visiblity toggle
|
|
20
|
+
* @param {boolean} props.isCollapsed whether or not is the wishlist unfolded
|
|
21
|
+
*/
|
|
22
|
+
const Wishlist = props => {
|
|
23
|
+
const { data, shouldRenderVisibilityToggle, isCollapsed } = props;
|
|
24
|
+
const { formatMessage } = useIntl();
|
|
25
|
+
const { id, items_count: itemsCount, name, visibility } = data;
|
|
26
|
+
|
|
27
|
+
const talonProps = useWishlist({ id, itemsCount, isCollapsed });
|
|
28
|
+
const {
|
|
29
|
+
handleContentToggle,
|
|
30
|
+
isOpen,
|
|
31
|
+
items,
|
|
32
|
+
isLoading,
|
|
33
|
+
isFetchingMore,
|
|
34
|
+
handleLoadMore
|
|
35
|
+
} = talonProps;
|
|
36
|
+
|
|
37
|
+
const classes = useStyle(defaultClasses, props.classes);
|
|
38
|
+
const contentClass = isOpen ? classes.content : classes.content_hidden;
|
|
39
|
+
const contentToggleIconSrc = isOpen ? ChevronUp : ChevronDown;
|
|
40
|
+
const contentToggleIcon = <Icon src={contentToggleIconSrc} size={24} />;
|
|
41
|
+
|
|
42
|
+
const itemsCountMessage =
|
|
43
|
+
itemsCount && isOpen
|
|
44
|
+
? formatMessage(
|
|
45
|
+
{
|
|
46
|
+
id: 'wishlist.itemCountOpen',
|
|
47
|
+
defaultMessage:
|
|
48
|
+
'Showing {currentCount} of {count} items in this list'
|
|
49
|
+
},
|
|
50
|
+
{ currentCount: items.length, count: itemsCount }
|
|
51
|
+
)
|
|
52
|
+
: formatMessage(
|
|
53
|
+
{
|
|
54
|
+
id: 'wishlist.itemCountClosed',
|
|
55
|
+
defaultMessage: `You have {count} {count, plural,
|
|
56
|
+
one {item}
|
|
57
|
+
other {items}
|
|
58
|
+
} in this list`
|
|
59
|
+
},
|
|
60
|
+
{ count: itemsCount }
|
|
61
|
+
);
|
|
62
|
+
const loadMoreButton =
|
|
63
|
+
items && items.length < itemsCount ? (
|
|
64
|
+
<div>
|
|
65
|
+
<Button
|
|
66
|
+
className={classes.loadMore}
|
|
67
|
+
disabled={isFetchingMore}
|
|
68
|
+
onClick={handleLoadMore}
|
|
69
|
+
>
|
|
70
|
+
<FormattedMessage
|
|
71
|
+
id={'wishlist.loadMore'}
|
|
72
|
+
defaultMessage={'Load more'}
|
|
73
|
+
/>
|
|
74
|
+
</Button>
|
|
75
|
+
</div>
|
|
76
|
+
) : null;
|
|
77
|
+
|
|
78
|
+
const contentMessageElement = itemsCount ? (
|
|
79
|
+
<Fragment>
|
|
80
|
+
<WishlistItems items={items} wishlistId={id} />
|
|
81
|
+
{loadMoreButton}
|
|
82
|
+
</Fragment>
|
|
83
|
+
) : (
|
|
84
|
+
<p className={classes.emptyListText}>
|
|
85
|
+
<FormattedMessage
|
|
86
|
+
id={'wishlist.emptyListText'}
|
|
87
|
+
defaultMessage={'There are currently no items in this list'}
|
|
88
|
+
/>
|
|
89
|
+
</p>
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
const wishlistName = name ? (
|
|
93
|
+
<div className={classes.nameContainer}>
|
|
94
|
+
<h2 className={classes.name} data-cy="Wishlist-name" title={name}>
|
|
95
|
+
{name}
|
|
96
|
+
</h2>
|
|
97
|
+
</div>
|
|
98
|
+
) : (
|
|
99
|
+
<div className={classes.nameContainer}>
|
|
100
|
+
<h2 className={classes.name}>
|
|
101
|
+
<FormattedMessage
|
|
102
|
+
id={'wishlist.name'}
|
|
103
|
+
defaultMessage={'Wish List'}
|
|
104
|
+
/>
|
|
105
|
+
</h2>
|
|
106
|
+
</div>
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
if (isLoading) {
|
|
110
|
+
return (
|
|
111
|
+
<div className={classes.root}>
|
|
112
|
+
<div className={classes.header}>
|
|
113
|
+
{wishlistName} {itemsCountMessage}
|
|
114
|
+
<div className={classes.buttonsContainer}>
|
|
115
|
+
<ActionMenu
|
|
116
|
+
id={id}
|
|
117
|
+
name={name}
|
|
118
|
+
visibility={visibility}
|
|
119
|
+
/>
|
|
120
|
+
</div>
|
|
121
|
+
</div>
|
|
122
|
+
<LoadingIndicator />
|
|
123
|
+
</div>
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const visibilityToggleClass = shouldRenderVisibilityToggle
|
|
128
|
+
? classes.visibilityToggle
|
|
129
|
+
: classes.visibilityToggle_hidden;
|
|
130
|
+
|
|
131
|
+
const buttonsContainer = id ? (
|
|
132
|
+
<div
|
|
133
|
+
className={classes.buttonsContainer}
|
|
134
|
+
data-cy="wishlist-buttonsContainer"
|
|
135
|
+
>
|
|
136
|
+
<ActionMenu id={id} name={name} visibility={visibility} />
|
|
137
|
+
<button
|
|
138
|
+
className={visibilityToggleClass}
|
|
139
|
+
onClick={handleContentToggle}
|
|
140
|
+
type="button"
|
|
141
|
+
>
|
|
142
|
+
{contentToggleIcon}
|
|
143
|
+
</button>
|
|
144
|
+
</div>
|
|
145
|
+
) : null;
|
|
146
|
+
|
|
147
|
+
return (
|
|
148
|
+
<div className={classes.root} data-cy="Wishlist-root">
|
|
149
|
+
<div className={classes.header}>
|
|
150
|
+
{wishlistName}
|
|
151
|
+
<div className={classes.itemsCountContainer}>
|
|
152
|
+
{itemsCountMessage}
|
|
153
|
+
</div>
|
|
154
|
+
{buttonsContainer}
|
|
155
|
+
</div>
|
|
156
|
+
<div className={contentClass}>{contentMessageElement}</div>
|
|
157
|
+
</div>
|
|
158
|
+
);
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
Wishlist.propTypes = {
|
|
162
|
+
classes: shape({
|
|
163
|
+
root: string,
|
|
164
|
+
header: string,
|
|
165
|
+
content: string,
|
|
166
|
+
content_hidden: string,
|
|
167
|
+
emptyListText: string,
|
|
168
|
+
name: string,
|
|
169
|
+
nameContainer: string,
|
|
170
|
+
visibilityToggle: string,
|
|
171
|
+
visibilityToggle_hidden: string,
|
|
172
|
+
visibility: string,
|
|
173
|
+
buttonsContainer: string,
|
|
174
|
+
loadMore: string
|
|
175
|
+
}),
|
|
176
|
+
shouldRenderVisibilityToggle: bool,
|
|
177
|
+
isCollapsed: bool,
|
|
178
|
+
data: shape({
|
|
179
|
+
id: int,
|
|
180
|
+
items_count: int,
|
|
181
|
+
name: string,
|
|
182
|
+
visibility: string
|
|
183
|
+
})
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
Wishlist.defaultProps = {
|
|
187
|
+
data: {
|
|
188
|
+
items_count: 0,
|
|
189
|
+
items_v2: []
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
export default Wishlist;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
.root {
|
|
2
|
+
composes: gap-y-md from global;
|
|
3
|
+
composes: grid from global;
|
|
4
|
+
composes: rounded-md from global;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.header {
|
|
8
|
+
composes: gap-y-0 from global;
|
|
9
|
+
composes: flex from global;
|
|
10
|
+
composes: grid-flow-col from global;
|
|
11
|
+
composes: items-center from global;
|
|
12
|
+
composes: justify-between from global;
|
|
13
|
+
|
|
14
|
+
composes: md_gap-y-2xs from global;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
@media (max-width: 799px) {
|
|
18
|
+
.header {
|
|
19
|
+
grid-template-rows: 1fr 1fr;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.nameContainer {
|
|
24
|
+
composes: gap-x-2xs from global;
|
|
25
|
+
composes: gap-y-xs from global;
|
|
26
|
+
composes: grid from global;
|
|
27
|
+
composes: grid-flow-row from global;
|
|
28
|
+
composes: items-center from global;
|
|
29
|
+
|
|
30
|
+
composes: md_grid-flow-col from global;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.emptyListText {
|
|
34
|
+
composes: py-md from global;
|
|
35
|
+
composes: text-center from global;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.name {
|
|
39
|
+
composes: font-semibold from global;
|
|
40
|
+
composes: overflow-hidden from global;
|
|
41
|
+
composes: whitespace-nowrap from global;
|
|
42
|
+
composes: text-ellipsis from global;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.buttonsContainer {
|
|
46
|
+
composes: gap-x-xs from global;
|
|
47
|
+
composes: grid from global;
|
|
48
|
+
composes: grid-flow-col from global;
|
|
49
|
+
composes: items-center from global;
|
|
50
|
+
composes: justify-self-end from global;
|
|
51
|
+
|
|
52
|
+
composes: md_justify-self-start from global;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.content_hidden {
|
|
56
|
+
composes: hidden from global;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.visibilityToggle_hidden {
|
|
60
|
+
composes: hidden from global;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.loadMore {
|
|
64
|
+
composes: root_lowPriority from '@magento/venia-ui/lib/components/Button/button.module.css';
|
|
65
|
+
|
|
66
|
+
composes: block from global;
|
|
67
|
+
composes: min-w-[20rem] from global;
|
|
68
|
+
composes: mx-auto from global;
|
|
69
|
+
composes: my-md from global;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.itemsCountContainer {
|
|
73
|
+
composes: col-end-span2 from global;
|
|
74
|
+
composes: justify-self-center from global;
|
|
75
|
+
|
|
76
|
+
composes: md_col-end-auto from global;
|
|
77
|
+
composes: md_justify-self-start from global;
|
|
78
|
+
}
|