diff options
Diffstat (limited to 'src/lib/product/components/ProductDesktop.jsx')
| -rw-r--r-- | src/lib/product/components/ProductDesktop.jsx | 123 |
1 files changed, 105 insertions, 18 deletions
diff --git a/src/lib/product/components/ProductDesktop.jsx b/src/lib/product/components/ProductDesktop.jsx index dc733eac..6eba2aed 100644 --- a/src/lib/product/components/ProductDesktop.jsx +++ b/src/lib/product/components/ProductDesktop.jsx @@ -3,14 +3,17 @@ import Link from '@/core/components/elements/Link/Link' import DesktopView from '@/core/components/views/DesktopView' import currencyFormat from '@/core/utils/currencyFormat' import { HeartIcon } from '@heroicons/react/24/outline' -import { useEffect, useState } from 'react' +import { Fragment, useEffect, useRef, useState } from 'react' +import LazyLoad from 'react-lazy-load' +import ProductSimilar from './ProductSimilar' const ProductDesktop = ({ product, wishlist, toggleWishlist }) => { const [variantQuantity, setVariantQuantity] = useState(null) + const [informationTab, setInformationTab] = useState(informationTabOptions[0].value) useEffect(() => { const mapVariantQuantity = product.variants.reduce((acc, cur) => { - acc[cur.id] = 1 + acc[cur.id] = '1' return acc }, {}) setVariantQuantity(mapVariantQuantity) @@ -20,6 +23,23 @@ const ProductDesktop = ({ product, wishlist, toggleWishlist }) => { setVariantQuantity((variantQuantity) => ({ ...variantQuantity, [variantId]: quantity })) } + const variantSectionRef = useRef(null) + const goToVariantSection = () => { + if (variantSectionRef.current) { + const position = variantSectionRef.current.getBoundingClientRect() + window.scrollTo({ + top: position.top - 120 + window.pageYOffset, + behavior: 'smooth' + }) + } + } + + const productSimilarQuery = [ + product?.name.replace(/[()/"&]/g, ''), + `fq=-product_id:${product.id}`, + `fq=-manufacture_id:${product.manufacture?.id || 0}` + ].join('&') + return ( <DesktopView> <div className='container mx-auto mt-10'> @@ -32,18 +52,18 @@ const ProductDesktop = ({ product, wishlist, toggleWishlist }) => { /> </div> <div className='w-6/12 px-4'> - <h1 className='text-title-md leading-8 font-medium'>{product?.name}</h1> - <div className='mt-6 flex flex-col gap-y-4'> - <div className='flex'> - <div className='w-1/4 text-gray_r-12/60'>Nomor SKU</div> + <h1 className='text-title-md leading-10 font-medium'>{product?.name}</h1> + <div className='mt-10'> + <div className='flex p-3'> + <div className='w-1/4 text-gray_r-12/70'>Nomor SKU</div> <div className='w-3/4'>SKU-{product.id}</div> </div> - <div className='flex'> - <div className='w-1/4 text-gray_r-12/60'>Part Number</div> + <div className='flex p-3 bg-gray_r-4'> + <div className='w-1/4 text-gray_r-12/70'>Part Number</div> <div className='w-3/4'>{product.code || '-'}</div> </div> - <div className='flex'> - <div className='w-1/4 text-gray_r-12/60'>Manufacture</div> + <div className='flex p-3'> + <div className='w-1/4 text-gray_r-12/70'>Manufacture</div> <div className='w-3/4'> {product.manufacture?.name ? ( <Link href='/'>{product.manufacture?.name}</Link> @@ -52,8 +72,8 @@ const ProductDesktop = ({ product, wishlist, toggleWishlist }) => { )} </div> </div> - <div className='flex'> - <div className='w-1/4 text-gray_r-12/60'>Berat Barang</div> + <div className='flex p-3 bg-gray_r-4'> + <div className='w-1/4 text-gray_r-12/70'>Berat Barang</div> <div className='w-3/4'> {product?.weight > 0 && <span>{product?.weight} KG</span>} {product?.weight == 0 && ( @@ -65,6 +85,7 @@ const ProductDesktop = ({ product, wishlist, toggleWishlist }) => { </div> </div> </div> + <div className='w-3/12'> {product.variants.length > 1 && product.lowestPrice.priceDiscount > 0 && ( <div className='text-gray_r-12/80'>Harga mulai dari: </div> @@ -79,7 +100,7 @@ const ProductDesktop = ({ product, wishlist, toggleWishlist }) => { </div> </div> )} - <h3 className='text-red_r-11 font-semibold mt-1 text-title-lg'> + <h3 className='text-red_r-11 font-semibold mt-1 text-title-md'> {product?.lowestPrice.priceDiscount > 0 ? ( currencyFormat(product?.lowestPrice.priceDiscount) ) : ( @@ -91,7 +112,11 @@ const ProductDesktop = ({ product, wishlist, toggleWishlist }) => { </span> )} </h3> - <button type='button' className='btn-solid-red w-full mt-6'> + <button + type='button' + onClick={goToVariantSection} + className='btn-solid-red w-full mt-6' + > Lihat Varian </button> @@ -108,13 +133,13 @@ const ProductDesktop = ({ product, wishlist, toggleWishlist }) => { </div> </div> - <div className='mt-12'> + <div className='mt-12' ref={variantSectionRef}> <div className='text-h-lg font-semibold mb-6'>Varian Produk</div> <div className='table-specification'> <table> <thead> <tr> - <th>No. SKU</th> + <th>Part Number</th> <th>Harga</th> <th>Jumlah</th> <th>Action</th> @@ -137,8 +162,8 @@ const ProductDesktop = ({ product, wishlist, toggleWishlist }) => { <td> <input type='number' - className='form-input w-16 text-center' - value={variantQuantity[variant.id]} + className='form-input w-16 py-2 text-center bg-gray_r-1' + value={variantQuantity?.[variant.id]} onChange={(e) => changeQuantity(variant.id, e.target.value)} /> </td> @@ -152,9 +177,71 @@ const ProductDesktop = ({ product, wishlist, toggleWishlist }) => { </table> </div> </div> + + <div className='mt-12'> + <div className='text-h-lg font-semibold'>Informasi Produk</div> + <div className='my-5 h-0.5 bg-gray_r-6' /> + <div className='flex gap-x-4 mb-5'> + {informationTabOptions.map((option) => ( + <TabButton + value={option.value} + key={option.value} + active={informationTab == option.value} + onClick={() => setInformationTab(option.value)} + > + {option.label} + </TabButton> + ))} + </div> + <div className='flex rounded'> + <TabContent active={informationTab == 'description'}> + <div className='w-3/4 leading-7 product__description'> + <span + dangerouslySetInnerHTML={{ + __html: + product.description != '' + ? product.description + : 'Belum ada deskripsi produk.' + }} + /> + </div> + </TabContent> + + <TabContent active={informationTab == 'information'}>Belum ada informasi.</TabContent> + </div> + </div> + + <div className='mt-12'> + <div className='text-h-lg font-semibold mb-6'>Kamu Mungkin Juga Suka</div> + <LazyLoad> + <ProductSimilar query={productSimilarQuery} /> + </LazyLoad> + </div> </div> </DesktopView> ) } +const informationTabOptions = [ + { value: 'description', label: 'Deskripsi' }, + { value: 'information', label: 'Info Penting' } +] + +const TabButton = ({ children, active, ...props }) => { + const activeClassName = active + ? 'text-red_r-11 underline underline-offset-4' + : 'text-gray_r-12/80' + return ( + <button {...props} type='button' className={`font-medium ${activeClassName}`}> + {children} + </button> + ) +} + +const TabContent = ({ children, active, className, ...props }) => ( + <div {...props} className={`${active ? 'block' : 'hidden'} ${className}`}> + {children} + </div> +) + export default ProductDesktop |
