diff options
| author | Rafi Zadanly <zadanlyr@gmail.com> | 2024-02-29 16:14:31 +0700 |
|---|---|---|
| committer | Rafi Zadanly <zadanlyr@gmail.com> | 2024-02-29 16:14:31 +0700 |
| commit | 037c06c8c7ee0751105b5aea22819a5c4c41fdd8 (patch) | |
| tree | e4c624ba777deba4a3dc840b7cec16fb5378292e | |
| parent | 58267593b6214ecc37489802729a5702116794af (diff) | |
Add utm source function on product card
| -rw-r--r-- | src-migrate/constants/utm-source.ts | 8 | ||||
| -rw-r--r-- | src-migrate/hooks/useUtmSource.ts | 20 | ||||
| -rw-r--r-- | src-migrate/modules/product-card/components/ProductCard.tsx | 8 | ||||
| -rw-r--r-- | src/lib/product/components/ProductCard.jsx | 134 |
4 files changed, 112 insertions, 58 deletions
diff --git a/src-migrate/constants/utm-source.ts b/src-migrate/constants/utm-source.ts new file mode 100644 index 00000000..95c03ed2 --- /dev/null +++ b/src-migrate/constants/utm-source.ts @@ -0,0 +1,8 @@ +export const UTM_SOURCE = { + '/': 'web.home', + '/shop/product/[slug]': 'web.other-product', + '/shop/search': 'web.search', + '/shop/brands/[slug]': 'web.brand', + '/shop/category/[slug]': 'web.category', + '/shop/cart': 'web.cart', +}; diff --git a/src-migrate/hooks/useUtmSource.ts b/src-migrate/hooks/useUtmSource.ts new file mode 100644 index 00000000..a72fae36 --- /dev/null +++ b/src-migrate/hooks/useUtmSource.ts @@ -0,0 +1,20 @@ +import { useRouter } from 'next/router'; +import { useEffect, useState } from 'react'; +import { UTM_SOURCE } from '~/constants/utm-source'; + +const useUtmSource = () => { + const router = useRouter(); + const [source, setSource] = useState<string>(); + + useEffect(() => { + console.log(router.pathname); + + if (router.pathname) { + setSource(UTM_SOURCE[router.pathname as keyof typeof UTM_SOURCE]); + } + }, [router.pathname]); + + return source; +}; + +export default useUtmSource; diff --git a/src-migrate/modules/product-card/components/ProductCard.tsx b/src-migrate/modules/product-card/components/ProductCard.tsx index 8487cd94..4ddebda5 100644 --- a/src-migrate/modules/product-card/components/ProductCard.tsx +++ b/src-migrate/modules/product-card/components/ProductCard.tsx @@ -1,8 +1,10 @@ import style from '../styles/product-card.module.css' +import clsx from 'clsx' import Link from 'next/link' -import React, { useMemo } from 'react' +import { useMemo } from 'react' import Image from '~/components/ui/image' +import useUtmSource from '~/hooks/useUtmSource' import clsxm from '~/libs/clsxm' import formatCurrency from '~/libs/formatCurrency' import { formatToShortText } from '~/libs/formatNumber' @@ -15,8 +17,10 @@ type Props = { } const ProductCard = ({ product, layout = 'vertical' }: Props) => { + const utmSource = useUtmSource() + const URL = { - product: createSlug('/shop/product/', product.name, product.id.toString()), + product: createSlug('/shop/product/', product.name, product.id.toString()) + `?utm_source=${utmSource}`, manufacture: createSlug('/shop/brands/', product.manufacture.name, product.manufacture.id.toString()), } diff --git a/src/lib/product/components/ProductCard.jsx b/src/lib/product/components/ProductCard.jsx index 1cec0804..9908a573 100644 --- a/src/lib/product/components/ProductCard.jsx +++ b/src/lib/product/components/ProductCard.jsx @@ -1,34 +1,46 @@ -import Image from '@/core/components/elements/Image/Image' -import Link from '@/core/components/elements/Link/Link' -import currencyFormat from '@/core/utils/currencyFormat' -import { sellingProductFormat } from '@/core/utils/formatValue' -import { createSlug } from '@/core/utils/slug' -import whatsappUrl from '@/core/utils/whatsappUrl' -import ImageNext from 'next/image' -import { useRouter } from 'next/router' -import { useMemo } from 'react' +import clsx from 'clsx'; +import ImageNext from 'next/image'; +import { useRouter } from 'next/router'; +import { useMemo } from 'react'; + +import Image from '@/core/components/elements/Image/Image'; +import Link from '@/core/components/elements/Link/Link'; +import currencyFormat from '@/core/utils/currencyFormat'; +import { sellingProductFormat } from '@/core/utils/formatValue'; +import { createSlug } from '@/core/utils/slug'; +import whatsappUrl from '@/core/utils/whatsappUrl'; +import useUtmSource from '~/hooks/useUtmSource'; const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => { - const router = useRouter() + const router = useRouter(); + const utmSource = useUtmSource(); const callForPriceWhatsapp = 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), + }); const image = useMemo(() => { - if (product.image) return product.image + '?ratio=square' - return '/images/noimage.jpeg' - }, [product.image]) + if (product.image) return product.image + '?ratio=square'; + return '/images/noimage.jpeg'; + }, [product.image]); + + const URL = { + product: + createSlug('/shop/product/', product?.name, product?.id) + + `?utm_source=${utmSource}`, + manufacture: createSlug( + '/shop/brands/', + product?.manufacture?.name, + product?.manufacture.id + ), + }; if (variant == 'vertical') { return ( <div className='rounded shadow-sm border border-gray_r-4 bg-white h-[300px] md:h-[350px]'> - <Link - href={createSlug('/shop/product/', product?.name, product?.id)} - className='border-b border-gray_r-4 relative' - > + <Link href={URL.product} className='border-b border-gray_r-4 relative'> <Image src={image} alt={product?.name} @@ -58,7 +70,8 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => { height={5} /> <span className='text-white text-[9px] md:text-[10px] font-semibold'> - {product?.flashSale?.tag != 'false' || product?.flashSale?.tag + {product?.flashSale?.tag != 'false' || + product?.flashSale?.tag ? product?.flashSale?.tag : 'FLASH SALE'} </span> @@ -75,27 +88,21 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => { </Link> <div className='p-2 sm:p-3 pb-3 text-caption-2 sm:text-body-2 leading-5'> {product?.manufacture?.name ? ( - <Link - href={createSlug( - '/shop/brands/', - product?.manufacture?.name, - product?.manufacture.id - )} - className='mb-1' - > + <Link href={URL.manufacture} className='mb-1'> {product.manufacture.name} </Link> ) : ( <div>-</div> )} <Link - href={createSlug('/shop/product/', product?.name, product?.id)} + href={URL.product} className={`mb-2 !text-gray_r-12 leading-6 block line-clamp-3 h-[64px]`} title={product?.name} > {product?.name} </Link> - {product?.flashSale?.id > 0 && product?.lowestPrice.discountPercentage > 0 ? ( + {product?.flashSale?.id > 0 && + product?.lowestPrice.discountPercentage > 0 ? ( <> <div className='flex gap-x-1 mb-1 items-center'> <div className='text-gray_r-11 line-through text-[11px] sm:text-caption-2'> @@ -109,7 +116,11 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => { {product?.lowestPrice.priceDiscount > 0 ? ( currencyFormat(product?.lowestPrice.priceDiscount) ) : ( - <a rel='noopener noreferrer' target='_blank' href={callForPriceWhatsapp}> + <a + rel='noopener noreferrer' + target='_blank' + href={callForPriceWhatsapp} + > Call for Inquiry </a> )} @@ -122,11 +133,17 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => { {currencyFormat(product?.lowestPrice.price)} <div className='text-gray_r-9 text-[10px] font-normal mt-2'> Inc. PPN:{' '} - {currencyFormat(product.lowestPrice.price * process.env.NEXT_PUBLIC_PPN)} + {currencyFormat( + product.lowestPrice.price * process.env.NEXT_PUBLIC_PPN + )} </div> </> ) : ( - <a rel='noopener noreferrer' target='_blank' href={callForPriceWhatsapp}> + <a + rel='noopener noreferrer' + target='_blank' + href={callForPriceWhatsapp} + > Call for Inquiry </a> )} @@ -134,7 +151,9 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => { )} <div className='flex w-full items-center gap-x-1 '> - {product?.stockTotal > 0 && <div className='badge-solid-red'>Ready Stock</div>} + {product?.stockTotal > 0 && ( + <div className='badge-solid-red'>Ready Stock</div> + )} {/* <div className='badge-gray'>{product?.stockTotal > 5 ? '> 5' : '< 5'}</div> */} {product?.qtySold > 0 && ( <div className='text-gray_r-9 text-[11px]'> @@ -144,17 +163,14 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => { </div> </div> </div> - ) + ); } if (variant == 'horizontal') { return ( <div className='flex bg-white'> <div className='w-4/12'> - <Link - href={createSlug('/shop/product/', product?.name, product?.id)} - className='relative' - > + <Link href={URL.product} className='relative'> <Image src={image} alt={product?.name} @@ -184,26 +200,20 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => { </div> )} {product?.manufacture?.name ? ( - <Link - href={createSlug( - '/shop/brands/', - product?.manufacture?.name, - product?.manufacture.id - )} - className='mb-1' - > + <Link href={URL.manufacture} className='mb-1'> {product.manufacture.name} </Link> ) : ( <div>-</div> )} <Link - href={createSlug('/shop/product/', product?.name, product?.id)} + href={URL.product} className={`mb-3 !text-gray_r-12 leading-6 line-clamp-3`} > {product?.name} </Link> - {product?.flashSale?.id > 0 && product?.lowestPrice?.discountPercentage > 0 ? ( + {product?.flashSale?.id > 0 && + product?.lowestPrice?.discountPercentage > 0 ? ( <> {product?.lowestPrice.discountPercentage > 0 && ( <div className='flex gap-x-1 mb-1 items-center'> @@ -220,7 +230,11 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => { {product?.lowestPrice?.priceDiscount > 0 ? ( currencyFormat(product?.lowestPrice?.priceDiscount) ) : ( - <a rel='noopener noreferrer' target='_blank' href={callForPriceWhatsapp}> + <a + rel='noopener noreferrer' + target='_blank' + href={callForPriceWhatsapp} + > Call for Inquiry </a> )} @@ -233,11 +247,17 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => { {currencyFormat(product?.lowestPrice.price)} <div className='text-gray_r-9 text-[11px] sm:text-caption-2 font-normal mt-2'> Inc. PPN:{' '} - {currencyFormat(product.lowestPrice.price * process.env.NEXT_PUBLIC_PPN)} + {currencyFormat( + product.lowestPrice.price * process.env.NEXT_PUBLIC_PPN + )} </div> </> ) : ( - <a rel='noopener noreferrer' target='_blank' href={callForPriceWhatsapp}> + <a + rel='noopener noreferrer' + target='_blank' + href={callForPriceWhatsapp} + > Call for Inquiry </a> )} @@ -245,7 +265,9 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => { )} <div className='flex w-full items-center gap-x-1 '> - {product?.stockTotal > 0 && <div className='badge-solid-red'>Ready Stock</div>} + {product?.stockTotal > 0 && ( + <div className='badge-solid-red'>Ready Stock</div> + )} {/* <div className='badge-gray'>{product?.stockTotal > 5 ? '> 5' : '< 5'}</div> */} {product?.qtySold > 0 && ( <div className='text-gray_r-9 text-[11px]'> @@ -255,8 +277,8 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => { </div> </div> </div> - ) + ); } -} +}; -export default ProductCard +export default ProductCard; |
