summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/components/elements/Popup/BottomPopup.jsx2
-rw-r--r--src/lib/cart/components/Cart.jsx2
-rw-r--r--src/lib/cart/hooks/useCart.js10
-rw-r--r--src/lib/product/components/Product/ProductDesktop.jsx74
-rw-r--r--src/lib/product/components/Product/ProductMobile.jsx101
-rw-r--r--src/lib/product/components/ProductCard.jsx99
-rw-r--r--src/pages/api/shop/search.js4
7 files changed, 114 insertions, 178 deletions
diff --git a/src/core/components/elements/Popup/BottomPopup.jsx b/src/core/components/elements/Popup/BottomPopup.jsx
index 5e9f68c7..4fd17ed0 100644
--- a/src/core/components/elements/Popup/BottomPopup.jsx
+++ b/src/core/components/elements/Popup/BottomPopup.jsx
@@ -53,7 +53,7 @@ const BottomPopup = ({ children, active = false, title, close }) => {
animate={{ bottom: '50%', opacity: 1 }}
exit={{ bottom: '45%', opacity: 0 }}
transition={transition}
- className='fixed left-1/2 -translate-x-1/2 w-2/5 border border-gray_r-6 rounded-xl z-[60] p-4 pt-0 bg-white'
+ className='fixed left-1/2 -translate-x-1/2 translate-y-1/2 w-2/5 border border-gray_r-6 rounded-xl z-[60] p-4 pt-0 bg-white'
>
<div className='flex justify-between py-4'>
<div className='font-semibold text-h-sm'>{title}</div>
diff --git a/src/lib/cart/components/Cart.jsx b/src/lib/cart/components/Cart.jsx
index 8400857d..1131fed7 100644
--- a/src/lib/cart/components/Cart.jsx
+++ b/src/lib/cart/components/Cart.jsx
@@ -288,7 +288,7 @@ const Cart = () => {
<DesktopView>
<div className='container mx-auto py-10 flex'>
- <div className='w-9/12 border border-gray_r-6 rounded bg-white p-4'>
+ <div className='w-9/12 border border-gray_r-6 rounded bg-white p-4 pt-6'>
<h1 className='text-title-sm font-semibold mb-6'>Daftar Produk Belanja</h1>
<table className='table-cart'>
diff --git a/src/lib/cart/hooks/useCart.js b/src/lib/cart/hooks/useCart.js
index bc1ea7ea..b91c8d90 100644
--- a/src/lib/cart/hooks/useCart.js
+++ b/src/lib/cart/hooks/useCart.js
@@ -4,14 +4,12 @@ import _ from 'lodash'
import CartApi from '../api/CartApi'
const useCart = ({ enabled }) => {
- const cart = getCart()
- const variantIds = _.keys(cart).join(',')
+ const cartStorage = getCart()
+ const variantIds = _.keys(cartStorage).join(',')
const fetchCart = async () => CartApi({ variantIds })
- const { data, isLoading } = useQuery('cart', fetchCart, { enabled })
+ const cart = useQuery('cart', fetchCart, { enabled })
- return {
- cart: { data, isLoading }
- }
+ return { cart }
}
export default useCart
diff --git a/src/lib/product/components/Product/ProductDesktop.jsx b/src/lib/product/components/Product/ProductDesktop.jsx
index c7554242..e0d2a959 100644
--- a/src/lib/product/components/Product/ProductDesktop.jsx
+++ b/src/lib/product/components/Product/ProductDesktop.jsx
@@ -3,19 +3,32 @@ 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 { useRef, useState } from 'react'
+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 useProductPrice from '../../hooks/useProductPrice'
-import PriceSkeleton from '@/core/components/elements/Skeleton/PriceSkeleton'
import { useRouter } from 'next/router'
import { createSlug } from '@/core/utils/slug'
const ProductDesktop = ({ product, wishlist, toggleWishlist }) => {
const router = useRouter()
- const { productPrice } = useProductPrice({ id: product.id })
+
+ const [lowestPrice, setLowestPrice] = useState(null)
+
+ const getLowestPrice = useCallback(() => {
+ const prices = product.variants.map((variant) => variant.price)
+ const lowest = prices.reduce((lowest, price) => {
+ return price.priceDiscount < lowest.priceDiscount ? price : lowest
+ }, prices[0])
+ return lowest
+ }, [product])
+
+ useEffect(() => {
+ const lowest = getLowestPrice()
+ setLowestPrice(lowest)
+ }, [getLowestPrice])
+
const [informationTab, setInformationTab] = useState(informationTabOptions[0].value)
const variantQuantityRefs = useRef([])
@@ -63,8 +76,8 @@ const ProductDesktop = ({ product, wishlist, toggleWishlist }) => {
const productSimilarQuery = [
product?.name.replace(/[()/"&]/g, ''),
- `fq=-product_id:${product.id}`,
- `fq=-manufacture_id:${product.manufacture?.id || 0}`
+ `fq=-product_id_i:${product.id}`,
+ `fq=-manufacture_id_i:${product.manufacture?.id || 0}`
].join('&')
return (
@@ -125,33 +138,30 @@ const ProductDesktop = ({ product, wishlist, toggleWishlist }) => {
{product.variants.length > 1 && product.lowestPrice.priceDiscount > 0 && (
<div className='text-gray_r-12/80'>Harga mulai dari: </div>
)}
- {productPrice.isLoading && <PriceSkeleton />}
- {productPrice.isFetched && (
- <>
- {productPrice?.data?.discount > 0 && (
- <div className='flex gap-x-1 items-center mt-2'>
- <div className='badge-solid-red text-caption-1'>
- {productPrice?.data?.discount}%
- </div>
- <div className='text-gray_r-11 line-through text-caption-1'>
- {currencyFormat(productPrice?.data?.priceExclude)}
- </div>
- </div>
- )}
- <h3 className='text-red_r-11 font-semibold mt-1 text-title-md'>
- {productPrice?.data?.priceExcludeAfterDiscount > 0 ? (
- currencyFormat(productPrice?.data?.priceExcludeAfterDiscount)
- ) : (
- <span className='text-gray_r-12/90 font-normal text-h-sm'>
- Hubungi kami untuk dapatkan harga terbaik,&nbsp;
- <a href='https://wa.me/' className='text-red_r-11 underline'>
- klik disini
- </a>
- </span>
- )}
- </h3>
- </>
+
+ {lowestPrice?.discountPercentage > 0 && (
+ <div className='flex gap-x-1 items-center mt-2'>
+ <div className='badge-solid-red text-caption-1'>
+ {lowestPrice?.discountPercentage}%
+ </div>
+ <div className='text-gray_r-11 line-through text-caption-1'>
+ {currencyFormat(lowestPrice?.price)}
+ </div>
+ </div>
)}
+ <h3 className='text-red_r-11 font-semibold mt-1 text-title-md'>
+ {lowestPrice?.priceDiscount > 0 ? (
+ currencyFormat(lowestPrice?.priceDiscount)
+ ) : (
+ <span className='text-gray_r-12/90 font-normal text-h-sm'>
+ Hubungi kami untuk dapatkan harga terbaik,&nbsp;
+ <a href='https://wa.me/' className='text-red_r-11 underline'>
+ klik disini
+ </a>
+ </span>
+ )}
+ </h3>
+
<button
type='button'
onClick={goToVariantSection}
diff --git a/src/lib/product/components/Product/ProductMobile.jsx b/src/lib/product/components/Product/ProductMobile.jsx
index e560639c..13b02354 100644
--- a/src/lib/product/components/Product/ProductMobile.jsx
+++ b/src/lib/product/components/Product/ProductMobile.jsx
@@ -11,24 +11,28 @@ import { HeartIcon } from '@heroicons/react/24/outline'
import { useRouter } from 'next/router'
import MobileView from '@/core/components/views/MobileView'
import { toast } from 'react-hot-toast'
-import useVariantPrice from '@/lib/variant/hooks/useVariantPrice'
-import PriceSkeleton from '@/core/components/elements/Skeleton/PriceSkeleton'
-import useProductPrice from '../../hooks/useProductPrice'
import { createSlug } from '@/core/utils/slug'
const ProductMobile = ({ product, wishlist, toggleWishlist }) => {
const router = useRouter()
- const { productPrice } = useProductPrice({ id: product.id })
const [quantity, setQuantity] = useState('1')
const [selectedVariant, setSelectedVariant] = useState(null)
const [informationTab, setInformationTab] = useState(informationTabOptions[0].value)
+ const getLowestPrice = () => {
+ const prices = product.variants.map((variant) => variant.price)
+ const lowest = prices.reduce((lowest, price) => {
+ return price.priceDiscount < lowest.priceDiscount ? price : lowest
+ }, prices[0])
+ return lowest
+ }
+
const [activeVariant, setActiveVariant] = useState({
id: null,
code: product.code,
name: product.name,
- price: product.lowestPrice,
+ price: getLowestPrice(),
stock: product.stockTotal,
weight: product.weight
})
@@ -93,8 +97,8 @@ const ProductMobile = ({ product, wishlist, toggleWishlist }) => {
const productSimilarQuery = [
product?.name.replace(/[()/"&]/g, ''),
- `fq=-product_id:${product.id}`,
- `fq=-manufacture_id:${product.manufacture?.id || 0}`
+ `fq=-product_id_i:${product.id}`,
+ `fq=-manufacture_id_i:${product.manufacture?.id || 0}`
].join('&')
return (
@@ -124,36 +128,32 @@ const ProductMobile = ({ product, wishlist, toggleWishlist }) => {
)}
</button>
</div>
- <h1 className='leading-6 font-medium'>{activeVariant?.name}</h1>
- {activeVariant.id && <VariantPrice id={activeVariant.id} />}
- {product.variants?.length > 1 && !activeVariant.id && productPrice.isLoading && (
- <PriceSkeleton />
+ <h1 className='leading-6 font-medium mb-3'>{activeVariant?.name}</h1>
+
+ {product.variants.length > 1 && activeVariant.price.priceDiscount > 0 && !selectedVariant && (
+ <div className='text-gray_r-12/80 text-caption-2 mt-2 mb-1'>Harga mulai dari: </div>
)}
- {product.variants?.length > 1 && !activeVariant.id && productPrice.isFetched && (
- <>
- <div className='text-gray_r-12/80 text-caption-2 mt-2 mb-1'>Harga mulai dari: </div>
- {productPrice?.data?.discount > 0 && (
- <div className='flex gap-x-1 items-center'>
- <div className='text-gray_r-11 line-through text-caption-1'>
- {currencyFormat(productPrice?.data?.priceExclude)}
- </div>
- <div className='badge-solid-red'>{productPrice?.data?.discount}%</div>
- </div>
- )}
- <h3 className='text-red_r-11 font-semibold mt-1'>
- {productPrice?.data?.priceExcludeAfterDiscount > 0 ? (
- currencyFormat(productPrice?.data?.priceExcludeAfterDiscount)
- ) : (
- <span className='text-gray_r-11 leading-6 font-normal'>
- Hubungi kami untuk dapatkan harga terbaik,&nbsp;
- <a href='https://wa.me/' className='text-red_r-11 underline'>
- klik disini
- </a>
- </span>
- )}
- </h3>
- </>
+
+ {activeVariant?.price?.discountPercentage > 0 && (
+ <div className='flex gap-x-1 items-center'>
+ <div className='text-gray_r-11 line-through text-caption-1'>
+ {currencyFormat(activeVariant?.price?.price)}
+ </div>
+ <div className='badge-solid-red'>{activeVariant?.price?.discountPercentage}%</div>
+ </div>
)}
+ <h3 className='text-red_r-11 font-semibold mt-1'>
+ {activeVariant?.price?.priceDiscount > 0 ? (
+ currencyFormat(activeVariant?.price?.priceDiscount)
+ ) : (
+ <span className='text-gray_r-11 leading-6 font-normal'>
+ Hubungi kami untuk dapatkan harga terbaik,&nbsp;
+ <a href='https://wa.me/' className='text-red_r-11 underline'>
+ klik disini
+ </a>
+ </span>
+ )}
+ </h3>
</div>
<Divider />
@@ -268,37 +268,6 @@ const ProductMobile = ({ product, wishlist, toggleWishlist }) => {
)
}
-const VariantPrice = ({ id }) => {
- const { variantPrice } = useVariantPrice({ id })
-
- if (variantPrice.isLoading) return <PriceSkeleton />
-
- return (
- <>
- {variantPrice?.data?.discount > 0 && (
- <div className='flex gap-x-1 items-center mt-2'>
- <div className='text-gray_r-11 line-through text-caption-1'>
- {currencyFormat(variantPrice?.data?.priceExclude)}
- </div>
- <div className='badge-solid-red'>{variantPrice?.data?.discount}%</div>
- </div>
- )}
- <h3 className='text-red_r-11 font-semibold mt-1'>
- {variantPrice?.data?.priceExcludeAfterDiscount > 0 ? (
- currencyFormat(variantPrice?.data?.priceExcludeAfterDiscount)
- ) : (
- <span className='text-gray_r-11 leading-6 font-normal'>
- Hubungi kami untuk dapatkan harga terbaik,&nbsp;
- <a href='https://wa.me/' className='text-red_r-11 underline'>
- klik disini
- </a>
- </span>
- )}
- </h3>
- </>
- )
-}
-
const informationTabOptions = [
{ value: 'specification', label: 'Spesifikasi' },
{ value: 'description', label: 'Deskripsi' },
diff --git a/src/lib/product/components/ProductCard.jsx b/src/lib/product/components/ProductCard.jsx
index e48ab88a..df709394 100644
--- a/src/lib/product/components/ProductCard.jsx
+++ b/src/lib/product/components/ProductCard.jsx
@@ -2,9 +2,6 @@ import Image from '@/core/components/elements/Image/Image'
import Link from '@/core/components/elements/Link/Link'
import currencyFormat from '@/core/utils/currencyFormat'
import { createSlug } from '@/core/utils/slug'
-import useProductPrice from '../hooks/useProductPrice'
-import { LazyLoadComponent } from 'react-lazy-load-image-component'
-import PriceSkeleton from '@/core/components/elements/Skeleton/PriceSkeleton'
const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => {
if (variant == 'vertical') {
@@ -48,9 +45,23 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => {
>
{product?.name}
</Link>
- <LazyLoadComponent>
- <ProductCardPrice variant='vertical' id={product.id} />
- </LazyLoadComponent>
+ {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'>
+ {currencyFormat(product.lowestPrice.price)}
+ </div>
+ <div className='badge-solid-red'>{product?.lowestPrice.discountPercentage}%</div>
+ </div>
+ )}
+
+ <div className='text-red_r-11 font-semibold mb-2'>
+ {product?.lowestPrice.priceDiscount > 0 ? (
+ currencyFormat(product?.lowestPrice.priceDiscount)
+ ) : (
+ <a href='https://wa.me/'>Call for price</a>
+ )}
+ </div>
+
{product?.stockTotal > 0 && (
<div className='flex gap-x-1'>
<div className='badge-solid-red'>Ready Stock</div>
@@ -106,83 +117,31 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => {
{product?.name}
</Link>
- <LazyLoadComponent>
- <ProductCardPrice variant='horizontal' id={product.id} />
- </LazyLoadComponent>
- {product?.stockTotal > 0 && (
- <div className='flex gap-x-1'>
- <div className='badge-solid-red'>Ready Stock</div>
- <div className='badge-gray'>{product?.stockTotal > 5 ? '> 5' : '< 5'}</div>
- </div>
- )}
- </div>
- </div>
- )
- }
-}
-
-const ProductCardPrice = ({ variant, id }) => {
- const { productPrice } = useProductPrice({ id })
-
- if (productPrice.isLoading) return <PriceSkeleton />
-
- if (variant == 'vertical') {
- return (
- productPrice.isFetched && (
- <>
- {productPrice?.data?.discount > 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'>
- {currencyFormat(
- productPrice?.data?.priceStartFrom || productPrice?.data?.priceExclude
- )}
+ <div className='badge-solid-red'>{product?.lowestPrice?.discountPercentage}%</div>
+ <div className='text-gray_r-11 line-through text-caption-2'>
+ {currencyFormat(product?.lowestPrice?.price)}
</div>
- <div className='badge-solid-red'>{productPrice?.data?.discount}%</div>
</div>
)}
<div className='text-red_r-11 font-semibold mb-2'>
- {productPrice?.data?.priceExcludeAfterDiscount > 0 ? (
- currencyFormat(
- productPrice?.data?.priceDiscStartFrom ||
- productPrice?.data?.priceExcludeAfterDiscount
- )
+ {product?.lowestPrice?.priceDiscount > 0 ? (
+ currencyFormat(product?.lowestPrice?.priceDiscount)
) : (
<a href='https://wa.me/'>Call for price</a>
)}
</div>
- </>
- )
- )
- }
- if (variant == 'horizontal') {
- return (
- productPrice.isFetched && (
- <>
- {productPrice?.data?.discount > 0 && (
- <div className='flex gap-x-1 mb-1 items-center'>
- <div className='badge-solid-red'>{productPrice?.data?.discount}%</div>
- <div className='text-gray_r-11 line-through text-caption-2'>
- {currencyFormat(
- productPrice?.data?.priceStartFrom || productPrice?.data?.priceExclude
- )}
- </div>
+ {product?.stockTotal > 0 && (
+ <div className='flex gap-x-1'>
+ <div className='badge-solid-red'>Ready Stock</div>
+ <div className='badge-gray'>{product?.stockTotal > 5 ? '> 5' : '< 5'}</div>
</div>
)}
-
- <div className='text-red_r-11 font-semibold mb-2'>
- {productPrice?.data?.priceExcludeAfterDiscount > 0 ? (
- currencyFormat(
- productPrice?.data?.priceDiscStartFrom ||
- productPrice?.data?.priceExcludeAfterDiscount
- )
- ) : (
- <a href='https://wa.me/'>Call for price</a>
- )}
- </div>
- </>
- )
+ </div>
+ </div>
)
}
}
diff --git a/src/pages/api/shop/search.js b/src/pages/api/shop/search.js
index d6829f6e..e174b06f 100644
--- a/src/pages/api/shop/search.js
+++ b/src/pages/api/shop/search.js
@@ -10,8 +10,8 @@ const productResponseMap = (products) => {
name: product.name_s || '',
lowestPrice: {
price: product.price_f || 0,
- priceDiscount: product.discount_f || 0,
- discountPercentage: product.price_discount_f || 0
+ priceDiscount: product.price_discount_f || 0,
+ discountPercentage: product.discount_f || 0
},
variantTotal: product.variant_total_i || 0,
stockTotal: product.stock_total_f || 0,