@riosst100/pwa-marketplace 2.7.5 → 2.7.8
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/CrossSeller/crossSellerBuy.js +20 -10
- package/src/components/CrossSeller/item.js +42 -60
- package/src/components/LinkToOtherStores/index.js +3 -4
- package/src/components/RFQ/index.js +26 -34
- package/src/components/SellerProducts/productContent.js +1 -1
- package/src/overwrites/venia-ui/lib/components/AccountMenu/accountMenu.js +1 -1
- package/src/overwrites/venia-ui/lib/components/Breadcrumbs/breadcrumbs.module.css +2 -2
- package/src/overwrites/venia-ui/lib/components/Header/header.js +4 -4
- package/src/overwrites/venia-ui/lib/components/Header/header.module.css +173 -0
- package/src/overwrites/venia-ui/lib/components/Main/main.module.css +1 -1
- package/src/overwrites/venia-ui/lib/components/MegaMenu/submenu.module.css +1 -1
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/CustomAttributes/customAttributes.js +1 -1
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/productFullDetail.js +236 -229
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/productFullDetail.module.css +73 -25
- package/src/overwrites/venia-ui/lib/components/ProductImageCarousel/carousel.module.css +2 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useState, useMemo, Fragment, Suspense } from 'react';
|
|
1
|
+
import React, { useState, useMemo, Fragment, Suspense, useRef, useEffect } from 'react';
|
|
2
2
|
import { FormattedMessage, useIntl } from 'react-intl';
|
|
3
3
|
import { arrayOf, bool, number, shape, string } from 'prop-types';
|
|
4
4
|
import { Form } from 'informed';
|
|
@@ -15,7 +15,6 @@ import Carousel from '@magento/venia-ui/lib/components/ProductImageCarousel';
|
|
|
15
15
|
import FormError from '@magento/venia-ui/lib/components/FormError';
|
|
16
16
|
import RichContent from '@magento/venia-ui/lib/components/RichContent/richContent';
|
|
17
17
|
import QuantityStepper from '../QuantityStepper';
|
|
18
|
-
// import RichContent from '../RichContent/richContent';
|
|
19
18
|
import { ProductOptionsShimmer } from '@magento/venia-ui/lib/components/ProductOptions';
|
|
20
19
|
import CustomAttributes from './CustomAttributes';
|
|
21
20
|
import defaultClasses from './productFullDetail.module.css';
|
|
@@ -23,7 +22,7 @@ import cn from 'classnames';
|
|
|
23
22
|
import Tabs from '@riosst100/pwa-marketplace/src/components/commons/Tabs';
|
|
24
23
|
import ProductReviews from './components/productReview';
|
|
25
24
|
import RichText from '@magento/venia-ui/lib/components/RichText';
|
|
26
|
-
import { Star1, Verify, Sms, Message, Shop } from 'iconsax-react';
|
|
25
|
+
import { Star1, Verify, Sms, Message, Shop, ArrowUp2 } from 'iconsax-react';
|
|
27
26
|
import { Link } from "react-router-dom";
|
|
28
27
|
import Divider from '@riosst100/pwa-marketplace/src/components/Divider';
|
|
29
28
|
|
|
@@ -33,13 +32,14 @@ import Share from '@riosst100/pwa-marketplace/src/components/SocialMediaShare';
|
|
|
33
32
|
import PreorderDetail from './components/preOrderDetail';
|
|
34
33
|
import AuctionDetail from './components/auctionDetail';
|
|
35
34
|
import CrossSeller from '@riosst100/pwa-marketplace/src/components/CrossSeller';
|
|
36
|
-
import RelatedProduct from '@riosst100/pwa-marketplace/src/components/RelatedProduct';
|
|
37
35
|
import ProductLabel from '@riosst100/pwa-marketplace/src/components/ProductLabel';
|
|
38
36
|
import RFQ from '@riosst100/pwa-marketplace/src/components/RFQ';
|
|
39
37
|
import LinkToOtherStores from '@riosst100/pwa-marketplace/src/components/LinkToOtherStores';
|
|
40
38
|
import Collapsible from '@riosst100/pwa-marketplace/src/components/commons/Collapsible';
|
|
41
39
|
import { useLocation } from 'react-router-dom';
|
|
42
40
|
|
|
41
|
+
import { totalListings, lowestPrice } from '@riosst100/pwa-marketplace/src/components/CrossSeller/crossSellerBuy';
|
|
42
|
+
|
|
43
43
|
// Correlate a GQL error message to a field. GQL could return a longer error
|
|
44
44
|
// string but it may contain contextual info such as product id. We can use
|
|
45
45
|
// parts of the string to check for which field to apply the error.
|
|
@@ -100,7 +100,7 @@ const ProductFullDetail = props => {
|
|
|
100
100
|
wishlistButtonProps,
|
|
101
101
|
sellerDetails
|
|
102
102
|
} = talonProps;
|
|
103
|
-
|
|
103
|
+
|
|
104
104
|
const { formatMessage } = useIntl();
|
|
105
105
|
|
|
106
106
|
const classes = useStyle(defaultClasses, props.classes);
|
|
@@ -126,7 +126,6 @@ const ProductFullDetail = props => {
|
|
|
126
126
|
currentProduct={productDetails.name}
|
|
127
127
|
/>
|
|
128
128
|
) : null;
|
|
129
|
-
|
|
130
129
|
// Fill a map with field/section -> error.
|
|
131
130
|
const errors = new Map();
|
|
132
131
|
if (errorMessage) {
|
|
@@ -184,22 +183,6 @@ const ProductFullDetail = props => {
|
|
|
184
183
|
const customAttributesDetails = useMemo(() => {
|
|
185
184
|
const list = [];
|
|
186
185
|
const pagebuilder = [];
|
|
187
|
-
// const skuAttribute = {
|
|
188
|
-
// attribute_metadata: {
|
|
189
|
-
// uid: 'attribute_sku',
|
|
190
|
-
// used_in_components: ['PRODUCT_DETAILS_PAGE'],
|
|
191
|
-
// ui_input: {
|
|
192
|
-
// ui_input_type: 'TEXT'
|
|
193
|
-
// },
|
|
194
|
-
// label: formatMessage({
|
|
195
|
-
// id: 'global.sku',
|
|
196
|
-
// defaultMessage: 'SKU'
|
|
197
|
-
// })
|
|
198
|
-
// },
|
|
199
|
-
// entered_attribute_value: {
|
|
200
|
-
// value: productDetails.sku
|
|
201
|
-
// }
|
|
202
|
-
// };
|
|
203
186
|
if (Array.isArray(customAttributes)) {
|
|
204
187
|
customAttributes.forEach(customAttribute => {
|
|
205
188
|
if (
|
|
@@ -233,8 +216,11 @@ const ProductFullDetail = props => {
|
|
|
233
216
|
);
|
|
234
217
|
// Error message for screen reader
|
|
235
218
|
const cartActionContent = isSupportedProductType ? (
|
|
236
|
-
<section className={cn(classes.actButton, 'flex gap-x-[
|
|
237
|
-
|
|
219
|
+
<section className={cn(classes.actButton, 'justify-between flex gap-x-[20px] px-[15px] py-0')}>
|
|
220
|
+
<RFQ
|
|
221
|
+
disabled={isAddToCartDisabled}
|
|
222
|
+
classes={{ rfqButton: cn(classes.rfqButton, "w-full") }}
|
|
223
|
+
/>
|
|
238
224
|
<Button
|
|
239
225
|
data-cy="ProductFullDetail-addToCartButton"
|
|
240
226
|
disabled={isAddToCartDisabled}
|
|
@@ -249,7 +235,8 @@ const ProductFullDetail = props => {
|
|
|
249
235
|
: ''
|
|
250
236
|
}
|
|
251
237
|
classes={{
|
|
252
|
-
|
|
238
|
+
rootClass: '!px-0 !py-3',
|
|
239
|
+
content: 'w-full normal-case font-medium text-[14px]'
|
|
253
240
|
}}
|
|
254
241
|
priority="high"
|
|
255
242
|
type="submit"
|
|
@@ -295,17 +282,7 @@ const ProductFullDetail = props => {
|
|
|
295
282
|
|
|
296
283
|
const contentContainerClass = 'content-container max-w-[1040px] p-2.5 m-auto relative mt-0 lg_mt-[34px] pb-6 lg_pb-0'
|
|
297
284
|
const ProductDescription = () => (
|
|
298
|
-
<div className={cn(contentContainerClass)}>
|
|
299
|
-
{/* <span
|
|
300
|
-
data-cy="ProductFullDetail-descriptionTitle"
|
|
301
|
-
className={classes.descriptionTitle}
|
|
302
|
-
>
|
|
303
|
-
<FormattedMessage
|
|
304
|
-
id={'productFullDetail.description'}
|
|
305
|
-
defaultMessage={'Description'}
|
|
306
|
-
/>
|
|
307
|
-
</span> */}
|
|
308
|
-
{/* <RichContent html={productDetails.description} /> */}
|
|
285
|
+
<div className={cn(contentContainerClass, classes.contentContainerTabOverride)}>
|
|
309
286
|
<RichText
|
|
310
287
|
rootClassName="px-0"
|
|
311
288
|
content={productDetails.description}
|
|
@@ -315,9 +292,10 @@ const ProductFullDetail = props => {
|
|
|
315
292
|
|
|
316
293
|
const ProductMoreInfo = () => (
|
|
317
294
|
<>
|
|
318
|
-
<div className={cn(contentContainerClass)}>
|
|
295
|
+
<div className={cn(contentContainerClass, classes.contentContainerTabOverride)}>
|
|
319
296
|
<CustomAttributes
|
|
320
297
|
customAttributes={customAttributesDetails.list}
|
|
298
|
+
classes={{ list: classes.customAttributesList }}
|
|
321
299
|
/>
|
|
322
300
|
</div>
|
|
323
301
|
{pageBuilderAttributes}
|
|
@@ -342,7 +320,7 @@ const ProductFullDetail = props => {
|
|
|
342
320
|
);
|
|
343
321
|
|
|
344
322
|
const ProductTNC = () => (
|
|
345
|
-
<div className={cn(contentContainerClass)}>
|
|
323
|
+
<div className={cn(contentContainerClass, classes.contentContainerTabOverride)}>
|
|
346
324
|
<p>{customAttributesList.map((data, index) => {
|
|
347
325
|
if (data.code == "term_and_conditions") {
|
|
348
326
|
return data.value;
|
|
@@ -352,7 +330,7 @@ const ProductFullDetail = props => {
|
|
|
352
330
|
)
|
|
353
331
|
|
|
354
332
|
const ShippingPolicy = () => (
|
|
355
|
-
<div className={cn(contentContainerClass)}>
|
|
333
|
+
<div className={cn(contentContainerClass, classes.contentContainerTabOverride)}>
|
|
356
334
|
<p>{customAttributesList.map((data, index) => {
|
|
357
335
|
if (data.code == "shipping_policy") {
|
|
358
336
|
return data.value;
|
|
@@ -362,7 +340,7 @@ const ProductFullDetail = props => {
|
|
|
362
340
|
)
|
|
363
341
|
|
|
364
342
|
const ReturnPolicy = () => (
|
|
365
|
-
<div className={cn(contentContainerClass)}>
|
|
343
|
+
<div className={cn(contentContainerClass, classes.contentContainerTabOverride)}>
|
|
366
344
|
<p>{customAttributesList.map((data, index) => {
|
|
367
345
|
if (data.code == "return_policy") {
|
|
368
346
|
return data.value;
|
|
@@ -372,7 +350,7 @@ const ProductFullDetail = props => {
|
|
|
372
350
|
)
|
|
373
351
|
|
|
374
352
|
const ProductFAQ = () => (
|
|
375
|
-
<div className={cn(contentContainerClass)}>
|
|
353
|
+
<div className={cn(contentContainerClass, classes.contentContainerTabOverride)}>
|
|
376
354
|
{customAttributesList.map((data, index) => {
|
|
377
355
|
if (data.code == "faq") {
|
|
378
356
|
return (
|
|
@@ -387,19 +365,108 @@ const ProductFullDetail = props => {
|
|
|
387
365
|
</div>
|
|
388
366
|
)
|
|
389
367
|
|
|
368
|
+
|
|
369
|
+
const getAttributeValue = (customAttributesDetails, key, useSuffix = false) => {
|
|
370
|
+
if (!customAttributesDetails?.list?.length) return "";
|
|
371
|
+
|
|
372
|
+
const attr = customAttributesDetails.list.find(attr => {
|
|
373
|
+
const code = attr.attribute_metadata?.code || "";
|
|
374
|
+
return useSuffix ? code.endsWith(key) : code === key;
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
if (!attr) return "";
|
|
378
|
+
|
|
379
|
+
if (attr.selected_attribute_options?.attribute_option?.length) {
|
|
380
|
+
return attr.selected_attribute_options.attribute_option
|
|
381
|
+
.map(opt => opt.label)
|
|
382
|
+
.join(", ");
|
|
383
|
+
}
|
|
384
|
+
return attr.entered_attribute_value?.value || "";
|
|
385
|
+
};
|
|
386
|
+
|
|
387
|
+
const setNameValue = getAttributeValue(customAttributesDetails, "card_set", true);
|
|
388
|
+
const cardNameValue = getAttributeValue(customAttributesDetails, "card_name", true);
|
|
389
|
+
const cardNumberValue = getAttributeValue(customAttributesDetails, "card_number", true);
|
|
390
|
+
const rarityValue = getAttributeValue(customAttributesDetails, "card_rarity", true);
|
|
391
|
+
const featureValue = getAttributeValue(customAttributesDetails, "card_feature", true);
|
|
392
|
+
const conditionValue = getAttributeValue(customAttributesDetails, "card_condition", true);
|
|
393
|
+
const foilValue = getAttributeValue(customAttributesDetails, "card_foil", true);
|
|
394
|
+
const ExpandableSection = ({ children, maxHeight = 480 }) => {
|
|
395
|
+
const [expanded, setExpanded] = useState(false);
|
|
396
|
+
const [showButton, setShowButton] = useState(false);
|
|
397
|
+
const contentRef = useRef(null);
|
|
398
|
+
|
|
399
|
+
useEffect(() => {
|
|
400
|
+
if (!contentRef.current) return;
|
|
401
|
+
|
|
402
|
+
const checkContent = () => {
|
|
403
|
+
const { scrollHeight } = contentRef.current;
|
|
404
|
+
const isDesktop = window.innerWidth >= 769;
|
|
405
|
+
|
|
406
|
+
if (isDesktop && scrollHeight > maxHeight) {
|
|
407
|
+
setShowButton(true);
|
|
408
|
+
} else {
|
|
409
|
+
setShowButton(false);
|
|
410
|
+
setExpanded(false);
|
|
411
|
+
}
|
|
412
|
+
};
|
|
413
|
+
|
|
414
|
+
checkContent();
|
|
415
|
+
window.addEventListener("resize", checkContent);
|
|
416
|
+
return () => window.removeEventListener("resize", checkContent);
|
|
417
|
+
}, [children, maxHeight]);
|
|
418
|
+
|
|
419
|
+
const isDesktop = typeof window !== "undefined" && window.innerWidth >= 769;
|
|
420
|
+
|
|
421
|
+
return (
|
|
422
|
+
<>
|
|
423
|
+
<div className="relative">
|
|
424
|
+
<div
|
|
425
|
+
ref={contentRef}
|
|
426
|
+
style={{
|
|
427
|
+
maxHeight:
|
|
428
|
+
isDesktop && showButton && !expanded
|
|
429
|
+
? `${maxHeight}px`
|
|
430
|
+
: "none",
|
|
431
|
+
overflow: "hidden",
|
|
432
|
+
transition: "max-height 0.3s ease"
|
|
433
|
+
}}
|
|
434
|
+
>
|
|
435
|
+
{children}
|
|
436
|
+
</div>
|
|
437
|
+
|
|
438
|
+
{isDesktop && !expanded && showButton && (
|
|
439
|
+
<div className={cn("absolute bottom-0 left-0 w-full h-16 bg-gradient-to-t to-transparent pointer-events-none", classes.productDetailsMaxContent)}/>
|
|
440
|
+
)}
|
|
441
|
+
</div>
|
|
442
|
+
{isDesktop && showButton && (
|
|
443
|
+
<button
|
|
444
|
+
type="button"
|
|
445
|
+
onClick={() => setExpanded(!expanded)}
|
|
446
|
+
className="mt-0 text-[14px] text-blue-600 font-medium underline focus:outline-none"
|
|
447
|
+
>
|
|
448
|
+
{expanded ? "Show Less" : "Read More"} <ArrowUp2 size="14" style={{
|
|
449
|
+
"display": "inline-block",
|
|
450
|
+
"marginLeft": "5px"
|
|
451
|
+
}} className={cn(expanded ? 'rotate-0 ' : 'rotate-180', 'transition-all stroke-current')} variant="Outline" />
|
|
452
|
+
</button>
|
|
453
|
+
)}
|
|
454
|
+
</>
|
|
455
|
+
);
|
|
456
|
+
};
|
|
390
457
|
|
|
391
458
|
const dataTabs =
|
|
392
459
|
[
|
|
393
|
-
{
|
|
394
|
-
id: 'product-detail',
|
|
395
|
-
title: 'Description',
|
|
396
|
-
content: <ProductDescription />
|
|
397
|
-
},
|
|
398
460
|
{
|
|
399
461
|
id: 'product-more-info',
|
|
400
|
-
title: '
|
|
462
|
+
title: 'Product Information',
|
|
401
463
|
content: <ProductMoreInfo />
|
|
402
464
|
},
|
|
465
|
+
{
|
|
466
|
+
id: 'product-detail',
|
|
467
|
+
title: 'Product Description',
|
|
468
|
+
content: <ProductDescription />
|
|
469
|
+
},
|
|
403
470
|
{
|
|
404
471
|
id: 'product-tnc',
|
|
405
472
|
title: 'Term & Conditions',
|
|
@@ -423,7 +490,7 @@ const ProductFullDetail = props => {
|
|
|
423
490
|
{
|
|
424
491
|
id: 'product-reviews',
|
|
425
492
|
title: 'Reviews',
|
|
426
|
-
content: <ProductReviews className={cn(contentContainerClass)} />
|
|
493
|
+
content: <ProductReviews className={cn(contentContainerClass, classes.contentContainerTabOverride)} />
|
|
427
494
|
}
|
|
428
495
|
];
|
|
429
496
|
|
|
@@ -478,22 +545,6 @@ const ProductFullDetail = props => {
|
|
|
478
545
|
<section className={cn(classes.leftContainer, 'relative')}>
|
|
479
546
|
<ProductLabel item={productDetails} />
|
|
480
547
|
<Carousel images={mediaGalleryEntries} hoveredMedia={hoveredMedia} selectedMedia={selectedMedia}/>
|
|
481
|
-
<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'>
|
|
482
|
-
<Suspense fallback={null}>
|
|
483
|
-
<WishlistButton
|
|
484
|
-
classes={{
|
|
485
|
-
root: cn(
|
|
486
|
-
'button_share border border-solid border-gray-100 p-2.5',
|
|
487
|
-
'rounded-full flex justify-center items-center h-fitContent min-w-min'
|
|
488
|
-
)
|
|
489
|
-
}}
|
|
490
|
-
{...wishlistButtonProps}
|
|
491
|
-
buttonText={''}
|
|
492
|
-
/>
|
|
493
|
-
</Suspense>
|
|
494
|
-
<Divider className="w-[1px] !h-[40px]" />
|
|
495
|
-
<Share />
|
|
496
|
-
</div>
|
|
497
548
|
</section>
|
|
498
549
|
<section className={classes.rightContainer}>
|
|
499
550
|
<div
|
|
@@ -506,179 +557,140 @@ const ProductFullDetail = props => {
|
|
|
506
557
|
aria-live="polite"
|
|
507
558
|
className={cn(
|
|
508
559
|
classes.productName,
|
|
509
|
-
'!font-medium leading-[
|
|
560
|
+
'!font-medium leading-[1] mb-1.5 line-clamp-2 !text-[1.5rem]'
|
|
510
561
|
)}
|
|
511
562
|
data-cy="ProductFullDetail-productName"
|
|
512
563
|
>
|
|
513
564
|
{productDetails.name}
|
|
514
565
|
</h1>
|
|
515
|
-
<div className='product_review-container flex items-center gap-x-2'>
|
|
516
|
-
<div className='product_rating leading-[14px] flex items-center gap-x-[5px]'>
|
|
517
|
-
<span className="w-3.5 h-3.5 relative">
|
|
518
|
-
<Star1 color='#F7C317' size={14} className='fill-[#F7C317]' />
|
|
519
|
-
</span>
|
|
520
|
-
<span className='text-gray-200 text-sm'>
|
|
521
|
-
{rating_value}
|
|
522
|
-
</span>
|
|
523
|
-
</div>
|
|
524
|
-
<div className='before_block before_w-[1px] before_bg-gray-200 before_h-full before_relative w-[1px] h-[14px]'></div>
|
|
525
|
-
<span className='review_count text-gray-200 text-base leading-[14px]'>
|
|
526
|
-
{review_count} Reviews
|
|
527
|
-
</span>
|
|
528
|
-
</div>
|
|
529
|
-
</div>
|
|
530
|
-
<div
|
|
531
|
-
className={cn(
|
|
532
|
-
'product_short_description',
|
|
533
|
-
'mb-xs',
|
|
534
|
-
)}
|
|
535
|
-
>
|
|
536
|
-
{shortDescription}
|
|
537
566
|
</div>
|
|
538
|
-
|
|
539
|
-
<
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
<div
|
|
545
|
-
className={cn(
|
|
546
|
-
'product_price_container',
|
|
547
|
-
'py-xs flex justify-between flex-wrap gap-y-5'
|
|
548
|
-
)}
|
|
549
|
-
>
|
|
550
|
-
<div className='flex flex-col gap-y-3'>
|
|
551
|
-
<div className='flex flex-col gap-y-3'>
|
|
552
|
-
<p
|
|
553
|
-
data-cy="ProductFullDetail-productPrice"
|
|
554
|
-
className={cn(
|
|
555
|
-
classes.productPrice,
|
|
556
|
-
'text-[32px] font-medium leading-[32px] mb-0',
|
|
567
|
+
<section className="bottom_right-container justify-center gap-x-6 block sm_flex md_flex lg_flex xl_flex 2xl_flex gap-[7px]">
|
|
568
|
+
<section className='right_left-container w-full'>
|
|
569
|
+
<ExpandableSection>
|
|
570
|
+
<div className="text-sm leading-6 leading-[2.5rem]">
|
|
571
|
+
{setNameValue && (
|
|
572
|
+
<p><strong>Set Name:</strong> {setNameValue}</p>
|
|
557
573
|
)}
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
574
|
+
{cardNameValue && (
|
|
575
|
+
<p><strong>Card Name:</strong> {cardNameValue}</p>
|
|
576
|
+
)}
|
|
577
|
+
{cardNumberValue && (
|
|
578
|
+
<p><strong>Card Number:</strong> {cardNumberValue}</p>
|
|
579
|
+
)}
|
|
580
|
+
{rarityValue && (
|
|
581
|
+
<p><strong>Rarity:</strong> {rarityValue}</p>
|
|
582
|
+
)}
|
|
583
|
+
{featureValue && (
|
|
584
|
+
<p><strong>Feature:</strong> {featureValue}</p>
|
|
585
|
+
)}
|
|
586
|
+
{conditionValue && (
|
|
587
|
+
<p><strong>Condition:</strong> {conditionValue}</p>
|
|
588
|
+
)}
|
|
589
|
+
{foilValue && (
|
|
590
|
+
<p><strong>Foil/Non Foil:</strong> {foilValue}</p>
|
|
591
|
+
)}
|
|
592
|
+
</div>
|
|
593
|
+
</ExpandableSection>
|
|
594
|
+
</section>
|
|
595
|
+
<section className='right_right-container w-full'>
|
|
596
|
+
<div className={cn('product_purchase-section', 'border border-[lightgray] rounded-[10px] mb-[15px]')}>
|
|
597
|
+
<div
|
|
567
598
|
className={cn(
|
|
568
|
-
|
|
569
|
-
'
|
|
599
|
+
'product_price_container',
|
|
600
|
+
'flex justify-between flex-wrap gap-y-5'
|
|
570
601
|
)}
|
|
571
602
|
>
|
|
572
|
-
<
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
</p>
|
|
588
|
-
</div>
|
|
589
|
-
</div>
|
|
590
|
-
<Divider />
|
|
591
|
-
<FormError
|
|
592
|
-
classes={{
|
|
593
|
-
root: classes.formErrors
|
|
594
|
-
}}
|
|
595
|
-
errors={errors.get('form') || []}
|
|
596
|
-
/>
|
|
597
|
-
<section className={classes.options}>{options}</section>
|
|
598
|
-
<section className={cn(classes.quantity, 'py-xs !border-none')}>
|
|
599
|
-
{/* <span
|
|
600
|
-
data-cy="ProductFullDetail-quantityTitle"
|
|
601
|
-
className={classes.quantityTitle}
|
|
602
|
-
>
|
|
603
|
-
<FormattedMessage
|
|
604
|
-
id={'global.quantity'}
|
|
605
|
-
defaultMessage={'Quantity'}
|
|
606
|
-
/>
|
|
607
|
-
</span> */}
|
|
608
|
-
<QuantityStepper
|
|
609
|
-
min={1}
|
|
610
|
-
message={errors.get('quantity')}
|
|
611
|
-
/>
|
|
612
|
-
|
|
613
|
-
{/* <div className='product_shipping-information mb-[30px] leading-[18px] mt-[25px]'>
|
|
614
|
-
{sellerDetails &&
|
|
615
|
-
<div className='text-xs'>
|
|
616
|
-
Ship From <span className='font-medium'>{sellerDetails.country}</span>
|
|
617
|
-
</div>}
|
|
618
|
-
<div className='text-xs'>
|
|
619
|
-
Ship To <span className='font-medium'>Yishun</span>
|
|
620
|
-
</div>
|
|
621
|
-
<div className='text-xs'>
|
|
622
|
-
Shiping Method <span className='font-medium'>Store Pick Up | Meet Up</span>
|
|
623
|
-
</div>
|
|
624
|
-
</div> */}
|
|
625
|
-
|
|
626
|
-
<div className='product_actions-wrapper'>
|
|
627
|
-
{cartActionContent}
|
|
628
|
-
</div>
|
|
629
|
-
</section>
|
|
630
|
-
{/* <Divider />
|
|
631
|
-
<section className={cn(classes.quantity, 'py-[30px] !border-none')}>
|
|
632
|
-
<RFQ />
|
|
633
|
-
</section> */}
|
|
634
|
-
<Divider />
|
|
635
|
-
<LinkToOtherStores productDetails={productDetails} />
|
|
636
|
-
<section className='seller-information py-xs'>
|
|
637
|
-
<div className='flex xs_flex-col md_flex-row xs_items-center md_items-start items-start gap-[15px] relative'>
|
|
638
|
-
<div className='flex flex-row justify-between relative w-full'>
|
|
639
|
-
<div className='flex flex-col xs_items-center md_items-start gap-[6px] relative'>
|
|
640
|
-
<div className="gap-x-[10px] gap-y-1 flex xs_flex-col md_flex-row xs_items-center md_items-start relative">
|
|
641
|
-
<div className="text-sm">
|
|
642
|
-
{sellerDetails ? sellerDetails.name : ''}
|
|
643
|
-
</div>
|
|
644
|
-
<div className="flex items-center relative">
|
|
645
|
-
<Verify variant='Bold' color='#f76b1c' size={20} />
|
|
646
|
-
</div>
|
|
647
|
-
</div>
|
|
648
|
-
<div class="relative w-fit font-normal text-[#999999] text-[12px] tracking-[0] leading-[14px] whitespace-nowrap">
|
|
649
|
-
{sellerDetails ? getSellerAddressDisplay(sellerDetails) : ''}
|
|
650
|
-
</div>
|
|
651
|
-
</div>
|
|
652
|
-
<div className='flex flex-wrap items-start gap-4 relative'>
|
|
653
|
-
<Link to='/' class="flex items-center justify-center gap-[5px] py-1 px-5 relative bg-white rounded-[30px] border border-solid border-[#f76b1c]">
|
|
654
|
-
<div class="flex items-center justify-center gap-[10px] relative">
|
|
655
|
-
<Sms color="#f76b1c" size={14} variant="Outline" className='stroke-[#f76b1c]' />
|
|
656
|
-
<div class="relative xs_hidden lg_flex w-fit font-medium text-[#f76b1c] text-[14px] tracking-[0] leading-[20px] whitespace-nowrap">
|
|
657
|
-
Message
|
|
658
|
-
</div>
|
|
659
|
-
</div>
|
|
660
|
-
</Link>
|
|
661
|
-
<Link to='/' class="flex items-center justify-center gap-[5px] py-1 px-5 relative bg-[#280135] rounded-[30px] border border-solid border-[#280135]">
|
|
662
|
-
<div class="flex items-center justify-center gap-[10px] relative">
|
|
663
|
-
<Message color='#FFFFFF' size={14} variant="Outline" className='stroke-[#FFFFFF]' />
|
|
664
|
-
<div class="relative xs_hidden lg_flex w-fit font-medium text-[#fff] text-[14px] tracking-[0] leading-[20px] whitespace-nowrap">
|
|
665
|
-
Chat With Seller
|
|
666
|
-
</div>
|
|
603
|
+
<div className='flex flex-col gap-y-2 pl-[1rem] pt-[1rem]'>
|
|
604
|
+
<div className='flex flex-col gap-y-1'>
|
|
605
|
+
<p
|
|
606
|
+
data-cy="ProductFullDetail-productPrice"
|
|
607
|
+
className={cn(
|
|
608
|
+
classes.productPrice,
|
|
609
|
+
'text-[32px] font-medium leading-[32px] mb-0',
|
|
610
|
+
)}
|
|
611
|
+
>
|
|
612
|
+
<Price
|
|
613
|
+
currencyCode={productDetails.price.currency}
|
|
614
|
+
priceRange={productDetails.price_range}
|
|
615
|
+
value={productDetails.price.value}
|
|
616
|
+
/>
|
|
617
|
+
</p>
|
|
667
618
|
</div>
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
<
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
619
|
+
<AuctionDetail className="auction_detail-container" />
|
|
620
|
+
<PreorderDetail className={'preorder_detail-container'} />
|
|
621
|
+
<small className='shipping-calculation-notes text-gray-200 text-xs'>
|
|
622
|
+
Shipping is calculated on checkout
|
|
623
|
+
</small>
|
|
624
|
+
<div className='flex flex-col xs_items-center md_items-start gap-[6px] relative'>
|
|
625
|
+
<div className="gap-x-[10px] gap-y-1 flex xs_flex-col md_flex-row xs_items-center md_items-start relative">
|
|
626
|
+
<Link to={"/seller/"+sellerDetails.url_key} class="flex items-center justify-center gap-[5px] py-1 relative bg-white">
|
|
627
|
+
<div class="flex items-center justify-center gap-[5px] relative">
|
|
628
|
+
<p>Sold by</p>
|
|
629
|
+
<div class="relative xs_hidden lg_flex w-fit font-medium text-[#f76b1c] text-[14px] tracking-[0] leading-[20px] whitespace-nowrap">
|
|
630
|
+
{sellerDetails ? sellerDetails.name : ''}
|
|
631
|
+
</div>
|
|
632
|
+
</div>
|
|
633
|
+
</Link>
|
|
674
634
|
</div>
|
|
675
635
|
</div>
|
|
676
|
-
</
|
|
636
|
+
</div>
|
|
677
637
|
</div>
|
|
638
|
+
<FormError
|
|
639
|
+
classes={{
|
|
640
|
+
root: classes.formErrors
|
|
641
|
+
}}
|
|
642
|
+
errors={errors.get('form') || []}
|
|
643
|
+
/>
|
|
644
|
+
{ options &&
|
|
645
|
+
<section className={classes.options}>{options}</section>
|
|
646
|
+
}
|
|
647
|
+
<section className={cn(classes.quantity, 'pb-[20px] pt-[10px] !border-none')}>
|
|
648
|
+
<div className='product_group-actions flex gap-x-[18px] gap-y-4 pl-[1rem] items-center mt-2 lg_mt-0 mb-6 lg_mb-0'>
|
|
649
|
+
<QuantityStepper
|
|
650
|
+
min={1}
|
|
651
|
+
message={errors.get('quantity')}
|
|
652
|
+
/>
|
|
653
|
+
<Suspense fallback={null}>
|
|
654
|
+
<WishlistButton
|
|
655
|
+
classes={{
|
|
656
|
+
root: cn(
|
|
657
|
+
'button_share border border-solid border-gray-100 p-2.5',
|
|
658
|
+
'rounded-full flex justify-center items-center h-fitContent min-w-min'
|
|
659
|
+
)
|
|
660
|
+
}}
|
|
661
|
+
{...wishlistButtonProps}
|
|
662
|
+
buttonText={''}
|
|
663
|
+
/>
|
|
664
|
+
</Suspense>
|
|
665
|
+
</div>
|
|
666
|
+
<div className='product_actions-wrapper'>
|
|
667
|
+
{cartActionContent}
|
|
668
|
+
</div>
|
|
669
|
+
</section>
|
|
670
|
+
</div>
|
|
671
|
+
<div className={cn('product_otherlink-section', 'border border-[lightgray] rounded-[10px] mb-[15px]')}>
|
|
672
|
+
<LinkToOtherStores productDetails={productDetails} />
|
|
678
673
|
</div>
|
|
679
|
-
|
|
674
|
+
<section>
|
|
675
|
+
<div
|
|
676
|
+
className="text-center pt-3 pb-3 cursor-pointer border border-[lightgray] rounded-[10px]"
|
|
677
|
+
onClick={() => {
|
|
678
|
+
const section = document.getElementById("cross-seller-section");
|
|
679
|
+
if (section) {
|
|
680
|
+
section.scrollIntoView({ behavior: "smooth" });
|
|
681
|
+
}
|
|
682
|
+
}}
|
|
683
|
+
>
|
|
684
|
+
<span className="font-bold underline text-[14px]">
|
|
685
|
+
View {totalListings} Other Listings
|
|
686
|
+
</span>
|
|
687
|
+
<p className="text-sm text-gray-600">
|
|
688
|
+
As low as ${lowestPrice.toFixed(2)}
|
|
689
|
+
</p>
|
|
690
|
+
</div>
|
|
691
|
+
</section>
|
|
692
|
+
</section>
|
|
680
693
|
</section>
|
|
681
|
-
<Divider />
|
|
682
694
|
</section>
|
|
683
695
|
</Form>
|
|
684
696
|
<section className='section_product-details-container mt-8 mb-10'>
|
|
@@ -687,21 +699,16 @@ const ProductFullDetail = props => {
|
|
|
687
699
|
data={dataTabs}
|
|
688
700
|
tabContentWrapperClassName='!p-0'
|
|
689
701
|
hasContent
|
|
690
|
-
tabWrapperClassName='xl_gap-x-[60px] justify-
|
|
702
|
+
tabWrapperClassName='xl_gap-x-[60px] justify-between'
|
|
691
703
|
/>
|
|
692
704
|
</div>
|
|
693
705
|
<div className='block lg_hidden'>
|
|
694
706
|
<ProductDetailsCollapsible data={dataTabs} />
|
|
695
707
|
</div>
|
|
696
708
|
</section>
|
|
697
|
-
|
|
698
|
-
<section className='pt-8 lg_pt-10'>
|
|
699
|
-
<RelatedProduct />
|
|
700
|
-
</section>
|
|
701
|
-
|
|
702
|
-
<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'>
|
|
709
|
+
<section id="cross-seller-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'>
|
|
703
710
|
<div className='lg_max-w-[1200px] px-2.5 mx-auto relative max-w-screen-md'>
|
|
704
|
-
<CrossSeller
|
|
711
|
+
<CrossSeller/>
|
|
705
712
|
</div>
|
|
706
713
|
</section>
|
|
707
714
|
</Fragment>
|