@riosst100/pwa-marketplace 3.0.3 → 3.0.5
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/i18n/en_US.json +3 -3
- package/i18n/id_ID.json +2 -2
- package/package.json +1 -1
- package/src/componentOverrideMapping.js +1 -0
- package/src/components/CrossSeller/item.js +3 -4
- package/src/components/LinkToOtherStores/index.js +4 -4
- package/src/components/OrderDetail/components/itemsOrdered.js +1 -6
- package/src/components/ProductListTab/productListTab.js +1 -1
- package/src/components/RMAPage/components/productItem.js +13 -43
- package/src/components/SellerCoupon/index.js +1 -0
- package/src/components/SellerCoupon/sellerCoupon.js +41 -6
- package/src/components/SellerCoupon/sellerCoupon.module.css +22 -0
- package/src/components/SellerCoupon/sellerCouponCheckout.js +36 -19
- package/src/components/SellerCoupon/sellerCouponCheckout.shimmer.js +21 -0
- package/src/components/commons/Select/index.js +8 -4
- package/src/overwrites/peregrine/lib/talons/CartPage/PriceSummary/priceSummaryFragments.gql.js +3 -0
- package/src/overwrites/peregrine/lib/talons/CartPage/PriceSummary/usePriceSummary.js +2 -2
- package/src/overwrites/peregrine/lib/talons/CartPage/ProductListing/productListingFragments.gql.js +4 -0
- package/src/overwrites/peregrine/lib/talons/CheckoutPage/checkoutPage.extended.gql.js +20 -1
- package/src/overwrites/peregrine/lib/talons/FilterSidebar/useFilterSidebar.js +3 -3
- package/src/overwrites/peregrine/lib/talons/ProductFullDetail/useProductFullDetail.js +7 -8
- package/src/overwrites/peregrine/lib/talons/RootComponents/Product/productDetailFragment.gql.js +5 -0
- package/src/overwrites/venia-ui/lib/components/Breadcrumbs/breadcrumbs.js +20 -1
- package/src/overwrites/venia-ui/lib/components/CartPage/PriceAdjustments/CouponCode/couponCode.js +24 -27
- package/src/overwrites/venia-ui/lib/components/CartPage/PriceAdjustments/CouponCode/couponCode.module.css +2 -0
- package/src/overwrites/venia-ui/lib/components/CartPage/PriceSummary/priceSummary.js +14 -5
- package/src/overwrites/venia-ui/lib/components/CartPage/ProductListing/product.js +41 -1
- package/src/overwrites/venia-ui/lib/components/CartPage/ProductListing/product.module.css +1 -1
- package/src/overwrites/venia-ui/lib/components/CartPage/ProductListingBySeller/productListingBySeller.js +41 -8
- package/src/overwrites/venia-ui/lib/components/CartPage/cartPage.js +0 -7
- package/src/overwrites/venia-ui/lib/components/CheckoutPage/ItemsReview/item.js +43 -2
- package/src/overwrites/venia-ui/lib/components/CheckoutPage/ItemsReview/item.module.css +36 -0
- package/src/overwrites/venia-ui/lib/components/CheckoutPage/ItemsReview/itemsReview.js +8 -2
- package/src/overwrites/venia-ui/lib/components/CheckoutPage/OrderSummary/orderSummary.js +4 -0
- package/src/overwrites/venia-ui/lib/components/CheckoutPage/PriceAdjustments/priceAdjustments.js +65 -57
- package/src/overwrites/venia-ui/lib/components/CheckoutPage/PriceAdjustments/priceAdjustments.module.css +29 -0
- package/src/overwrites/venia-ui/lib/components/CheckoutPage/checkoutPage.js +9 -4
- package/src/overwrites/venia-ui/lib/components/CheckoutPage/checkoutPage.module.css +2 -0
- package/src/overwrites/venia-ui/lib/components/FilterModal/CurrentFilters/currentFilters.js +1 -1
- package/src/overwrites/venia-ui/lib/components/FilterSidebar/filterSidebar.js +1 -1
- package/src/overwrites/venia-ui/lib/components/Gallery/item.js +2 -10
- package/src/overwrites/venia-ui/lib/components/Gallery/item.module.css +5 -4
- package/src/overwrites/venia-ui/lib/components/OrderHistoryPage/Reviews/index.js +1 -0
- package/src/overwrites/venia-ui/lib/components/OrderHistoryPage/Reviews/reviewModal.js +316 -0
- package/src/overwrites/venia-ui/lib/components/OrderHistoryPage/Reviews/starInput.js +33 -0
- package/src/overwrites/venia-ui/lib/components/OrderHistoryPage/orderHistoryPage.js +29 -2
- package/src/overwrites/venia-ui/lib/components/OrderHistoryPage/orderRow.js +70 -34
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/CustomAttributes/customAttributes.js +10 -2
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/components/modalFormReview.js +8 -8
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/components/preOrderDetail.js +195 -37
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/components/productReview.js +4 -27
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/productFullDetail.js +194 -63
- package/src/talons/ProductContent/productContent.gql.js +11 -1
- package/src/talons/ProductContent/useProductContent.js +14 -2
- package/src/talons/ReviewModal/reviewModal.gql.js +45 -0
- package/src/talons/ReviewModal/useReviewModal.js +87 -0
- package/src/components/RMAPage/components/productItem.css +0 -15
- package/src/components/RMAPage/components/productItem.module.css +0 -15
package/src/overwrites/venia-ui/lib/components/CheckoutPage/PriceAdjustments/priceAdjustments.js
CHANGED
|
@@ -5,15 +5,17 @@ import { useMutation, useQuery } from '@apollo/client';
|
|
|
5
5
|
import { useCartContext } from '@magento/peregrine/lib/context/cart';
|
|
6
6
|
|
|
7
7
|
import { useStyle } from '@magento/venia-ui/lib/classify';
|
|
8
|
-
import LoadingIndicator from '@magento/venia-ui/lib/components/LoadingIndicator';
|
|
9
8
|
import { Accordion, Section } from '@magento/venia-ui/lib/components/Accordion';
|
|
10
9
|
import SellerCouponCheckout from '@riosst100/pwa-marketplace/src/components/SellerCoupon/sellerCouponCheckout';
|
|
11
10
|
import couponCodeOperations from '@magento/peregrine/lib/talons/CartPage/PriceAdjustments/CouponCode/couponCode.gql';
|
|
12
11
|
import GiftCardSection from '@magento/venia-ui/lib/components/CartPage/PriceAdjustments/giftCardSection';
|
|
13
12
|
import GiftOptionsSection from '@magento/venia-ui/lib/components/CartPage/PriceAdjustments/giftOptionsSection';
|
|
14
|
-
|
|
13
|
+
import CouponCode from '@magento/venia-ui/lib/components/CartPage/PriceAdjustments/CouponCode';
|
|
14
|
+
import Shimmer from '@magento/venia-ui/lib/components/Shimmer';
|
|
15
15
|
import defaultClasses from './priceAdjustments.module.css';
|
|
16
16
|
import cn from 'classnames';
|
|
17
|
+
import LoadingIndicator from '@magento/venia-ui/lib/components/LoadingIndicator';
|
|
18
|
+
import { FormattedMessage } from 'react-intl';
|
|
17
19
|
|
|
18
20
|
/**
|
|
19
21
|
* PriceAdjustments component for the Checkout page.
|
|
@@ -32,7 +34,8 @@ const PriceAdjustments = props => {
|
|
|
32
34
|
couponCodeOperations.getAppliedCouponsQuery,
|
|
33
35
|
{ variables: { cartId }, skip: !cartId }
|
|
34
36
|
);
|
|
35
|
-
const [sectionOpen, setSectionOpen] = useState(
|
|
37
|
+
const [sectionOpen, setSectionOpen] = useState(true);
|
|
38
|
+
const [couponModalOpen, setCouponModalOpen] = useState(false);
|
|
36
39
|
|
|
37
40
|
const handleApplyFromClaim = useCallback(async (item) => {
|
|
38
41
|
if (!item?.code || !cartId) return;
|
|
@@ -48,6 +51,10 @@ const PriceAdjustments = props => {
|
|
|
48
51
|
}
|
|
49
52
|
}, [applyCoupon, cartId, setPageIsUpdating]);
|
|
50
53
|
|
|
54
|
+
const handleViewCoupons = useCallback(() => {
|
|
55
|
+
setCouponModalOpen(true);
|
|
56
|
+
}, [setCouponModalOpen]);
|
|
57
|
+
|
|
51
58
|
const handleRemoveCoupon = useCallback(async () => {
|
|
52
59
|
if (!cartId) return;
|
|
53
60
|
try {
|
|
@@ -64,62 +71,63 @@ const PriceAdjustments = props => {
|
|
|
64
71
|
|
|
65
72
|
return (
|
|
66
73
|
<div className={classes.root}>
|
|
67
|
-
<
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
root: 'w-full'
|
|
71
|
-
}}
|
|
72
|
-
>
|
|
73
|
-
<Section
|
|
74
|
-
data-cy="PriceAdjustments-couponCodeSection"
|
|
75
|
-
id={'coupon_code'}
|
|
76
|
-
title={formatMessage({
|
|
74
|
+
<div className={classes.coupon_container}>
|
|
75
|
+
<h5 className={classes.cardTitle}>
|
|
76
|
+
{formatMessage({
|
|
77
77
|
id: 'checkoutPage.couponCode',
|
|
78
|
-
defaultMessage: 'Apply Coupon
|
|
78
|
+
defaultMessage: 'Apply Coupon'
|
|
79
79
|
})}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
{
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
80
|
+
</h5>
|
|
81
|
+
{applyingCoupon || appliedLoading ? <LoadingIndicator classes={{ root: classes.loading }}>
|
|
82
|
+
<FormattedMessage
|
|
83
|
+
id={'checkoutPage.loadingApplyingCoupon'}
|
|
84
|
+
defaultMessage={'Applying Coupon'}
|
|
85
|
+
/>
|
|
86
|
+
</LoadingIndicator> : removingCoupon ? <LoadingIndicator classes={{ root: classes.loading }}>
|
|
87
|
+
<FormattedMessage
|
|
88
|
+
id={'checkoutPage.loadingRemovingCoupon'}
|
|
89
|
+
defaultMessage={'Removing Coupon'}
|
|
90
|
+
/>
|
|
91
|
+
</LoadingIndicator> :
|
|
92
|
+
<Suspense fallback={<LoadingIndicator />}>
|
|
93
|
+
<CouponCode setIsCartUpdating={setPageIsUpdating} />
|
|
94
|
+
{appliedCoupons.length > 0 && (
|
|
95
|
+
<div className="mt-3 flex items-center gap-2 flex-wrap">
|
|
96
|
+
{appliedCoupons.map(c => {
|
|
97
|
+
const coupon = couponData.sellerCoupons.items.find(item => item.code === c.code);
|
|
98
|
+
return <div key={c.code} className="flex items-center gap-2 bg-[#fff8f1] border border-[#ffb891] rounded px-2 py-1 text-sm font-medium text-[#f76b1c]">
|
|
99
|
+
<span>{coupon.name} ({coupon.code})</span>
|
|
100
|
+
<button
|
|
101
|
+
type="button"
|
|
102
|
+
onClick={handleRemoveCoupon}
|
|
103
|
+
disabled={removingCoupon}
|
|
104
|
+
className="text-[#a94442] hover:text-[#f26313] disabled:opacity-50"
|
|
105
|
+
aria-label={formatMessage({ id: 'checkoutPage.removeCoupon', defaultMessage: 'Remove coupon' })}
|
|
106
|
+
>
|
|
107
|
+
×
|
|
108
|
+
</button>
|
|
109
|
+
</div>
|
|
110
|
+
})}
|
|
111
|
+
</div>
|
|
112
|
+
)}
|
|
113
|
+
{!appliedCoupons.length && couponData?.sellerCoupons?.items.length ? <button class="p-2 text-[13px] text-blue-700 border border-solid cursor-pointer rounded-full w-full mt-4" onClick={handleViewCoupons}>Select coupon to apply</button> : ''}
|
|
114
|
+
{couponModalOpen && (
|
|
115
|
+
<SellerCouponCheckout
|
|
116
|
+
couponData={couponData}
|
|
117
|
+
couponLoading={couponLoading || applyingCoupon || appliedLoading || removingCoupon}
|
|
118
|
+
couponError={couponError}
|
|
119
|
+
autoOpen={true}
|
|
120
|
+
closeOnClaim={true}
|
|
121
|
+
couponModalOpen={couponModalOpen}
|
|
122
|
+
setCouponModalOpen={setCouponModalOpen}
|
|
123
|
+
onSelectCoupon={handleApplyFromClaim}
|
|
124
|
+
onTriggerRender={() => null}
|
|
125
|
+
/>
|
|
126
|
+
)}
|
|
127
|
+
</Suspense>}
|
|
128
|
+
</div>
|
|
129
|
+
<GiftCardSection setIsCartUpdating={setPageIsUpdating} />
|
|
130
|
+
<GiftOptionsSection />
|
|
123
131
|
</div>
|
|
124
132
|
);
|
|
125
133
|
};
|
|
@@ -1,2 +1,31 @@
|
|
|
1
1
|
.root {
|
|
2
|
+
composes: gap-xs from global;
|
|
3
|
+
composes: grid from global;
|
|
4
|
+
composes: grid-cols-1 from global;
|
|
2
5
|
}
|
|
6
|
+
|
|
7
|
+
.coupon_container {
|
|
8
|
+
composes: border from global;
|
|
9
|
+
composes: p-4 from global;
|
|
10
|
+
composes: pb-6 from global;
|
|
11
|
+
composes: border-gray-100 from global;
|
|
12
|
+
composes: rounded-md from global;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.loading {
|
|
16
|
+
composes: root from '@magento/venia-ui/lib/components/LoadingIndicator/indicator.module.css';
|
|
17
|
+
|
|
18
|
+
composes: text-center from global;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.heading {
|
|
22
|
+
composes: border-0 from global;
|
|
23
|
+
|
|
24
|
+
composes: lg_border from global;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.cardTitle {
|
|
28
|
+
composes: font-medium from global;
|
|
29
|
+
composes: text-[16px] from global;
|
|
30
|
+
composes: mb-4 from global;
|
|
31
|
+
}
|
|
@@ -84,7 +84,7 @@ const CheckoutPage = props => {
|
|
|
84
84
|
toggleAddressBookContent,
|
|
85
85
|
toggleSignInContent
|
|
86
86
|
} = talonProps;
|
|
87
|
-
|
|
87
|
+
|
|
88
88
|
const [, { addToast }] = useToasts();
|
|
89
89
|
|
|
90
90
|
const history = useHistory();
|
|
@@ -301,7 +301,12 @@ const CheckoutPage = props => {
|
|
|
301
301
|
// Show ItemsReview from the beginning, not only at the REVIEW step
|
|
302
302
|
const itemsReview = (
|
|
303
303
|
<div className={classes.items_review_container}>
|
|
304
|
-
<ItemsReview
|
|
304
|
+
<ItemsReview
|
|
305
|
+
isPreorder={cartItems?.[0]?.is_preorder}
|
|
306
|
+
preOrderDeposit={cartItems?.[0]?.pre_order_deposit}
|
|
307
|
+
preOrderPaymentType={cartItems?.[0]?.pre_order_payment_type}
|
|
308
|
+
releaseDate={cartItems?.[0]?.product?.release_date}
|
|
309
|
+
/>
|
|
305
310
|
</div>
|
|
306
311
|
);
|
|
307
312
|
|
|
@@ -345,7 +350,7 @@ const CheckoutPage = props => {
|
|
|
345
350
|
: '')
|
|
346
351
|
}
|
|
347
352
|
>
|
|
348
|
-
<OrderSummary isUpdating={isUpdating} />
|
|
353
|
+
<OrderSummary isUpdating={isUpdating} placeOrderButton={placeOrderButton} />
|
|
349
354
|
{itemsReview}
|
|
350
355
|
</div>
|
|
351
356
|
);
|
|
@@ -430,7 +435,7 @@ const CheckoutPage = props => {
|
|
|
430
435
|
{priceAdjustmentsSection}
|
|
431
436
|
{reviewOrderButton}
|
|
432
437
|
{orderSummary}
|
|
433
|
-
{placeOrderButton}
|
|
438
|
+
{/* {placeOrderButton} */}
|
|
434
439
|
<GoogleReCaptcha {...recaptchaWidgetProps} />
|
|
435
440
|
</div>
|
|
436
441
|
);
|
|
@@ -20,7 +20,7 @@ const CurrentFilters = props => {
|
|
|
20
20
|
const { title, value } = item || {};
|
|
21
21
|
const key = `${group}::${title}_${value}`;
|
|
22
22
|
|
|
23
|
-
const customAttributeLandingPage = ['bricks_categories','sc_sports_categories','card_game', 'sc_baseball_release','auction','special_price','lof_preorder','sc_baseball_inserts','sc_baseball_parallel','sc_set_type'];
|
|
23
|
+
const customAttributeLandingPage = ['bricks_categories','sc_sports_categories','card_game', 'sc_baseball_release','auction','special_price','lof_preorder','card_pre_orders','sc_baseball_inserts','sc_baseball_parallel','sc_set_type'];
|
|
24
24
|
|
|
25
25
|
if (!customAttributeLandingPage.includes(group)) {
|
|
26
26
|
elements.push(
|
|
@@ -125,7 +125,7 @@ const FilterSidebar = props => {
|
|
|
125
125
|
const groupName = filterNames.get(group);
|
|
126
126
|
const frontendInput = filterFrontendInput.get(group);
|
|
127
127
|
|
|
128
|
-
const hideFilters = ['card_game','bricks_categories','sc_sports_categories','trains','trains_locomotives','trains_supplies_type','lof_preorder','auction','special_price','sc_baseball_inserts','sc_baseball_parallel','sale','sc_set_type','sc_brands'];
|
|
128
|
+
const hideFilters = ['card_game','bricks_categories','sc_sports_categories','trains','trains_locomotives','trains_supplies_type','lof_preorder','card_pre_orders','auction','special_price','sc_baseball_inserts','sc_baseball_parallel','sale','sc_set_type','sc_brands'];
|
|
129
129
|
if (!allowedFiltersArr?.length || filterState.size && allowedFiltersArr.length || !filterState.size && allowedFiltersArr.length && allowedFiltersArr.includes(group)) {
|
|
130
130
|
if (!hideFilters.includes(group) && groupName && !group.includes('card_release') && !group.includes('card_set') && !group.includes('sc_set_name')) {
|
|
131
131
|
|
|
@@ -140,7 +140,7 @@ const GalleryItem = props => {
|
|
|
140
140
|
data-cy="GalleryItem-name">{name}</span>
|
|
141
141
|
{/* </Link> */}
|
|
142
142
|
<div data-cy="GalleryItem-price" className={cn(classes.price, 'mb-2.5 pt-2.5')}>
|
|
143
|
-
<p className='font-medium !text-[#f76b1c]
|
|
143
|
+
<p className='font-medium !text-[#f76b1c] !mb-1'>
|
|
144
144
|
<Price
|
|
145
145
|
value={priceSource.value}
|
|
146
146
|
currencyCode={priceSource.currency}
|
|
@@ -154,16 +154,8 @@ const GalleryItem = props => {
|
|
|
154
154
|
</p> */}
|
|
155
155
|
</div>
|
|
156
156
|
|
|
157
|
-
<div data-cy="GalleryItem-Rating" className={cn('flex gap-[5px] items-center mb-2')}>
|
|
158
|
-
<Star />
|
|
159
|
-
<span className='text-[12px] leading-normal'>
|
|
160
|
-
{rating_summary}
|
|
161
|
-
</span>
|
|
162
|
-
</div>
|
|
163
|
-
|
|
164
157
|
<div data-cy="GalleryItem-Seller" className={cn('flex gap-[5px] items-center')}>
|
|
165
|
-
<
|
|
166
|
-
<span className='text-[12px] text-gray-300 leading-normal'>
|
|
158
|
+
<span className='text-[12px] text-gray-400 leading-normal'>
|
|
167
159
|
{seller}
|
|
168
160
|
</span>
|
|
169
161
|
</div>
|
|
@@ -74,11 +74,11 @@
|
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
.name {
|
|
77
|
-
composes: font-medium from global;
|
|
77
|
+
/* composes: font-medium from global; */
|
|
78
78
|
composes: text-base from global;
|
|
79
79
|
composes: mb-1 from global;
|
|
80
80
|
display: -webkit-box;
|
|
81
|
-
-webkit-line-clamp:
|
|
81
|
+
-webkit-line-clamp: 3;
|
|
82
82
|
-webkit-box-orient: vertical;
|
|
83
83
|
overflow: hidden;
|
|
84
84
|
line-height: normal;
|
|
@@ -87,13 +87,14 @@
|
|
|
87
87
|
.name,
|
|
88
88
|
.price {
|
|
89
89
|
composes: text-colorDefault from global;
|
|
90
|
-
composes: text-[14px] from global;
|
|
91
|
-
composes: font-medium from global;
|
|
90
|
+
/* composes: text-[14px] from global; */
|
|
91
|
+
/* composes: font-medium from global; */
|
|
92
92
|
min-height: 1rem;
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
.price {
|
|
96
96
|
padding-top: 2.5;
|
|
97
|
+
composes: font-medium from global;
|
|
97
98
|
}
|
|
98
99
|
|
|
99
100
|
.unavailableContainer {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as ReviewModal } from './reviewModal';
|
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
import React, { useMemo, useState, useEffect } from 'react';
|
|
2
|
+
import Modal from '@riosst100/pwa-marketplace/src/components/Modal';
|
|
3
|
+
import { X } from 'react-feather';
|
|
4
|
+
import { Text } from 'informed';
|
|
5
|
+
|
|
6
|
+
import Field from '@magento/venia-ui/lib/components/Field';
|
|
7
|
+
// import TextInput from '@magento/venia-ui/lib/components/TextInput';
|
|
8
|
+
import Button from '@magento/venia-ui/lib/components/Button';
|
|
9
|
+
import { isRequired } from '@magento/venia-ui/lib/util/formValidators';
|
|
10
|
+
import StarRating from './starInput';
|
|
11
|
+
|
|
12
|
+
import { primary900 } from '@riosst100/pwa-marketplace/src/theme/vars';
|
|
13
|
+
import { useReviewModal } from '@riosst100/pwa-marketplace/src/talons/ReviewModal/useReviewModal';
|
|
14
|
+
import { useStyle } from '@magento/venia-ui/lib/classify';
|
|
15
|
+
import defaultClasses from '../orderRow.module.css';
|
|
16
|
+
import cn from 'classnames';
|
|
17
|
+
|
|
18
|
+
import { arrayOf, number, shape, string } from 'prop-types';
|
|
19
|
+
import { ChevronDown, ChevronUp } from 'react-feather';
|
|
20
|
+
import { FormattedMessage, useIntl } from 'react-intl';
|
|
21
|
+
import Price from '@magento/venia-ui/lib/components/Price';
|
|
22
|
+
|
|
23
|
+
import Icon from '@magento/venia-ui/lib/components/Icon';
|
|
24
|
+
import CollapsedImageGallery from '../collapsedImageGallery';
|
|
25
|
+
import OrderProgressBar from '../orderProgressBar';
|
|
26
|
+
import OrderDetails from '../OrderDetails';
|
|
27
|
+
import { Verify, Shop, ConvertCard } from 'iconsax-react';
|
|
28
|
+
import PlaceholderImage from '@magento/venia-ui/lib/components/Image/placeholderImage';
|
|
29
|
+
import { Link, useHistory } from 'react-router-dom';
|
|
30
|
+
|
|
31
|
+
const ReviewModal = (props) => {
|
|
32
|
+
const { reviewOrder, setReviewOrder } = props;
|
|
33
|
+
|
|
34
|
+
const [submitting, setSubmitting] = useState(false)
|
|
35
|
+
|
|
36
|
+
const classes = useStyle(defaultClasses, props.classes);
|
|
37
|
+
|
|
38
|
+
const talonProps = useReviewModal({ reviewOrder, setSubmitting });
|
|
39
|
+
|
|
40
|
+
const {
|
|
41
|
+
ratingsMetadata,
|
|
42
|
+
loadingRatingsMetadata,
|
|
43
|
+
handleSubmitReview,
|
|
44
|
+
loadingCreateReview,
|
|
45
|
+
errorCreateReview,
|
|
46
|
+
defaultNickname,
|
|
47
|
+
handleToastAction
|
|
48
|
+
} = talonProps;
|
|
49
|
+
|
|
50
|
+
const [formState, setFormState] = useState({ nickname: defaultNickname || '' });
|
|
51
|
+
|
|
52
|
+
useEffect(() => {
|
|
53
|
+
if (reviewOrder && defaultNickname && !formState.nickname) {
|
|
54
|
+
setFormState(prev => ({ ...prev, nickname: defaultNickname }));
|
|
55
|
+
}
|
|
56
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
57
|
+
}, [reviewOrder, defaultNickname]);
|
|
58
|
+
|
|
59
|
+
// ratings: [{ id, value_id }]
|
|
60
|
+
const [ratings, setRatings] = useState(null);
|
|
61
|
+
|
|
62
|
+
const handleRatingChange = (id, value_id) => {
|
|
63
|
+
// setRatings(prev => {
|
|
64
|
+
// const filtered = prev.filter(r => r.id !== id);
|
|
65
|
+
// return [...filtered, { id, value_id }];
|
|
66
|
+
// });
|
|
67
|
+
setRatings(value_id)
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const handleChange = (field, value) => {
|
|
71
|
+
setFormState(prev => ({ ...prev, [field]: value }));
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const handleSubmit = async (e) => {
|
|
75
|
+
e.preventDefault();
|
|
76
|
+
// if (onSubmit) {
|
|
77
|
+
// onSubmit({ ...formState, ratings });
|
|
78
|
+
// }
|
|
79
|
+
console.log('formState',formState)
|
|
80
|
+
console.log('e',e)
|
|
81
|
+
setSubmitting(true);
|
|
82
|
+
const input = {
|
|
83
|
+
nickname: formState.nickname,
|
|
84
|
+
summary: formState.summary,
|
|
85
|
+
text: formState.review,
|
|
86
|
+
sku: e.target.sku.value,
|
|
87
|
+
ratings: [{
|
|
88
|
+
id: ratingsMetadata.id,
|
|
89
|
+
value_id: ratings
|
|
90
|
+
}]
|
|
91
|
+
};
|
|
92
|
+
const result = await handleSubmitReview(input);
|
|
93
|
+
setSubmitting(false);
|
|
94
|
+
if (result.success) setReviewOrder(null);
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
// Helper to resolve a product image by SKU with graceful fallback, now prefers product_image_url from order.items
|
|
98
|
+
const getThumbnailForSku = (sku, fallbackLabel, idx) => {
|
|
99
|
+
let url = null;
|
|
100
|
+
let label = fallbackLabel;
|
|
101
|
+
// Prefer product_image_url from order.items if present and is a non-empty string
|
|
102
|
+
if (reviewOrder && reviewOrder.items && reviewOrder.items[idx] && typeof reviewOrder.items[idx].product_image_url === 'string' && reviewOrder.items[idx].product_image_url.trim() !== '') {
|
|
103
|
+
url = reviewOrder.items[idx].product_image_url;
|
|
104
|
+
} else if (imagesData && typeof imagesData === 'object') {
|
|
105
|
+
const byKey = sku && imagesData[sku];
|
|
106
|
+
const byValue = !byKey && sku
|
|
107
|
+
? Object.values(imagesData).find(entry => entry?.sku === sku)
|
|
108
|
+
: null;
|
|
109
|
+
const chosen = byKey || byValue;
|
|
110
|
+
if (chosen?.thumbnail?.url && typeof chosen.thumbnail.url === 'string' && chosen.thumbnail.url.trim() !== '') {
|
|
111
|
+
url = chosen.thumbnail.url;
|
|
112
|
+
label = chosen.thumbnail.label || label;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// If url is not a non-empty string, fallback to null (will trigger placeholder)
|
|
116
|
+
if (typeof url !== 'string' || url.trim() === '') {
|
|
117
|
+
url = null;
|
|
118
|
+
}
|
|
119
|
+
return { url, label };
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
console.log('ratings',ratings)
|
|
123
|
+
|
|
124
|
+
const ratingStars = useMemo(() => {
|
|
125
|
+
console.log('ratingsMetadata22',ratingsMetadata)
|
|
126
|
+
if (!ratingsMetadata) {
|
|
127
|
+
return '';
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Find value (1-5) for selected value_id
|
|
131
|
+
const selectedValue = ratings && ratingsMetadata.values.find(v => v.value_id === ratings) || '';
|
|
132
|
+
console.log('selectedValue',selectedValue)
|
|
133
|
+
|
|
134
|
+
let starButtons = [];
|
|
135
|
+
|
|
136
|
+
[1,2,3,4,5].map(star => {
|
|
137
|
+
const valObj = ratingsMetadata.values.find(v => v.value === String(star));
|
|
138
|
+
console.log('String(star)',String(star))
|
|
139
|
+
console.log('valObj',valObj)
|
|
140
|
+
if (valObj) {
|
|
141
|
+
starButtons.push(
|
|
142
|
+
<button
|
|
143
|
+
key={valObj.value_id}
|
|
144
|
+
type="button"
|
|
145
|
+
aria-label={`${star} star${star > 1 ? 's' : ''}`}
|
|
146
|
+
className={`focus:outline-none ${selectedValue.value == star ? 'text-yellow-400' : 'text-gray-300'}`}
|
|
147
|
+
onClick={() => handleRatingChange(ratingsMetadata.id, valObj.value_id)}
|
|
148
|
+
>
|
|
149
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill={selectedValue.value >= star ? '#F7C317' : '#D9D9D9'} viewBox="0 0 20 20" width="25" height="25">
|
|
150
|
+
<path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.286 3.967a1 1 0 00.95.69h4.175c.969 0 1.371 1.24.588 1.81l-3.38 2.455a1 1 0 00-.364 1.118l1.287 3.966c.3.922-.755 1.688-1.54 1.118l-3.38-2.454a1 1 0 00-1.175 0l-3.38 2.454c-.784.57-1.838-.196-1.54-1.118l1.287-3.966a1 1 0 00-.364-1.118L2.05 9.394c-.783-.57-.38-1.81.588-1.81h4.175a1 1 0 00.95-.69l1.286-3.967z" />
|
|
151
|
+
</svg>
|
|
152
|
+
</button>
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
return (
|
|
158
|
+
<div className="mb-2">
|
|
159
|
+
<label className="block mb-1 font-bold text-gray-700">{ratingsMetadata.name}</label>
|
|
160
|
+
<div className="flex items-center gap-1">
|
|
161
|
+
{starButtons}
|
|
162
|
+
</div>
|
|
163
|
+
</div>
|
|
164
|
+
);
|
|
165
|
+
}, [ratingsMetadata, ratings]);
|
|
166
|
+
|
|
167
|
+
return (
|
|
168
|
+
<>
|
|
169
|
+
<Modal
|
|
170
|
+
open={reviewOrder}
|
|
171
|
+
className="modal_form_review !p-[30px] md_min-w-[650px]"
|
|
172
|
+
>
|
|
173
|
+
<div className='form_review-container'>
|
|
174
|
+
<div className='header_title-modal flex justify-between mb-5'>
|
|
175
|
+
<div className='text-lg text-black font-medium'>
|
|
176
|
+
Write Review
|
|
177
|
+
</div>
|
|
178
|
+
<button onClick={() => { setReviewOrder(!reviewOrder) }} >
|
|
179
|
+
<X size={24} color={primary900} />
|
|
180
|
+
</button>
|
|
181
|
+
</div>
|
|
182
|
+
|
|
183
|
+
{/* <Field id="nickname_field" label={'Nickname'}>
|
|
184
|
+
<input
|
|
185
|
+
id="nickname"
|
|
186
|
+
name="nickname"
|
|
187
|
+
type="text"
|
|
188
|
+
required
|
|
189
|
+
readOnly
|
|
190
|
+
value={formState.nickname || ''}
|
|
191
|
+
onChange={e => handleChange('nickname', e.target.value)}
|
|
192
|
+
data-cy="nickname"
|
|
193
|
+
aria-label={'nickname'}
|
|
194
|
+
placeholder={'e.g John Doe'}
|
|
195
|
+
className="border border-gray-100 rounded px-3 py-2 bg-gray-50 cursor-not-allowed"
|
|
196
|
+
aria-readonly="true"
|
|
197
|
+
/>
|
|
198
|
+
</Field> */}
|
|
199
|
+
{/* Ratings breakdown from metadata */}
|
|
200
|
+
{reviewOrder && reviewOrder.items && reviewOrder.items.length > 0 && reviewOrder.items.map((it, idx) => {
|
|
201
|
+
const { url, label } = getThumbnailForSku(it.product_sku, it.product_name, idx);
|
|
202
|
+
return (
|
|
203
|
+
<>
|
|
204
|
+
<form className="flex flex-col gap-y-3" onSubmit={handleSubmit}>
|
|
205
|
+
<div key={it.id || idx} className='flex flex-row gap-4 mb-1 justify-between' style={{
|
|
206
|
+
"borderBottom": "1px solid #e6e9ea",
|
|
207
|
+
"paddingBottom": "10px"
|
|
208
|
+
}}>
|
|
209
|
+
<div className={classes.productImage}>
|
|
210
|
+
{url ? (
|
|
211
|
+
<img
|
|
212
|
+
src={url}
|
|
213
|
+
alt={label}
|
|
214
|
+
width={80}
|
|
215
|
+
className={classes.thumbnail}
|
|
216
|
+
/>
|
|
217
|
+
) : (
|
|
218
|
+
<PlaceholderImage alt={it.product_name} classes={{ root: classes.thumbnail }} width={60} />
|
|
219
|
+
)}
|
|
220
|
+
</div>
|
|
221
|
+
<div className='flex flex-col gap-1 pb-2 last_pb-0 max-w-[375px]'>
|
|
222
|
+
<div className={cn(classes.productName, 'text-[14px] font-medium')}>
|
|
223
|
+
<span>{it.product_name}</span>
|
|
224
|
+
</div>
|
|
225
|
+
<div className="text-[12px]">
|
|
226
|
+
<span>x{`${it.quantity_ordered}`}</span>
|
|
227
|
+
</div>
|
|
228
|
+
</div>
|
|
229
|
+
<div class="flex flex-col gap-1 pb-2 last_pb-0 justify-center">
|
|
230
|
+
<div class="text-[14px] text-blue-700">
|
|
231
|
+
<span><Price currencyCode={it?.product_sale_price?.currency} value={it?.product_sale_price?.value} /></span>
|
|
232
|
+
</div>
|
|
233
|
+
</div>
|
|
234
|
+
</div>
|
|
235
|
+
<div className="flex flex-col gap-y-3">
|
|
236
|
+
{loadingRatingsMetadata ? (
|
|
237
|
+
<div>Loading ratings...</div>
|
|
238
|
+
) : ratingStars}
|
|
239
|
+
</div>
|
|
240
|
+
<input type="hidden" id="sku" name="sku" value={it.product_sku} />
|
|
241
|
+
{/* <Field id="summary_field" label={'Summary'}>
|
|
242
|
+
<input
|
|
243
|
+
id="summary"
|
|
244
|
+
name="summary"
|
|
245
|
+
type="text"
|
|
246
|
+
required
|
|
247
|
+
value={formState.summary || ''}
|
|
248
|
+
onChange={e => handleChange('summary', e.target.value)}
|
|
249
|
+
data-cy="summary"
|
|
250
|
+
aria-label={'summary'}
|
|
251
|
+
placeholder={'Summary of your rating'}
|
|
252
|
+
className="border border-gray-100 rounded px-3 py-2"
|
|
253
|
+
/>
|
|
254
|
+
</Field> */}
|
|
255
|
+
<Field id="summary_field" label={'Summary'}>
|
|
256
|
+
<input
|
|
257
|
+
id="summary"
|
|
258
|
+
name="summary"
|
|
259
|
+
type="text"
|
|
260
|
+
required
|
|
261
|
+
value={formState.summary || ''}
|
|
262
|
+
onChange={e => handleChange('summary', e.target.value)}
|
|
263
|
+
data-cy="summary"
|
|
264
|
+
aria-label={'summary'}
|
|
265
|
+
placeholder={'Summary of your rating'}
|
|
266
|
+
className="border border-gray-100 rounded px-3 py-2"
|
|
267
|
+
/>
|
|
268
|
+
</Field>
|
|
269
|
+
<Field id="review_field" label={'Review'}>
|
|
270
|
+
<textarea
|
|
271
|
+
id="review"
|
|
272
|
+
name="review"
|
|
273
|
+
required
|
|
274
|
+
value={formState.review || ''}
|
|
275
|
+
onChange={e => handleChange('review', e.target.value)}
|
|
276
|
+
data-cy="review"
|
|
277
|
+
aria-label={'review'}
|
|
278
|
+
placeholder={'Let us know your thoughts'}
|
|
279
|
+
className="border border-gray-100 rounded px-3 py-2"
|
|
280
|
+
rows={3}
|
|
281
|
+
/>
|
|
282
|
+
</Field>
|
|
283
|
+
<div className='actions flex justify-end gap-x-2.5 mt-4'>
|
|
284
|
+
{/* <Button
|
|
285
|
+
priority='low'
|
|
286
|
+
classes={{
|
|
287
|
+
content: 'capitalize text-[16px] font-medium'
|
|
288
|
+
}}
|
|
289
|
+
onClick={() => setReviewOrder(false)}
|
|
290
|
+
type="button"
|
|
291
|
+
>
|
|
292
|
+
Cancel
|
|
293
|
+
</Button> */}
|
|
294
|
+
<Button
|
|
295
|
+
priority='high'
|
|
296
|
+
classes={{
|
|
297
|
+
content: 'capitalize text-[16px] font-medium'
|
|
298
|
+
}}
|
|
299
|
+
type="submit"
|
|
300
|
+
disabled={submitting}
|
|
301
|
+
>
|
|
302
|
+
{submitting ? 'Submitting...' : 'Submit Review'}
|
|
303
|
+
</Button>
|
|
304
|
+
</div>
|
|
305
|
+
</form>
|
|
306
|
+
</>
|
|
307
|
+
);
|
|
308
|
+
})}
|
|
309
|
+
|
|
310
|
+
</div>
|
|
311
|
+
</Modal>
|
|
312
|
+
</>
|
|
313
|
+
);
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
export default ReviewModal;
|