From f62b2345f463695ef0f8f79830cd76b6e0332821 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Sat, 13 Jan 2024 10:35:22 +0700 Subject: Refactor src migrate folder --- .../product-detail/components/AddToCart.tsx | 79 +++++++++++++ .../product-detail/components/AddToWishlist.tsx | 17 +++ .../modules/product-detail/components/Image.tsx | 37 ++++++ .../product-detail/components/Information.tsx | 84 ++++++++++++++ .../product-detail/components/PriceAction.tsx | 53 +++++++++ .../product-detail/components/ProductDetail.tsx | 126 +++++++++++++++++++++ .../product-detail/components/SimilarBottom.tsx | 21 ++++ .../product-detail/components/SimilarSide.tsx | 34 ++++++ .../product-detail/components/VariantList.tsx | 85 ++++++++++++++ 9 files changed, 536 insertions(+) create mode 100644 src-migrate/modules/product-detail/components/AddToCart.tsx create mode 100644 src-migrate/modules/product-detail/components/AddToWishlist.tsx create mode 100644 src-migrate/modules/product-detail/components/Image.tsx create mode 100644 src-migrate/modules/product-detail/components/Information.tsx create mode 100644 src-migrate/modules/product-detail/components/PriceAction.tsx create mode 100644 src-migrate/modules/product-detail/components/ProductDetail.tsx create mode 100644 src-migrate/modules/product-detail/components/SimilarBottom.tsx create mode 100644 src-migrate/modules/product-detail/components/SimilarSide.tsx create mode 100644 src-migrate/modules/product-detail/components/VariantList.tsx (limited to 'src-migrate/modules/product-detail/components') diff --git a/src-migrate/modules/product-detail/components/AddToCart.tsx b/src-migrate/modules/product-detail/components/AddToCart.tsx new file mode 100644 index 00000000..4accab17 --- /dev/null +++ b/src-migrate/modules/product-detail/components/AddToCart.tsx @@ -0,0 +1,79 @@ +import React from 'react' +import { Button, useToast } from '@chakra-ui/react' +import { getAuth } from '~/libs/auth' +import { useRouter } from 'next/router' +import Link from 'next/link' +import { upsertUserCart } from '~/services/cart' + +type Props = { + variantId: number | null, + quantity?: number; + source?: 'buy' | 'add_to_cart'; +} + +const AddToCart = ({ + variantId, + quantity = 1, + source = 'add_to_cart' +}: Props) => { + const auth = getAuth() + const router = useRouter() + const toast = useToast({ + position: 'top', + isClosable: true + }) + + const handleClick = async () => { + if (typeof auth !== 'object') { + const currentUrl = encodeURIComponent(router.asPath) + toast({ + title: 'Masuk Akun', + description: <> + Masuk akun untuk dapat menambahkan barang ke keranjang belanja. {' '} + Klik disini + , + status: 'error', + duration: 4000, + }) + return; + } + + if ( + !variantId || + isNaN(quantity) || + typeof auth !== 'object' + ) return; + + toast.promise( + upsertUserCart(auth.id, 'product', variantId, quantity, true, source), + { + loading: { title: 'Menambahkan ke keranjang', description: 'Mohon tunggu...' }, + success: { title: 'Menambahkan ke keranjang', description: 'Berhasil menambahkan ke keranjang belanja' }, + error: { title: 'Menambahkan ke keranjang', description: 'Gagal menambahkan ke keranjang belanja' }, + } + ) + + if (source === 'buy') { + router.push('/shop/checkout?source=buy') + } + } + + const btnConfig = { + 'add_to_cart': { + colorScheme: 'yellow', + text: 'Keranjang' + }, + 'buy': { + colorScheme: 'red', + text: 'Beli' + } + } + + return ( + + ) +} + +export default AddToCart \ No newline at end of file diff --git a/src-migrate/modules/product-detail/components/AddToWishlist.tsx b/src-migrate/modules/product-detail/components/AddToWishlist.tsx new file mode 100644 index 00000000..eab3c7be --- /dev/null +++ b/src-migrate/modules/product-detail/components/AddToWishlist.tsx @@ -0,0 +1,17 @@ +import { Button } from '@chakra-ui/react' +import { HeartIcon } from 'lucide-react' +import React from 'react' + +const AddToWishlist = () => { + return ( + + ) +} + +export default AddToWishlist \ No newline at end of file diff --git a/src-migrate/modules/product-detail/components/Image.tsx b/src-migrate/modules/product-detail/components/Image.tsx new file mode 100644 index 00000000..361580ea --- /dev/null +++ b/src-migrate/modules/product-detail/components/Image.tsx @@ -0,0 +1,37 @@ +import React from 'react' +import { InfoIcon } from 'lucide-react' +import { Tooltip } from '@chakra-ui/react' + +import { IProductDetail } from '~/types/product' +import ImageUI from '~/components/ui/image' + +type Props = { + product: IProductDetail +} + +const Image = ({ product }: Props) => { + return ( +
+ +
+ +
+ +
+
+
+
+ ) +} + +export default Image \ No newline at end of file diff --git a/src-migrate/modules/product-detail/components/Information.tsx b/src-migrate/modules/product-detail/components/Information.tsx new file mode 100644 index 00000000..fd0e0b3c --- /dev/null +++ b/src-migrate/modules/product-detail/components/Information.tsx @@ -0,0 +1,84 @@ +import style from '../styles/information.module.css' + +import React from 'react' +import dynamic from 'next/dynamic' +import Link from 'next/link' +import { useQuery } from 'react-query' + +import { IProductDetail } from '~/types/product' +import { IProductVariantSLA } from '~/types/productVariant' +import { createSlug } from '~/libs/slug' +import { getVariantSLA } from '~/services/productVariant' + +const Skeleton = dynamic(() => import('@chakra-ui/react').then((mod) => mod.Skeleton)) + +type Props = { + product: IProductDetail +} + +const Information = ({ product }: Props) => { + const querySLA = useQuery({ + queryKey: ['variant-sla', product.variants[0].id], + queryFn: () => getVariantSLA(product.variants[0].id), + enabled: product.variant_total === 1 + }) + + const sla = querySLA?.data + + return ( +
+
+
SKU Number
+
SKU-{product.id}
+
+ {/*
+
Part Number
+
{product.code || '-'}
+
*/} +
+
Manufacture
+
+ {!!product.manufacture.name ? ( + + {product.manufacture.name} + + ) : '-'} +
+
+ {/*
+
Preparation Time
+
+ {product.variant_total > 1 && 'Lihat Variant'} + {product.variant_total === 1 && ( + + {sla?.sla_date} + + )} +
+
+
+
Stock
+
+ {product.variant_total > 1 && 'Lihat Variant'} + {product.variant_total === 1 && ( + + {sla?.qty && sla.qty > 0 ? sla?.qty : '-'} + + )} +
+
+
+
Weight
+
+ {product.variant_total > 1 && 'Lihat Variant'} + {product.variant_total === 1 && (product.weight > 0 ? `${product.weight} kg` : '-')} +
+
*/} +
+ ) +} + +export default Information \ No newline at end of file diff --git a/src-migrate/modules/product-detail/components/PriceAction.tsx b/src-migrate/modules/product-detail/components/PriceAction.tsx new file mode 100644 index 00000000..8189e5bd --- /dev/null +++ b/src-migrate/modules/product-detail/components/PriceAction.tsx @@ -0,0 +1,53 @@ +import style from '../styles/price-action.module.css' + +import React, { useEffect } from 'react' +import formatCurrency from '~/libs/formatCurrency' +import { formatToShortText } from '~/libs/formatNumber' +import { IProductDetail } from '~/types/product' +import { useProductDetail } from '../stores/useProductDetail' +import AddToCart from './AddToCart' + +type Props = { + product: IProductDetail +} + +const PriceAction = ({ product }: Props) => { + const { activePrice, setActive, activeVariantId, quantityInput, setQuantityInput } = useProductDetail() + + useEffect(() => { + setActive(product.variants[0]) + }, [product, setActive]); + + return ( +
+ {product.qty_sold > 0 && ( +
+ {formatToShortText(product.qty_sold)} Terjual +
+ )} +
+
+ Rp {formatCurrency(activePrice?.price || 0)} +
+
+
+ {!!activePrice && ( + <> + Termasuk PPN: {' '} + Rp {formatCurrency(Math.round(activePrice?.price * 1.11))} + + )} +
+ +
+ +
+ setQuantityInput(e.target.value)} className={style['quantity-input']} /> + + +
+
+ ) +} + +export default PriceAction \ No newline at end of file diff --git a/src-migrate/modules/product-detail/components/ProductDetail.tsx b/src-migrate/modules/product-detail/components/ProductDetail.tsx new file mode 100644 index 00000000..b752a138 --- /dev/null +++ b/src-migrate/modules/product-detail/components/ProductDetail.tsx @@ -0,0 +1,126 @@ +import style from '../styles/product-detail.module.css' + +import React from 'react' +import Link from 'next/link' +import { MessageCircleIcon } from 'lucide-react' +import { Button } from '@chakra-ui/react' + +import { IProductDetail } from '~/types/product' + +import ProductImage from './Image' +import Information from './Information' +import AddToWishlist from './AddToWishlist' +import VariantList from './VariantList' +import SimilarSide from './SimilarSide' +import SimilarBottom from './SimilarBottom' +import useDevice from '@/core/hooks/useDevice' +import PriceAction from './PriceAction' + +type Props = { + product: IProductDetail +} + +const ProductDetail = ({ product }: Props) => { + const { isDesktop, isMobile } = useDevice() + + return ( + <> +
+
+
+
+ +
+ +
+
+ +

+ {product.name} +

+ +
+ + + +
+ + +
+
+ +
+ {isMobile && ( +
+ +
+ )} + +
+ +
+

+ Variant ({product.variant_total}) +

+
+ +
+ +
+ +
+

+ Informasi Produk +

+
+

' ? 'Belum ada deskripsi' : product.description }} + /> +
+
+
+ + {isDesktop && ( +
+ + + + +
+ +
+ Produk Serupa +
+ +
+ + +
+ )} + +
+
+ Kamu Mungkin Juga Suka +
+ +
+ + +
+ +
+
+ + ) +} + +export default ProductDetail \ No newline at end of file diff --git a/src-migrate/modules/product-detail/components/SimilarBottom.tsx b/src-migrate/modules/product-detail/components/SimilarBottom.tsx new file mode 100644 index 00000000..9a12a6ef --- /dev/null +++ b/src-migrate/modules/product-detail/components/SimilarBottom.tsx @@ -0,0 +1,21 @@ +import React from 'react' +import useProductSimilar from '~/modules/product-similar/hooks/useProductSimilar' +import ProductSlider from '~/modules/product-slider' +import { IProductDetail } from '~/types/product' + +type Props = { + product: IProductDetail +} + +const SimilarBottom = ({ product }: Props) => { + const productSimilar = useProductSimilar({ + name: product.name, + except: { productId: product.id } + }) + + const products = productSimilar.data?.products || [] + + return ; +} + +export default SimilarBottom \ No newline at end of file diff --git a/src-migrate/modules/product-detail/components/SimilarSide.tsx b/src-migrate/modules/product-detail/components/SimilarSide.tsx new file mode 100644 index 00000000..646a1c51 --- /dev/null +++ b/src-migrate/modules/product-detail/components/SimilarSide.tsx @@ -0,0 +1,34 @@ +import style from '../styles/side-similar.module.css' + +import React from 'react' + +import ProductCard from '~/modules/product-card' +import useProductSimilar from '~/modules/product-similar/hooks/useProductSimilar' +import { IProductDetail } from '~/types/product' + +type Props = { + product: IProductDetail +} + +const SimilarSide = ({ product }: Props) => { + const productSimilar = useProductSimilar({ + name: product.name, + except: { productId: product.id, manufactureId: product.manufacture.id }, + }) + + const products = productSimilar.data?.products || [] + + return ( +
+ {products.map((product) => ( + + ))} +
+ ) +} + +export default SimilarSide \ No newline at end of file diff --git a/src-migrate/modules/product-detail/components/VariantList.tsx b/src-migrate/modules/product-detail/components/VariantList.tsx new file mode 100644 index 00000000..d07e6b23 --- /dev/null +++ b/src-migrate/modules/product-detail/components/VariantList.tsx @@ -0,0 +1,85 @@ +import style from '../styles/variant-list.module.css' + +import React from 'react' +import { Button, Skeleton } from '@chakra-ui/react' + +import formatCurrency from '~/libs/formatCurrency' +import clsxm from '~/libs/clsxm' +import { IProductVariantDetail, IProductVariantSLA } from '~/types/productVariant' +import { useProductDetail } from '../stores/useProductDetail' +import { LazyLoadComponent } from 'react-lazy-load-image-component'; +import { getVariantSLA } from '~/services/productVariant' +import { useQuery } from 'react-query' + +type Props = { + variants: IProductVariantDetail[] +} + +const VariantList = ({ variants }: Props) => { + return ( +
+
+
+
Part Number
+
Variant
+
Stock
+
Time
+
Weight
+
Price
+
+ {variants.map((variant) => ( + + + + ))} +
+
+ ) +} + +const Row = ({ variant }: { variant: IProductVariantDetail }) => { + const { activeVariantId, setActive } = useProductDetail() + const querySLA = useQuery({ + queryKey: ['variant-sla', variant.id], + queryFn: () => getVariantSLA(variant.id), + }) + + const sla = querySLA?.data + + return ( +
+
{variant.code}
+
{variant.attributes.join(', ')}
+
+ + {sla?.qty} + +
+
+ + {sla?.sla_date} + +
+
+ {variant.weight > 0 ? `${variant.weight} Kg` : '-'} +
+
+ Rp {formatCurrency(variant.price.price)} +
+
+ +
+
+ ) +} + +export default VariantList \ No newline at end of file -- cgit v1.2.3 From c42f03768e4c009a247d5cacbecaf4ac952752c9 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Mon, 15 Jan 2024 13:54:30 +0700 Subject: Improve product detail performance --- .../product-detail/components/PriceAction.tsx | 42 +++++++++++++++------- .../product-detail/components/ProductDetail.tsx | 32 ++++++++++++++--- .../product-detail/components/VariantList.tsx | 12 +++++-- 3 files changed, 67 insertions(+), 19 deletions(-) (limited to 'src-migrate/modules/product-detail/components') 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) => {
)}
-
- Rp {formatCurrency(activePrice?.price || 0)} -
-
-
- {!!activePrice && ( - <> + + {!!activePrice && activePrice.price > 0 && ( + <> +
+ Rp {formatCurrency(activePrice.price || 0)} +
+
+
Termasuk PPN: {' '} - Rp {formatCurrency(Math.round(activePrice?.price * 1.11))} - - )} -
+ Rp {formatCurrency(Math.round(activePrice.price * 1.11))} +
+ + )} + + {!!activePrice && activePrice.price === 0 && ( + + Hubungi kami untuk dapatkan harga terbaik,{' '} + + klik disini + + + )}
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) => {
)} -
+
+ {activeVariantId && ( + + )}

