summaryrefslogtreecommitdiff
path: root/src/lib/product
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/product')
-rw-r--r--src/lib/product/components/Product/ProductDesktop.jsx2
-rw-r--r--src/lib/product/components/Product/ProductDesktopVariant.jsx324
-rw-r--r--src/lib/product/components/Product/ProductMobile.jsx4
-rw-r--r--src/lib/product/components/Product/ProductMobileVariant.jsx240
-rw-r--r--src/lib/product/components/ProductCard.jsx195
-rw-r--r--src/lib/product/components/ProductFilterDesktop.jsx10
-rw-r--r--src/lib/product/components/ProductFilterDesktopPromotion.jsx132
-rw-r--r--src/lib/product/components/ProductSearch.jsx25
8 files changed, 630 insertions, 302 deletions
diff --git a/src/lib/product/components/Product/ProductDesktop.jsx b/src/lib/product/components/Product/ProductDesktop.jsx
index a12b8609..444ddd8e 100644
--- a/src/lib/product/components/Product/ProductDesktop.jsx
+++ b/src/lib/product/components/Product/ProductDesktop.jsx
@@ -235,7 +235,7 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => {
<ImageNext
src={
backgorundFlashSale ||
- '/images/GAMBAR-BG-FLASH-SALE.jpg'
+ '/images/BG-FLASH-SALE.jpg'
}
width={1000}
height={100}
diff --git a/src/lib/product/components/Product/ProductDesktopVariant.jsx b/src/lib/product/components/Product/ProductDesktopVariant.jsx
index ef61bafd..09b30a44 100644
--- a/src/lib/product/components/Product/ProductDesktopVariant.jsx
+++ b/src/lib/product/components/Product/ProductDesktopVariant.jsx
@@ -1,137 +1,155 @@
-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 useAuth from '@/core/hooks/useAuth'
-import odooApi from '@/core/api/odooApi'
-import { useProductCartContext } from '@/contexts/ProductCartContext'
-import { Box, Skeleton, Tooltip } from '@chakra-ui/react'
-import { Info } from 'lucide-react'
-
-const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant }) => {
- const router = useRouter()
- const auth = useAuth()
- const { slug } = router.query
-
- const [lowestPrice, setLowestPrice] = useState(null)
-
- const [addCartAlert, setAddCartAlert] = useState(false)
- const [isLoadingSLA, setIsLoadingSLA] = useState(true)
-
- const { setRefreshCart } = useProductCartContext()
+
+import { Box, Skeleton, Tooltip } from '@chakra-ui/react';
+import { HeartIcon } from '@heroicons/react/24/outline';
+import { Info } from 'lucide-react';
+import { useRouter } from 'next/router';
+import { useCallback, useEffect, useRef, useState } from 'react';
+import { toast } from 'react-hot-toast';
+import LazyLoad from 'react-lazy-load';
+
+import { useProductCartContext } from '@/contexts/ProductCartContext';
+import odooApi from '@/core/api/odooApi';
+import Image from '@/core/components/elements/Image/Image';
+import Link from '@/core/components/elements/Link/Link';
+import BottomPopup from '@/core/components/elements/Popup/BottomPopup';
+import DesktopView from '@/core/components/views/DesktopView';
+import useAuth from '@/core/hooks/useAuth';
+import { updateItemCart } from '@/core/utils/cart';
+import currencyFormat from '@/core/utils/currencyFormat';
+import { createSlug } from '@/core/utils/slug';
+import whatsappUrl from '@/core/utils/whatsappUrl';
+
+import productSimilarApi from '../../api/productSimilarApi';
+import ProductCard from '../ProductCard';
+import ProductSimilar from '../ProductSimilar';
+
+const ProductDesktopVariant = ({
+ product,
+ wishlist,
+ toggleWishlist,
+ isVariant,
+}) => {
+ const router = useRouter();
+ const auth = useAuth();
+ const { slug } = router.query;
+
+ const [lowestPrice, setLowestPrice] = useState(null);
+
+ const [addCartAlert, setAddCartAlert] = useState(false);
+ const [isLoadingSLA, setIsLoadingSLA] = useState(true);
+
+ const { setRefreshCart } = useProductCartContext();
const getLowestPrice = useCallback(() => {
- const lowest = product.price
+ const lowest = product.price;
/* const lowest = prices.reduce((lowest, price) => {
return price.priceDiscount < lowest.priceDiscount ? price : lowest
}, prices[0])*/
- return lowest
- }, [product])
+ return lowest;
+ }, [product]);
useEffect(() => {
- const lowest = getLowestPrice()
- setLowestPrice(lowest)
- }, [getLowestPrice])
+ const lowest = getLowestPrice();
+ setLowestPrice(lowest);
+ }, [getLowestPrice]);
- const [informationTab, setInformationTab] = useState(informationTabOptions[0].value)
+ const [informationTab, setInformationTab] = useState(
+ informationTabOptions[0].value
+ );
- const variantQuantityRefs = useRef([])
+ const variantQuantityRefs = useRef([]);
const setVariantQuantityRef = (variantId) => (element) => {
- 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 handleAddToCart = (variant) => {
if (!auth) {
- router.push(`/login?next=/shop/product/${slug}`)
- return
+ router.push(`/login?next=/shop/product/${slug}`);
+ return;
}
- const quantity = variantQuantityRefs.current[product.id].value
- if (!validQuantity(quantity)) return
+ const quantity = variantQuantityRefs.current[product.id].value;
+ if (!validQuantity(quantity)) return;
updateItemCart({
productId: product.id,
quantity,
programLineId: null,
selected: true,
- source: null
+ source: null,
}).then(() => {
- setRefreshCart(true)
- })
- setAddCartAlert(true)
- }
+ setRefreshCart(true);
+ });
+ setAddCartAlert(true);
+ };
const handleBuy = (variant) => {
- const quantity = variantQuantityRefs.current[product.id].value
- if (!validQuantity(quantity)) return
+ const quantity = variantQuantityRefs.current[product.id].value;
+ if (!validQuantity(quantity)) return;
updateItemCart({
productId: variant,
quantity,
programLineId: null,
selected: true,
- source: 'buy'
- })
- router.push(`/shop/checkout?source=buy`)
- }
+ source: 'buy',
+ });
+ 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 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 dataProductSimilar = await productSimilarApi({ query: productSimilarQuery })
- setProductSimilarInBrand(dataProductSimilar.products)
- }
- if (!productSimilarInBrand) loadProductSimilarInBrand()
- }, [product, productSimilarInBrand])
+ const productSimilarQuery = [
+ product?.name,
+ `fq=-product_id_i:${product.id}`,
+ ].join('&');
+ const dataProductSimilar = await productSimilarApi({
+ query: productSimilarQuery,
+ });
+ setProductSimilarInBrand(dataProductSimilar.products);
+ };
+ if (!productSimilarInBrand) loadProductSimilarInBrand();
+ }, [product, productSimilarInBrand]);
useEffect(() => {
const fetchData = async () => {
- const dataSLA = await odooApi('GET', `/api/v1/product_variant/${product.id}/stock`)
- product.sla = dataSLA
+ const dataSLA = await odooApi(
+ 'GET',
+ `/api/v1/product_variant/${product.id}/stock`
+ );
+ product.sla = dataSLA;
- setIsLoadingSLA(false)
- }
- fetchData()
- }, [product])
+ setIsLoadingSLA(false);
+ };
+ fetchData();
+ }, [product]);
return (
<DesktopView>
@@ -140,14 +158,16 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant })
<div className='w-full flex flex-wrap'>
<div className='w-5/12'>
<Image
- src={product.image}
+ src={product.image + '?variant=True'}
alt={product.name}
className='h-[430px] object-contain object-center w-full border border-gray_r-4'
/>
</div>
<div className='w-7/12 px-4'>
- <h1 className='text-title-md leading-10 font-medium'>{product?.name}</h1>
+ <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>
@@ -177,7 +197,9 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant })
</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-4/12 text-gray_r-12/70'>
+ Persiapan Barang
+ </div>
<div className='w-8/12'>
{!product?.sla && <Skeleton width='20%' height='16px' />}
{product?.sla && (
@@ -203,8 +225,13 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant })
<a
href={whatsappUrl('product', {
name: product.name,
- manufacture: product?.manufacture?.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'
>
@@ -221,7 +248,12 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant })
<a
href={whatsappUrl('productWeight', {
name: product.name,
- url: createSlug('/shop/product/', product.name, product.id, true)
+ url: createSlug(
+ '/shop/product/',
+ product.name,
+ product.id,
+ true
+ ),
})}
className='text-danger-500 font-medium'
>
@@ -233,44 +265,23 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant })
</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-7 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> */}
+ <div className='p-4 md:p-6 md:bg-gray-50 rounded-xl'>
+ <h2 className='text-h-md md:text-h-lg font-medium'>Informasi Produk</h2>
+ <div className='h-4' />
+ <div
+ className='leading-relaxed text-gray-700'
+ dangerouslySetInnerHTML={{
+ __html:
+ !product.parent.description || product.parent.description == '<p><br></p>'
+ ? 'Belum ada deskripsi'
+ : product.parent.description,
+ }}
+ />
+ </div>
</div>
<div className='w-[25%]'>
- {product?.isFlashsale > 0 && product?.price?.discountPercentage > 0? (
+ {product?.isFlashsale > 0 &&
+ product?.price?.discountPercentage > 0 ? (
<>
<div className='flex gap-x-1 items-center mt-2'>
<div className='badge-solid-red text-caption-1'>
@@ -285,7 +296,9 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant })
</div>
<div className='text-gray_r-9 text-base font-normal mt-1'>
Termasuk PPN:{' '}
- {currencyFormat(product?.price?.priceDiscount * process.env.NEXT_PUBLIC_PPN)}
+ {currencyFormat(
+ product?.price?.priceDiscount * process.env.NEXT_PUBLIC_PPN
+ )}
</div>
</>
) : (
@@ -295,7 +308,9 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant })
{currencyFormat(product?.price?.price)}
<div className='text-gray_r-9 text-base font-normal mt-1'>
Termasuk PPN:{' '}
- {currencyFormat(product?.price?.price * process.env.NEXT_PUBLIC_PPN)}
+ {currencyFormat(
+ product?.price?.price * process.env.NEXT_PUBLIC_PPN
+ )}
</div>
</>
) : (
@@ -305,7 +320,12 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant })
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'
@@ -340,7 +360,10 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant })
</button>
</div>
<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' />
) : (
@@ -366,7 +389,9 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant })
</div>
<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>
@@ -381,21 +406,28 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant })
<div className='flex mt-4'>
<div className='w-[10%]'>
<Image
- src={product.image}
+ src={product.image + '?variant=True'}
alt={product.name}
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>
@@ -403,29 +435,33 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant })
</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 ProductDesktopVariant
+export default ProductDesktopVariant;
diff --git a/src/lib/product/components/Product/ProductMobile.jsx b/src/lib/product/components/Product/ProductMobile.jsx
index e9e64469..113a1e42 100644
--- a/src/lib/product/components/Product/ProductMobile.jsx
+++ b/src/lib/product/components/Product/ProductMobile.jsx
@@ -202,9 +202,7 @@ const ProductMobile = ({ product, wishlist, toggleWishlist }) => {
<div className={`absolute bottom-0 w-full`}>
<div className='absolute bottom-0 w-full'>
<ImageNext
- src={
- backgorundFlashSale || '/images/GAMBAR-BG-FLASH-SALE.jpg'
- }
+ src={backgorundFlashSale || '/images/BG-FLASH-SALE.jpg'}
width={1000}
height={100}
/>
diff --git a/src/lib/product/components/Product/ProductMobileVariant.jsx b/src/lib/product/components/Product/ProductMobileVariant.jsx
index 9888e482..af9e52bb 100644
--- a/src/lib/product/components/Product/ProductMobileVariant.jsx
+++ b/src/lib/product/components/Product/ProductMobileVariant.jsx
@@ -1,37 +1,40 @@
-import Divider from '@/core/components/elements/Divider/Divider'
-import Image from '@/core/components/elements/Image/Image'
-import Link from '@/core/components/elements/Link/Link'
-import currencyFormat from '@/core/utils/currencyFormat'
-import { useEffect, useState } from 'react'
-import Select from 'react-select'
-import ProductSimilar from '../ProductSimilar'
-import LazyLoad from 'react-lazy-load'
-import { updateItemCart } from '@/core/utils/cart'
-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 { createSlug } from '@/core/utils/slug'
-import BottomPopup from '@/core/components/elements/Popup/BottomPopup'
-import whatsappUrl from '@/core/utils/whatsappUrl'
-import { gtagAddToCart } from '@/core/utils/googleTag'
-import odooApi from '@/core/api/odooApi'
-import { Skeleton } from '@chakra-ui/react'
+import { Skeleton } from '@chakra-ui/react';
+import { HeartIcon } from '@heroicons/react/24/outline';
+import { useRouter } from 'next/router';
+import { useEffect, useState } from 'react';
+import { toast } from 'react-hot-toast';
+import LazyLoad from 'react-lazy-load';
+
+import odooApi from '@/core/api/odooApi';
+import Divider from '@/core/components/elements/Divider/Divider';
+import Image from '@/core/components/elements/Image/Image';
+import Link from '@/core/components/elements/Link/Link';
+import BottomPopup from '@/core/components/elements/Popup/BottomPopup';
+import MobileView from '@/core/components/views/MobileView';
+import { updateItemCart } from '@/core/utils/cart';
+import currencyFormat from '@/core/utils/currencyFormat';
+import { gtagAddToCart } from '@/core/utils/googleTag';
+import { createSlug } from '@/core/utils/slug';
+import whatsappUrl from '@/core/utils/whatsappUrl';
+
+import ProductSimilar from '../ProductSimilar';
const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => {
- const router = useRouter()
+ const router = useRouter();
- const [quantity, setQuantity] = useState('1')
- const [selectedVariant, setSelectedVariant] = useState(product.id)
- const [informationTab, setInformationTab] = useState(informationTabOptions[0].value)
- const [addCartAlert, setAddCartAlert] = useState(false)
+ const [quantity, setQuantity] = useState('1');
+ const [selectedVariant, setSelectedVariant] = useState(product.id);
+ const [informationTab, setInformationTab] = useState(
+ informationTabOptions[0].value
+ );
+ const [addCartAlert, setAddCartAlert] = useState(false);
- const [isLoadingSLA, setIsLoadingSLA] = useState(true)
+ const [isLoadingSLA, setIsLoadingSLA] = useState(true);
const getLowestPrice = () => {
- const lowest = product.lowestPrice
- return lowest
- }
+ const lowest = product.lowestPrice;
+ return lowest;
+ };
const [activeVariant, setActiveVariant] = useState({
id: null,
@@ -40,8 +43,8 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => {
price: getLowestPrice(),
stock: product.stockTotal,
weight: product.weight,
- isFlashSale: product.isFlashSale
- })
+ isFlashSale: product.isFlashSale,
+ });
useEffect(() => {
if (selectedVariant) {
@@ -52,70 +55,73 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => {
price: product.price,
stock: product.stockTotal,
weight: product.weight,
- isFlashSale: product.isFlashSale
- })
+ isFlashSale: product.isFlashSale,
+ });
}
- }, [selectedVariant, product])
+ }, [selectedVariant, product]);
const validAction = () => {
- let isValid = true
+ let isValid = true;
if (!selectedVariant) {
- toast.error('Pilih varian terlebih dahulu')
- isValid = false
+ toast.error('Pilih varian terlebih dahulu');
+ isValid = false;
}
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 handleClickCart = () => {
- if (!validAction()) return
- gtagAddToCart(activeVariant, quantity)
+ if (!validAction()) return;
+ gtagAddToCart(activeVariant, quantity);
updateItemCart({
productId: variant,
quantity,
programLineId: null,
selected: true,
- source: null
- })
- setAddCartAlert(true)
- }
+ source: null,
+ });
+ setAddCartAlert(true);
+ };
const handleClickBuy = () => {
- if (!validAction()) return
+ if (!validAction()) return;
updateItemCart({
productId: product.id,
quantity,
programLineId: null,
selected: true,
- source: 'buy'
- })
- router.push(`/shop/checkout?source=buy`)
- }
+ source: 'buy',
+ });
+ router.push(`/shop/checkout?source=buy`);
+ };
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('&');
useEffect(() => {
const fetchData = async () => {
- const dataSLA = await odooApi('GET', `/api/v1/product_variant/${product.id}/stock`)
- product.sla = dataSLA
+ const dataSLA = await odooApi(
+ 'GET',
+ `/api/v1/product_variant/${product.id}/stock`
+ );
+ product.sla = dataSLA;
- setIsLoadingSLA(false)
- }
- fetchData()
- }, [product])
+ setIsLoadingSLA(false);
+ };
+ fetchData();
+ }, [product]);
return (
<MobileView>
<Image
- src={product.image}
+ src={product.image + '?variant=True'}
alt={product.name}
className='h-72 object-contain object-center w-full border-b border-gray_r-4'
/>
@@ -124,7 +130,11 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => {
<div className='flex items-end mb-2'>
{product.manufacture?.name ? (
<Link
- href={createSlug('/shop/brands/', product.manufacture?.name, product.manufacture?.id)}
+ href={createSlug(
+ '/shop/brands/',
+ product.manufacture?.name,
+ product.manufacture?.id
+ )}
>
{product.manufacture?.name}
</Link>
@@ -141,10 +151,13 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => {
</div>
<h1 className='leading-6 font-medium mb-3'>{activeVariant?.name}</h1>
- {activeVariant.isFlashSale && activeVariant?.price?.discountPercentage > 0 ? (
+ {activeVariant.isFlashSale &&
+ activeVariant?.price?.discountPercentage > 0 ? (
<>
<div className='flex gap-x-1 items-center'>
- <div className='badge-solid-red'>{activeVariant?.price?.discountPercentage}%</div>
+ <div className='badge-solid-red'>
+ {activeVariant?.price?.discountPercentage}%
+ </div>
<div className='text-gray_r-11 line-through text-caption-1'>
{currencyFormat(activeVariant?.price?.price)}
</div>
@@ -154,7 +167,9 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => {
</div>
<div className='text-gray_r-9 text-base font-normal mt-1'>
Termasuk PPN:{' '}
- {currencyFormat(activeVariant?.price.priceDiscount * process.env.NEXT_PUBLIC_PPN)}
+ {currencyFormat(
+ activeVariant?.price.priceDiscount * process.env.NEXT_PUBLIC_PPN
+ )}
</div>
</>
) : (
@@ -164,7 +179,9 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => {
{currencyFormat(activeVariant?.price?.price)}
<div className='text-gray_r-9 text-base font-normal mt-1'>
Termasuk PPN:{' '}
- {currencyFormat(activeVariant?.price.price * process.env.NEXT_PUBLIC_PPN)}
+ {currencyFormat(
+ activeVariant?.price.price * process.env.NEXT_PUBLIC_PPN
+ )}
</div>
</>
) : (
@@ -173,7 +190,12 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => {
<a
href={whatsappUrl('product', {
name: product.name,
- url: createSlug('/shop/product/', product.name, product.id, true)
+ url: createSlug(
+ '/shop/product/',
+ product.name,
+ product.id,
+ true
+ ),
})}
className='text-danger-500 underline'
>
@@ -199,10 +221,18 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => {
onChange={(e) => setQuantity(e.target.value)}
/>
</div>
- <button type='button' className='btn-yellow flex-1' onClick={handleClickCart}>
+ <button
+ type='button'
+ className='btn-yellow flex-1'
+ onClick={handleClickCart}
+ >
Keranjang
</button>
- <button type='button' className='btn-solid-red flex-1' onClick={handleClickBuy}>
+ <button
+ type='button'
+ className='btn-solid-red flex-1'
+ onClick={handleClickBuy}
+ >
Beli
</button>
</div>
@@ -238,7 +268,9 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => {
type='button'
title={`Masa Persiapan Barang ${product?.sla?.slaDate}`}
className={`flex gap-x-1 items-center p-2 h-8 rounded-lg w-full ${
- product?.sla?.slaDate === 'indent' ? 'bg-indigo-900' : 'btn-light'
+ product?.sla?.slaDate === 'indent'
+ ? 'bg-indigo-900'
+ : 'btn-light'
}`}
>
<div
@@ -281,14 +313,21 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => {
{activeVariant?.stock > 0 && (
<span className='flex gap-x-1.5'>
<div className='badge-solid-red'>Ready Stock</div>
- <div className='badge-gray'>{activeVariant?.stock > 5 ? '> 5' : '< 5'}</div>
+ <div className='badge-gray'>
+ {activeVariant?.stock > 5 ? '> 5' : '< 5'}
+ </div>
</span>
)}
{activeVariant?.stock == 0 && (
<a
href={whatsappUrl('product', {
name: product.name,
- url: createSlug('/shop/product/', product.name, product.id, true)
+ url: createSlug(
+ '/shop/product/',
+ product.name,
+ product.id,
+ true
+ ),
})}
className='text-danger-500 font-medium'
>
@@ -297,12 +336,19 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => {
)}
</SpecificationContent>
<SpecificationContent label='Berat Barang'>
- {activeVariant?.weight > 0 && <span>{activeVariant?.weight} KG</span>}
+ {activeVariant?.weight > 0 && (
+ <span>{activeVariant?.weight} KG</span>
+ )}
{activeVariant?.weight == 0 && (
<a
href={whatsappUrl('productWeight', {
name: product.name,
- url: createSlug('/shop/product/', product.name, product.id, true)
+ url: createSlug(
+ '/shop/product/',
+ product.name,
+ product.id,
+ true
+ ),
})}
className='text-danger-500 font-medium'
>
@@ -316,7 +362,10 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => {
active={informationTab == 'description'}
className='leading-6 text-gray_r-11'
dangerouslySetInnerHTML={{
- __html: product.description != '' ? product.description : 'Belum ada deskripsi produk.'
+ __html:
+ product.description != ''
+ ? product.description
+ : 'Belum ada deskripsi produk.',
}}
/>
</div>
@@ -338,55 +387,68 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => {
<div className='flex mt-4'>
<div className='w-[15%]'>
<Image
- src={product.image}
+ src={product.image + '?variant=True'}
alt={product.name}
className='h-20 object-contain object-center w-full border border-gray_r-4'
/>
</div>
- <div className='ml-3 flex flex-1 items-center text-sm font-normal'>{product.name}</div>
+ <div className='ml-3 flex flex-1 items-center text-sm font-normal'>
+ {product.name}
+ </div>
<div className='ml-3 flex items-center text-sm 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>
</div>
</BottomPopup>
</MobileView>
- )
-}
+ );
+};
const informationTabOptions = [
- { value: 'specification', label: 'Spesifikasi' }
+ { value: 'specification', label: 'Spesifikasi' },
// { value: 'description', label: 'Deskripsi' },
// { value: 'information', label: 'Info Penting' }
-]
+];
const TabButton = ({ children, active, ...props }) => {
- const activeClassName = active ? 'text-danger-500 underline underline-offset-4' : 'text-gray_r-11'
+ const activeClassName = active
+ ? 'text-danger-500 underline underline-offset-4'
+ : 'text-gray_r-11';
return (
- <button {...props} type='button' className={`font-medium pb-1 ${activeClassName}`}>
+ <button
+ {...props}
+ type='button'
+ className={`font-medium pb-1 ${activeClassName}`}
+ >
{children}
</button>
- )
-}
+ );
+};
const TabContent = ({ children, active, className, ...props }) => (
<div {...props} className={`${active ? 'block' : 'hidden'} ${className}`}>
{children}
</div>
-)
+);
const SpecificationContent = ({ children, label }) => (
<div className='flex justify-between p-3'>
<span className='text-gray_r-11'>{label}</span>
{children}
</div>
-)
+);
-export default ProductMobileVariant
+export default ProductMobileVariant;
diff --git a/src/lib/product/components/ProductCard.jsx b/src/lib/product/components/ProductCard.jsx
index 1cec0804..98732407 100644
--- a/src/lib/product/components/ProductCard.jsx
+++ b/src/lib/product/components/ProductCard.jsx
@@ -1,44 +1,85 @@
-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, useEffect, useState } 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'>
+ <div className="relative">
<Image
src={image}
alt={product?.name}
- className='w-full object-contain object-center h-36 sm:h-48'
+ className="gambarA w-full object-contain object-center h-36 sm:h-48"
/>
+ <div className="absolute top-0 right-0 flex mt-3">
+ <div className="gambarB ">
+ {product?.isSni && (
+ <ImageNext
+ src="/images/sni-logo.png"
+ alt="SNI Logo"
+ className="w-4 h-5 object-contain object-top sm:h-6"
+ width={50}
+ height={50}
+ />
+ )}
+ </div>
+ <div className="gambarC ">
+ {product?.isTkdn && (
+ <ImageNext
+ src="/images/TKDN.png"
+ alt="TKDN"
+ className="w-11 h-6 object-contain object-top ml-1 mr-1 sm:h-6"
+ width={50}
+ height={50}
+ />
+ )}
+ </div>
+ </div>
+ </div>
+
+
{router.pathname != '/' && product?.flashSale?.id > 0 && (
<div className='absolute bottom-0 w-full grid'>
<div className='absolute bottom-0 w-full h-full'>
<ImageNext
- src='/images/GAMBAR-BG-FLASH-SALE.jpg'
+ src='/images/BG-FLASH-SALE.jpg'
className='h-full'
width={1000}
height={100}
@@ -58,7 +99,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 +117,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 +145,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 +162,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 +180,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,22 +192,45 @@ 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'>
+ <div className="relative">
<Image
src={image}
alt={product?.name}
- className='w-full object-contain object-center h-36'
+ className="gambarA w-full object-contain object-center h-36 sm:h-48"
/>
+ <div className="absolute top-0 right-0 flex mt-3">
+ <div className="gambarB ">
+ {product?.isSni && (
+ <ImageNext
+ src="/images/sni-logo.png"
+ alt="SNI Logo"
+ className="w-4 h-5 object-contain object-top sm:h-6"
+ width={50}
+ height={50}
+ />
+ )}
+ </div>
+ <div className="gambarC ">
+ {product?.isTkdn && (
+ <ImageNext
+ src="/images/TKDN.png"
+ alt="TKDN"
+ className="w-11 h-6 object-contain object-top ml-1 sm:h-6"
+ width={50}
+ height={50}
+ />
+ )}
+ </div>
+ </div>
+ </div>
{product.variantTotal > 1 && (
<div className='absolute badge-gray bottom-1.5 left-1.5'>
{product.variantTotal} Varian
@@ -184,26 +255,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 +285,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 +302,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 +320,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 +332,8 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => {
</div>
</div>
</div>
- )
+ );
}
-}
+};
-export default ProductCard
+export default ProductCard;
diff --git a/src/lib/product/components/ProductFilterDesktop.jsx b/src/lib/product/components/ProductFilterDesktop.jsx
index e4a62abb..b4afebc2 100644
--- a/src/lib/product/components/ProductFilterDesktop.jsx
+++ b/src/lib/product/components/ProductFilterDesktop.jsx
@@ -21,6 +21,7 @@ import Image from '@/core/components/elements/Image/Image'
import { formatCurrency } from '@/core/utils/formatValue'
const ProductFilterDesktop = ({ brands, categories, prefixUrl, defaultBrand = null }) => {
+ console.log("prefixUrl",prefixUrl)
const router = useRouter()
const { query } = router
const [order, setOrder] = useState(query?.orderBy)
@@ -102,7 +103,14 @@ const ProductFilterDesktop = ({ brands, categories, prefixUrl, defaultBrand = nu
}
params = _.pickBy(params, _.identity)
params = toQuery(params)
- router.push(`${prefixUrl}?${params}`)
+
+ const slug = Array.isArray(router.query.slug) ? router.query.slug[0] : router.query.slug;
+
+ if (slug) {
+ router.push(`${prefixUrl}/${slug}?${params}`)
+ } else {
+ router.push(`${prefixUrl}?${params}`)
+ }
}
diff --git a/src/lib/product/components/ProductFilterDesktopPromotion.jsx b/src/lib/product/components/ProductFilterDesktopPromotion.jsx
new file mode 100644
index 00000000..0815b881
--- /dev/null
+++ b/src/lib/product/components/ProductFilterDesktopPromotion.jsx
@@ -0,0 +1,132 @@
+import { useRouter } from 'next/router';
+import { useEffect, useState } from 'react';
+import _ from 'lodash';
+import { toQuery } from 'lodash-contrib';
+import { Button } from '@chakra-ui/react';
+import { MultiSelect } from 'react-multi-select-component';
+
+const ProductFilterDesktop = ({ brands, categories, prefixUrl }) => {
+ const router = useRouter();
+ const { query } = router;
+ const [order, setOrder] = useState(query?.orderBy);
+ const [brandValues, setBrand] = useState([]);
+ const [categoryValues, setCategory] = useState([]);
+ const [priceFrom, setPriceFrom] = useState(query?.priceFrom);
+ const [priceTo, setPriceTo] = useState(query?.priceTo);
+ const [stock, setStock] = useState(query?.stock);
+ const [activeRange, setActiveRange] = useState(null);
+ const [isBrandDropdownClicked, setIsBrandDropdownClicked] = useState(false);
+ const [isCategoryDropdownClicked, setIsCategoryDropdownClicked] = useState(false);
+
+ // Effect to set brandValues from query parameter 'brand'
+ useEffect(() => {
+ const brandParam = query?.brand;
+ if (brandParam) {
+ const brandsArray = brandParam.split(',').map((b) => ({
+ label: b,
+ value: b,
+ }));
+ setBrand(brandsArray);
+ }
+
+ }, [query.brand]); // Trigger effect whenever query.brand changes
+
+ useEffect(() => {
+ const categoryParam = query?.category;
+ if (categoryParam) {
+ const categoriesArray = categoryParam.split(',').map((c) => ({
+ label: c,
+ value: c,
+ }));
+ setCategory(categoriesArray);
+ }
+ }, [query.category]); // Trigger effect whenever query.category changes
+
+ const handleSubmit = () => {
+ let params = {
+ q: router.query.q,
+ orderBy: order,
+ brand: brandValues.map((b) => b.value).join(','),
+ category: categoryValues.map((c) => c.value).join(','),
+ priceFrom,
+ priceTo,
+ stock: stock,
+ };
+ params = _.pickBy(params, _.identity);
+ params = toQuery(params);
+
+ const slug = Array.isArray(router.query.slug)
+ ? router.query.slug[0]
+ : router.query.slug;
+
+ if (slug) {
+ router.push(`${prefixUrl}/${slug}?${params}`);
+ } else {
+ router.push(`${prefixUrl}?${params}`);
+ }
+ };
+
+
+ const brandOptions = brands.map((brand) => ({
+ label: `${brand.brand} (${brand.qty})`,
+ value: brand.brand,
+ }));
+
+ const categoryOptions = categories.map((category) => ({
+ label: `${category.name} (${category.qty})`,
+ value: category.name,
+ }));
+
+ return (
+ <>
+ <div className='flex h-full w-[100%] justify-end '>
+ {/* Brand MultiSelect */}
+ <div className='mb-[20px] mr-4 w-64 h-full flex justify-start '>
+ <div className='relative'>
+ <label>Brand</label>
+ <div className='h-auto z-50 w-64 '>
+ <MultiSelect
+ options={brandOptions}
+ value={brandValues}
+ onChange={setBrand}
+ labelledBy='Select Brand'
+ onMenuToggle={(isOpen) => setIsBrandDropdownClicked(isOpen)}
+ hasSelectAll={false}
+ />
+ </div>
+ </div>
+ </div>
+
+ {/* Category MultiSelect */}
+ <div className='mb-[20px] mr-4 w-64 h-full flex justify-start '>
+ <div className='relative'>
+ <label>Kategori</label>
+ <div className=' h-auto w-64'>
+ <MultiSelect
+ options={categoryOptions}
+ value={categoryValues}
+ onChange={setCategory}
+ labelledBy='Select Kategori'
+ onMenuToggle={() =>
+ setIsCategoryDropdownClicked(!isCategoryDropdownClicked)
+ }
+ hasSelectAll={false}
+ />
+ </div>
+ </div>
+ </div>
+
+ {/* Apply Button */}
+ <div className='TOMBOL mb-1 h-24 flex justify-center items-center w-24'>
+ <div className=' bottom-1 pb-1 left-0 right-0 flex justify-center rounded' >
+ <Button colorScheme='red' width={"full"} onClick={handleSubmit}>
+ Terapkan
+ </Button>
+ </div>
+ </div>
+ </div>
+ </>
+ );
+};
+
+export default ProductFilterDesktop;
diff --git a/src/lib/product/components/ProductSearch.jsx b/src/lib/product/components/ProductSearch.jsx
index b3fdf888..ec0077c2 100644
--- a/src/lib/product/components/ProductSearch.jsx
+++ b/src/lib/product/components/ProductSearch.jsx
@@ -24,6 +24,9 @@ import ProductFilter from './ProductFilter';
import ProductFilterDesktop from './ProductFilterDesktop';
import ProductSearchSkeleton from './Skeleton/ProductSearchSkeleton';
+import SideBanner from '~/modules/side-banner';
+import FooterBanner from '~/modules/footer-banner';
+
const ProductSearch = ({
query,
prefixUrl,
@@ -127,6 +130,7 @@ const ProductSearch = ({
brands.push({ brand, qty });
}
}
+ console.log("daftar brand",brands)
const categories = [];
for (
@@ -141,6 +145,7 @@ const ProductSearch = ({
categories.push({ name, qty });
}
}
+ console.log("daftar kategori",categories)
const orderOptions = [
{ value: 'price-asc', label: 'Harga Terendah' },
@@ -268,11 +273,16 @@ const ProductSearch = ({
<h1 className='mb-2 font-semibold text-h-sm'>
Brand Pencarian {q}
</h1>
- <Image
- src={isBrand?.logo}
- alt=''
- className='object-cover object-center h-[60px]'
- />
+ <Link
+ href={createSlug('/shop/brands/', isBrand.name, isBrand.id)}
+ className='inline'
+ >
+ <Image
+ src={isBrand?.logo}
+ alt=''
+ className='object-cover object-center h-[60px]'
+ />
+ </Link>
</div>
)}
<h1 className='mb-2 font-semibold text-h-sm'>Produk</h1>
@@ -396,6 +406,10 @@ const ProductSearch = ({
prefixUrl={prefixUrl}
defaultBrand={defaultBrand}
/>
+
+ <div className='h-6' />
+
+ <SideBanner />
</div>
<div className='w-9/12 pl-6'>
{bannerPromotionHeader && bannerPromotionHeader?.image && (
@@ -547,6 +561,7 @@ const ProductSearch = ({
/>
</div>
)}
+ <FooterBanner />
</div>
</div>
</DesktopView>