diff options
| author | Rafi Zadanly <zadanlyr@gmail.com> | 2024-01-15 13:54:30 +0700 |
|---|---|---|
| committer | Rafi Zadanly <zadanlyr@gmail.com> | 2024-01-15 13:54:30 +0700 |
| commit | c42f03768e4c009a247d5cacbecaf4ac952752c9 (patch) | |
| tree | 9199f9b7fae77e1988724159380567b8046c94a9 /src-migrate/modules | |
| parent | f62b2345f463695ef0f8f79830cd76b6e0332821 (diff) | |
Improve product detail performance
Diffstat (limited to 'src-migrate/modules')
6 files changed, 86 insertions, 21 deletions
diff --git a/src-migrate/modules/product-detail/components/PriceAction.tsx b/src-migrate/modules/product-detail/components/PriceAction.tsx index 8189e5bd..cfb596fa 100644 --- a/src-migrate/modules/product-detail/components/PriceAction.tsx +++ b/src-migrate/modules/product-detail/components/PriceAction.tsx @@ -6,13 +6,21 @@ import { formatToShortText } from '~/libs/formatNumber' import { IProductDetail } from '~/types/product' import { useProductDetail } from '../stores/useProductDetail' import AddToCart from './AddToCart' +import Link from 'next/link' type Props = { product: IProductDetail } const PriceAction = ({ product }: Props) => { - const { activePrice, setActive, activeVariantId, quantityInput, setQuantityInput } = useProductDetail() + const { + activePrice, + setActive, + activeVariantId, + quantityInput, + setQuantityInput, + askAdminUrl + } = useProductDetail() useEffect(() => { setActive(product.variants[0]) @@ -26,18 +34,28 @@ const PriceAction = ({ product }: Props) => { </div> )} <div className='h-2' /> - <div className={style['main-price']}> - Rp {formatCurrency(activePrice?.price || 0)} - </div> - <div className='h-1' /> - <div className={style['secondary-text']}> - {!!activePrice && ( - <> + + {!!activePrice && activePrice.price > 0 && ( + <> + <div className={style['main-price']}> + Rp {formatCurrency(activePrice.price || 0)} + </div> + <div className='h-1' /> + <div className={style['secondary-text']}> Termasuk PPN: {' '} - Rp {formatCurrency(Math.round(activePrice?.price * 1.11))} - </> - )} - </div> + Rp {formatCurrency(Math.round(activePrice.price * 1.11))} + </div> + </> + )} + + {!!activePrice && activePrice.price === 0 && ( + <span> + Hubungi kami untuk dapatkan harga terbaik,{' '} + <Link href={askAdminUrl} target='_blank' className={style['contact-us']}> + klik disini + </Link> + </span> + )} <div className='h-4' /> diff --git a/src-migrate/modules/product-detail/components/ProductDetail.tsx b/src-migrate/modules/product-detail/components/ProductDetail.tsx index b752a138..d38e0686 100644 --- a/src-migrate/modules/product-detail/components/ProductDetail.tsx +++ b/src-migrate/modules/product-detail/components/ProductDetail.tsx @@ -1,6 +1,6 @@ import style from '../styles/product-detail.module.css' -import React from 'react' +import React, { useEffect } from 'react' import Link from 'next/link' import { MessageCircleIcon } from 'lucide-react' import { Button } from '@chakra-ui/react' @@ -15,6 +15,10 @@ import SimilarSide from './SimilarSide' import SimilarBottom from './SimilarBottom' import useDevice from '@/core/hooks/useDevice' import PriceAction from './PriceAction' +import { whatsappUrl } from '~/libs/whatsappUrl' +import { useRouter } from 'next/router' +import { useProductDetail } from '../stores/useProductDetail' +import ProductPromoSection from '~/modules/product-promo/components/Section' type Props = { product: IProductDetail @@ -22,6 +26,22 @@ type Props = { const ProductDetail = ({ product }: Props) => { const { isDesktop, isMobile } = useDevice() + const router = useRouter() + const { setAskAdminUrl, askAdminUrl, activeVariantId } = useProductDetail() + + useEffect(() => { + const createdAskUrl = whatsappUrl({ + template: 'product', + payload: { + manufacture: product.manufacture.name, + productName: product.name, + url: process.env.NEXT_PUBLIC_SELF_HOST + router.asPath + }, + fallbackUrl: router.asPath + }) + + setAskAdminUrl(createdAskUrl) + }, [router.asPath, product.manufacture.name, product.name, setAskAdminUrl]) return ( <> @@ -47,8 +67,9 @@ const ProductDetail = ({ product }: Props) => { <Button as={Link} - href='' + href={askAdminUrl} variant='link' + target='_blank' colorScheme='red' leftIcon={<MessageCircleIcon size={18} />} > @@ -64,7 +85,10 @@ const ProductDetail = ({ product }: Props) => { </div> )} - <div className='h-4 md:h-10'></div> + <div className='h-4 md:h-10' /> + {activeVariantId && ( + <ProductPromoSection productId={activeVariantId} /> + )} <div className={style['section-card']}> <h2 className={style['heading']}> @@ -74,7 +98,7 @@ const ProductDetail = ({ product }: Props) => { <VariantList variants={product.variants} /> </div> - <div className='h-0 md:h-6'></div> + <div className='h-0 md:h-6' /> <div className={style['section-card']}> <h2 className={style['heading']}> diff --git a/src-migrate/modules/product-detail/components/VariantList.tsx b/src-migrate/modules/product-detail/components/VariantList.tsx index d07e6b23..f8aa5565 100644 --- a/src-migrate/modules/product-detail/components/VariantList.tsx +++ b/src-migrate/modules/product-detail/components/VariantList.tsx @@ -48,11 +48,16 @@ const Row = ({ variant }: { variant: IProductVariantDetail }) => { return ( <div className={style['row']}> - <div className='w-2/12 sticky left-0 bg-white'>{variant.code}</div> + <div className='w-2/12 sticky left-0 bg-white md:bg-transparent'>{variant.code}</div> <div className='w-2/12'>{variant.attributes.join(', ')}</div> <div className='w-1/12'> <Skeleton isLoaded={querySLA.isSuccess} h='21px' w={16}> - {sla?.qty} + {sla?.qty !== undefined && ( + <> + {sla.qty > 0 && sla.qty} + {sla.qty == 0 && '-'} + </> + )} </Skeleton> </div> <div className='w-2/12'> @@ -64,7 +69,8 @@ const Row = ({ variant }: { variant: IProductVariantDetail }) => { {variant.weight > 0 ? `${variant.weight} Kg` : '-'} </div> <div className='w-2/12'> - Rp {formatCurrency(variant.price.price)} + {variant.price.price > 0 && `Rp ${formatCurrency(variant.price.price)}`} + {variant.price.price === 0 && '-'} </div> <div className='w-2/12'> <Button diff --git a/src-migrate/modules/product-detail/stores/useProductDetail.ts b/src-migrate/modules/product-detail/stores/useProductDetail.ts index 984d7948..794f0346 100644 --- a/src-migrate/modules/product-detail/stores/useProductDetail.ts +++ b/src-migrate/modules/product-detail/stores/useProductDetail.ts @@ -5,21 +5,27 @@ type State = { activeVariantId: number | null; activePrice: IProductVariantDetail['price'] | null; quantityInput: string; + askAdminUrl: string; }; type Action = { setActive: (variant: IProductVariantDetail) => void; setQuantityInput: (value: string) => void; + setAskAdminUrl: (url: string) => void; }; export const useProductDetail = create<State & Action>((set, get) => ({ activeVariantId: null, activePrice: null, quantityInput: '1', + askAdminUrl: '', setActive: (variant) => { set({ activeVariantId: variant.id, activePrice: variant.price }); }, setQuantityInput: (value: string) => { set({ quantityInput: value }); }, + setAskAdminUrl: (url: string) => { + set({ askAdminUrl: url }); + }, })); diff --git a/src-migrate/modules/product-detail/styles/price-action.module.css b/src-migrate/modules/product-detail/styles/price-action.module.css index 594167af..a8ec0ed3 100644 --- a/src-migrate/modules/product-detail/styles/price-action.module.css +++ b/src-migrate/modules/product-detail/styles/price-action.module.css @@ -9,4 +9,8 @@ } .quantity-input { @apply px-2 rounded text-center border border-gray-300 w-14 h-10 focus:outline-none; -}
\ No newline at end of file +} + +.contact-us { + @apply text-danger-500 font-medium underline; +} diff --git a/src-migrate/modules/product-promo/components/Section.tsx b/src-migrate/modules/product-promo/components/Section.tsx index 04cf1363..b6753be7 100644 --- a/src-migrate/modules/product-promo/components/Section.tsx +++ b/src-migrate/modules/product-promo/components/Section.tsx @@ -8,6 +8,7 @@ import ProductPromoCard from './Card' import { IPromotion } from '~/types/promotion' import ProductPromoModal from "./Modal" import { useModalStore } from "../stores/useModalStore" +import clsxm from "~/libs/clsxm" type Props = { productId: number @@ -36,7 +37,13 @@ const ProductPromoSection = ({ productId }: Props) => { </div> )} - <Skeleton isLoaded={promotionsQuery.isSuccess} className="flex gap-x-4 overflow-x-auto min-h-[340px] px-4 md:px-0"> + <Skeleton + isLoaded={promotionsQuery.isSuccess} + className={clsxm( + "flex gap-x-4 overflow-x-auto px-4 md:px-0", { + "min-h-[340px]": promotions?.data && promotions?.data.length > 0 + })} + > {promotions?.data.map((promotion) => ( <div key={promotion.id} className="min-w-[400px] max-w-[400px]"> <ProductPromoCard promotion={promotion} /> |