@@ -74,7 +98,7 @@ const ProductDetail = ({ product }: Props) => {

-
+

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 (
-
{variant.code}
+
{variant.code}
{variant.attributes.join(', ')}
- {sla?.qty} + {sla?.qty !== undefined && ( + <> + {sla.qty > 0 && sla.qty} + {sla.qty == 0 && '-'} + + )}
@@ -64,7 +69,8 @@ const Row = ({ variant }: { variant: IProductVariantDetail }) => { {variant.weight > 0 ? `${variant.weight} Kg` : '-'}
- Rp {formatCurrency(variant.price.price)} + {variant.price.price > 0 && `Rp ${formatCurrency(variant.price.price)}`} + {variant.price.price === 0 && '-'}
+ + + + + + +
-

@@ -117,9 +147,7 @@ const ProductDetail = ({ product }: Props) => {
- - -
+
Produk Serupa @@ -131,7 +159,7 @@ const ProductDetail = ({ product }: Props) => {
)} -
+
Kamu Mungkin Juga Suka
diff --git a/src-migrate/modules/product-detail/components/VariantList.tsx b/src-migrate/modules/product-detail/components/VariantList.tsx index 96b7486b..e8c18921 100644 --- a/src-migrate/modules/product-detail/components/VariantList.tsx +++ b/src-migrate/modules/product-detail/components/VariantList.tsx @@ -22,10 +22,10 @@ const VariantList = ({ variants }: Props) => {
Part Number
Variant
-
Stock
+
Stock
Masa Persiapan
Berat
-
Harga
+
Harga
{variants.map((variant) => ( @@ -49,8 +49,8 @@ const Row = ({ variant }: { variant: IProductVariantDetail }) => { return (
{variant.code}
-
{variant.attributes.join(', ')}
-
+
{variant.attributes.join(', ') || '-'}
+
{sla?.qty !== undefined && ( <> @@ -68,7 +68,7 @@ const Row = ({ variant }: { variant: IProductVariantDetail }) => {
{variant.weight > 0 ? `${variant.weight} Kg` : '-'}
-
+
{variant.price.price > 0 && `Rp ${formatCurrency(variant.price.price)}`} {variant.price.price === 0 && '-'}
-- cgit v1.2.3 From 7072d220bc86b56e76716d114e28af98219e3f69 Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Wed, 17 Jan 2024 09:54:59 +0700 Subject: Update image for performance --- src-migrate/modules/product-detail/components/Image.tsx | 1 - 1 file changed, 1 deletion(-) (limited to 'src-migrate/modules/product-detail/components') diff --git a/src-migrate/modules/product-detail/components/Image.tsx b/src-migrate/modules/product-detail/components/Image.tsx index 2c5e989b..6ec715d8 100644 --- a/src-migrate/modules/product-detail/components/Image.tsx +++ b/src-migrate/modules/product-detail/components/Image.tsx @@ -18,7 +18,6 @@ const Image = ({ product }: Props) => { width={256} height={256} className='object-contain object-center h-full w-full' - classNames={{ wrapper: 'h-full w-full' }} loading='eager' priority /> -- cgit v1.2.3 From f7a0be1407da7edab60f6cb2ca3f1ef97acf811a Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Wed, 17 Jan 2024 16:03:48 +0700 Subject: Update product detail page ui --- .../product-detail/components/PriceAction.tsx | 3 +-- .../product-detail/components/VariantList.tsx | 31 +++++++++++++++++----- 2 files changed, 26 insertions(+), 8 deletions(-) (limited to 'src-migrate/modules/product-detail/components') diff --git a/src-migrate/modules/product-detail/components/PriceAction.tsx b/src-migrate/modules/product-detail/components/PriceAction.tsx index dd211f6f..cade21b8 100644 --- a/src-migrate/modules/product-detail/components/PriceAction.tsx +++ b/src-migrate/modules/product-detail/components/PriceAction.tsx @@ -2,7 +2,6 @@ import style from '../styles/price-action.module.css' import React, { useEffect } from 'react' import formatCurrency from '~/libs/formatCurrency' -import { formatToShortText } from '~/libs/formatNumber' import { IProductDetail } from '~/types/product' import { useProductDetail } from '../stores/useProductDetail' import AddToCart from './AddToCart' @@ -27,7 +26,7 @@ const PriceAction = ({ product }: Props) => { }, [product, setActive]); return ( -
+
{!!activePrice && activePrice.price > 0 && ( <>
diff --git a/src-migrate/modules/product-detail/components/VariantList.tsx b/src-migrate/modules/product-detail/components/VariantList.tsx index e8c18921..931563e0 100644 --- a/src-migrate/modules/product-detail/components/VariantList.tsx +++ b/src-migrate/modules/product-detail/components/VariantList.tsx @@ -10,6 +10,7 @@ import { useProductDetail } from '../stores/useProductDetail' import { LazyLoadComponent } from 'react-lazy-load-image-component'; import { getVariantSLA } from '~/services/productVariant' import { useQuery } from 'react-query' +import useDevice from '@/core/hooks/useDevice' type Props = { variants: IProductVariantDetail[] @@ -20,12 +21,13 @@ const VariantList = ({ variants }: Props) => {
-
Part Number
+
Part Number
Variant
Stock
Masa Persiapan
Berat
Harga
+
{variants.map((variant) => ( @@ -38,6 +40,8 @@ const VariantList = ({ variants }: Props) => { } const Row = ({ variant }: { variant: IProductVariantDetail }) => { + const { isMobile } = useDevice() + const { activeVariantId, setActive } = useProductDetail() const querySLA = useQuery({ queryKey: ['variant-sla', variant.id], @@ -46,17 +50,32 @@ const Row = ({ variant }: { variant: IProductVariantDetail }) => { const sla = querySLA?.data + const handleSelect = (variant: IProductVariantDetail) => { + const priceSectionEl = document.getElementById('price-section') + if (isMobile && priceSectionEl) { + window.scrollTo({ + top: priceSectionEl.offsetTop - 120, + behavior: 'smooth' + }) + } + setActive(variant) + } + return (
-
{variant.code}
+
{variant.code}
{variant.attributes.join(', ') || '-'}
{sla?.qty !== undefined && ( - <> +
0, + })} + > {sla.qty > 0 && sla.qty} {sla.qty == 0 && '-'} - +
)}
@@ -72,9 +91,9 @@ const Row = ({ variant }: { variant: IProductVariantDetail }) => { {variant.price.price > 0 && `Rp ${formatCurrency(variant.price.price)}`} {variant.price.price === 0 && '-'}
-
+
diff --git a/src-migrate/modules/product-detail/components/Breadcrumb.tsx b/src-migrate/modules/product-detail/components/Breadcrumb.tsx index 0ee5b115..ec445b60 100644 --- a/src-migrate/modules/product-detail/components/Breadcrumb.tsx +++ b/src-migrate/modules/product-detail/components/Breadcrumb.tsx @@ -18,7 +18,7 @@ const Breadcrumb = ({ id, name }: Props) => { const breadcrumbs = query.data || [] return ( -
+
Home / {breadcrumbs.map((category, index) => ( diff --git a/src-migrate/modules/product-detail/components/ProductDetail.tsx b/src-migrate/modules/product-detail/components/ProductDetail.tsx index 93fa7118..80f43aea 100644 --- a/src-migrate/modules/product-detail/components/ProductDetail.tsx +++ b/src-migrate/modules/product-detail/components/ProductDetail.tsx @@ -52,10 +52,10 @@ const ProductDetail = ({ product }: Props) => { return ( <>
-
+
-
+
@@ -86,7 +86,7 @@ const ProductDetail = ({ product }: Props) => { Ask Admin - + Date: Thu, 18 Jan 2024 13:18:04 +0700 Subject: Update product detail performance --- src-migrate/modules/product-detail/components/AddToWishlist.tsx | 3 ++- src-migrate/modules/product-detail/components/Breadcrumb.tsx | 3 ++- src-migrate/modules/product-detail/components/VariantList.tsx | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) (limited to 'src-migrate/modules/product-detail/components') diff --git a/src-migrate/modules/product-detail/components/AddToWishlist.tsx b/src-migrate/modules/product-detail/components/AddToWishlist.tsx index cb11e837..697b2d5c 100644 --- a/src-migrate/modules/product-detail/components/AddToWishlist.tsx +++ b/src-migrate/modules/product-detail/components/AddToWishlist.tsx @@ -23,7 +23,8 @@ const AddToWishlist = ({ productId }: Props) => { queryFn: () => { if (typeof auth !== 'object') return null; return getUserWishlist(auth.id, searchParams) - } + }, + refetchOnWindowFocus: false }) const isAdded = query.data?.product_total ? query.data.product_total > 0 : false; diff --git a/src-migrate/modules/product-detail/components/Breadcrumb.tsx b/src-migrate/modules/product-detail/components/Breadcrumb.tsx index ec445b60..f41859a9 100644 --- a/src-migrate/modules/product-detail/components/Breadcrumb.tsx +++ b/src-migrate/modules/product-detail/components/Breadcrumb.tsx @@ -12,7 +12,8 @@ type Props = { const Breadcrumb = ({ id, name }: Props) => { const query = useQuery({ queryKey: ['product-category-breadcrumb'], - queryFn: () => getProductCategoryBreadcrumb(id) + queryFn: () => getProductCategoryBreadcrumb(id), + refetchOnWindowFocus: false }) const breadcrumbs = query.data || [] diff --git a/src-migrate/modules/product-detail/components/VariantList.tsx b/src-migrate/modules/product-detail/components/VariantList.tsx index 931563e0..1da478e7 100644 --- a/src-migrate/modules/product-detail/components/VariantList.tsx +++ b/src-migrate/modules/product-detail/components/VariantList.tsx @@ -46,6 +46,7 @@ const Row = ({ variant }: { variant: IProductVariantDetail }) => { const querySLA = useQuery({ queryKey: ['variant-sla', variant.id], queryFn: () => getVariantSLA(variant.id), + refetchOnWindowFocus: false, }) const sla = querySLA?.data -- cgit v1.2.3 From 5ac82c38ed3ec4db1fe4ae96e7493a55154716ef Mon Sep 17 00:00:00 2001 From: Rafi Zadanly Date: Thu, 18 Jan 2024 16:24:54 +0700 Subject: Update product detail page --- .../modules/product-detail/components/Image.tsx | 69 ++++++++++++++++++++-- .../product-detail/components/PriceAction.tsx | 18 +++++- .../product-detail/components/VariantList.tsx | 10 +++- 3 files changed, 88 insertions(+), 9 deletions(-) (limited to 'src-migrate/modules/product-detail/components') diff --git a/src-migrate/modules/product-detail/components/Image.tsx b/src-migrate/modules/product-detail/components/Image.tsx index 6ec715d8..2ab3ff59 100644 --- a/src-migrate/modules/product-detail/components/Image.tsx +++ b/src-migrate/modules/product-detail/components/Image.tsx @@ -1,27 +1,53 @@ -import React from 'react' +import style from '../styles/image.module.css'; + +import React, { useEffect, useState } from 'react' import { InfoIcon } from 'lucide-react' import { Tooltip } from '@chakra-ui/react' import { IProductDetail } from '~/types/product' import ImageUI from '~/components/ui/image' +import moment from 'moment'; type Props = { product: IProductDetail } const Image = ({ product }: Props) => { + const flashSale = product.flash_sale + + const [count, setCount] = useState(flashSale?.remaining_time || 0); + + useEffect(() => { + let interval: NodeJS.Timeout; + + if (flashSale?.remaining_time && flashSale.remaining_time > 0) { + setCount(flashSale.remaining_time); + + interval = setInterval(() => { + setCount((prevCount) => prevCount - 1); + }, 1000); + } + + return () => { + clearInterval(interval); + }; + }, [flashSale?.remaining_time]); + + const duration = moment.duration(count, 'seconds') + return ( -
+
-
+ +
{
+ + {flashSale.remaining_time > 0 && ( +
+
+ + +
+
+
{Math.floor(product.lowest_price.discount_percentage)}%
+
+ + {product.flash_sale.tag} +
+
+
+ {duration.hours().toString().padStart(2, '0')} + {duration.minutes().toString().padStart(2, '0')} + {duration.seconds().toString().padStart(2, '0')} +
+
+ +
+
+ )}
) } diff --git a/src-migrate/modules/product-detail/components/PriceAction.tsx b/src-migrate/modules/product-detail/components/PriceAction.tsx index cade21b8..f25847a5 100644 --- a/src-migrate/modules/product-detail/components/PriceAction.tsx +++ b/src-migrate/modules/product-detail/components/PriceAction.tsx @@ -29,13 +29,25 @@ const PriceAction = ({ product }: Props) => {
{!!activePrice && activePrice.price > 0 && ( <> -
- Rp {formatCurrency(activePrice.price || 0)} +
+ {activePrice.discount_percentage > 0 && ( + <> +
+ {Math.floor(activePrice.discount_percentage)}% +
+
+ Rp {formatCurrency(activePrice.price || 0)} +
+ + )} +
+ Rp {formatCurrency(activePrice.price_discount || 0)} +
Termasuk PPN: {' '} - Rp {formatCurrency(Math.round(activePrice.price * 1.11))} + Rp {formatCurrency(Math.round(activePrice.price_discount * 1.11))}
)} diff --git a/src-migrate/modules/product-detail/components/VariantList.tsx b/src-migrate/modules/product-detail/components/VariantList.tsx index 1da478e7..3d5b9b74 100644 --- a/src-migrate/modules/product-detail/components/VariantList.tsx +++ b/src-migrate/modules/product-detail/components/VariantList.tsx @@ -89,8 +89,14 @@ const Row = ({ variant }: { variant: IProductVariantDetail }) => { {variant.weight > 0 ? `${variant.weight} Kg` : '-'}
- {variant.price.price > 0 && `Rp ${formatCurrency(variant.price.price)}`} - {variant.price.price === 0 && '-'} + {variant.price.discount_percentage > 0 && ( +
+
{Math.floor(variant.price.discount_percentage)}%
+
Rp {formatCurrency(variant.price.price)}
+
+ )} + {variant.price.price_discount > 0 && `Rp ${formatCurrency(variant.price.price_discount)}`} + {variant.price.price_discount === 0 && '-'}