Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import React, { useEffect, useState } from 'react';
- import { FormattedMessage } from 'react-intl';
- import { Info } from 'react-feather';
- import { string, number, shape } from 'prop-types';
- import { Link } from 'react-router-dom';
- import Price from '../Price/price';
- import { UNCONSTRAINED_SIZE_KEY } from '@magento/peregrine/lib/talons/Image/useImage';
- import { useGalleryItem } from '../../talons/Gallery/useGalleryItem';
- import resourceUrl from '@magento/peregrine/lib/util/makeUrl';
- import VideoCallButton from './videoCallButton';
- import { useStyle } from '@magento/venia-ui/lib/classify';
- import Image from '@magento/venia-ui/lib/components/Image';
- import GalleryItemShimmer from '@magento/venia-ui/lib/components/Gallery/item.shimmer';
- import defaultClasses from './item.module.css';
- import WishlistGalleryButton from './addToListButton.ce.js';
- import Rating from '@magento/venia-ui/lib/components/Rating';
- import './item.module.css';
- import ProductTags from '../Common/productTags';
- import { useWindowSize } from '@magento/peregrine';
- import { useQuery, gql } from '@apollo/client';
- import Button from '@magento/venia-ui/lib/components/Button';
- import { BrowserPersistence } from '@magento/peregrine/lib/util';
- import { useSelector, useDispatch } from 'react-redux';
- import apiClient from '../../api';
- // The placeholder image is 4:5, so we should make sure to size our product
- // images appropriately.
- const IMAGE_WIDTH = '100%';
- const IMAGE_HEIGHT = 375;
- const storage = new BrowserPersistence();
- // Gallery switches from two columns to three at 640px.
- const IMAGE_WIDTHS = new Map()
- .set(640, IMAGE_WIDTH)
- .set(UNCONSTRAINED_SIZE_KEY, 840);
- const GET_PRODUCT_CUSTOM_ATTRIBUTES = gql`
- query getProducts($key: String!) {
- products(filter: { sku: { in: [$key] } }) {
- items {
- sku
- uid
- id
- categories {
- uid
- name
- is_anchor
- url_key
- url_path
- level
- display_mode
- default_sort_by
- description
- }
- ... on CustomizableProductInterface {
- options {
- title
- required
- sort_order
- option_id
- ... on CustomizableDropDownOption {
- value {
- option_type_id
- price
- price_type
- sku
- sort_order
- title
- }
- }
- }
- }
- custom_attributes {
- attribute_metadata {
- code
- }
- selected_attribute_options {
- attribute_option {
- label
- }
- }
- }
- }
- }
- }
- `;
- const GalleryItem = props => {
- const [isItemAvailableInStore, setIsItemAvailableInStore] = useState(false);
- const {
- handleLinkClick,
- item,
- itemRef,
- wishlistButtonProps,
- isSupportedProductType
- } = useGalleryItem(props);
- const { storeConfig } = props;
- const productUrlSuffix = storeConfig && storeConfig.product_url_suffix;
- const classes = useStyle(defaultClasses, props.classes);
- const customData = useSelector(state => state.custom);
- const { storeUserInfo } = customData;
- const { isStorefrontUser: isStoreUser, outlet } = storeUserInfo;
- useEffect(() => {
- if (outlet?.outletFilterId && item?.is_outlet_available) {
- if (outlet.outletFilterId == item.is_outlet_available) {
- setIsItemAvailableInStore(true);
- }
- }
- }, []);
- const windowSize = useWindowSize();
- const isMobile = windowSize.innerWidth <= 840 ? true : false;
- const isTab =
- windowSize.innerWidth >= 841 && windowSize.innerWidth <= 1040
- ? true
- : false;
- const isLap =
- windowSize.innerWidth >= 1041 && windowSize.innerWidth <= 1240
- ? true
- : false;
- const titleTextSize = isMobile
- ? 'text-[12px]'
- : isTab
- ? 'text-[14px]'
- : isLap
- ? 'text-[16px]'
- : '';
- if (!item) {
- return <GalleryItemShimmer classes={classes} />;
- }
- // eslint-disable-next-line no-unused-vars
- const { name, price_range, small_image, url_key, rating_summary } = item;
- const { url } = small_image;
- const [image, setImage] = useState(url ? url : '');
- const [hoverImage, setProductGallery] = useState(null);
- const [fireWishListEvent,setFireWishListEvent] = useState(false);
- const productLink = resourceUrl(`/${url_key}${productUrlSuffix || ''}`);
- const productEnquiry = 'I want to enquire about ' + name + '\n\n' + url_key;
- const productEnquiryLink = 'https://wa.me/919943212511?text='+ encodeURIComponent(productEnquiry);
- const wishlistButton = wishlistButtonProps ? (
- <WishlistGalleryButton
- fireWishListEvent={fireWishListEvent}
- setFireWishListEvent={setFireWishListEvent}
- {...wishlistButtonProps}
- />
- ) : null;
- const { error, loading, data } = useQuery(GET_PRODUCT_CUSTOM_ATTRIBUTES, {
- fetchPolicy: 'cache-and-network',
- nextFetchPolicy: 'cache-first',
- skip: !item.sku,
- variables: {
- key: item.sku
- }
- });
- const customAttributes = data?.products?.items[0]?.custom_attributes;
- const customOptions = data?.products?.items[0]?.options?.filter(
- i => i.required
- );
- var isVirtualTryOn = false;
- if (Array.isArray(customAttributes)) {
- customAttributes.filter(customAttribute => {
- if (
- customAttribute.attribute_metadata.code === 'is_virtual_try_on'
- ) {
- if (
- customAttribute?.selected_attribute_options
- ?.attribute_option[0]?.label == 'Yes'
- ) {
- isVirtualTryOn = true;
- }
- }
- });
- }
- const addButton =
- customOptions && customOptions.length > 0 ? (
- <a
- id="productFullDetail.addItemToCart1"
- target={'_blank'}
- class="w-full text-xs tracking-[2.4px] h-[38px] text-[0.7rem]"
- >
- <button
- class="tryVirtualButton-root-aqT bg-[#F8F3EC] border-2 border-[#EFEAE2] p-2 w-full rounded-sm h-[38px] product_button"
- type="button"
- >
- <span class="button-content-TD8 gap-1.5 grid-flow-col inline-grid items-center justify-center justify-items-center">
- <span class="text-[#181A1D] tracking-widest font-semibold">
- {isStoreUser ? 'SELECT' : 'BUY NOW'}
- </span>
- </span>
- </button>
- </a>
- ) : isSupportedProductType ? (
- <div class="w-full text-xs tracking-[2.4px] h-[38px] text-[0.7rem]">
- <VideoCallButton
- item={item}
- urlSuffix={productUrlSuffix}
- isStoreUser={isStoreUser}
- />
- </div>
- ) : (
- <div className={classes.unavailableContainer}>
- <Info />
- <p>
- <FormattedMessage
- id={'galleryItem.unavailableProduct'}
- defaultMessage={
- isStoreUser
- ? 'Currently unavailable to select'
- : 'Currently unavailable for purchase.'
- }
- />
- </p>
- </div>
- );
- const viewDetails = (
- <Link
- to={productLink}
- target="_blank"
- class="w-full text-xs tracking-[2.4px] h-[38px] text-[0.7rem]"
- >
- <button
- class="tryVirtualButton-root-aqT bg-[#F8F3EC] border-2 border-[#EFEAE2] p-2 w-full rounded-sm h-[38px] product_button"
- type="button"
- >
- <span class="button-content-TD8 gap-1.5 grid-flow-col inline-grid items-center justify-center justify-items-center">
- <span class="text-[#181A1D] tracking-widest font-semibold">
- VIEW DETAILS4
- </span>
- </span>
- </button>
- </Link>
- );
- // fallback to regular price when final price is unavailable
- const priceSource = price_range.maximum_price.final_price;
- const regurlarPrice = price_range.maximum_price.regular_price;
- // Hide the Rating component until it is updated with the new look and feel (PWA-2512).
- // const ratingAverage = null;
- const ratingAverage = rating_summary ? (
- <Rating rating={rating_summary} />
- ) : null;
- const virtualTryOn = isVirtualTryOn ? (
- <Button
- className={
- 'tracking-[1.2px] uppercase text-[10px] bg-[#774E4F] rounded-sm focus:outline-none flex justify-center items-center px-[5px] h-[25px] virtual'
- }
- onClick={() => {
- let script = document.createElement('script');
- script.onload = () => {
- let options = {
- brandId: '42241de3-5614-4e87-8e63-89103d6ea5d7'
- };
- initMirrarUI(item.sku, options);
- };
- script.src =
- 'https://cdn.mirrar.com/general/scripts/mirrar-ui.js';
- document.body.append(script);
- }}
- >
- <span className="text-[#FFF] text-[10px] uppercase tracking-[1.2px]">
- <FormattedMessage
- id="addToCartButton.tryBefore"
- defaultMessage="VIRTUAL TRY ON"
- />
- </span>
- </Button>
- ) : <div className='h-[25px]'></div>;
- const itemAvailable = isItemAvailableInStore ? (
- <div className="flex bg-green-200 h-5 mt-2 text-xs">
- <p className="w-full text-center font-semibold tracking-widest m-auto">
- Available In Store
- </p>
- </div>
- ) : (
- <div className="flex bg-red-200 h-5 mt-2 text-xs">
- <p className="w-full text-center font-semibold tracking-widest m-auto">
- Not available at this Store
- </p>
- </div>
- );
- return (
- <div
- data-cy="GalleryItem-root"
- className={classes.itemCard + ' bg-[#FFF] rounded-[10px]'}
- aria-live="polite"
- aria-busy="false"
- ref={itemRef}
- >
- <input type="hidden" name="productid" value={data?.products?.items[0]?.id} />
- <ProductTags
- product={item}
- page={'PLP'}
- setProductGallery={setProductGallery}
- />
- <div className="absolute top-0 right-0 z-[9]" >{wishlistButton}</div>
- <Link
- onClick={handleLinkClick}
- to={productLink}
- className={classes.images}
- target="_blank"
- >
- {image ? (
- <Image
- onMouseEnter={() =>
- hoverImage && hoverImage.url
- ? setImage(hoverImage.url)
- : null
- }
- onMouseLeave={() => setImage(url)}
- style={{ backgroundColor: 'white', marginTop: 5 }}
- alt={name}
- classes={{
- image: classes.image,
- loaded: classes.imageLoaded,
- notLoaded: classes.imageNotLoaded,
- root: classes.imageContainer
- }}
- height={IMAGE_HEIGHT}
- resource={image}
- widths={IMAGE_WIDTHS}
- />
- ) : null}
- </Link>
- <div className="p-2">
- <div className="flex justify-between items-center mprice">
- <div data-cy="GalleryItem-price" className={classes.price + " !font-bold"}>
- <Price
- value={priceSource.value}
- currencyCode={priceSource.currency}
- />
- {regurlarPrice.value !== priceSource.value ?
- <s
- data-cy="ProductFullDetail-productPrice"
- className={
- classes.productPrice +
- ' text-[16px] py-1 ml-1 text-[#35383A] font-bold'
- }
- >
- <Price
- value={regurlarPrice.value}
- currencyCode={regurlarPrice.currency}
- />
- </s> : null}
- </div>
- {virtualTryOn}
- {ratingAverage}
- </div>
- <Link
- onClick={handleLinkClick}
- to={productLink}
- className={classes.name + ' mt-[10px] pb-[5px]'}
- data-cy="GalleryItem-name"
- style={{ width: '100%', display: 'inline-block' }}
- >
- {isMobile ? (
- <span className="text-[12px]">
- {name && name.substring(0, 25)}
- {name && name.length > 25 && '...'}
- </span>
- ) : (
- <span className={titleTextSize}>
- {name &&
- name.substring(0, windowSize.innerWidth / 35)}
- {name &&
- name.length > windowSize.innerWidth / 35 &&
- '...'}
- </span>
- )}
- {/* {isMobile ? (
- <span className='text-[14px]'>
- {name && name.substring(0, 20)}
- {name && name.length > 20 && '...'}
- </span>
- ) : isTab ? (
- <span className='text-[14px]'>
- {name && name.substring(0, 20)}
- {name && name.length > 20 && '...'}
- </span>
- ) : isLap ? (
- <span className='text-[16px]'>
- {name && name.substring(0, 30)}
- {name && name.length > 30 && '...'}
- </span>
- )
- : (
- <span>
- {name && name.substring(0, 35)}
- {name && name.length > 35 && '...'}
- </span>
- )} */}
- </Link>
- <div class="flex pt-4 flex-col gap-x-2.5 gap-y-1.5 lg_flex-row">
- {viewDetails}
- {addButton}
- </div>
- {isStoreUser ? itemAvailable : null}
- </div>
- </div>
- );
- };
- GalleryItem.propTypes = {
- classes: shape({
- image: string,
- imageLoaded: string,
- imageNotLoaded: string,
- imageContainer: string,
- images: string,
- name: string,
- price: string,
- root: string
- }),
- item: shape({
- id: number.isRequired,
- uid: string.isRequired,
- name: string.isRequired,
- small_image: shape({
- url: string.isRequired
- }),
- stock_status: string.isRequired,
- __typename: string.isRequired,
- url_key: string.isRequired,
- sku: string.isRequired,
- price_range: shape({
- maximum_price: shape({
- final_price: shape({
- value: number.isRequired,
- currency: string.isRequired
- }),
- regular_price: shape({
- value: number.isRequired,
- currency: string.isRequired
- }).isRequired,
- discount: shape({
- amount_off: number.isRequired
- }).isRequired
- }).isRequired
- }).isRequired
- }),
- storeConfig: shape({
- magento_wishlist_general_is_enabled: string.isRequired,
- product_url_suffix: string
- })
- };
- export default GalleryItem;
Advertisement
Add Comment
Please, Sign In to add comment