diff options
| author | IT Fixcomart <it@fixcomart.co.id> | 2024-01-04 03:07:56 +0000 |
|---|---|---|
| committer | IT Fixcomart <it@fixcomart.co.id> | 2024-01-04 03:07:56 +0000 |
| commit | 0d33de3744f612262c12d648cd7147a2ef238a36 (patch) | |
| tree | 285af0ed69169621228e252affdac958f016dab2 /src/lib/product/components/Product/ProductDesktop.jsx | |
| parent | bb8ee26d89842b4f9b99b48f2a7cc464c6ecc4ee (diff) | |
| parent | 67398e6f10d6f7729d8f1ace7005ef13d32c5ddd (diff) | |
Merged in Feature/promotion-program (pull request #124)
Feature/promotion program
Diffstat (limited to 'src/lib/product/components/Product/ProductDesktop.jsx')
| -rw-r--r-- | src/lib/product/components/Product/ProductDesktop.jsx | 763 |
1 files changed, 432 insertions, 331 deletions
diff --git a/src/lib/product/components/Product/ProductDesktop.jsx b/src/lib/product/components/Product/ProductDesktop.jsx index 5f034c09..4074f243 100644 --- a/src/lib/product/components/Product/ProductDesktop.jsx +++ b/src/lib/product/components/Product/ProductDesktop.jsx @@ -1,416 +1,441 @@ -import Image from '@/core/components/elements/Image/Image' -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 { useCallback, useEffect, useRef, useState } from 'react' -import LazyLoad from 'react-lazy-load' -import ProductSimilar from '../ProductSimilar' -import { toast } from 'react-hot-toast' -import { updateItemCart } from '@/core/utils/cart' -import { useRouter } from 'next/router' -import { createSlug } from '@/core/utils/slug' -import BottomPopup from '@/core/components/elements/Popup/BottomPopup' -import ProductCard from '../ProductCard' -import productSimilarApi from '../../api/productSimilarApi' -import whatsappUrl from '@/core/utils/whatsappUrl' -import odooApi from '@/core/api/odooApi' -import PromotionType from '@/lib/promotinProgram/components/PromotionType' -import useAuth from '@/core/hooks/useAuth' -import ImageNext from 'next/image' -import CountDown2 from '@/core/components/elements/CountDown/CountDown2' -import { LazyLoadComponent } from 'react-lazy-load-image-component' -import ColumnsSLA from './ColumnsSLA' -import { useProductCartContext } from '@/contexts/ProductCartContext' -import { Box, Skeleton, Tooltip } from '@chakra-ui/react' -import { Info } from 'lucide-react' -import Breadcrumb from './Breadcrumb' -import { sellingProductFormat } from '@/core/utils/formatValue' +import { useEffect, useRef, useState } from 'react'; +import ImageNext from 'next/image'; +import { LazyLoadComponent } from 'react-lazy-load-image-component'; +import { Box, Skeleton, Tooltip } from '@chakra-ui/react'; +import { HeartIcon } from '@heroicons/react/24/outline'; +import { Info } from 'lucide-react'; +import LazyLoad from 'react-lazy-load'; +import { toast } from 'react-hot-toast'; +import { useRouter } from 'next/router'; + +import Image from '@/core/components/elements/Image/Image'; +import Link from '@/core/components/elements/Link/Link'; +import DesktopView from '@/core/components/views/DesktopView'; +import BottomPopup from '@/core/components/elements/Popup/BottomPopup'; +import CountDown2 from '@/core/components/elements/CountDown/CountDown2'; + +import currencyFormat from '@/core/utils/currencyFormat'; +import { updateItemCart } from '@/core/utils/cart'; +import { createSlug } from '@/core/utils/slug'; +import whatsappUrl from '@/core/utils/whatsappUrl'; +import { sellingProductFormat } from '@/core/utils/formatValue'; + +import odooApi from '@/core/api/odooApi'; +import useAuth from '@/core/hooks/useAuth'; + +import { useProductCartContext } from '@/contexts/ProductCartContext'; + +import PromotionType from '@/lib/promotinProgram/components/PromotionType'; + +import ProductSimilar from '../ProductSimilar'; +import ProductCard from '../ProductCard'; +import productSimilarApi from '../../api/productSimilarApi'; +import ColumnsSLA from './ColumnsSLA'; +import Breadcrumb from './Breadcrumb'; + +import ProductPromoSection from '~/modules/product-promo/components/Section'; const ProductDesktop = ({ products, wishlist, toggleWishlist }) => { - const router = useRouter() - const auth = useAuth() - const { slug } = router.query + const router = useRouter(); + const auth = useAuth(); + const { slug } = router.query; - const [quantityActive, setQuantity] = useState(null) - const [lowestPrice, setLowestPrice] = useState(null) - const [product, setProducts] = useState(products) + const [quantityActive, setQuantity] = useState(null); + const [lowestPrice, setLowestPrice] = useState(null); + const [product, setProducts] = useState(products); - const [addCartAlert, setAddCartAlert] = useState(false) - const [isLoadingSLA, setIsLoadingSLA] = useState(true) - const [promotionType, setPromotionType] = useState(false) - const [promotionActiveId, setPromotionActiveId] = useState(null) - const [selectVariantPromoActive, setSelectVariantPromoActive] = useState(null) - const [backgorundFlashSale, setBackgorundFlashSale] = useState(null) + const [addCartAlert, setAddCartAlert] = useState(false); + const [isLoadingSLA, setIsLoadingSLA] = useState(true); + const [promotionType, setPromotionType] = useState(false); + const [promotionActiveId, setPromotionActiveId] = useState(null); + const [selectVariantPromoActive, setSelectVariantPromoActive] = + useState(null); + const [backgorundFlashSale, setBackgorundFlashSale] = useState(null); - const { setRefreshCart, refreshCart } = useProductCartContext() + const { setRefreshCart, refreshCart } = useProductCartContext(); useEffect(() => { - setLowestPrice({ price: product?.lowestPrice }) - }, [product]) + setLowestPrice({ price: product?.lowestPrice }); + }, [product]); useEffect(() => { const getBackgound = async () => { - const get = await odooApi('GET', '/api/v1/banner?type=flash-sale-background-banner') - setBackgorundFlashSale(get[0].image) - } - getBackgound() - }, []) + const get = await odooApi( + 'GET', + '/api/v1/banner?type=flash-sale-background-banner' + ); + setBackgorundFlashSale(get[0].image); + }; + getBackgound(); + }, []); - const [informationTab, setInformationTab] = useState(informationTabOptions[0].value) + const [informationTab, setInformationTab] = useState( + informationTabOptions[0].value + ); - const variantQuantityRefs = useRef([]) + const variantQuantityRefs = useRef([]); const setVariantQuantityRef = (variantId) => (element) => { if (element) { - let variantIndex = product.variants.findIndex((varian) => varian.id == variantId) - product.variants[variantIndex].quantity = element?.value + let variantIndex = product.variants.findIndex( + (varian) => varian.id == variantId + ); + product.variants[variantIndex].quantity = element?.value; } - variantQuantityRefs.current[variantId] = element - } + variantQuantityRefs.current[variantId] = element; + }; const validQuantity = (quantity) => { - let isValid = true + let isValid = true; if (!quantity || quantity < 1 || isNaN(parseInt(quantity))) { - toast.error('Jumlah barang minimal 1') - isValid = false + toast.error('Jumlah barang minimal 1'); + isValid = false; } - return isValid - } + return isValid; + }; const updateCart = (variantId, quantity, source) => { let dataUpdate = { productId: variantId, quantity, selected: true, - source: source === 'buy' ? 'buy' : null - } + source: source === 'buy' ? 'buy' : null, + }; if (product.variants.length > 1) { - let variantIndex = product.variants.findIndex((varian) => varian.id == variantId) - dataUpdate['programLineId'] = product.variants[variantIndex].programActive + let variantIndex = product.variants.findIndex( + (varian) => varian.id == variantId + ); + dataUpdate['programLineId'] = + product.variants[variantIndex].programActive; } else { - dataUpdate['programLineId'] = promotionActiveId + dataUpdate['programLineId'] = promotionActiveId; } - updateItemCart(dataUpdate) - } + updateItemCart(dataUpdate); + }; const redirectToLogin = (action, variantId, quantity) => { - const nextURL = `/shop/product/${slug}?action=${action}&variantId=${variantId}&qty=${quantity}` - router.push(`/login?next=${encodeURIComponent(nextURL)}`) - return true - } + const nextURL = `/shop/product/${slug}?action=${action}&variantId=${variantId}&qty=${quantity}`; + router.push(`/login?next=${encodeURIComponent(nextURL)}`); + return true; + }; const handleAddToCart = (variantId) => { - const quantity = variantQuantityRefs.current[variantId].value + const quantity = variantQuantityRefs.current[variantId].value; - if (!validQuantity(quantity)) return + if (!validQuantity(quantity)) return; if (!auth) { - return redirectToLogin('add_to_cart', variantId, quantity) + return redirectToLogin('add_to_cart', variantId, quantity); } - let source = 'cart' - updateCart(variantId, quantity, source) - setRefreshCart(true) - setAddCartAlert(true) - } + let source = 'cart'; + updateCart(variantId, quantity, source); + setRefreshCart(true); + setAddCartAlert(true); + }; const handleQuantityChange = (variantId) => (event) => { - const { value } = event.target - const variantIndex = product.variants.findIndex((variant) => variant.id === variantId) + const { value } = event.target; + const variantIndex = product.variants.findIndex( + (variant) => variant.id === variantId + ); if (variantIndex !== -1) { - product.variants[variantIndex].quantity = parseInt(value, 10) // Pastikan untuk mengubah ke tipe number jika diperlukan + product.variants[variantIndex].quantity = parseInt(value, 10); // Pastikan untuk mengubah ke tipe number jika diperlukan // Lakukan sesuatu jika nilai quantity diubah } - } + }; const handleBuy = (variant) => { - const quantity = variantQuantityRefs.current[variant].value - if (!validQuantity(quantity)) return + const quantity = variantQuantityRefs.current[variant].value; + if (!validQuantity(quantity)) return; if (!auth) { - return redirectToLogin('buy', variant, quantity) + return redirectToLogin('buy', variant, quantity); } - let source = 'buy' - updateCart(variant, quantity, source) - router.push(`/shop/checkout?source=buy`) - } + let source = 'buy'; + updateCart(variant, quantity, source); + router.push(`/shop/checkout?source=buy`); + }; - const variantSectionRef = useRef(null) + const variantSectionRef = useRef(null); const goToVariantSection = () => { if (variantSectionRef.current) { - const position = variantSectionRef.current.getBoundingClientRect() + const position = variantSectionRef.current.getBoundingClientRect(); window.scrollTo({ top: position.top - 120 + window.pageYOffset, - behavior: 'smooth' - }) + behavior: 'smooth', + }); } - } + }; const handlePromoClick = (variantId) => { - setSelectVariantPromoActive(variantId) - setPromotionType(true) - } + setSelectVariantPromoActive(variantId); + setPromotionType(true); + }; const productSimilarQuery = [ product?.name, `fq=-product_id_i:${product.id}`, - `fq=-manufacture_id_i:${product.manufacture?.id || 0}` - ].join('&') + `fq=-manufacture_id_i:${product.manufacture?.id || 0}`, + ].join('&'); - const [productSimilarInBrand, setProductSimilarInBrand] = useState(null) + const [productSimilarInBrand, setProductSimilarInBrand] = useState(null); useEffect(() => { const loadProductSimilarInBrand = async () => { - const productSimilarQuery = [product?.name, `fq=-product_id_i:${product.id}`].join('&') - const source = 'right' - const dataProductSimilar = await productSimilarApi({ query: productSimilarQuery, source }) - setProductSimilarInBrand(dataProductSimilar.products) - } - if (!productSimilarInBrand) loadProductSimilarInBrand() - }, [product, productSimilarInBrand]) + const productSimilarQuery = [ + product?.name, + `fq=-product_id_i:${product.id}`, + ].join('&'); + const source = 'right'; + const dataProductSimilar = await productSimilarApi({ + query: productSimilarQuery, + source, + }); + setProductSimilarInBrand(dataProductSimilar.products); + }; + if (!productSimilarInBrand) loadProductSimilarInBrand(); + }, [product, productSimilarInBrand]); useEffect(() => { const fetchData = async () => { const promises = product.variants.map(async (variant) => { - const dataSLA = await odooApi('GET', `/api/v1/product_variant/${variant.id}/stock`) + const dataSLA = await odooApi( + 'GET', + `/api/v1/product_variant/${variant.id}/stock` + ); return { ...variant, - sla: dataSLA - } - }) - const variantData = await Promise.all(promises) - product.variants = variantData + sla: dataSLA, + }; + }); + const variantData = await Promise.all(promises); + product.variants = variantData; - setIsLoadingSLA(false) - } - if (product.variantTotal == 1) fetchData() - }, [product]) + setIsLoadingSLA(false); + }; + if (product.variantTotal == 1) fetchData(); + }, [product]); return ( <DesktopView> <div className='container mx-auto pt-10'> <Breadcrumb productId={product.id} productName={product.name} /> - <div className='flex'> - <div className='w-full flex flex-wrap'> - <div className='w-5/12'> - <div className='relative mb-2'> - {product?.flashSale?.remainingTime > 0 && - lowestPrice?.price.discountPercentage > 0 && ( - <div className={`absolute bottom-0 w-full`}> - <div className='absolute bottom-0 w-full h-full'> - <ImageNext - src={backgorundFlashSale || '/images/GAMBAR-BG-FLASH-SALE.jpg'} - width={1000} - height={100} - /> - </div> - <div className='relative'> - <div className='flex gap-x-2 items-center p-2'> - <div className='bg-yellow-400 rounded-full p-1 h-9 w-20 flex items-center justify-center '> - <span className='text-lg font-bold'> - {Math.floor(product.lowestPrice.discountPercentage)}% - </span> - </div> - <div - className={`bg-red-600 border border-solid border-yellow-400 rounded-full h-9 p-2 flex w-[50%] items-center justify-center gap-x-4`} - > - <ImageNext - src='/images/ICON_FLASH_SALE_WEBSITE_INDOTEKNIK.svg' - width={17} - height={10} - /> - <span className='text-white text-lg font-semibold'> - {product?.flashSale?.tag != 'false' || product?.flashSale?.tag - ? product?.flashSale?.tag - : 'FLASH SALE'} - </span> - </div> - <div> - <CountDown2 initialTime={product.flashSale.remainingTime} /> - </div> + + <div className='w-full flex flex-wrap'> + <div className='w-3/12'> + <div className='relative mb-2'> + {product?.flashSale?.remainingTime > 0 && + lowestPrice?.price.discountPercentage > 0 && ( + <div className={`absolute bottom-0 w-full`}> + <div className='absolute bottom-0 w-full h-full'> + <ImageNext + src={ + backgorundFlashSale || + '/images/GAMBAR-BG-FLASH-SALE.jpg' + } + width={1000} + height={100} + /> + </div> + <div className='relative'> + <div className='flex gap-x-2 items-center p-2'> + <div className='bg-yellow-400 rounded-full p-1 h-9 w-20 flex items-center justify-center '> + <span className='text-lg font-bold'> + {Math.floor(product.lowestPrice.discountPercentage)} + % + </span> + </div> + <div + className={`bg-red-600 border border-solid border-yellow-400 rounded-full h-9 p-2 flex w-[50%] items-center justify-center gap-x-4`} + > + <ImageNext + src='/images/ICON_FLASH_SALE_WEBSITE_INDOTEKNIK.svg' + width={17} + height={10} + /> + <span className='text-white text-lg font-semibold'> + {product?.flashSale?.tag != 'false' || + product?.flashSale?.tag + ? product?.flashSale?.tag + : 'FLASH SALE'} + </span> + </div> + <div> + <CountDown2 + initialTime={product.flashSale.remainingTime} + /> </div> </div> </div> - )} - <Image - src={product.image} - alt={product.name} - className='h-[430px] object-contain object-center w-full border border-gray_r-4' - /> - </div> - <div> - <p className='text-justify text-xs leading-5'> - <span className='font-semibold '>Keterangan : </span>Gambar atau foto berperan - sebagai ilustrasi produk. Kadang tidak sesuai dengan kondisi terbaru dengan - berbagai perubahan dan perbaikan. Hubungi tim sales kami untuk informasi yang - lebih baik perihal gambar di 021-2933 8828. - </p> - </div> - </div> - - <div className='w-7/12 px-4'> - <h1 className='text-title-md leading-10 font-medium'>{product?.name}</h1> - <div className='mt-10'> - <div className='flex p-3'> - <div className='w-4/12 text-gray_r-12/70'>Nomor SKU</div> - <div className='w-8/12'>SKU-{product.id}</div> - </div> - <div className='flex p-3 bg-gray_r-4'> - <div className='w-4/12 text-gray_r-12/70'>Part Number</div> - <div className='w-8/12'>{product.code || '-'}</div> - </div> - <div className='flex p-3'> - <div className='w-4/12 text-gray_r-12/70'>Manufacture</div> - <div className='w-8/12'> - {product.manufacture?.name ? ( - <Link - href={createSlug( - '/shop/brands/', - product.manufacture?.name, - product.manufacture?.id - )} - > - {product.manufacture?.name} - </Link> - ) : ( - <div>-</div> - )} </div> - </div> - <div className='flex p-3 items-center bg-gray_r-4'> - <div className='w-4/12 text-gray_r-12/70'>Persiapan Barang</div> - <div className='w-8/12'> - {product.variants.length > 1 && ( - <button - type='button' - onClick={goToVariantSection} - className={`flex gap-x-1 items-center p-2 rounded-lg w-auto btn-light`} - > - <span className='text-red-600 text-sm'>Lihat Selengkapnya</span> - </button> - )} + )} + <Image + src={product.image} + alt={product.name} + className='h-[430px] object-contain object-center w-full border border-gray_r-4' + /> + </div> + <div> + <p className='text-justify text-xs leading-5'> + <span className='font-semibold '>Keterangan : </span>Gambar atau + foto berperan sebagai ilustrasi produk. Kadang tidak sesuai + dengan kondisi terbaru dengan berbagai perubahan dan perbaikan. + Hubungi tim sales kami untuk informasi yang lebih baik perihal + gambar di 021-2933 8828. + </p> + </div> + </div> - {product.variants.length === 1 && ( - <> - {!product.variants[0]?.sla && <Skeleton width='20%' height='16px' />} - {product.variants[0]?.sla && ( - <Tooltip - placement='top' - label={`Masa Persiapan Barang ${product.variants[0]?.sla?.slaDate}`} - > - <Box className='w-fit flex items-center gap-x-2'> - {product.variants[0]?.sla?.slaDate} - <Info size={16} /> - </Box> - </Tooltip> - )} - </> - )} - </div> + <div className='w-6/12 px-6'> + <h1 className='text-title-md leading-10 font-medium'> + {product?.name} + </h1> + <div className='mt-10'> + <div className='flex p-3'> + <div className='w-4/12 text-gray_r-12/70'>Nomor SKU</div> + <div className='w-8/12'>SKU-{product.id}</div> + </div> + <div className='flex p-3 bg-gray_r-4'> + <div className='w-4/12 text-gray_r-12/70'>Part Number</div> + <div className='w-8/12'>{product.code || '-'}</div> + </div> + <div className='flex p-3'> + <div className='w-4/12 text-gray_r-12/70'>Manufacture</div> + <div className='w-8/12'> + {product.manufacture?.name ? ( + <Link + href={createSlug( + '/shop/brands/', + product.manufacture?.name, + product.manufacture?.id + )} + > + {product.manufacture?.name} + </Link> + ) : ( + <div>-</div> + )} </div> + </div> + <div className='flex p-3 items-center bg-gray_r-4'> + <div className='w-4/12 text-gray_r-12/70'>Persiapan Barang</div> + <div className='w-8/12'> + {product.variants.length > 1 && ( + <button + type='button' + onClick={goToVariantSection} + className={`flex gap-x-1 items-center p-2 rounded-lg w-auto btn-light`} + > + <span className='text-red-600 text-sm'> + Lihat Selengkapnya + </span> + </button> + )} - {product.variants.length === 1 && ( - <div className='flex p-3 '> - <div className='w-4/12 text-gray_r-12/70'>Stock</div> - <div className='w-8/12'> - {!product.variants[0]?.sla && <Skeleton width='10%' height='16px' />} - {product?.variants[0].sla?.qty > 0 && ( - <span>{product?.variants[0].sla?.qty}</span> + {product.variants.length === 1 && ( + <> + {!product.variants[0]?.sla && ( + <Skeleton width='20%' height='16px' /> )} - {product?.variants[0].sla?.qty == 0 && ( - <a - href={whatsappUrl('product', { - name: product.name, - manufacture: product?.manufacture?.name, - url: createSlug('/shop/product/', product.name, product.id, true) - })} - className='text-danger-500 font-medium' + {product.variants[0]?.sla && ( + <Tooltip + placement='top' + label={`Masa Persiapan Barang ${product.variants[0]?.sla?.slaDate}`} > - Tanya Admin - </a> + <Box className='w-fit flex items-center gap-x-2'> + {product.variants[0]?.sla?.slaDate} + <Info size={16} /> + </Box> + </Tooltip> )} - </div> - </div> - )} + </> + )} + </div> + </div> - <div className={`flex p-3 ${product.variants.length > 1 ? '' : 'bg-gray_r-4'} `}> - <div className='w-4/12 text-gray_r-12/70'>Berat Barang</div> + {product.variants.length === 1 && ( + <div className='flex p-3 '> + <div className='w-4/12 text-gray_r-12/70'>Stock</div> <div className='w-8/12'> - {product?.weight > 0 && <span>{product?.weight} KG</span>} - {product?.weight == 0 && ( + {!product.variants[0]?.sla && ( + <Skeleton width='10%' height='16px' /> + )} + {product?.variants[0].sla?.qty > 0 && ( + <span>{product?.variants[0].sla?.qty}</span> + )} + {product?.variants[0].sla?.qty == 0 && ( <a - href={whatsappUrl('productWeight', { + href={whatsappUrl('product', { name: product.name, - url: createSlug('/shop/product/', product.name, product.id, true) + manufacture: product?.manufacture?.name, + url: createSlug( + '/shop/product/', + product.name, + product.id, + true + ), })} className='text-danger-500 font-medium' > - Tanya Berat + Tanya Admin </a> )} </div> </div> - {product.variants.length <= 1 && ( - <div className='pt-3'> - <div className='flex mt-1'> - <PromotionType - variantId={product.variants[0].id} - setPromotionActiveId={setPromotionActiveId} - promotionActiveId={promotionActiveId} - quantity={quantityActive} - product={product} - ></PromotionType> - </div> - </div> - )} - </div> - </div> + )} - <div className='w-full'> - <div className='mt-12'> - <div className='text-h-lg font-semibold'>Informasi Produk</div> - <div className='flex gap-x-4 mt-6 mb-4'> - {informationTabOptions.map((option) => ( - <TabButton - value={option.value} - key={option.value} - active={informationTab == option.value} - onClick={() => setInformationTab(option.value)} + <div + className={`flex p-3 ${ + product.variants.length > 1 ? '' : 'bg-gray_r-4' + } `} + > + <div className='w-4/12 text-gray_r-12/70'>Berat Barang</div> + <div className='w-8/12'> + {product?.weight > 0 && <span>{product?.weight} KG</span>} + {product?.weight == 0 && ( + <a + href={whatsappUrl('productWeight', { + name: product.name, + url: createSlug( + '/shop/product/', + product.name, + product.id, + true + ), + })} + className='text-danger-500 font-medium' > - {option.label} - </TabButton> - ))} + Tanya Berat + </a> + )} </div> - <div className='flex'> - <div className='w-3/4 leading-8 product__description'> - <TabContent active={informationTab == 'description'}> - <span - dangerouslySetInnerHTML={{ - __html: - product.description != '' - ? product.description - : 'Belum ada deskripsi produk.' - }} - /> - </TabContent> - - <TabContent active={informationTab == 'information'}> - Belum ada informasi. - </TabContent> + </div> + {product.variants.length <= 1 && ( + <div className='pt-3'> + <div className='flex mt-1'> + <PromotionType + variantId={product.variants[0].id} + setPromotionActiveId={setPromotionActiveId} + promotionActiveId={promotionActiveId} + quantity={quantityActive} + product={product} + ></PromotionType> + <ProductPromoSection productId={product.variants[0].id} /> </div> </div> - </div> + )} </div> </div> - <div className='w-[30%]'> - {product.variants.length > 1 && product.lowestPrice.priceDiscount > 0 && ( - <div className='text-gray_r-12/80'>Harga mulai dari: </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> + )} {/* {lowestPrice?.discountPercentage > 0 && ( <div className='flex gap-x-1 items-center mt-2'> @@ -441,7 +466,8 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => { {sellingProductFormat(product?.qtySold) + ' Terjual'} </div> )} - {product?.flashSale?.id && lowestPrice?.price.discountPercentage > 0 ? ( + {product?.flashSale?.id && + lowestPrice?.price.discountPercentage > 0 ? ( <> <div className='flex gap-x-1 items-center mt-2'> <div className='badge-solid-red text-caption-1'> @@ -456,7 +482,10 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => { </div> <div className='text-gray_r-9 text-base font-normal mt-1'> Termasuk PPN:{' '} - {currencyFormat(lowestPrice?.price.priceDiscount * process.env.NEXT_PUBLIC_PPN)} + {currencyFormat( + lowestPrice?.price.priceDiscount * + process.env.NEXT_PUBLIC_PPN + )} </div> </> ) : ( @@ -466,7 +495,9 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => { {currencyFormat(lowestPrice?.price.price)} <div className='text-gray_r-9 text-base font-normal mt-1'> Termasuk PPN:{' '} - {currencyFormat(lowestPrice?.price.price * process.env.NEXT_PUBLIC_PPN)} + {currencyFormat( + lowestPrice?.price.price * process.env.NEXT_PUBLIC_PPN + )} </div> </> ) : ( @@ -476,7 +507,12 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => { href={whatsappUrl('product', { name: product.name, manufacture: product.manufacture?.name, - url: createSlug('/shop/product/', product.name, product.id, true) + url: createSlug( + '/shop/product/', + product.name, + product.id, + true + ), })} className='text-danger-500 underline' rel='noopener noreferrer' @@ -524,7 +560,10 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => { )} <div className='flex mt-4'> - <button className='flex items-center gap-x-1' onClick={toggleWishlist}> + <button + className='flex items-center gap-x-1' + onClick={toggleWishlist} + > {wishlist.data?.productTotal > 0 ? ( <HeartIcon className='w-6 fill-danger-500 text-danger-500' /> ) : ( @@ -538,7 +577,7 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => { <div className='font-medium text-center p-4 bg-gray_r-1 border-b border-gray_r-6 sticky top-0 z-10'> Produk Serupa </div> - <div className='h-full divide-y divide-gray_r-6 max-h-96'> + <div className='h-full divide-y divide-gray_r-6 max-h-[550px]'> {productSimilarInBrand && productSimilarInBrand?.map((product) => ( <div className='py-2' key={product.id}> @@ -550,6 +589,42 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => { </div> </div> + <div className='w-full'> + <div className='mt-12'> + <div className='text-h-lg font-semibold'>Informasi Produk</div> + <div className='flex gap-x-4 mt-6 mb-4'> + {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'> + <div className='w-3/4 leading-8 product__description'> + <TabContent active={informationTab == 'description'}> + <span + dangerouslySetInnerHTML={{ + __html: + product.description != '' + ? product.description + : 'Belum ada deskripsi produk.', + }} + /> + </TabContent> + + <TabContent active={informationTab == 'information'}> + Belum ada informasi. + </TabContent> + </div> + </div> + </div> + </div> + {product.variants.length > 1 && ( <div className='mt-12' ref={variantSectionRef}> <div className='text-h-lg font-semibold mb-6'>Varian Produk</div> @@ -571,7 +646,9 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => { <tr key={variant.id}> <td className='flex items-center justify-center gap-x-1'> {variant.isFlashsale && ( - <span className='blink-color-flash-sale'>🗲</span> + <span className='blink-color-flash-sale'> + 🗲 + </span> )} {variant.code} </td> @@ -580,11 +657,13 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => { <ColumnsSLA variant={variant} product={product} /> </LazyLoadComponent> <td> - {variant.isFlashsale && variant?.price?.discountPercentage > 0 ? ( + {variant.isFlashsale && + variant?.price?.discountPercentage > 0 ? ( <> <div className='flex items-center gap-x-1 justify-center'> <div className='badge-solid-red text-caption-1'> - {Math.floor(variant?.price?.discountPercentage)}% + {Math.floor(variant?.price?.discountPercentage)} + % </div> <div className='line-through text-caption-1 text-gray_r-11'> {currencyFormat(variant?.price?.price)} @@ -596,7 +675,8 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => { <div className=' text-caption-1 text-gray_r-11 mb-1'> Inc. PPN:{' '} {currencyFormat( - variant.price.priceDiscount * process.env.NEXT_PUBLIC_PPN + variant.price.priceDiscount * + process.env.NEXT_PUBLIC_PPN )} </div> </> @@ -610,7 +690,8 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => { <div className=' text-caption-1 text-gray_r-11 mb-1'> Inc. PPN:{' '} {currencyFormat( - variant?.price?.price * process.env.NEXT_PUBLIC_PPN + variant?.price?.price * + process.env.NEXT_PUBLIC_PPN )} </div> </> @@ -619,7 +700,12 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => { href={whatsappUrl('product', { name: variant.name, manufacture: product.manufacture?.name, - url: createSlug('/shop/product/', product.name, product.id, true) + url: createSlug( + '/shop/product/', + product.name, + product.id, + true + ), })} className='text-red_r-11' rel='noopener noreferrer' @@ -705,11 +791,14 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => { )} <div className='my-12'> - <div className='text-h-lg font-semibold mb-6'>Kamu Mungkin Juga Suka</div> + <div className='text-h-lg font-semibold mb-6'> + Kamu Mungkin Juga Suka + </div> <LazyLoad> <ProductSimilar query={productSimilarQuery} /> </LazyLoad> </div> + <BottomPopup className=' !h-[75%]' title='Pakai Promo' @@ -728,6 +817,7 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => { ></PromotionType> </div> </BottomPopup> + <BottomPopup className='!container' title='Berhasil Ditambahkan' @@ -742,16 +832,23 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => { className='h-32 object-contain object-center w-full border border-gray_r-4' /> </div> - <div className='ml-3 flex flex-1 items-center font-normal'>{product.name}</div> + <div className='ml-3 flex flex-1 items-center font-normal'> + {product.name} + </div> <div className='ml-3 flex items-center font-normal'> - <Link href='/shop/cart' className='flex-1 py-2 text-gray_r-12 btn-yellow'> + <Link + href='/shop/cart' + className='flex-1 py-2 text-gray_r-12 btn-yellow' + > Lihat Keranjang </Link> </div> </div> <div className='mt-8 mb-4'> - <div className='text-h-sm font-semibold mb-6'>Kamu Mungkin Juga Suka</div> + <div className='text-h-sm font-semibold mb-6'> + Kamu Mungkin Juga Suka + </div> <LazyLoad> <ProductSimilar query={productSimilarQuery} /> </LazyLoad> @@ -759,29 +856,33 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => { </BottomPopup> </div> </DesktopView> - ) -} + ); +}; const informationTabOptions = [ { value: 'description', label: 'Deskripsi' }, - { value: 'information', label: 'Info Penting' } -] + { value: 'information', label: 'Info Penting' }, +]; const TabButton = ({ children, active, ...props }) => { const activeClassName = active ? 'text-danger-500 underline underline-offset-4' - : 'text-gray_r-12/80' + : 'text-gray_r-12/80'; return ( - <button {...props} type='button' className={`font-medium ${activeClassName}`}> + <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 +export default ProductDesktop; |
