summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/brand/components/Brands.jsx15
-rw-r--r--src/lib/cart/components/Cartheader.jsx12
-rw-r--r--src/lib/checkout/components/CheckoutOld.jsx1
-rw-r--r--src/lib/home/components/PreferredBrand.jsx6
-rw-r--r--src/lib/home/components/ServiceList.jsx105
-rw-r--r--src/lib/home/components/Skeleton/PopularProductSkeleton.jsx3
-rw-r--r--src/lib/home/hooks/usePreferredBrand.js13
-rw-r--r--src/lib/product/components/Product/ColumnsSLA.jsx89
-rw-r--r--src/lib/product/components/Product/ProductDesktop.jsx172
-rw-r--r--src/lib/product/components/Product/ProductDesktopVariant.jsx164
-rw-r--r--src/lib/product/components/Product/ProductMobile.jsx70
-rw-r--r--src/lib/product/components/Product/ProductMobileVariant.jsx84
-rw-r--r--src/lib/product/components/ProductCard.jsx89
-rw-r--r--src/lib/product/components/ProductFilterDesktop.jsx165
-rw-r--r--src/lib/product/components/ProductSearch.jsx8
-rw-r--r--src/lib/product/components/ProductSlider.jsx2
16 files changed, 577 insertions, 421 deletions
diff --git a/src/lib/brand/components/Brands.jsx b/src/lib/brand/components/Brands.jsx
index c7483e40..f6cb4fbf 100644
--- a/src/lib/brand/components/Brands.jsx
+++ b/src/lib/brand/components/Brands.jsx
@@ -1,7 +1,7 @@
-import odooApi from '@/core/api/odooApi'
import { useCallback, useEffect, useState } from 'react'
import BrandCard from './BrandCard'
import LogoSpinner from '@/core/components/elements/Spinner/LogoSpinner'
+import axios from 'axios'
const Brands = () => {
const alpha = Array.from(Array(26)).map((e, i) => i + 65)
@@ -13,13 +13,18 @@ const Brands = () => {
const loadBrand = useCallback(async () => {
setIsLoading(true)
- const name = startWith ? `${startWith}%` : ''
- const result = await odooApi(
+ const name = startWith ? `${startWith}*` : ''
+ //Get brand from odoo
+ /*const result = await odooApi(
'GET',
`/api/v1/manufacture?limit=0&offset=${manufactures.length}&name=${name}`
- )
+ )*/
+
+ // Change get brands from solr
+ const result = await axios(`${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/brands?params=${name}`)
+
setIsLoading(false)
- setManufactures((manufactures) => [...manufactures, ...result.manufactures])
+ setManufactures((manufactures) => [...result.data])
}, [startWith])
const toggleStartWith = (alphabet) => {
diff --git a/src/lib/cart/components/Cartheader.jsx b/src/lib/cart/components/Cartheader.jsx
index dd6c276e..cbe7c7e1 100644
--- a/src/lib/cart/components/Cartheader.jsx
+++ b/src/lib/cart/components/Cartheader.jsx
@@ -48,7 +48,7 @@ const Cardheader = (cartCount) => {
setProductCart(cart)
setCountCart(cart.productTotal)
setIsloading(false)
- }, [setProductCart])
+ }, [setProductCart, setIsloading])
useEffect(() => {
if (!products) return
@@ -158,14 +158,14 @@ const Cardheader = (cartCount) => {
</div>
</div>
))}
- {products.length === 0 && !isLoading && (
+ {auth && products.length === 0 && !isLoading && (
<div className='justify-center p-4'>
<p className='text-gray-500 text-center '>
Tidak Ada Produk di Keranjang Belanja Anda
</p>
</div>
)}
- {products.length > 0 && !isLoading && (
+ {auth && products.length > 0 && !isLoading && (
<>
<ul role='list' class='divide-y divide-gray-200 dark:divide-gray-700'>
{products &&
@@ -251,11 +251,11 @@ const Cardheader = (cartCount) => {
</>
)}
</div>
- {products.length > 0 && !isLoading && (
+ {auth && products.length > 0 && !isLoading && (
<>
<div className='mt-3'>
- <span className='text-gray-400 text-caption-2'>Sub Total Sebelum PPN : </span>
- <span className='font-semibold text-red-600'>Rp. {currencyFormat(subTotal)}</span>
+ <span className='text-gray-400 text-caption-2'>Subtotal Sebelum PPN : </span>
+ <span className='font-semibold text-red-600'>{currencyFormat(subTotal)}</span>
</div>
<div className='mt-5 mb-2'>
<button
diff --git a/src/lib/checkout/components/CheckoutOld.jsx b/src/lib/checkout/components/CheckoutOld.jsx
index 088b641b..6852059e 100644
--- a/src/lib/checkout/components/CheckoutOld.jsx
+++ b/src/lib/checkout/components/CheckoutOld.jsx
@@ -22,7 +22,6 @@ import DesktopView from '@/core/components/views/DesktopView'
import ExpedisiList from '../api/ExpedisiList'
import whatsappUrl from '@/core/utils/whatsappUrl'
import { createSlug } from '@/core/utils/slug'
-import { Button, Modal } from 'flowbite-react'
import BottomPopup from '@/core/components/elements/Popup/BottomPopup'
const SELF_PICKUP_ID = 32
diff --git a/src/lib/home/components/PreferredBrand.jsx b/src/lib/home/components/PreferredBrand.jsx
index 55abe0b7..571c4745 100644
--- a/src/lib/home/components/PreferredBrand.jsx
+++ b/src/lib/home/components/PreferredBrand.jsx
@@ -6,7 +6,9 @@ import useDevice from '@/core/hooks/useDevice'
import Link from '@/core/components/elements/Link/Link'
const PreferredBrand = () => {
- const { preferredBrands } = usePreferredBrand()
+ let query = 'level_s'
+ let params = 'prioritas'
+ const { preferredBrands } = usePreferredBrand(query)
const { isMobile, isDesktop } = useDevice()
return (
@@ -22,7 +24,7 @@ const PreferredBrand = () => {
{preferredBrands.isLoading && <PreferredBrandSkeleton />}
{!preferredBrands.isLoading && (
<Swiper slidesPerView={isMobile ? 3.5 : 7.5} spaceBetween={isMobile ? 12 : 24} freeMode>
- {preferredBrands.data?.manufactures.map((brand) => (
+ {preferredBrands.data?.data.map((brand) => (
<SwiperSlide key={brand.id}>
<BrandCard brand={brand} />
</SwiperSlide>
diff --git a/src/lib/home/components/ServiceList.jsx b/src/lib/home/components/ServiceList.jsx
new file mode 100644
index 00000000..b8799d7d
--- /dev/null
+++ b/src/lib/home/components/ServiceList.jsx
@@ -0,0 +1,105 @@
+import Image from 'next/image'
+import Link from '@/core/components/elements/Link/Link'
+
+const ServiceList = () => {
+ return (
+ <div className='px-4 sm:px-0'>
+ <div className='grid md:grid-cols-4 grid-cols-2 justify-between gap-2 items-center'>
+ <div className='w-full'>
+ <Link
+ href='/tentang-kami'
+ className='border border-gray-200 p-2 flex items-center gap-x-2 rounded-lg'
+ >
+ <div className=''>
+ <Image
+ width={24}
+ height={24}
+ quality={100}
+ src='/images/icon_service/ONE-STOP-SOLUTIONS.svg'
+ alt=''
+ className='h-20 w-20 rounded'
+ />
+ </div>
+ <div className=''>
+ <h1 className='text-gray-900 font-semibold text-base'>One Stop Solution</h1>
+ <p className='text-xs md:text-sm text-gray-500'>
+ Temukan Solusi Lengkap Anda dalam Satu Tempat.
+ </p>
+ </div>
+ </Link>
+ </div>
+ <div className='w-full'>
+ <Link
+ href='/tentang-kami'
+ className='border border-gray-200 p-2 flex items-center gap-x-2 rounded-lg'
+ >
+ <div className=''>
+ <Image
+ width={24}
+ height={24}
+ quality={100}
+ src='/images/icon_service/WARRANTY.svg'
+ alt=''
+ className='h-20 w-20 rounded'
+ />
+ </div>
+ <div>
+ <h1 className='text-gray-900 font-semibold text-base'>Garansi Resmi</h1>
+ <p className='text-xs md:text-sm text-gray-500'>
+ Garansi Keaslian Barang dan Jaminan Purna Jual.
+ </p>
+ </div>
+ </Link>
+ </div>
+ <div className='w-full '>
+ <Link
+ href='/tentang-kami'
+ className='border border-gray-200 p-2 flex items-center gap-x-2 rounded-lg'
+ >
+ <div className=''>
+ <Image
+ width={24}
+ height={24}
+ quality={100}
+ src='/images/icon_service/DUE-PAYMENT.svg'
+ alt=''
+ className='h-20 w-20 rounded'
+ />
+ </div>
+ <div>
+ <h1 className='text-gray-900 font-semibold text-base'>Pembayaran Tempo</h1>
+ <p className='text-xs md:text-sm text-gray-500'>
+ Lebih mudah mengatur pembelian dengan pembayaran tempo.
+ </p>
+ </div>
+ </Link>
+ </div>
+ <div className='w-full'>
+ <Link
+ href='/tentang-kami'
+ className='border border-gray-200 p-2 flex items-center gap-x-2 rounded-lg'
+ >
+ <div className=''>
+ <Image
+ width={24}
+ height={24}
+ quality={100}
+ src='/images/icon_service/TAX.svg'
+ alt=''
+ className='h-20 w-20 rounded'
+ />
+ </div>
+ <div>
+ <h1 className='text-gray-900 font-semibold text-base'>Faktur Pajak</h1>
+ <p className='text-xs md:text-sm text-gray-500'>
+ Dapat Faktur pajak untuk setiap transaksi dengan indoteknik.com
+ </p>
+ </div>
+ </Link>
+ </div>
+ </div>
+ </div>
+ )
+}
+
+export default ServiceList
diff --git a/src/lib/home/components/Skeleton/PopularProductSkeleton.jsx b/src/lib/home/components/Skeleton/PopularProductSkeleton.jsx
index 29fda966..754bdd57 100644
--- a/src/lib/home/components/Skeleton/PopularProductSkeleton.jsx
+++ b/src/lib/home/components/Skeleton/PopularProductSkeleton.jsx
@@ -11,7 +11,8 @@ const PopularProductSkeleton = () => (
</div>
</MobileView>
<DesktopView>
- <div className='grid grid-cols-5 gap-x-3'>
+ <div className='grid grid-cols-6 gap-x-3'>
+ <ProductCardSkeleton />
<ProductCardSkeleton />
<ProductCardSkeleton />
<ProductCardSkeleton />
diff --git a/src/lib/home/hooks/usePreferredBrand.js b/src/lib/home/hooks/usePreferredBrand.js
index e56d361f..b7d707e6 100644
--- a/src/lib/home/hooks/usePreferredBrand.js
+++ b/src/lib/home/hooks/usePreferredBrand.js
@@ -1,3 +1,4 @@
+import axios from 'axios'
import preferredBrandApi from '../api/preferredBrandApi'
import { useQuery } from 'react-query'
@@ -10,4 +11,14 @@ const usePreferredBrand = () => {
}
}
-export default usePreferredBrand
+const GetBrands = (query) => {
+ const fetchingbrand = async () =>
+ await axios(`${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/brands?params=` + query)
+
+ const { data, isLoading } = useQuery('preferredBrand', fetchingbrand)
+ return {
+ preferredBrands: { data, isLoading }
+ }
+}
+
+export default GetBrands
diff --git a/src/lib/product/components/Product/ColumnsSLA.jsx b/src/lib/product/components/Product/ColumnsSLA.jsx
index 33da703a..e5296f96 100644
--- a/src/lib/product/components/Product/ColumnsSLA.jsx
+++ b/src/lib/product/components/Product/ColumnsSLA.jsx
@@ -1,8 +1,9 @@
import odooApi from '@/core/api/odooApi'
import { createSlug } from '@/core/utils/slug'
import whatsappUrl from '@/core/utils/whatsappUrl'
-import { Button, Spinner } from 'flowbite-react'
-import { memo, useEffect, useState } from 'react'
+import { Box, Skeleton, Tooltip } from '@chakra-ui/react'
+import { Info } from 'lucide-react'
+import { memo } from 'react'
import { useQuery } from 'react-query'
const ColumnSLA = ({ variant, product }) => {
@@ -12,67 +13,35 @@ const ColumnSLA = ({ variant, product }) => {
return (
<>
<td>
- {dataSLA.isFetching ? (
- <div className='text-center'>
- <Spinner aria-label='Center-aligned spinner example' />
- </div>
- ) : dataSLA?.data?.qty > 0 ? (
- dataSLA?.data?.qty
- ) : (
- <a
- href={whatsappUrl('product', {
- name: variant.name,
- manufacture: product.manufacture?.name,
- url: createSlug('/shop/product/', product.name, product.id, true)
- })}
- className='text-danger-500 font-medium'
- target='_blank'
- rel='noreferrer noopener'
- >
- Tanya Admin
- </a>
- )}
+ <Skeleton isLoaded={!dataSLA.isFetching} w='full'>
+ {dataSLA?.data?.qty > 0 ? (
+ dataSLA?.data?.qty
+ ) : (
+ <a
+ href={whatsappUrl('product', {
+ name: variant.name,
+ manufacture: product.manufacture?.name,
+ url: createSlug('/shop/product/', product.name, product.id, true)
+ })}
+ className='text-danger-500 font-medium'
+ target='_blank'
+ rel='noreferrer noopener'
+ >
+ Tanya Admin
+ </a>
+ )}
+ </Skeleton>
</td>
+
<td className='flex justify-center'>
- {dataSLA.isFetching ? (
- <Button color='gray'>
- <Spinner aria-label='Alternate spinner button example' />
- <span className='pl-3'>Loading...</span>
- </Button>
- ) : dataSLA?.data?.slaDate != '-' ? (
- <button
- type='button'
- title={`Masa Persiapan Barang ${dataSLA?.data?.slaDate}`}
- className={`flex gap-x-1 items-center p-2 rounded-lg w-full ${
- dataSLA?.data?.slaDate === 'indent' ? 'bg-indigo-900' : 'btn-light'
- }`}
- >
- <div
- className={`flex-1 text-caption-1 ${
- dataSLA?.data?.slaDate === 'indent' ? 'text-white' : ''
- }`}
- >
+ <Skeleton isLoaded={!dataSLA.isFetching} w='75%'>
+ <Tooltip placement='top' label={`Masa Persiapan Barang ${dataSLA?.data?.slaDate}`}>
+ <Box className='border border-gray_r-7 rounded-md p-2 flex justify-center items-center gap-x-2'>
{dataSLA?.data?.slaDate}
- </div>
- <div className='flex-end'>
- <svg
- aria-hidden='true'
- fill='none'
- stroke='currentColor'
- stroke-width='1.5'
- className={`w-7 h-7 ${dataSLA?.data?.slaDate === 'indent' ? 'text-white' : ''}`}
- >
- <path
- d='M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z'
- stroke-linecap='round'
- stroke-linejoin='round'
- ></path>
- </svg>
- </div>
- </button>
- ) : (
- '-'
- )}
+ <Info size={16} />
+ </Box>
+ </Tooltip>
+ </Skeleton>
</td>
</>
)
diff --git a/src/lib/product/components/Product/ProductDesktop.jsx b/src/lib/product/components/Product/ProductDesktop.jsx
index 6da289bc..0df60673 100644
--- a/src/lib/product/components/Product/ProductDesktop.jsx
+++ b/src/lib/product/components/Product/ProductDesktop.jsx
@@ -15,7 +15,6 @@ import ProductCard from '../ProductCard'
import productSimilarApi from '../../api/productSimilarApi'
import whatsappUrl from '@/core/utils/whatsappUrl'
import odooApi from '@/core/api/odooApi'
-import { Button, Spinner } from 'flowbite-react'
import PromotionType from '@/lib/promotinProgram/components/PromotionType'
import useAuth from '@/core/hooks/useAuth'
import ImageNext from 'next/image'
@@ -23,6 +22,8 @@ import CountDown2 from '@/core/components/elements/CountDown/CountDown2'
import { LazyLoadComponent } from 'react-lazy-load-image-component'
import ColumnsSLA from './ColumnsSLA'
import { useProductCartContext } from '@/contexts/ProductCartContext'
+import { Box, Skeleton, Tooltip } from '@chakra-ui/react'
+import { Info } from 'lucide-react'
const ProductDesktop = ({ products, wishlist, toggleWishlist }) => {
const router = useRouter()
@@ -40,7 +41,7 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => {
const [selectVariantPromoActive, setSelectVariantPromoActive] = useState(null)
const [backgorundFlashSale, setBackgorundFlashSale] = useState(null)
- const {setRefreshCart , refreshCart} = useProductCartContext()
+ const { setRefreshCart, refreshCart } = useProductCartContext()
const getLowestPrice = useCallback(() => {
const prices = product.variants.map((variant) => variant.price)
@@ -256,16 +257,16 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => {
<h1 className='text-title-md leading-10 font-medium'>{product?.name}</h1>
<div className='mt-10'>
<div className='flex p-3'>
- <div className='w-1/4 text-gray_r-12/70'>Nomor SKU</div>
- <div className='w-3/4'>SKU-{product.id}</div>
+ <div className='w-4/12 text-gray_r-12/70'>Nomor SKU</div>
+ <div className='w-8/12'>SKU-{product.id}</div>
</div>
<div className='flex p-3 bg-gray_r-4'>
- <div className='w-1/4 text-gray_r-12/70'>Part Number</div>
- <div className='w-3/4'>{product.code || '-'}</div>
+ <div className='w-4/12 text-gray_r-12/70'>Part Number</div>
+ <div className='w-8/12'>{product.code || '-'}</div>
</div>
<div className='flex p-3'>
- <div className='w-1/4 text-gray_r-12/70'>Manufacture</div>
- <div className='w-3/4'>
+ <div className='w-4/12 text-gray_r-12/70'>Manufacture</div>
+ <div className='w-8/12'>
{product.manufacture?.name ? (
<Link
href={createSlug(
@@ -282,9 +283,9 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => {
</div>
</div>
<div className='flex p-3 items-center bg-gray_r-4'>
- <div className='w-1/4 text-gray_r-12/70'>Persiapan Barang</div>
- <div className='w-3/4'>
- {product.variants.length > 1 ? (
+ <div className='w-4/12 text-gray_r-12/70'>Persiapan Barang</div>
+ <div className='w-8/12'>
+ {product.variants.length > 1 && (
<button
type='button'
onClick={goToVariantSection}
@@ -292,62 +293,32 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => {
>
<span className='text-red-600 text-sm'>Lihat Selengkapnya</span>
</button>
- ) : product.variants[0].sla ? (
- product.variants[0].sla?.slaDate != '-' ? (
- <button
- type='button'
- title={`Masa Persiapan Barang ${product.variants[0].sla?.slaDate}`}
- className={`flex gap-x-1 items-center p-2 rounded-lg w-auto ${
- product.variants[0].sla?.slaDate === 'indent'
- ? 'bg-indigo-900'
- : 'btn-light'
- }`}
- >
- <div
- className={`flex-1 text-caption-1 ${
- product.variants[0].sla?.slaDate === 'indent' ? 'text-white' : ''
- }`}
+ )}
+
+ {product.variants.length === 1 && (
+ <>
+ {!product.variants[0]?.sla && <Skeleton width='20%' height='16px' />}
+ {product.variants[0]?.sla && (
+ <Tooltip
+ placement='top'
+ label={`Masa Persiapan Barang ${product.variants[0]?.sla?.slaDate}`}
>
- {product.variants[0].sla?.slaDate}
- </div>
- <div className='flex-end'>
- <svg
- aria-hidden='true'
- fill='none'
- stroke='currentColor'
- stroke-width='1.5'
- className={`w-7 h-7 ${
- product.variants[0].sla?.slaDate === 'indent' ? 'text-white' : ''
- }`}
- >
- <path
- d='M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z'
- stroke-linecap='round'
- stroke-linejoin='round'
- ></path>
- </svg>
- </div>
- </button>
- ) : (
- '-'
- )
- ) : (
- <Button color='gray'>
- <Spinner aria-label='Alternate spinner button example' />
- <span className='pl-3'>Loading...</span>
- </Button>
+ <Box className='w-fit flex items-center gap-x-2'>
+ {product.variants[0]?.sla?.slaDate}
+ <Info size={16} />
+ </Box>
+ </Tooltip>
+ )}
+ </>
)}
</div>
</div>
+
{product.variants.length === 1 && (
<div className='flex p-3 '>
- <div className='w-1/4 text-gray_r-12/70'>Stock</div>
- <div className='w-3/4'>
- {isLoadingSLA && (
- <div className=''>
- <Spinner aria-label='Center-aligned spinner example' />
- </div>
- )}
+ <div className='w-4/12 text-gray_r-12/70'>Stock</div>
+ <div className='w-8/12'>
+ {!product.variants[0]?.sla && <Skeleton width='10%' height='16px' />}
{product?.variants[0].sla?.qty > 0 && (
<span>{product?.variants[0].sla?.qty}</span>
)}
@@ -366,9 +337,10 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => {
</div>
</div>
)}
+
<div className={`flex p-3 ${product.variants.length > 1 ? '' : 'bg-gray_r-4'} `}>
- <div className='w-1/4 text-gray_r-12/70'>Berat Barang</div>
- <div className='w-3/4'>
+ <div className='w-4/12 text-gray_r-12/70'>Berat Barang</div>
+ <div className='w-8/12'>
{product?.weight > 0 && <span>{product?.weight} KG</span>}
{product?.weight == 0 && (
<a
@@ -441,13 +413,13 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => {
<div className='text-gray_r-12/80'>Harga mulai dari: </div>
)}
- {lowestPrice?.discountPercentage > 0 && (
+ {/* {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 className='text-gray_r-9 text-caption-1'>
+ Include PPN {currencyFormat(lowestPrice?.price * process.env.NEXT_PUBLIC_PPN)}
</div>
{product.flashSale.remainingTime > 0 && (
<div className='bg-red-600 rounded-full mb-1 p-2 pl-3 pr-3 flex w-fit items-center gap-x-1'>
@@ -464,28 +436,54 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => {
</div>
)}
</div>
+ )} */}
+
+ {product?.flashSale?.remainingTime > 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-9 line-through text-caption-1'>
+ {currencyFormat(lowestPrice?.price)}
+ </div>
+ <div className='text-danger-500 font-semibold text-xl'>
+ {currencyFormat(lowestPrice?.priceDiscount)}
+ </div>
+ </div>
+ <div className='text-gray_r-9 text-base font-normal mt-1'>
+ Termasuk PPN: {currencyFormat(lowestPrice?.priceDiscount * process.env.NEXT_PUBLIC_PPN)}
+ </div>
+ </>
+ ) : (
+ <h3 className='text-danger-500 font-semibold mt-1 text-title-md'>
+ {lowestPrice?.price > 0 ? (
+ <>
+ {currencyFormat(lowestPrice?.price)}
+ <div className='text-gray_r-9 text-base font-normal mt-1'>
+ Termasuk PPN: {currencyFormat(lowestPrice?.price * process.env.NEXT_PUBLIC_PPN)}
+ </div>
+ </>
+ ) : (
+ <span className='text-gray_r-12/90 font-normal text-h-sm'>
+ Hubungi kami untuk dapatkan harga terbaik,&nbsp;
+ <a
+ href={whatsappUrl('product', {
+ name: product.name,
+ manufacture: product.manufacture?.name,
+ url: createSlug('/shop/product/', product.name, product.id, true)
+ })}
+ className='text-danger-500 underline'
+ rel='noopener noreferrer'
+ target='_blank'
+ >
+ klik disini
+ </a>
+ </span>
+ )}
+ </h3>
)}
- <h3 className='text-danger-500 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={whatsappUrl('product', {
- name: product.name,
- manufacture: product.manufacture?.name,
- url: createSlug('/shop/product/', product.name, product.id, true)
- })}
- className='text-danger-500 underline'
- rel='noopener noreferrer'
- target='_blank'
- >
- klik disini
- </a>
- </span>
- )}
- </h3>
+
{product.variants.length > 1 ? (
<button
type='button'
diff --git a/src/lib/product/components/Product/ProductDesktopVariant.jsx b/src/lib/product/components/Product/ProductDesktopVariant.jsx
index 940ba46f..51739bc9 100644
--- a/src/lib/product/components/Product/ProductDesktopVariant.jsx
+++ b/src/lib/product/components/Product/ProductDesktopVariant.jsx
@@ -16,7 +16,9 @@ import productSimilarApi from '../../api/productSimilarApi'
import whatsappUrl from '@/core/utils/whatsappUrl'
import useAuth from '@/core/hooks/useAuth'
import odooApi from '@/core/api/odooApi'
-import { Button, Spinner } from 'flowbite-react'
+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()
@@ -28,6 +30,8 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant })
const [addCartAlert, setAddCartAlert] = useState(false)
const [isLoadingSLA, setIsLoadingSLA] = useState(true)
+ const { setRefreshCart } = useProductCartContext()
+
const getLowestPrice = useCallback(() => {
const lowest = product.price
/* const lowest = prices.reduce((lowest, price) => {
@@ -71,6 +75,8 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant })
programLineId: null,
selected: true,
source: null
+ }).then(() => {
+ setRefreshCart(true)
})
setAddCartAlert(true)
}
@@ -144,16 +150,16 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant })
<h1 className='text-title-md leading-10 font-medium'>{product?.name}</h1>
<div className='mt-10'>
<div className='flex p-3'>
- <div className='w-1/4 text-gray_r-12/70'>Nomor SKU</div>
- <div className='w-3/4'>SKU-{product.id}</div>
+ <div className='w-4/12 text-gray_r-12/70'>Nomor SKU</div>
+ <div className='w-8/12'>SKU-{product.id}</div>
</div>
<div className='flex p-3 bg-gray_r-4'>
- <div className='w-1/4 text-gray_r-12/70'>Part Number</div>
- <div className='w-3/4'>{product.code || '-'}</div>
+ <div className='w-4/12 text-gray_r-12/70'>Part Number</div>
+ <div className='w-8/12'>{product.code || '-'}</div>
</div>
<div className='flex p-3'>
- <div className='w-1/4 text-gray_r-12/70'>Manufacture</div>
- <div className='w-3/4'>
+ <div className='w-4/12 text-gray_r-12/70'>Manufacture</div>
+ <div className='w-8/12'>
{product.manufacture?.name ? (
<Link
href={createSlug(
@@ -169,68 +175,36 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant })
)}
</div>
</div>
+
<div className='flex p-3 items-center bg-gray_r-4'>
- <div className='w-1/4 text-gray_r-12/70'>Persiapan Barang</div>
- <div className='w-3/4'>
- {product.sla ? (
- product.sla?.slaDate != '-' ? (
- <button
- type='button'
- title={`Masa Persiapan Barang ${product.sla?.slaDate}`}
- className={`flex gap-x-1 items-center p-2 rounded-lg w-auto ${
- product.sla?.slaDate === 'indent' ? 'bg-indigo-900' : 'btn-light'
- }`}
- >
- <div
- className={`flex-1 text-caption-1 ${
- product.sla?.slaDate === 'indent' ? 'text-white' : ''
- }`}
- >
- {product.sla?.slaDate}
- </div>
- <div className='flex-end'>
- <svg
- aria-hidden='true'
- fill='none'
- stroke='currentColor'
- stroke-width='1.5'
- className={`w-7 h-7 ${
- product.sla?.slaDate === 'indent' ? 'text-white' : ''
- }`}
- >
- <path
- d='M11.25 11.25l.041-.02a.75.75 0 011.063.852l-.708 2.836a.75.75 0 001.063.853l.041-.021M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-9-3.75h.008v.008H12V8.25z'
- stroke-linecap='round'
- stroke-linejoin='round'
- ></path>
- </svg>
- </div>
- </button>
- ) : (
- '-'
- )
- ) : (
- <Button color='gray'>
- <Spinner aria-label='Alternate spinner button example' />
- <span className='pl-3'>Loading...</span>
- </Button>
+ <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 && (
+ <Tooltip
+ placement='top'
+ label={`Masa Persiapan Barang ${product?.sla?.slaDate}`}
+ >
+ <Box className='w-fit flex items-center gap-x-2'>
+ {product?.sla?.slaDate}
+ <Info size={16} />
+ </Box>
+ </Tooltip>
)}
</div>
</div>
+
<div className='flex p-3'>
- <div className='w-1/4 text-gray_r-12/70'>Stock</div>
- <div className='w-3/4'>
- {isLoadingSLA && (
- <div className=''>
- <Spinner aria-label='Center-aligned spinner example' />
- </div>
- )}
+ <div className='w-4/12 text-gray_r-12/70'>Stock</div>
+ <div className='w-8/12'>
+ {!product?.sla && <Skeleton width='10%' height='16px' />}
{product?.sla?.qty > 0 && <span>{product?.sla?.qty}</span>}
{product?.sla?.qty == 0 && (
<a
href={whatsappUrl('product', {
name: product.name,
- url: createSlug('/shop/product/variant/', product.name, product.id, true)
+ manufacture: product?.manufacture?.name,
+ url: createSlug('/shop/product/', product.name, product.id, true)
})}
className='text-danger-500 font-medium'
>
@@ -240,8 +214,8 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant })
</div>
</div>
<div className='flex p-3 bg-gray_r-4'>
- <div className='w-1/4 text-gray_r-12/70'>Berat Barang</div>
- <div className='w-3/4'>
+ <div className='w-4/12 text-gray_r-12/70'>Berat Barang</div>
+ <div className='w-8/12'>
{product?.weight > 0 && <span>{product?.weight} KG</span>}
{product?.weight == 0 && (
<a
@@ -296,44 +270,52 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant })
</div> */}
</div>
<div className='w-[25%]'>
- {lowestPrice?.priceDiscount > 0 ? (
+ {product?.flashSale?.remainingTime > 0 ? (
<>
- <div className='flex gap-x-2 mb-3 items-center'>
- <div className='flex'>
- <span className='text-gray-400 text-md'>Harga Sebelum PPN : </span>
- </div>
- <div className='flex'>
- <span className=' text-body-1 '>
- {currencyFormat(lowestPrice?.priceDiscount)}
- </span>
- </div>
- </div>
- <span className='font-semibold'>Termasuk PPN :</span>
- <div className='flex gap-x-1 items-center mt-2 '>
+ <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 * 1.11)}
+ <div className='text-gray_r-9 line-through text-caption-1'>
+ {currencyFormat(lowestPrice?.price)}
+ </div>
+ <div className='text-danger-500 font-semibold text-xl'>
+ {currencyFormat(lowestPrice?.priceDiscount)}
</div>
- <h3 className='text-danger-500 font-semibold text-title-sm'>
- {currencyFormat(lowestPrice?.priceDiscount * 1.11)}
- </h3>
+ </div>
+ <div className='text-gray_r-9 text-base font-normal mt-1'>
+ Termasuk PPN:{' '}
+ {currencyFormat(lowestPrice?.priceDiscount * process.env.NEXT_PUBLIC_PPN)}
</div>
</>
) : (
- <span className='text-gray_r-12/90 font-normal text-h-sm'>
- Hubungi kami untuk dapatkan harga terbaik,&nbsp;
- <a
- href={whatsappUrl('product', {
- name: product.name,
- url: createSlug('/shop/product/', product.name, product.id, true)
- })}
- className='text-danger-500 underline'
- >
- klik disini
- </a>
- </span>
+ <h3 className='text-danger-500 font-semibold mt-1 text-title-md'>
+ {lowestPrice?.price > 0 ? (
+ <>
+ {currencyFormat(lowestPrice?.price)}
+ <div className='text-gray_r-9 text-base font-normal mt-1'>
+ Termasuk PPN:{' '}
+ {currencyFormat(lowestPrice?.price * process.env.NEXT_PUBLIC_PPN)}
+ </div>
+ </>
+ ) : (
+ <span className='text-gray_r-12/90 font-normal text-h-sm'>
+ Hubungi kami untuk dapatkan harga terbaik,&nbsp;
+ <a
+ href={whatsappUrl('product', {
+ name: product.name,
+ manufacture: product.manufacture?.name,
+ url: createSlug('/shop/product/', product.name, product.id, true)
+ })}
+ className='text-danger-500 underline'
+ rel='noopener noreferrer'
+ target='_blank'
+ >
+ klik disini
+ </a>
+ </span>
+ )}
+ </h3>
)}
<div className='flex gap-x-3 mt-4'>
<input
diff --git a/src/lib/product/components/Product/ProductMobile.jsx b/src/lib/product/components/Product/ProductMobile.jsx
index 6b0b27a5..a9d34683 100644
--- a/src/lib/product/components/Product/ProductMobile.jsx
+++ b/src/lib/product/components/Product/ProductMobile.jsx
@@ -17,7 +17,6 @@ import whatsappUrl from '@/core/utils/whatsappUrl'
import PromotionType from '@/lib/promotinProgram/components/PromotionType'
import { gtagAddToCart } from '@/core/utils/googleTag'
import odooApi from '@/core/api/odooApi'
-import { Button, Spinner } from 'flowbite-react'
import ImageNext from 'next/image'
import CountDown2 from '@/core/components/elements/CountDown/CountDown2'
@@ -101,7 +100,8 @@ const ProductMobile = ({ product, wishlist, toggleWishlist }) => {
price: variant.price,
stock: variant.stock,
weight: variant.weight,
- hasProgram: variant.hasProgram
+ hasProgram: variant.hasProgram,
+ isFlashsale: variant.isFlashsale
}
setActiveVariant(newActiveVariant)
@@ -152,6 +152,8 @@ const ProductMobile = ({ product, wishlist, toggleWishlist }) => {
router.push(`/shop/checkout?source=buy`)
}
+ console.log('ini log', activeVariant)
+
const productSimilarQuery = [
product?.name,
`fq=-product_id_i:${product.id}`,
@@ -232,32 +234,48 @@ const ProductMobile = ({ product, wishlist, toggleWishlist }) => {
<div className='text-gray_r-12/80 text-caption-2 mt-2 mb-1'>Harga mulai dari: </div>
)}
- {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)}
+ {activeVariant.isFlashsale ? (
+ <>
+ <div className='flex gap-x-1 items-center'>
+ <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>
+ <div className='text-danger-500 font-semibold'>
+ {currencyFormat(activeVariant?.price?.priceDiscount)}
+ </div>
</div>
- <div className='badge-solid-red'>{activeVariant?.price?.discountPercentage}%</div>
- </div>
+ <div className='text-gray_r-9 text-base font-normal mt-1'>
+ Termasuk PPN:{' '}
+ {currencyFormat(activeVariant?.price.priceDiscount * process.env.NEXT_PUBLIC_PPN)}
+ </div>
+ </>
+ ) : (
+ <h3 className='text-danger-500 font-semibold mt-1'>
+ {activeVariant?.price?.priceDiscount > 0 ? (
+ <>
+ {currencyFormat(activeVariant?.price?.priceDiscount)}
+ <div className='text-gray_r-9 text-base font-normal mt-1'>
+ Termasuk PPN:{' '}
+ {currencyFormat(activeVariant?.price.priceDiscount * process.env.NEXT_PUBLIC_PPN)}
+ </div>
+ </>
+ ) : (
+ <span className='text-gray_r-11 leading-6 font-normal'>
+ Hubungi kami untuk dapatkan harga terbaik,&nbsp;
+ <a
+ href={whatsappUrl('product', {
+ name: product.name,
+ url: createSlug('/shop/product/', product.name, product.id, true)
+ })}
+ className='text-danger-500 underline'
+ >
+ klik disini
+ </a>
+ </span>
+ )}
+ </h3>
)}
- <h3 className='text-danger-500 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={whatsappUrl('product', {
- name: product.name,
- url: createSlug('/shop/product/', product.name, product.id, true)
- })}
- className='text-danger-500 underline'
- >
- klik disini
- </a>
- </span>
- )}
- </h3>
</div>
<Divider />
diff --git a/src/lib/product/components/Product/ProductMobileVariant.jsx b/src/lib/product/components/Product/ProductMobileVariant.jsx
index e0ba90c3..a7b1a543 100644
--- a/src/lib/product/components/Product/ProductMobileVariant.jsx
+++ b/src/lib/product/components/Product/ProductMobileVariant.jsx
@@ -16,7 +16,7 @@ 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 { Button, Spinner } from 'flowbite-react'
+import { Skeleton } from '@chakra-ui/react'
const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => {
const router = useRouter()
@@ -39,7 +39,8 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => {
name: product.name,
price: getLowestPrice(),
stock: product.stockTotal,
- weight: product.weight
+ weight: product.weight,
+ isFlashSale: product.isFlashsale
})
useEffect(() => {
@@ -50,7 +51,8 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => {
name: product.name,
price: product.price,
stock: product.stock,
- weight: product.weight
+ weight: product.weight,
+ isFlashSale: product.isFlashsale
})
}
}, [selectedVariant, product])
@@ -80,6 +82,7 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => {
})
setAddCartAlert(true)
}
+ console.log('ini log', activeVariant)
const handleClickBuy = () => {
if (!validAction()) return
@@ -89,7 +92,7 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => {
quantity,
programLineId: null,
selected: true,
- source : 'buy'
+ source: 'buy'
})
router.push(`/shop/checkout?source=buy`)
}
@@ -139,47 +142,47 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => {
</div>
<h1 className='leading-6 font-medium mb-3'>{activeVariant?.name}</h1>
- {activeVariant?.price?.priceDiscount > 0 ? (
+ {activeVariant.isFlashsale ? (
<>
<div className='flex gap-x-1 items-center'>
- <div className='text-gray_r-11 text-caption-1'>Harga Sebelum PPN :</div>
- <div className='text-gray_r-12 line-through text-caption-1'>
- {' '}
+ <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>
+ <div className='text-danger-500 font-semibold'>
{currencyFormat(activeVariant?.price?.priceDiscount)}
</div>
</div>
- <div className='mt-2'>
- <span className='font-semibold '>Termasuk PPN :</span>
- <div className='flex gap-x-2 items-center mt-2'>
- {activeVariant?.price?.discountPercentage > 0 && (
- <>
- <div className='badge-solid-red'>
- {activeVariant?.price?.discountPercentage}%
- </div>
- <div className='text-gray_r-11 line-through text-caption-1'>
- {currencyFormat(activeVariant?.price?.price * 1.11)}
- </div>
- </>
- )}
- <h3 className='text-danger-500 font-semibold'>
- {currencyFormat(activeVariant?.price?.priceDiscount * 1.11)}
- </h3>
- </div>
+ <div className='text-gray_r-9 text-base font-normal mt-1'>
+ Termasuk PPN:{' '}
+ {currencyFormat(activeVariant?.price.priceDiscount * process.env.NEXT_PUBLIC_PPN)}
</div>
</>
) : (
- <span className='text-gray_r-11 leading-6 font-normal'>
- Hubungi kami untuk dapatkan harga terbaik,&nbsp;
- <a
- href={whatsappUrl('product', {
- name: product.name,
- url: createSlug('/shop/product/', product.name, product.id, true)
- })}
- className='text-danger-500 underline'
- >
- klik disini
- </a>
- </span>
+ <h3 className='text-danger-500 font-semibold mt-1'>
+ {activeVariant?.price?.priceDiscount > 0 ? (
+ <>
+ {currencyFormat(activeVariant?.price?.priceDiscount)}
+ <div className='text-gray_r-9 text-base font-normal mt-1'>
+ Termasuk PPN:{' '}
+ {currencyFormat(activeVariant?.price.priceDiscount * process.env.NEXT_PUBLIC_PPN)}
+ </div>
+ </>
+ ) : (
+ <span className='text-gray_r-11 leading-6 font-normal'>
+ Hubungi kami untuk dapatkan harga terbaik,&nbsp;
+ <a
+ href={whatsappUrl('product', {
+ name: product.name,
+ url: createSlug('/shop/product/', product.name, product.id, true)
+ })}
+ className='text-danger-500 underline'
+ >
+ klik disini
+ </a>
+ </span>
+ )}
+ </h3>
)}
</div>
@@ -230,10 +233,7 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => {
<SpecificationContent label='Ketersediaan'>
<span>
{isLoadingSLA ? (
- <Button color='gray'>
- <Spinner aria-label='Alternate spinner button example' />
- <span className='pl-3'>Loading...</span>
- </Button>
+ <Skeleton width='100px' height='full' />
) : product?.sla?.slaDate != '-' ? (
<button
type='button'
@@ -267,7 +267,7 @@ const ProductMobileVariant = ({ product, wishlist, toggleWishlist }) => {
</svg>
</div>
</button>
- ): (
+ ) : (
'-'
)}
</span>
diff --git a/src/lib/product/components/ProductCard.jsx b/src/lib/product/components/ProductCard.jsx
index 10ffdaec..16c63c00 100644
--- a/src/lib/product/components/ProductCard.jsx
+++ b/src/lib/product/components/ProductCard.jsx
@@ -82,30 +82,47 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => {
)}
<Link
href={createSlug('/shop/product/', product?.name, product?.id)}
- className={`mb-2 !text-gray_r-12 leading-6 block ${
+ className={`mb-3 !text-gray_r-12 leading-6 block ${
simpleTitle ? 'line-clamp-2 h-12' : 'line-clamp-3 h-[64px]'
}`}
title={product?.name}
>
{product?.name}
</Link>
- {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)}
+ {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'>
+ {currencyFormat(product.lowestPrice.price)}
+ </div>
+ <div className='badge-solid-red'>{product?.lowestPrice.discountPercentage}%</div>
+ </div>
+ )}
+
+ <div className='text-danger-500 font-semibold mb-2'>
+ {product?.lowestPrice.priceDiscount > 0 ? (
+ currencyFormat(product?.lowestPrice.priceDiscount)
+ ) : (
+ <a href={callForPriceWhatsapp}>Call for price</a>
+ )}
</div>
- <div className='badge-solid-red'>{product?.lowestPrice.discountPercentage}%</div>
+ </>
+ ) : (
+ <div className='text-danger-500 font-semibold mb-2 min-h-[40px]'>
+ {product?.lowestPrice.price > 0 ? (
+ <>
+ {currencyFormat(product?.lowestPrice.price)}
+ <div className='text-gray_r-9 text-[11px] font-normal sm:text-caption-2 mt-2'>
+ + PPN: {currencyFormat(product.lowestPrice.price * process.env.NEXT_PUBLIC_PPN)}
+ </div>
+ </>
+ ) : (
+ <a href={callForPriceWhatsapp}>Call for price</a>
+ )}
</div>
)}
- <div className='text-danger-500 font-semibold mb-2'>
- {product?.lowestPrice.priceDiscount > 0 ? (
- currencyFormat(product?.lowestPrice.priceDiscount)
- ) : (
- <a href={callForPriceWhatsapp}>Call for price</a>
- )}
- </div>
-
{product?.stockTotal > 0 && (
<div className='flex gap-x-1'>
<div className='badge-solid-red'>Ready Stock</div>
@@ -169,30 +186,46 @@ const ProductCard = ({ product, simpleTitle, variant = 'vertical' }) => {
)}
<Link
href={createSlug('/shop/product/', product?.name, product?.id)}
- className={`mb-2 !text-gray_r-12 leading-6 ${
+ className={`mb-3 !text-gray_r-12 leading-6 ${
simpleTitle ? 'line-clamp-2' : 'line-clamp-3'
}`}
>
{product?.name}
</Link>
+ {product?.flashSale?.id > 0 ? (
+ <>
+ {product?.lowestPrice.discountPercentage > 0 && (
+ <div className='flex gap-x-1 mb-1 items-center'>
+ <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>
+ )}
- {product?.lowestPrice?.discountPercentage > 0 && (
- <div className='flex gap-x-1 mb-1 items-center'>
- <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 className='text-danger-500 font-semibold mb-2'>
+ {product?.lowestPrice?.priceDiscount > 0 ? (
+ currencyFormat(product?.lowestPrice?.priceDiscount)
+ ) : (
+ <a href={callForPriceWhatsapp}>Call for price</a>
+ )}
</div>
+ </>
+ ) : (
+ <div className='text-danger-500 font-semibold mb-2 min-h-[40px]'>
+ {product?.lowestPrice.price > 0 ? (
+ <>
+ {currencyFormat(product?.lowestPrice.price)}
+ <div className='text-gray_r-9 text-[11px] sm:text-caption-2 font-normal mt-2'>
+ + PPN: {currencyFormat(product.lowestPrice.price * process.env.NEXT_PUBLIC_PPN)}
+ </div>
+ </>
+ ) : (
+ <a href={callForPriceWhatsapp}>Call for price</a>
+ )}
</div>
)}
- <div className='text-danger-500 font-semibold mb-2'>
- {product?.lowestPrice?.priceDiscount > 0 ? (
- currencyFormat(product?.lowestPrice?.priceDiscount)
- ) : (
- <a href={callForPriceWhatsapp}>Call for price</a>
- )}
- </div>
-
{product?.stockTotal > 0 && (
<div className='flex gap-x-1'>
<div className='badge-solid-red'>Ready Stock</div>
diff --git a/src/lib/product/components/ProductFilterDesktop.jsx b/src/lib/product/components/ProductFilterDesktop.jsx
index ce6c12ed..b64349c7 100644
--- a/src/lib/product/components/ProductFilterDesktop.jsx
+++ b/src/lib/product/components/ProductFilterDesktop.jsx
@@ -2,7 +2,21 @@ import { useRouter } from 'next/router'
import { useState } from 'react'
import _ from 'lodash'
import { toQuery } from 'lodash-contrib'
-import { Accordion, Checkbox, Label, TextInput } from 'flowbite-react'
+import {
+ Accordion,
+ AccordionButton,
+ AccordionIcon,
+ AccordionItem,
+ AccordionPanel,
+ Box,
+ Button,
+ Checkbox,
+ Input,
+ InputGroup,
+ InputLeftAddon,
+ Stack,
+ VStack
+} from '@chakra-ui/react'
const ProductFilterDesktop = ({ brands, categories, prefixUrl, defaultBrand = null }) => {
const router = useRouter()
@@ -13,7 +27,7 @@ const ProductFilterDesktop = ({ brands, categories, prefixUrl, defaultBrand = nu
const [priceFrom, setPriceFrom] = useState(query?.priceFrom)
const [priceTo, setPriceTo] = useState(query?.priceTo)
- const handleCategorysChange = (event) => {
+ const handleCategoriesChange = (event) => {
const value = event.target.value
const isChecked = event.target.checked
if (isChecked) {
@@ -48,80 +62,95 @@ const ProductFilterDesktop = ({ brands, categories, prefixUrl, defaultBrand = nu
return (
<>
- <Accordion flush={true} alwaysOpen={true}>
- <Accordion.Panel>
- <Accordion.Title>Kategori</Accordion.Title>
- <Accordion.Content className='overflow-auto max-h-[200px]'>
- <div className='flex flex-col gap-4 scroll-snap' id='checkbox'>
+ <Accordion defaultIndex={[0]} allowMultiple>
+ <AccordionItem>
+ <AccordionButton padding={[2, 4]}>
+ <Box as='span' flex='1' textAlign='left' fontWeight='semibold'>
+ Brand
+ </Box>
+ <AccordionIcon />
+ </AccordionButton>
+
+ <AccordionPanel>
+ <Stack gap={3} direction='column' maxH={'240px'} overflow='auto'>
+ {brands.map((brand, index) => (
+ <div className='flex items-center gap-2' key={index}>
+ <Checkbox
+ isChecked={brandValues.includes(brand)}
+ onChange={handleBrandsChange}
+ value={brand}
+ size='md'
+ >
+ {brand}
+ </Checkbox>
+ </div>
+ ))}
+ </Stack>
+ </AccordionPanel>
+ </AccordionItem>
+
+ <AccordionItem>
+ <AccordionButton padding={[2, 4]}>
+ <Box as='span' flex='1' textAlign='left' fontWeight='semibold'>
+ Kategori
+ </Box>
+ <AccordionIcon />
+ </AccordionButton>
+
+ <AccordionPanel>
+ <Stack gap={3} direction='column' maxH={'240px'} overflow='auto'>
{categories.map((category, index) => (
<div className='flex items-center gap-2' key={index}>
<Checkbox
- id={`categoryOption${index}`}
- checked={categoryValues.includes(category)}
- onChange={handleCategorysChange}
+ isChecked={categoryValues.includes(category)}
+ onChange={handleCategoriesChange}
value={category}
- />
- <Label htmlFor={`categoryOption${index}`} className='dark:text-gray_r-12/80'>
+ size='md'
+ >
{category}
- </Label>
+ </Checkbox>
</div>
))}
- </div>
- </Accordion.Content>
- </Accordion.Panel>
- <Accordion.Panel>
- {!defaultBrand && (
- <>
- <Accordion.Title>Brand</Accordion.Title>
- <Accordion.Content className='overflow-auto max-h-[200px]'>
- <div className='flex flex-col gap-4 scroll-snap' id='checkbox'>
- {brands.map((brand, index) => (
- <div className='flex items-center gap-2' key={index}>
- <Checkbox
- id={`brandOption${index}`}
- checked={brandValues.includes(brand)}
- onChange={handleBrandsChange}
- value={brand}
- />
- <Label htmlFor={`brandOption${index}`} className='dark:text-gray_r-12/80'>
- {brand}
- </Label>
- </div>
- ))}
- </div>
- </Accordion.Content>
- </>
- )}
- </Accordion.Panel>
- <Accordion.Panel>
- <Accordion.Title>Harga</Accordion.Title>
- <Accordion.Content>
- <div className='mb-3'>
- <TextInput
- placeholder='Harga Minimum'
- addon='Rp'
- type='number'
- value={priceFrom}
- onChange={(e) => setPriceFrom(e.target.value)}
- />
- </div>
- <div className='mb-3'>
- <TextInput
- placeholder='Harga Maximum'
- addon='Rp'
- type='number'
- value={priceTo}
- onChange={(e) => setPriceTo(e.target.value)}
- />
- </div>
- </Accordion.Content>
- </Accordion.Panel>
+ </Stack>
+ </AccordionPanel>
+ </AccordionItem>
+
+ <AccordionItem>
+ <AccordionButton padding={[2, 4]}>
+ <Box as='span' flex='1' textAlign='left' fontWeight='semibold'>
+ Harga
+ </Box>
+ <AccordionIcon />
+ </AccordionButton>
+
+ <AccordionPanel paddingY={4}>
+ <VStack gap={4}>
+ <InputGroup>
+ <InputLeftAddon>Rp</InputLeftAddon>
+ <Input
+ type='number'
+ placeholder='Harga minimum'
+ value={priceFrom}
+ onChange={(e) => setPriceFrom(e.target.value)}
+ />
+ </InputGroup>
+ <InputGroup>
+ <InputLeftAddon>Rp</InputLeftAddon>
+ <Input
+ type='number'
+ placeholder='Harga maximum'
+ value={priceTo}
+ onChange={(e) => setPriceTo(e.target.value)}
+ />
+ </InputGroup>
+ </VStack>
+ </AccordionPanel>
+ </AccordionItem>
</Accordion>
- <div className='p-5'>
- <button type='button' className='btn-solid-red w-full mt-6' onClick={handleSubmit}>
- Terapkan
- </button>
- </div>
+
+ <Button className='w-full mt-6' colorScheme='red' onClick={handleSubmit}>
+ Terapkan
+ </Button>
</>
)
}
diff --git a/src/lib/product/components/ProductSearch.jsx b/src/lib/product/components/ProductSearch.jsx
index ae9618d2..df9aa91b 100644
--- a/src/lib/product/components/ProductSearch.jsx
+++ b/src/lib/product/components/ProductSearch.jsx
@@ -39,9 +39,11 @@ const ProductSearch = ({ query, prefixUrl, defaultBrand = null }) => {
const oddIndexSuggestions = response.data.spellcheck.suggestions.filter(
(_, index) => index % 2 === 1
)
+
const oddIndexCollations = response.data.spellcheck.collations.filter(
(_, index) => index % 2 === 1
)
+
const dataSpellings = oddIndexSuggestions.reduce((acc, curr) => {
oddIndexCollations.forEach((collation) => {
acc.push(collation.collationQuery)
@@ -52,7 +54,9 @@ const ProductSearch = ({ query, prefixUrl, defaultBrand = null }) => {
return acc
}, [])
- setQ(dataSpellings[0])
+ if (dataSpellings.length > 0) {
+ setQ(dataSpellings[0])
+ }
setSpellings(dataSpellings)
})
@@ -183,7 +187,7 @@ const ProductSearch = ({ query, prefixUrl, defaultBrand = null }) => {
defaultBrand={defaultBrand}
/>
</div>
- <div className='w-9/12 p-3'>
+ <div className='w-9/12 pl-6'>
<h1 className='text-2xl mb-2 font-semibold'>Hasil Pencarian</h1>
<div className='flex justify-between items-center mb-2'>
<div className='mb-2 leading-6 text-gray_r-11'>
diff --git a/src/lib/product/components/ProductSlider.jsx b/src/lib/product/components/ProductSlider.jsx
index dedbd6ab..54f209cc 100644
--- a/src/lib/product/components/ProductSlider.jsx
+++ b/src/lib/product/components/ProductSlider.jsx
@@ -10,7 +10,7 @@ import MobileView from '@/core/components/views/MobileView'
import DesktopView from '@/core/components/views/DesktopView'
const bannerClassName =
- 'absolute rounded-r top-0 left-0 h-full w-auto md:w-[20%] idt-transition border border-gray_r-6'
+ 'absolute rounded-r top-0 left-0 h-full w-auto md:w-[20%] border border-gray_r-6'
const ProductSlider = ({ products, simpleTitle = false, bannerMode = false }) => {
const bannerRef = useRef('')