Guest User

frrf

a guest
Mar 27th, 2024
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 66.03 KB | None | 0 0
  1. import React, { useMemo, Fragment, Suspense, useState, useEffect } from 'react';
  2. import { Link, useHistory } from 'react-router-dom';
  3. import { FormattedMessage, useIntl } from 'react-intl';
  4. import { arrayOf, bool, number, shape, string } from 'prop-types';
  5. import { Form } from 'informed';
  6. import {
  7. Info,
  8. ChevronRight,
  9. ChevronDown as ArrowDown,
  10. ChevronUp as ArrowUp,
  11. Check
  12. } from 'react-feather';
  13. import LoadingIndicator from '../LoadingIndicator';
  14. // import Price from '@magento/venia-ui/lib/components/Price';
  15.  
  16. import { useProductFullDetail } from '../../talons/ProductFullDetail/useProductFullDetail';
  17. import { isProductConfigurable } from '@magento/peregrine/lib/util/isProductConfigurable';
  18. import {getTryProductConfiguration} from '../../reducers/CustomReducer';
  19. import { useStyle } from '@magento/venia-ui/lib/classify';
  20. import Breadcrumbs from '../Breadcrumbs';
  21. import Carousel from '../ProductImageCarousel';
  22. import FormError from '@magento/venia-ui/lib/components/FormError';
  23. import QuantityStepper from '@magento/venia-ui/lib/components/QuantityStepper';
  24. import RichContent from '@magento/venia-ui/lib/components/RichContent/richContent';
  25. import { ProductOptionsShimmer } from '@magento/venia-ui/lib/components/ProductOptions';
  26. import CustomAttributes from '@magento/venia-ui/lib/components/ProductFullDetail/CustomAttributes';
  27. import defaultClasses from './productFullDetail.module.css';
  28. import shareIcon from './ShareIcon.svg';
  29. import reviewsIcon from './ReviewsIcon.svg';
  30. import Field from '../Field';
  31. import timeIcon from './TimeIcon.svg';
  32.  
  33. import CompleteLook from './components/CompleteLook';
  34. import LinkButton from '@magento/venia-ui/lib/components/LinkButton';
  35. import Promise from './components/Promise';
  36.  
  37. import DropdownBlock from './components/DropdownBlock';
  38. import TrustedPartners from './components/TrustedPartners';
  39. import apiClient from '../../api';
  40.  
  41. import TrendingProducts from '../HomePage/components/TrendingProducts';
  42. import ShopPdpCategory from './components/PDPCategory/ShopByPdpCategory';
  43. import Price, { CurrencyCodeUI } from '../Price/price';
  44. import TryAtHomeSection from './components/TryAtHomeSection';
  45. import './index.css';
  46. import { BrowserPersistence } from '@magento/peregrine/lib/util';
  47. import ProductTags from '../Common/productTags';
  48. import { useWindowSize } from '@magento/peregrine';
  49. import whatsapp from './images/whatsapp.png';
  50. import RelatedProducts from './RelatedProducts';
  51. import CustomizableOptions from './components/CustomizableOptions';
  52. import ProductDetailsBlock from './components/ProductDetailsBlock';
  53. import { useSelector,useDispatch } from 'react-redux';
  54. const WishlistButton = React.lazy(() => import('../Wishlist/AddToListButton'));
  55. import { gql, useQuery } from '@apollo/client';
  56. import SimilarProduct from './SimilarProduct';
  57. import GlowPromise from '../HomePage/components/GlowPromise';
  58. import ForeverGlow from './components/ForeverGlow';
  59. import UserDetails from './components/UserDetails';
  60. import rating from './images/rating.png';
  61. import { netcoreEvent } from '../../initialize-netcore.js';
  62. import resourceUrl from '@magento/peregrine/lib/util/makeUrl';
  63. const Options = React.lazy(() =>
  64. import('@magento/venia-ui/lib/components/ProductOptions')
  65. );
  66. // Correlate a GQL error message to a field. GQL could return a longer error
  67. // string but it may contain contextual info such as product id. We can use
  68. // parts of the string to check for which field to apply the error.
  69. const ERROR_MESSAGE_TO_FIELD_MAPPING = {
  70. 'The requested qty is not available': 'quantity',
  71. 'Product that you are trying to add is not available.': 'quantity',
  72. "The product that was requested doesn't exist.": 'quantity'
  73. };
  74.  
  75. // Field level error messages for rendering.
  76. const ERROR_FIELD_TO_MESSAGE_MAPPING = {
  77. quantity: 'The requested quantity is not available.'
  78. };
  79.  
  80. const MINUS_SYMBOL = '-';
  81.  
  82. const storage = new BrowserPersistence();
  83.  
  84. const ProductFullDetail = props => {
  85. const { product, element } = props;
  86. const [showShare, setShowShare] = useState(false);
  87. const [showModal, setShowModal] = useState(false);
  88. const [popUpModal, setPopupModal] = useState(false);
  89. const [openScheduleModel, setOpenScheduleModel] = useState(false);
  90. const [userName, setUserName] = useState('');
  91. const [phoneNumber, setPhoneNumber] = useState('');
  92. const [slotDate, setSlotDate] = useState('');
  93. const [showPopup, setShowPopup] = useState('');
  94. const { tryProductConfiguration } = useSelector(
  95. state => state.custom
  96. );
  97.  
  98. const handleCloseModal = () => {
  99. setShowModal(!showModal);
  100. };
  101.  
  102. const handleChange = (e) => {
  103. const { name, value } = e.target;
  104. if (name === 'name') setUserName(value);
  105. else if (name === 'phone') setPhoneNumber(value);
  106. else if (name === 'slotDate') {
  107. setSlotDate(value)
  108. };
  109. };
  110.  
  111. const scheduleCall = async (e) => {
  112. e.preventDefault();
  113. try {
  114. const formattedDateTime = new Date(slotDate).toISOString().slice(0, 19).replace('T', ' ');
  115. const response = await apiClient.post(apiClient.Urls.scheduleCall, {
  116. params: {
  117. name: userName,
  118. phone_number: phoneNumber,
  119. slot_date: formattedDateTime
  120. }
  121. });
  122. if (response.success) {
  123. setShowPopup(true)
  124. setOpenScheduleModel(false)
  125. setTimeout(() => {
  126. setShowPopup(false)
  127. }, 3000);
  128. }
  129. } catch (error) {
  130. console.log('scheduleCall error', error);
  131. }
  132. };
  133.  
  134. const talonProps = useProductFullDetail({ product });
  135.  
  136. const {
  137. breadcrumbCategoryId,
  138. errorMessage,
  139. handleAddToCart,
  140. handleCustomizableProductToCart,
  141. handleSelectionChange,
  142. isOutOfStock,
  143. isAddToCartDisabled,
  144. isSupportedProductType,
  145. mediaGalleryEntries,
  146. productDetails,
  147. customAttributes,
  148. wishlistButtonProps,
  149. setFormApi,
  150. handleSubmit,
  151. isBusy,
  152. clearErrors,
  153. isAddedItem,
  154. setIsAddedItem,
  155. handlePincode,
  156. checkDeliveryDate,
  157. pincode,
  158. deliveryDate,
  159. isInvalidPincode,
  160. parentCategoryId,
  161. designFamilyValue,
  162. crossSellProducts
  163. } = talonProps;
  164.  
  165. const { formatMessage } = useIntl();
  166.  
  167. const regularPrice = product?.price?.regularPrice?.amount;
  168.  
  169. const discountPercent =
  170. ((regularPrice.value - productDetails.price.value) /
  171. regularPrice.value) *
  172. 100;
  173.  
  174. const windowSize = useWindowSize();
  175. const isMobile = windowSize.innerWidth <= 640;
  176.  
  177. const pinCode = storage.getItem('pin_code');
  178.  
  179. const userInfo = JSON.parse(localStorage.getItem('user_info')) || null;
  180.  
  181. const customData = useSelector(state => state.custom);
  182.  
  183.  
  184. // Overall Rating of the product
  185.  
  186.  
  187. const GET_CART_DETAILS = gql`
  188. query GetCartDetails($cartId: String!) {
  189. cart(cart_id: $cartId) {
  190. id
  191. items {
  192. uid
  193. product {
  194. uid
  195. sku
  196. }
  197. }
  198. }
  199. }
  200. `;
  201.  
  202. const cart = useSelector(state => state.cart);
  203. const { cartId } = cart;
  204.  
  205. const { data, loading } = useQuery(GET_CART_DETAILS, {
  206. fetchPolicy: 'cache-and-network',
  207. nextFetchPolicy: 'cache-first',
  208. skip: !cartId,
  209. variables: {
  210. cartId: cartId
  211. }
  212. });
  213.  
  214. const GET_CUSTOMER = gql`
  215. query getCustomer {
  216. customer {
  217. addresses {
  218. postcode
  219. default_shipping
  220. }
  221. }
  222. }
  223. `;
  224.  
  225. const { data: getCustomerData, error: errorCustomer } = useQuery(
  226. GET_CUSTOMER
  227. );
  228.  
  229. const customerDetails =
  230. getCustomerData &&
  231. getCustomerData.customer.addresses.find(i =>
  232. i.default_shipping == true ? i : null
  233. );
  234. const customerPostcode = customerDetails && customerDetails.postcode;
  235.  
  236. const { storeUserInfo } = customData;
  237.  
  238. const isStoreUser = storeUserInfo?.isStorefrontUser;
  239.  
  240. const dispatch = useDispatch();
  241.  
  242. useEffect(() => {
  243. handlePincode(customerPostcode || pinCode);
  244. dispatch(getTryProductConfiguration());
  245.  
  246. }, []);
  247. useEffect(() => {
  248. if (pincode && pincode.length >= 6) {
  249. checkDeliveryDate(productDetails.sku);
  250. }
  251. }, [pincode]);
  252.  
  253. const history = useHistory();
  254.  
  255. useEffect(() => {
  256. if (isAddedItem) {
  257.  
  258.  
  259. netcoreEvent('dispatch','Add to Cart', {
  260. 'prid': product.id,
  261. 'name': product?.name,
  262. 'brand':'glow',
  263. 'sale_price':product?.price_range?.maximum_price?.final_price.value,
  264. 'price': product?.price_range?.maximum_price?.final_price.value,
  265. 'prqt':1,
  266. 'is_in_stock':product?.stock_status,
  267. 'product_image': product?.small_image,
  268. 'produrl': resourceUrl(`${location.host}/${product?.url_key}` || ''),
  269. 'product_type':product?.__typename,
  270. 'currency': product?.price_range?.maximum_price?.final_price.currency
  271. });
  272.  
  273. history.push('cart');
  274. setIsAddedItem(false);
  275. }
  276. }, [isAddedItem]);
  277.  
  278.  
  279. const getMostViewedItems = async () => {
  280. try {
  281. const response = await apiClient.get(apiClient.Urls.getMostViewedProducts, {
  282. productId: product.id
  283. });
  284. if (response.success) {
  285. }
  286. }
  287. catch (error) {
  288. console.log('error', error);
  289. }
  290. }
  291. const productViews = () => {
  292. netcoreEvent('dispatch','Product view', {
  293. 'prid': product.id,
  294. 'name': product?.name,
  295. 'brand': 'glow',
  296. 'sale_price': product?.price_range?.maximum_price?.final_price.value,
  297. 'price':product?.price_range?.maximum_price?.final_price.value,
  298. 'prqt': 1,
  299. 'is_in_stock':product?.stock_status,
  300. 'product_image': product?.small_image,
  301. 'produrl': resourceUrl(`${location.host}/${product?.url_key}` || ''),
  302. 'currency': product?.price_range?.maximum_price?.final_price.currency
  303. });
  304. }
  305.  
  306. useEffect(() => {
  307. getMostViewedItems()
  308. productViews()
  309. }, []);
  310.  
  311. const [contactInfo, setContactInfo] = useState()
  312. const getContactDetails = async () => {
  313. try {
  314. const response = await apiClient.get(apiClient.Urls.getSlider, {
  315. identifier: 'contact_info'
  316. });
  317. if (response.success) {
  318. setContactInfo(response.data);
  319. }
  320. } catch (error) {
  321. console.log('error', error);
  322. }
  323. };
  324.  
  325.  
  326. useEffect(() => {
  327. getContactDetails()
  328. }, [])
  329.  
  330. const whatsappNumber = contactInfo && contactInfo.find(i => i.slide_title === "whatsapp_number");
  331.  
  332. const classes = useStyle(defaultClasses, props.classes);
  333. const options = isProductConfigurable(product) ? (
  334. <Suspense fallback={<ProductOptionsShimmer />}>
  335. <Options
  336. onSelectionChange={handleSelectionChange}
  337. options={product.configurable_options}
  338. />
  339. </Suspense>
  340. ) : null;
  341.  
  342. const breadcrumbs = breadcrumbCategoryId ? (
  343. <Breadcrumbs
  344. categoryId={breadcrumbCategoryId}
  345. currentProduct={productDetails.name}
  346. />
  347. ) : null;
  348.  
  349. // Fill a map with field/section -> error.
  350. const errors = new Map();
  351.  
  352. if (errorMessage) {
  353. Object.keys(ERROR_MESSAGE_TO_FIELD_MAPPING).forEach(key => {
  354. if (errorMessage.includes(key)) {
  355. const target = ERROR_MESSAGE_TO_FIELD_MAPPING[key];
  356. const message = ERROR_FIELD_TO_MESSAGE_MAPPING[target];
  357. errors.set(target, message);
  358. }
  359. });
  360.  
  361. // Handle cases where a user token is invalid or expired. Preferably
  362. // this would be handled elsewhere with an error code and not a string.
  363. if (errorMessage.includes('The current user cannot')) {
  364. errors.set('form', [
  365. new Error(
  366. formatMessage({
  367. id: 'productFullDetail.errorToken',
  368. defaultMessage:
  369. 'There was a problem with your cart. Please sign in again and try adding the item once more.'
  370. })
  371. )
  372. ]);
  373. }
  374.  
  375. // Handle cases where a cart wasn't created properly.
  376. if (
  377. errorMessage.includes('Variable "$cartId" got invalid value null')
  378. ) {
  379. errors.set('form', [
  380. new Error(
  381. formatMessage({
  382. id: 'productFullDetail.errorCart',
  383. defaultMessage:
  384. 'There was a problem with your cart. Please refresh the page and try adding the item once more.'
  385. })
  386. )
  387. ]);
  388. }
  389.  
  390. // An unknown error should still present a readable message.
  391. if (!errors.size) {
  392. errors.set('form', [
  393. new Error(
  394. formatMessage({
  395. id: 'productFullDetail.errorUnknown',
  396. defaultMessage:
  397. 'Could not add item to cart. Please check required options and try again.'
  398. })
  399. )
  400. ]);
  401. }
  402. }
  403.  
  404. var readyToShip = false;
  405.  
  406. if (Array.isArray(customAttributes)) {
  407. customAttributes.filter(customAttribute => {
  408. if (customAttribute.attribute_metadata.code === 'ready_to_ship') {
  409. if (
  410. customAttribute?.selected_attribute_options
  411. ?.attribute_option[0]?.label == 'Yes'
  412. ) {
  413. readyToShip = true;
  414. }
  415. }
  416. });
  417. }
  418.  
  419. var isVirtualTryOn = false;
  420. var glowSku = '';
  421.  
  422. if (Array.isArray(customAttributes)) {
  423. customAttributes.filter(customAttribute => {
  424. if (
  425. customAttribute.attribute_metadata.code === 'is_virtual_try_on'
  426. ) {
  427. if (
  428. customAttribute?.selected_attribute_options
  429. ?.attribute_option[0]?.label == 'Yes'
  430. ) {
  431. isVirtualTryOn = true;
  432. }
  433. }
  434. });
  435. const glowSkuAttribute = customAttributes.find(
  436. customAttribute =>
  437. customAttribute.attribute_metadata.code === 'glow_sku'
  438. );
  439. if (glowSkuAttribute) {
  440. glowSku = glowSkuAttribute.entered_attribute_value?.value;
  441. }
  442. }
  443.  
  444. const customAttributesDetails = useMemo(() => {
  445. const list = [];
  446. const pagebuilder = [];
  447. const skuAttribute = {
  448. attribute_metadata: {
  449. uid: 'attribute_sku',
  450. used_in_components: ['PRODUCT_DETAILS_PAGE'],
  451. ui_input: {
  452. ui_input_type: 'TEXT'
  453. },
  454. label: formatMessage({
  455. id: 'global.sku',
  456. defaultMessage: 'SKU'
  457. })
  458. },
  459. entered_attribute_value: {
  460. value: productDetails.sku
  461. }
  462. };
  463. if (Array.isArray(customAttributes)) {
  464. customAttributes.forEach(customAttribute => {
  465. if (
  466. customAttribute.attribute_metadata.ui_input
  467. .ui_input_type === 'PAGEBUILDER'
  468. ) {
  469. pagebuilder.push(customAttribute);
  470. } else {
  471. list.push(customAttribute);
  472. }
  473. });
  474. }
  475. list.unshift(skuAttribute);
  476. return {
  477. list: list,
  478. pagebuilder: pagebuilder
  479. };
  480. }, [customAttributes, productDetails.sku, formatMessage]);
  481.  
  482. const cartDetails = data ? data.cart.items : null;
  483. const handleProductModal = e => {
  484. var isMatched =
  485. cartDetails &&
  486. cartDetails.find(item => item.product.sku == product.sku);
  487. if (isMatched) {
  488. e.preventDefault();
  489. setShowModal(!showModal);
  490. }
  491. };
  492.  
  493.  
  494. const cartCallToActionText = !isOutOfStock ? (
  495. isStoreUser ? (
  496. <FormattedMessage
  497. id="productFullDetail.addItemToCart1"
  498. defaultMessage="ADD TO CART"
  499. />
  500. ) : (
  501. <FormattedMessage
  502. id="productFullDetail.addItemToCart1"
  503. defaultMessage="BUY NOW"
  504. />
  505. )
  506. ) : (
  507. <FormattedMessage
  508. id="productFullDetail.itemOutOfStock"
  509. defaultMessage="Out of Stock"
  510. />
  511. );
  512.  
  513. const cartActionContent = isSupportedProductType ? (
  514. <button
  515. className={isInvalidPincode ? 'rounded' : 'rounded buy_now_button'}
  516. data-cy="ProductFullDetail-addToCartButton"
  517. disabled={isAddToCartDisabled || isInvalidPincode}
  518. priority="high"
  519. type="submit"
  520. style={
  521. isInvalidPincode
  522. ? {
  523. background: 'rgb(199, 164, 111, 0.5)',
  524. width: '100%',
  525. height: '40px',
  526. color: '#fff',
  527. letterSpacing: 4
  528. }
  529. : {
  530. background:
  531. 'linear-gradient(90deg, #C7A46F 0%, #886C44 100%)',
  532. width: '100%',
  533. height: '40px',
  534. color: '#fff',
  535. letterSpacing: 4
  536. }
  537. }
  538. >
  539. {cartCallToActionText}
  540. </button>
  541. ) : (
  542. <div className={classes.unavailableContainer}>
  543. <Info />
  544. <p>
  545. <FormattedMessage
  546. id={'productFullDetail.unavailableProduct'}
  547. defaultMessage={
  548. 'This product is currently unavailable for purchase.'
  549. }
  550. />
  551. </p>
  552. </div>
  553. );
  554.  
  555. const shortDescription = productDetails.shortDescription ? (
  556. <div className="text-[#656565]"
  557. style={{display:'none'}}>
  558. <RichContent html={productDetails.shortDescription.html}/>
  559. </div>
  560. ) : null;
  561.  
  562. const pageBuilderAttributes = customAttributesDetails.pagebuilder.length ? (
  563. <section className={classes.detailsPageBuilder}>
  564. <CustomAttributes
  565. classes={{ list: classes.detailsPageBuilderList }}
  566. customAttributes={customAttributesDetails.pagebuilder}
  567. showLabels={false}
  568. />
  569. </section>
  570. ) : null;
  571.  
  572. // let selectedProductColorId = null;
  573. // const handleProductSelected = productColorId => {
  574. // setSelectedProductColorId(productColorId);
  575. // };
  576.  
  577. const productDetailsAc = (
  578. <div dangerouslySetInnerHTML={{ __html: product.description || '' }} />
  579. );
  580.  
  581. const [breakDown, setBreakDown] = useState([]);
  582. const [selectedSize, setSelectedSize] = useState(null);
  583. const [selectedColor, setSelectedColor] = useState(null);
  584. const [fireWishListEvent,setFireWishListEvent] = useState(false);
  585.  
  586. const [isCustomizable, setIsCustomizable] = useState(false);
  587.  
  588. const [extraPrice, setExtraPrice] = useState(null);
  589.  
  590. useEffect(() => {
  591. getProductBreakDown();
  592. }, [selectedSize,selectedColor]);
  593.  
  594. const getProductBreakDown = async () => {
  595. try {
  596. const customOptionId = storage.getItem('size_id');
  597. const optionValue = storage.getItem('size');
  598. const ringSize = selectedSize?.title;
  599. const goldColor = selectedColor?.title;
  600. const productVariant = '';
  601. const response = await apiClient.get(
  602. apiClient.Urls.productBreakDown, {
  603. productId: product.id,
  604. customOptionId,
  605. optionValue,
  606. ringSize,
  607. goldColor,
  608. productVariant
  609. }
  610. );
  611.  
  612. if (response.success && response.data) {
  613. setBreakDown(response.data);
  614. }
  615. } catch (error) {
  616. console.log('error', error);
  617. }
  618. };
  619.  
  620. const glow_sku = breakDown ? breakDown?.productDetails?.variant_sku : null;
  621.  
  622. const productPriceBreakdownAc = (
  623. <div>
  624. {breakDown.content &&
  625. breakDown.content.map((i, index) => {
  626. return (
  627. i.variant_type && (
  628. <div
  629. className="flex justify-between p-1"
  630. key={index}
  631. >
  632. <span
  633. className={
  634. classes.nameColumn +
  635. ' font-bold !w-auto'
  636. }
  637. >
  638. {i.variant_type}
  639. </span>
  640. <span>
  641. <CurrencyCodeUI
  642. currencyCode={
  643. productDetails?.price?.currency
  644. }
  645. />
  646. {Math.round(i.variant_price)}
  647. </span>
  648. </div>
  649. )
  650. );
  651. })}
  652. <div className="flex justify-between p-1">
  653. <span className={classes.nameColumn + ' font-bold !w-auto'}>
  654. Value Addition
  655. </span>
  656. <span>
  657. <CurrencyCodeUI
  658. currencyCode={productDetails?.price?.currency}
  659. />{' '}
  660. {Math.round(breakDown.valueAddition)}
  661. </span>
  662. </div>
  663. {
  664. // breakDown && breakDown?.subTotal ? <div className="flex justify-between p-1">
  665. // <span className={classes.nameColumn + ' font-bold !w-auto'}>
  666. // Sub Total
  667. // </span>
  668. // <span>
  669. // <CurrencyCodeUI
  670. // currencyCode={productDetails?.price?.currency}
  671. // />{' '}
  672. // {Math.round(breakDown.subTotal)}
  673. // </span>
  674. // </div> : null
  675. }
  676. {
  677. breakDown && breakDown?.discountAmount ? <div className="flex justify-between p-1">
  678. <span className={classes.nameColumn + ' font-bold !w-auto'}>
  679. Discount Amount
  680. </span>
  681. <span>
  682. {MINUS_SYMBOL}
  683. <CurrencyCodeUI
  684. currencyCode={productDetails?.price?.currency}
  685. />{' '}
  686. {Math.round(breakDown.discountAmount)}
  687. </span>
  688. </div> : null
  689. }
  690. {
  691. // breakDown && breakDown?.netAmount ? <div className="flex justify-between p-1">
  692. // <span className={classes.nameColumn + ' font-bold !w-auto'}>
  693. // Net Amount
  694. // </span>
  695. // <span>
  696. // <CurrencyCodeUI
  697. // currencyCode={productDetails?.price?.currency}
  698. // />{' '}
  699. // {Math.round(breakDown.netAmount)}
  700. // </span>
  701. // </div> : null
  702. }
  703. <div className="flex justify-between p-1">
  704. <span className={classes.nameColumn + ' font-bold !w-auto'}>
  705. Tax
  706. </span>
  707. <span>
  708. <CurrencyCodeUI
  709. currencyCode={productDetails?.price?.currency}
  710. />{' '}
  711. {Math.round(breakDown.tax)}
  712. </span>
  713. </div>
  714. </div>
  715. );
  716.  
  717. const hiddenTags = [
  718. 'setting_type',
  719. 'is_on_sale',
  720. 'ready_to_ship',
  721. 'best_seller',
  722. 'new_launch',
  723. 'make_on_order',
  724. 'design_family',
  725. 'is_outlet_available',
  726. 'is_virtual_try_on'
  727. ];
  728.  
  729. const productCustomAttributeData = (
  730. <div>
  731. <table>
  732. <tbody>
  733. {customAttributes &&
  734. customAttributes.map((i, index) => {
  735. return (
  736. !hiddenTags.includes(
  737. i?.attribute_metadata?.code
  738. ) && (
  739. <tr key={index}>
  740. <td
  741. className={
  742. classes.nameColumn +
  743. ' font-semibold'
  744. }
  745. >
  746. {i?.attribute_metadata?.label}
  747. </td>
  748. <td>
  749. {i?.selected_attribute_options
  750. ?.attribute_option?.length
  751. ? i?.selected_attribute_options?.attribute_option.map(
  752. (j, index) => {
  753. return index ==
  754. i
  755. ?.selected_attribute_options
  756. ?.attribute_option
  757. ?.length -
  758. 1
  759. ? j.label
  760. : j.label + ', ';
  761. }
  762. )
  763. : i?.entered_attribute_value
  764. ?.value
  765. ? i?.entered_attribute_value
  766. ?.value
  767. : ''}
  768. </td>
  769. </tr>
  770. )
  771. );
  772. })}
  773. </tbody>
  774. </table>
  775. </div>
  776. );
  777.  
  778. const disclaimerAc = (
  779. <div>
  780. <p>
  781. Actual product dimensions may vary, please refer to the
  782. dimensions of the product for exact size. Color of the product
  783. may slightly vary from the image. We here by convey that final
  784. prices might vary depending on weight and size. A credit note or
  785. refund will be issued for any Difference value of less amount
  786. and If any access value incurred to be paid by customers. Our
  787. customer care team will inform you on prior before dispatching
  788. the product with complete details.
  789.  
  790. </p>
  791. </div>
  792. );
  793.  
  794. const more_info = (
  795. <div>
  796. <p>
  797. KIRTILAL KALIDAS JEWELLERS PVT LTD
  798. <br/>
  799. ADDRESS: No 11 GN Mills Post, MTP Road, COIMBATORE 6410 29, Tamil Nadu.
  800. <br/><br/>
  801.  
  802. Country of Origin - India
  803. <br/>
  804.  
  805.  
  806.  
  807. Manufacturer & Packer - KIRTILAL KALIDAS JEWELLERS PVT LTD
  808. <br/>
  809.  
  810. ADDRESS: No 11 GN Mills Post, MTP Road, COIMBATORE 6410 29, Tamil Nadu.
  811. <br/><br/>
  812.  
  813.  
  814.  
  815. Net Qty - 1 N
  816. <br/>
  817.  
  818.  
  819.  
  820. contact customer care executive at the manufacturing address above or call us 18001212511 . Email us at [email protected]
  821.  
  822.  
  823.  
  824. </p>
  825. </div>
  826. );
  827.  
  828.  
  829. const facebookShareLink = () => {
  830. const currentUri = encodeURIComponent(window.location.href);
  831. const shareUrl1 = currentUri;
  832. return `https://www.facebook.com/dialog/share?display=popup&href=${shareUrl1}&redirect_uri=${currentUri}`;
  833. };
  834. const whatsappShareLink = () => {
  835. const text = encodeURIComponent(window.location.href);
  836. return `https://api.whatsapp.com/send?text=${text}`;
  837. };
  838.  
  839. const twitterShareLink = () => {
  840. const text = encodeURIComponent(window.location.href);
  841. return `https://twitter.com/intent/tweet?text=${text}`;
  842. };
  843.  
  844. const emailShareLink = () => {
  845. const text = encodeURIComponent(shareContent);
  846. const subject = encodeURIComponent(shareTitle);
  847. return `mailto:?body=${text}&subject=${subject}`;
  848. };
  849.  
  850. const [earnedPoints, setEarnedPoints] = useState(null);
  851.  
  852. useEffect(() => {
  853. getEarnedPoints();
  854. }, []);
  855.  
  856. const [isDefaultProduct, setDefaultProduct] = useState(true);
  857.  
  858. const getEarnedPoints = async () => {
  859. const customOptionId = storage.getItem('size_id');
  860. const optionValue = storage.getItem('size');
  861. try {
  862. const response = await apiClient.post(apiClient.Urls.getPoints, {
  863. params: {
  864. sku: product.sku,
  865. customOptionId: customOptionId,
  866. optionValue: optionValue
  867. }
  868. });
  869.  
  870. if (response.success) {
  871. setEarnedPoints(response.points);
  872. }
  873. } catch (error) {
  874. console.log('error', error);
  875. }
  876. };
  877.  
  878. var isMatched = cartDetails && cartDetails.find(item => item.product.sku == product.sku);
  879.  
  880. return (
  881. <Fragment>
  882. {!isMobile && breadcrumbs}
  883. <Form
  884. className={classes.root}
  885. style={{ paddingTop: 0 }}
  886. data-cy="ProductFullDetail-root"
  887. onSubmit={(...args) => {
  888. // if (userInfo == null || userInfo?.userName == '') {
  889. // setPopupModal(true);
  890. // }
  891. // else {
  892. const handler = isCustomizable
  893. ? handleCustomizableProductToCart
  894. : handleAddToCart;
  895. return popUpModal ? null : handler(...args);
  896. // }
  897. }
  898. }
  899. >
  900. {
  901. popUpModal || userInfo?.userName == '' ? <UserDetails
  902. popUpModal={popUpModal}
  903. setPopupModal={setPopupModal}
  904. history={history}
  905. onSubmit={(...args) => {
  906. const handler = isCustomizable
  907. ? handleCustomizableProductToCart
  908. : handleAddToCart;
  909. return handler(...args)
  910. }}
  911. /> : null
  912. }
  913.  
  914. <SimilarProduct
  915. showModal={showModal}
  916. handleAddToCart={
  917. isCustomizable
  918. ? handleCustomizableProductToCart
  919. : handleAddToCart
  920. }
  921. setShowModal={setShowModal}
  922. handleCloseModal={handleCloseModal}
  923. />
  924.  
  925. <section className={classes.imageCarousel + ' max-w-[640px]'}>
  926. <ProductTags product={product} page={'PDP'} />
  927. <Carousel
  928. images={mediaGalleryEntries}
  929. item={product}
  930. isVirtualTryOn={isVirtualTryOn}
  931. selectedColor={selectedColor}
  932. />
  933. </section>
  934. <div
  935. className={
  936. classes.productDesc +
  937. ' overflow-y-scroll overflow-x-auto'
  938. }
  939. >
  940. <section
  941. className={classes.title}
  942. style={{ paddingTop: 0 }}
  943. >
  944. <div className="relative">
  945. <p className="flex justify-between text-[12px] text-[#939BA5] uppercase">
  946. SKU {glow_sku}
  947. <input type="hidden" name="productid" value={product.id} />
  948. </p>
  949. {earnedPoints ? (
  950. <h3 className="bg-[#363636] product_points">
  951. <span className="selected_product">
  952. Buy this & earn upto
  953. </span>
  954. <span className="points_section">
  955. {earnedPoints}
  956. </span>
  957. points
  958. </h3>
  959. ) : (
  960. <div className="min-h-[50px]" />
  961. )}
  962. <div className="flex">
  963. <h1
  964. aria-live="polite"
  965. className={
  966. classes.productName +
  967. ' text-[22px] font-ivyModeRegular'
  968. }
  969. data-cy="ProductFullDetail-productName"
  970. >
  971. {productDetails.name}
  972. </h1>
  973.  
  974. <div className="flex absolute top-[30px] right-0">
  975. <Suspense fallback={null}>
  976. <div
  977. className="flex items-center relative">
  978. <div
  979. onClick={() =>
  980. setShowShare(!showShare)
  981. }
  982. className="cursor-pointer"
  983. >
  984. <img
  985. src={shareIcon}
  986. class="mr-[20px]"
  987. alt="Share Icon"
  988. />
  989. </div>
  990. {showShare && (
  991. <div onMouseLeave={()=>setShowShare(false)} className="rounded-[6px] absolute bg-[#fff] border-[#C1A87E] border-[1px] flex flex-col right-[10px] top-[25px]">
  992. <a
  993. href={facebookShareLink()}
  994. target="blank"
  995. title="Share on Facebook"
  996. class="flex px-4 py-2 text-sm text-gray-800 border-b hover:bg-blue-100"
  997. >
  998. <svg
  999. aria-hidden="true"
  1000. focusable="false"
  1001. data-prefix="fab"
  1002. data-icon="facebook-messenger"
  1003. class="w-5 h-5 mr-4 text-[#227aff]"
  1004. role="img"
  1005. xmlns="http://www.w3.org/2000/svg"
  1006. viewBox="0 0 512 512"
  1007. >
  1008. <path
  1009. fill="currentColor"
  1010. d="M256.55 8C116.52 8 8 110.34 8 248.57c0 72.3 29.71 134.78 78.07 177.94 8.35 7.51 6.63 11.86 8.05 58.23A19.92 19.92 0 0 0 122 502.31c52.91-23.3 53.59-25.14 62.56-22.7C337.85 521.8 504 423.7 504 248.57 504 110.34 396.59 8 256.55 8zm149.24 185.13l-73 115.57a37.37 37.37 0 0 1-53.91 9.93l-58.08-43.47a15 15 0 0 0-18 0l-78.37 59.44c-10.46 7.93-24.16-4.6-17.11-15.67l73-115.57a37.36 37.36 0 0 1 53.91-9.93l58.06 43.46a15 15 0 0 0 18 0l78.41-59.38c10.44-7.98 24.14 4.54 17.09 15.62z"
  1011. />
  1012. </svg>
  1013. <span class="text-gray-600">
  1014. Facebook
  1015. </span>
  1016. </a>
  1017. <a
  1018. href={twitterShareLink()}
  1019. target="blank"
  1020. title="Share on Twitter"
  1021. class="flex px-4 py-2 text-sm text-gray-800 border-b hover:bg-blue-100"
  1022. >
  1023. <svg
  1024. aria-hidden="true"
  1025. focusable="false"
  1026. data-prefix="fab"
  1027. data-icon="twitter-square"
  1028. class="w-5 h-5 mr-4 text-[#329bff]"
  1029. role="img"
  1030. xmlns="http://www.w3.org/2000/svg"
  1031. viewBox="0 0 448 512"
  1032. >
  1033. <path
  1034. fill="currentColor"
  1035. d="M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-48.9 158.8c.2 2.8.2 5.7.2 8.5 0 86.7-66 186.6-186.6 186.6-37.2 0-71.7-10.8-100.7-29.4 5.3.6 10.4.8 15.8.8 30.7 0 58.9-10.4 81.4-28-28.8-.6-53-19.5-61.3-45.5 10.1 1.5 19.2 1.5 29.6-1.2-30-6.1-52.5-32.5-52.5-64.4v-.8c8.7 4.9 18.9 7.9 29.6 8.3a65.447 65.447 0 0 1-29.2-54.6c0-12.2 3.2-23.4 8.9-33.1 32.3 39.8 80.8 65.8 135.2 68.6-9.3-44.5 24-80.6 64-80.6 18.9 0 35.9 7.9 47.9 20.7 14.8-2.8 29-8.3 41.6-15.8-4.9 15.2-15.2 28-28.8 36.1 13.2-1.4 26-5.1 37.8-10.2-8.9 13.1-20.1 24.7-32.9 34z"
  1036. />
  1037. </svg>
  1038. <span class="text-gray-600">
  1039. Twitter
  1040. </span>
  1041. </a>
  1042. <a
  1043. href={whatsappShareLink()}
  1044. target="blank"
  1045. title="Share on Whatsapp"
  1046. class="flex px-4 py-2 text-sm text-gray-800 border-b hover:bg-blue-100"
  1047. >
  1048. <svg
  1049. xmlns="http://www.w3.org/2000/svg"
  1050. width="16"
  1051. height="16"
  1052. class="w-5 h-5 mr-4 text-[#25D366] bi bi-whatsapp"
  1053. fill="currentColor"
  1054. viewBox="0 0 16 16"
  1055. >
  1056. <path d="M13.601 2.326A7.854 7.854 0 0 0 7.994 0C3.627 0 .068 3.558.064 7.926c0 1.399.366 2.76 1.057 3.965L0 16l4.204-1.102a7.933 7.933 0 0 0 3.79.965h.004c4.368 0 7.926-3.558 7.93-7.93A7.898 7.898 0 0 0 13.6 2.326zM7.994 14.521a6.573 6.573 0 0 1-3.356-.92l-.24-.144-2.494.654.666-2.433-.156-.251a6.56 6.56 0 0 1-1.007-3.505c0-3.626 2.957-6.584 6.591-6.584a6.56 6.56 0 0 1 4.66 1.931 6.557 6.557 0 0 1 1.928 4.66c-.004 3.639-2.961 6.592-6.592 6.592zm3.615-4.934c-.197-.099-1.17-.578-1.353-.646-.182-.065-.315-.099-.445.099-.133.197-.513.646-.627.775-.114.133-.232.148-.43.05-.197-.1-.836-.308-1.592-.985-.59-.525-.985-1.175-1.103-1.372-.114-.198-.011-.304.088-.403.087-.088.197-.232.296-.346.1-.114.133-.198.198-.33.065-.134.034-.248-.015-.347-.05-.099-.445-1.076-.612-1.47-.16-.389-.323-.335-.445-.34-.114-.007-.247-.007-.38-.007a.729.729 0 0 0-.529.247c-.182.198-.691.677-.691 1.654 0 .977.71 1.916.81 2.049.098.133 1.394 2.132 3.383 2.992.47.205.84.326 1.129.418.475.152.904.129 1.246.08.38-.058 1.171-.48 1.338-.943.164-.464.164-.86.114-.943-.049-.084-.182-.133-.38-.232z" />{' '}
  1057. </svg>
  1058. <span class="text-gray-600">
  1059. Whatsapp
  1060. </span>
  1061. </a>
  1062. </div>
  1063. )}
  1064. </div>
  1065.  
  1066.  
  1067. </Suspense>
  1068. </div>
  1069. </div>
  1070.  
  1071. </div>
  1072. {/* <div>
  1073. <img
  1074. src={reviewsIcon}
  1075. className="mr-3"
  1076. alt="Reviews icon"
  1077. />
  1078. <p className="text-xs">102 Reviews</p>
  1079. </div> */}
  1080. <div className="flex items-end mt-[15px]">
  1081. <p
  1082. data-cy="ProductFullDetail-productPrice"
  1083. className={
  1084. classes.productPrice +
  1085. ' text-[22px] font-bold'
  1086. }
  1087. >
  1088. <Price
  1089. currencyCode={productDetails.price.currency}
  1090. value={
  1091. productDetails.price.value +
  1092. extraPrice -
  1093. (discountPercent
  1094. ? extraPrice / discountPercent
  1095. : 0)
  1096. }
  1097. />
  1098. </p>
  1099. {regularPrice.value !==
  1100. productDetails.price.value ? (
  1101. <s
  1102. data-cy="ProductFullDetail-productPrice"
  1103. className={
  1104. classes.productPrice +
  1105. ' text-xs py-1 ml-1 text-[#35383A] font-bold'
  1106. }
  1107. >
  1108. <Price
  1109. currencyCode={regularPrice.currency}
  1110. value={regularPrice.value + extraPrice}
  1111. />
  1112.  
  1113. </s>
  1114.  
  1115. ) : null}
  1116. <br/>
  1117. <span className="mrp-legal">MRP Inclusive of all taxes.</span>
  1118. </div>
  1119. {shortDescription}
  1120. <CustomizableOptions
  1121. setExtraPrice={setExtraPrice}
  1122. sku={product.sku}
  1123. setIsCustomizable={setIsCustomizable}
  1124. customAttributes={customAttributes}
  1125. setDefaultProduct={setDefaultProduct}
  1126. checkDeliveryDate={checkDeliveryDate}
  1127. setSelectedSize={setSelectedSize}
  1128. setSelectedColor={setSelectedColor}
  1129. getEarnedPoints={getEarnedPoints}
  1130. />
  1131. <div className="max-w-[392px] mt-[10px] ">
  1132. <div
  1133. getApi={setFormApi}
  1134. className={
  1135. 'border-[#e1e6eb] border-[1px] flex justify-between px-2 items-center'
  1136. }
  1137. >
  1138. <input
  1139. autoComplete="pincode"
  1140. field="pincode"
  1141. id="pincode"
  1142. className="h-[40px] px-[10px] text-[14px] focus:border-none"
  1143. value={pincode}
  1144. placeholder="Enter Pin Code"
  1145. onChange={e => {
  1146. storage.setItem(
  1147. 'pin_code',
  1148. e.target.value,
  1149. null
  1150. );
  1151. handlePincode(e.target.value);
  1152. }}
  1153. />
  1154. <LinkButton
  1155. data-cy="Newsletter-submitButton"
  1156. className={
  1157. ' max-h-[35px] py-2 focus:outline-none'
  1158. }
  1159. // type="submit"
  1160. disabled={isBusy}
  1161. // onClick={clearErrors}
  1162. onClick={() =>
  1163. checkDeliveryDate(productDetails.sku)
  1164. }
  1165. >
  1166. <ChevronRight
  1167. size={20}
  1168. className="rounded-full border border-[#C77F44] text-[#C77F44]"
  1169. />
  1170. </LinkButton>
  1171. </div>
  1172. <p>{deliveryDate}</p>
  1173. </div>
  1174. <p className="text-sm flex items-center my-[20px]">
  1175. <span className="mr-[5px]">Need help ?</span>
  1176. <a
  1177. href={"https://wa.me/+91" + `${whatsappNumber?.mapping_value}`}
  1178. target={'_blank'}
  1179. data-cy="ScheduleAppointment-link"
  1180. className="flex items-center"
  1181. >
  1182. <span className="flex text-[#C77F44] text-xs cursor-pointer tracking-[1.2px] mr-[5px]">
  1183. CHAT WITH US ON WHATSAPP
  1184. </span>
  1185. <img
  1186. src={whatsapp}
  1187. alt="whatsapp_icon"
  1188. className="w-[20px] h-[20px]"
  1189. />
  1190. {/* <svg
  1191. aria-hidden="true"
  1192. focusable="false"
  1193. data-prefix="fab"
  1194. data-icon="linkedin"
  1195. class="w-5 h-5 mr-4 text-[#C77F44]"
  1196. role="img"
  1197. xmlns="http://www.w3.org/2000/svg"
  1198. viewBox="0 0 32 32"
  1199. >
  1200. <path
  1201. d=" M19.11 17.205c-.372 0-1.088 1.39-1.518 1.39a.63.63 0 0 1-.315-.1c-.802-.402-1.504-.817-2.163-1.447-.545-.516-1.146-1.29-1.46-1.963a.426.426 0 0 1-.073-.215c0-.33.99-.945.99-1.49 0-.143-.73-2.09-.832-2.335-.143-.372-.214-.487-.6-.487-.187 0-.36-.043-.53-.043-.302 0-.53.115-.746.315-.688.645-1.032 1.318-1.06 2.264v.114c-.015.99.472 1.977 1.017 2.78 1.23 1.82 2.506 3.41 4.554 4.34.616.287 2.035.888 2.722.888.817 0 2.15-.515 2.478-1.318.13-.33.244-.73.244-1.088 0-.058 0-.144-.03-.215-.1-.172-2.434-1.39-2.678-1.39zm-2.908 7.593c-1.747 0-3.48-.53-4.942-1.49L7.793 24.41l1.132-3.337a8.955 8.955 0 0 1-1.72-5.272c0-4.955 4.04-8.995 8.997-8.995S25.2 10.845 25.2 15.8c0 4.958-4.04 8.998-8.998 8.998zm0-19.798c-5.96 0-10.8 4.842-10.8 10.8 0 1.964.53 3.898 1.546 5.574L5 27.176l5.974-1.92a10.807 10.807 0 0 0 16.03-9.455c0-5.958-4.842-10.8-10.802-10.8z"
  1202. fill-rule="evenodd"
  1203. />
  1204. </svg> */}
  1205. </a>
  1206. </p>
  1207. {readyToShip && isDefaultProduct && (
  1208. <div className="flex text-sm mt-[15px]">
  1209. <div className="flex w-1/2 gap-2">
  1210. <img src={timeIcon} alt="Time Icon" />
  1211. <span className="text-xs uppercase tracking-[1.2px]">
  1212. {' '}
  1213. Ready to ship
  1214. </span>
  1215. </div>
  1216. <div className="flex gap-2 w-1/2">
  1217. <div
  1218. data-cy="ScheduleAppointment-link"
  1219. onClick={() => {
  1220. const element = document.getElementById(
  1221. 'try-at-store'
  1222. );
  1223. if (element) {
  1224. element.scrollIntoView({
  1225. behavior: 'smooth'
  1226. });
  1227. }
  1228. }}
  1229. >
  1230. <span className="text-[#C77F44] text-xs uppercase cursor-pointer tracking-[1.2px]">
  1231. Find in store
  1232. </span>
  1233. </div>
  1234. </div>
  1235. </div>
  1236. )}
  1237. </section>
  1238. <FormError
  1239. classes={{
  1240. root: classes.formErrors
  1241. }}
  1242. errors={errors.get('form') || []}
  1243. />
  1244. <section className={classes.options}>{options}</section>
  1245. <section className={classes.quantity + ' hidden'}>
  1246. <span
  1247. data-cy="ProductFullDetail-quantityTitle"
  1248. className={classes.quantityTitle}
  1249. >
  1250. <FormattedMessage
  1251. id={'global.quantity'}
  1252. defaultMessage={'Quantity'}
  1253. />
  1254. </span>
  1255. <QuantityStepper
  1256. classes={{ root: classes.quantityRoot }}
  1257. min={1}
  1258. message={errors.get('quantity')}
  1259. />
  1260. </section>
  1261. <section
  1262. className={classes.actions}
  1263. style={{ paddingTop: 0 }}
  1264. >
  1265. {!isMobile && (
  1266. <div
  1267. className="lg_pr-[74px]"
  1268. // onClick={(e) => {
  1269. // if (userInfo?.userName != '') {
  1270. // if (isMatched) {
  1271. // e.preventDefault();
  1272. // setShowModal(!showModal);
  1273. // }
  1274. // }
  1275. // }}
  1276. >
  1277. {cartActionContent}
  1278.  
  1279. <Suspense fallback={null}>
  1280. <WishlistButton {...wishlistButtonProps} />
  1281. </Suspense>
  1282.  
  1283. </div>
  1284. )}
  1285. {/* <p className="text-sm mt-2.5">
  1286. Want a get Notification on a{' '}
  1287. <span className="font-bold text-sm">
  1288. Price drop
  1289. </span>{' '}
  1290. <span className="text-[#C77F44] text-xs">
  1291. NOTIFY ME
  1292. </span>
  1293. </p> */}
  1294. <div className={classes.dropdownBlock}>
  1295. <DropdownBlock
  1296. name="Product Details"
  1297. content={
  1298. <ProductDetailsBlock
  1299. selectedSize={selectedSize}
  1300. selectedColor={selectedColor}
  1301. classes={classes}
  1302. customAttributes={customAttributes}
  1303. breakDown={breakDown}
  1304. productDetails={breakDown?.productDetails}
  1305. />
  1306. }
  1307. />
  1308. <DropdownBlock
  1309. name="Product Story"
  1310. content={productDetailsAc}
  1311. />
  1312. {breakDown.content ? (
  1313. <DropdownBlock
  1314. name="Product Price / Breakdown"
  1315. content={productPriceBreakdownAc}
  1316. />
  1317. ) : null}
  1318. <DropdownBlock
  1319. name="Disclaimers"
  1320. content={disclaimerAc}
  1321. />
  1322. <DropdownBlock
  1323. name="More Information"
  1324. content={more_info}
  1325. />
  1326. </div>
  1327. </section>
  1328. </div>
  1329. {isMobile && (
  1330. <div className={classes.cartActionButton}
  1331. // onClick={(e) => {
  1332. // if (userInfo?.userName != '') {
  1333. // if (isMatched) {
  1334. // e.preventDefault();
  1335. // setShowModal(!showModal);
  1336. // }
  1337. // }
  1338. // }}
  1339. >
  1340. <div className="px-3 h-[46px] m-auto w-full">
  1341. {cartActionContent}
  1342. <Suspense fallback={null}>
  1343. <WishlistButton {...wishlistButtonProps} />
  1344. </Suspense>
  1345. </div>
  1346. </div>
  1347. )}
  1348. {pageBuilderAttributes}
  1349. </Form>
  1350.  
  1351. <div className={`transition-all duration-1000 z-[100] bg-green-500 text-white px-4 py-2 fixed ${showPopup ? "top-0":"-top-full"} left-0 right-0 text-center`}>
  1352. Success!! Our team will promptly reach out to you to arrange a scheduled call
  1353. </div>
  1354. {openScheduleModel &&
  1355. <div className={`fixed inset-0 flex items-center justify-center z-50 `}>
  1356. <div className="fixed inset-0 bg-black opacity-50"></div>
  1357. <div className="relative bg-white p-8 rounded-lg max-w-md w-full">
  1358. <span className="absolute top-0 right-0 cursor-pointer text-gray-600 hover:text-gray-800 mr-2 text-xl" onClick={() => setOpenScheduleModel(false)}>&times;</span>
  1359. <h2 className="text-xl font-bold text-gray-800 mb-4">Schedule A Video Call</h2>
  1360. <form onSubmit={scheduleCall} className="space-y-4">
  1361. <div>
  1362. <label className="block text-gray-700" htmlFor="name">Name:</label>
  1363. <input className="form-input w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:border-blue-500" type="text" id="name" name="name" value={userName} onChange={handleChange} required />
  1364. </div>
  1365. <div>
  1366. <label className="block text-gray-700" htmlFor="phone">Phone Number:</label>
  1367. <input className="form-input w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:border-blue-500" type="text" id="phone" name="phone" value={phoneNumber} onChange={handleChange} required />
  1368. </div>
  1369. <div>
  1370. <label className="block text-gray-700" htmlFor="slotDate">Slot Date:</label>
  1371. <input className="relative form-input w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:border-blue-500" type="datetime-local" id="slotDate" name="slotDate" value={slotDate} onChange={handleChange} required />
  1372. </div>
  1373. <div className="flex justify-end">
  1374. <button
  1375. className="rounded buy_now_button" style={{
  1376. background:
  1377. 'linear-gradient(90deg, #C7A46F 0%, #886C44 100%)',
  1378. width: '100%',
  1379. height: '40px',
  1380. color: '#fff',
  1381. letterSpacing: 4,
  1382. textTransform: 'uppercase'
  1383. }} type="submit">Submit</button>
  1384. </div>
  1385. </form>
  1386. </div>
  1387. </div>
  1388. }
  1389.  
  1390.  
  1391. <div className="flex pb-[2rem] justify-center mt-10">
  1392. {crossSellProducts && crossSellProducts.length > 0 && (
  1393. <div className="w-[100%] bg-[#F7F2EC] rounded-lg">
  1394. <CompleteLook
  1395. wishlistButtonProps={wishlistButtonProps}
  1396. productDetails={productDetails}
  1397. products={crossSellProducts}
  1398. />
  1399. </div>
  1400. )}
  1401. </div>
  1402. <ForeverGlow />
  1403. <div className="flex justify-center">
  1404. {/* <Promise /> */}
  1405.  
  1406. <GlowPromise />
  1407. </div>
  1408.  
  1409. {designFamilyValue && parentCategoryId ? (
  1410. <RelatedProducts
  1411. df_id={designFamilyValue}
  1412. category_id={parentCategoryId}
  1413. current={product.sku}
  1414. />
  1415. ) : null}
  1416. <div id="try-at-store">
  1417. <TryAtHomeSection
  1418. sku={product.sku}
  1419. tryProductConfiguration={tryProductConfiguration}
  1420. openScheduleModel={openScheduleModel}
  1421. setOpenScheduleModel={setOpenScheduleModel}
  1422. pincode={pincode}
  1423. handlePincode={handlePincode}
  1424. />
  1425. </div>
  1426.  
  1427. {/* <div className="flex p-[1rem] justify-center mt-10">
  1428. <div className="w-[100%]">
  1429. <TrustedPartners />
  1430. </div>
  1431. </div> */}
  1432. {/* <div className="flex justify-center mt-10">
  1433. <div className="text-center">
  1434. <h1 className="text-[42px] text-[#774E4F] font-medium font-ivyModeRegular">
  1435. Watch How It is Designed
  1436. </h1>
  1437. <p className="text-sm text-[#181A1D]">
  1438. Lorem ipsum dolor sit amet, consetetur sadipscing
  1439. </p>
  1440. </div>
  1441. </div> */}
  1442. {/* <div className="flex justify-center p-[1rem]">
  1443. <div className="w-[100%] h-[600px] border-2 border-solid bg-[#F7F2EC]">
  1444. <iframe
  1445. width="100%"
  1446. height="100%"
  1447. src="https://www.youtube.com/embed/J-N4qrH6Lgk"
  1448. title="Making of a Masterpiece"
  1449. frameborder="0"
  1450. allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
  1451. allowfullscreen
  1452. />
  1453. </div>
  1454. </div> */}
  1455. <TrendingProducts />
  1456.  
  1457. <ShopPdpCategory />
  1458. </Fragment>
  1459. );
  1460. };
  1461.  
  1462. ProductFullDetail.propTypes = {
  1463. classes: shape({
  1464. cartActions: string,
  1465. description: string,
  1466. descriptionTitle: string,
  1467. details: string,
  1468. detailsPageBuilder: string,
  1469. detailsPageBuilderList: string,
  1470. detailsTitle: string,
  1471. imageCarousel: string,
  1472. options: string,
  1473. productName: string,
  1474. productPrice: string,
  1475. quantity: string,
  1476. quantityTitle: string,
  1477. quantityRoot: string,
  1478. root: string,
  1479. title: string,
  1480. unavailableContainer: string
  1481. }),
  1482. product: shape({
  1483. __typename: string,
  1484. id: number,
  1485. stock_status: string,
  1486. sku: string.isRequired,
  1487. price: shape({
  1488. regularPrice: shape({
  1489. amount: shape({
  1490. currency: string.isRequired,
  1491. value: number.isRequired
  1492. })
  1493. }).isRequired
  1494. }).isRequired,
  1495. media_gallery_entries: arrayOf(
  1496. shape({
  1497. uid: string,
  1498. label: string,
  1499. position: number,
  1500. disabled: bool,
  1501. file: string.isRequired
  1502. })
  1503. ),
  1504. description: string,
  1505. short_description: shape({
  1506. html: string,
  1507. __typename: string
  1508. })
  1509. }).isRequired
  1510. };
  1511.  
  1512. //fbq('track', 'ViewContent');
  1513.  
  1514.  
  1515. fbq('track','ViewContent', {
  1516. 'name': product?.name
  1517. });
  1518.  
  1519. export default ProductFullDetail;
  1520.  
Advertisement
Add Comment
Please, Sign In to add comment