summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/components/elements/Product/cartProductsList.jsx267
-rw-r--r--src/lib/cart/components/Cart.jsx257
-rw-r--r--src/lib/cart/components/Cartheader.jsx2
-rw-r--r--src/lib/checkout/components/Checkout.jsx42
-rw-r--r--src/lib/product/components/Product/ProductDesktop.jsx154
-rw-r--r--src/lib/product/components/Product/ProductDesktopVariant.jsx71
-rw-r--r--src/lib/product/components/Product/ProductMobile.jsx67
-rw-r--r--src/lib/product/components/Product/ProductMobileVariant.jsx72
-rw-r--r--src/lib/product/components/ProductCard.jsx89
-rw-r--r--src/lib/quotation/components/Quotation.jsx66
-rw-r--r--src/lib/variant/components/VariantCard.jsx2
-rw-r--r--src/lib/variant/components/VariantGroupCard.jsx1
-rw-r--r--src/pages/api/shop/product-detail.js32
-rw-r--r--src/pages/api/shop/search.js21
-rw-r--r--src/pages/shop/product/[slug].jsx3
-rw-r--r--src/utils/solrMapping.js113
16 files changed, 731 insertions, 528 deletions
diff --git a/src/core/components/elements/Product/cartProductsList.jsx b/src/core/components/elements/Product/cartProductsList.jsx
new file mode 100644
index 00000000..5887b425
--- /dev/null
+++ b/src/core/components/elements/Product/cartProductsList.jsx
@@ -0,0 +1,267 @@
+import Link from '@/core/components/elements/Link/Link'
+import Image from '@/core/components/elements/Image/Image'
+import LogoSpinner from '../Spinner/LogoSpinner'
+import { TrashIcon } from '@heroicons/react/24/outline'
+import { useEffect } from 'react'
+import { createSlug } from '@/core/utils/slug'
+import currencyFormat from '@/core/utils/currencyFormat'
+
+const CardProdcuctsList = ({
+ isLoading,
+ products,
+ source,
+ handlePopUpPromo = () => {},
+ toggleSelected = () => {},
+ updateQuantity = () => {},
+ setDeleteConfirmation = () => {}
+}) => {
+
+ return (
+ <table className='table-cart'>
+ <thead>
+ <tr>
+ <th colSpan={2}>Nama Produk</th>
+ <th>Jumlah</th>
+ <th>Harga</th>
+ <th>Subtotal</th>
+ {source == 'cart' && <th>Action</th>}
+ </tr>
+ </thead>
+ <tbody>
+ {isLoading && (
+ <tr>
+ <td colSpan={6}>
+ <div className='container flex justify-center my-4'>
+ <LogoSpinner width={48} height={48} />
+ </div>
+ </td>
+ </tr>
+ )}
+ {!isLoading && (!products || products?.length == 0) && (
+ <tr>
+ <td colSpan={6}>Keranjang belanja anda masih kosong</td>
+ </tr>
+ )}
+ {products &&
+ products?.map((product) => (
+ <>
+ {product.hasProgram && (
+ <tr className='!border-b-0 pb-0'>
+ <td colSpan={6}>
+ <div className='flex gap-x-2 bg-yellow-100 p-2 items-center'>
+ {product.program ? (
+ <>
+ <div className='flex border border-solid border-red-600 rounded-md p-1'>
+ <span className='text-red-600'>{product.program.type.label}</span>
+ </div>
+ <div className='flex'>
+ {product.program.type.value == 'merchandise' ? (
+ <>Selamat anda mendapatkan merchandise indoteknik.com</>
+ ) : (
+ <>
+ Selamat! Pembelian anda lebih hemat
+ <span className='text-red-600 font-semibold ml-2'>
+ {' '}
+ {currencyFormat(product.program?.totalSavings)}
+ </span>
+ </>
+ )}
+ </div>
+ </>
+ ) : (
+ <>
+ <div className='flex border border-solid border-red-600 rounded-md p-1'>
+ <span className='text-red-600'>Promo</span>
+ </div>
+ <div className='flex'>Pilih Promo Yang Tersedia Bisa lebih Hemat</div>
+ </>
+ )}
+ <div
+ onClick={() =>
+ handlePopUpPromo(product.id, product.quantity, product.program?.id)
+ }
+ className='ml-auto text-red-500 flex gap-x-1 cursor-pointer'
+ >
+ <div className='font-semibold'> Cek Promo</div>
+ <div>
+ <svg
+ aria-hidden='true'
+ fill='none'
+ stroke='currentColor'
+ stroke-width='1.5'
+ viewBox='0 0 20 24'
+ className='h-5 w-5 font-semibold'
+ >
+ <path
+ d='M8.25 4.5l7.5 7.5-7.5 7.5'
+ stroke-linecap='round'
+ stroke-linejoin='round'
+ ></path>
+ </svg>
+ </div>
+ </div>
+ </div>
+ </td>
+ </tr>
+ )}
+ <tr
+ key={product.id}
+ className={`${product.hasProgram ? '!border-t-0 !border-b-0' : ''}`}
+ >
+ <td className='relative'>
+ {source == 'cart' && (
+ <>
+ <ComponentCanBuy canBuy={product.canBuy} />
+ <input
+ type='checkbox'
+ onClick={() => toggleSelected(product.id)}
+ checked={product?.selected}
+ className='accent-danger-500 w-4'
+ />
+ </>
+ )}
+ </td>
+ <td className='flex relative'>
+ <ComponentCanBuy canBuy={product.canBuy} />
+ <Link
+ href={createSlug('/shop/product/', product?.parent.name, product?.parent.id)}
+ className='w-[20%] flex-shrink-0'
+ >
+ <Image
+ src={product?.parent?.image}
+ alt={product?.name}
+ className='object-contain object-center border border-gray_r-6 h-28 w-full rounded-md'
+ />
+ </Link>
+ <div className='px-2 text-left'>
+ <Link
+ href={createSlug('/shop/product/', product?.parent.name, product?.parent.id)}
+ className='line-clamp-2 leading-6 !text-gray_r-12 font-normal'
+ >
+ {product?.parent?.name}
+ </Link>
+ <div className='text-gray_r-11 mt-2'>
+ {product?.code}{' '}
+ {product?.attributes.length > 0 ? `| ${product?.attributes.join(', ')}` : ''}
+ </div>
+ <div className='text-gray_r-11 mt-2'>Berat item : {product?.weight} Kg</div>
+ </div>
+ </td>
+ <td className='relative'>
+ <ComponentCanBuy canBuy={product.canBuy} />
+ <input
+ className='form-input w-16 py-2 text-center bg-gray_r-1'
+ type='number'
+ value={product?.quantity}
+ disabled={source === 'cart' ? false : true}
+ onChange={(e) => updateQuantity(e.target.value, product?.id)}
+ onBlur={(e) => updateQuantity(e.target.value, product?.id, 'BLUR')}
+ />
+ </td>
+ <td className='relative'>
+ <ComponentCanBuy canBuy={product.canBuy} />
+ {product?.hasFlashsale ? (
+ <>
+ <div className='flex gap-x-1 items-center justify-center mt-3'>
+ <div className='text-gray_r-11 line-through text-caption-1'>
+ {currencyFormat(product?.price?.price)}
+ </div>
+ <div className='badge-solid-red'>{product?.price?.discountPercentage}%</div>
+ </div>
+ <div className='font-normal mt-1'>
+ {currencyFormat(product?.price?.priceDiscount)}
+ </div>
+ </>
+ ) : (
+ <div className='font-normal mt-1'>{currencyFormat(product?.price?.price)}</div>
+ )}
+ </td>
+ <td className='relative'>
+ <ComponentCanBuy canBuy={product.canBuy} />
+ <div className='text-danger-500 font-medium'>
+ {currencyFormat(product?.price?.priceDiscount * product?.quantity)}
+ </div>
+ </td>
+ {source == 'cart' && (
+ <td>
+ <div className='flex justify-center items-center h-full'>
+ <button
+ className='btn-red p-1 ml-1'
+ onClick={() => setDeleteConfirmation(product)}
+ >
+ <TrashIcon className='w-4' />
+ </button>
+ </div>
+ </td>
+ )}
+ </tr>
+ {/* Component for promotion program product */}
+ {product?.program?.items && (
+ <tr key={product.program.id} className='!border-t-0'>
+ {product.program.items.map((item) => (
+ <>
+ <td className='relative'>
+ <ComponentCanBuy canBuy={product.canBuy} />
+ </td>
+ <td className='flex relative'>
+ <ComponentCanBuy canBuy={product.canBuy} />
+ <div className='w-[20%] flex-shrink-0'>
+ <Image
+ src={item.parent.image}
+ alt={item.name}
+ className='object-contain object-center border border-gray_r-6 h-28 w-full rounded-md'
+ />
+ </div>
+ <div className='px-2 text-left'>
+ <div className=''>
+ <span className='border border-solid border-red-600 rounded-md p-1 text-red-600'>
+ {product.program.type.label}
+ </span>
+ </div>
+ <div className='mt-2 line-clamp-2 leading-6'>{item.name}</div>
+ </div>
+ </td>
+ <td className='relative'>
+ <ComponentCanBuy canBuy={product.canBuy} />
+ <input
+ className='form-input w-16 py-2 text-center bg-gray_r-1'
+ type='number'
+ value={1}
+ disabled
+ />
+ </td>
+ <td className='relative'>
+ <ComponentCanBuy canBuy={product.canBuy} />
+ {item?.price?.discountPercentage > 0 && (
+ <div className='flex gap-x-1 items-center justify-center mt-3'>
+ <div className='text-gray_r-11 line-through text-caption-1'>
+ {currencyFormat(product?.price?.price)}
+ </div>
+ </div>
+ )}
+ <div className='font-normal mt-1'>
+ {item?.price.priceDiscount > 0 ? 'Gratis' : ''}
+ </div>
+ </td>
+ <td className='relative'>
+ <ComponentCanBuy canBuy={product.canBuy} />
+ <div className='text-danger-500 font-medium'>
+ {item.price.priceDiscount > 0 ? 'Gratis' : ''}
+ </div>
+ </td>
+ <td></td>
+ </>
+ ))}
+ </tr>
+ )}
+ </>
+ ))}
+ </tbody>
+ </table>
+ )
+}
+
+const ComponentCanBuy = ({ canBuy }) =>
+ !canBuy && <div className='absolute w-full h-full bg-gray_r-3/40 top-0 left-0' />
+
+export default CardProdcuctsList
diff --git a/src/lib/cart/components/Cart.jsx b/src/lib/cart/components/Cart.jsx
index b5976a1b..c6aaa596 100644
--- a/src/lib/cart/components/Cart.jsx
+++ b/src/lib/cart/components/Cart.jsx
@@ -23,6 +23,8 @@ import { getPromotionProgram } from '@/lib/promotinProgram/api/homepageApi'
import PromotionType from '@/lib/promotinProgram/components/PromotionType'
import { gtagBeginCheckout } from '@/core/utils/googleTag'
import { useProductCartContext } from '@/contexts/ProductCartContext'
+import CardProdcuctsList from '@/core/components/elements/Product/cartProductsList'
+// import cardProdcuctsList from '@/core/components/elements/Product/cartProductsList'
const Cart = () => {
const router = useRouter()
@@ -32,7 +34,7 @@ const Cart = () => {
const [cart, setCart] = useState(null)
- const {setRefreshCart} = useProductCartContext()
+ const { setRefreshCart } = useProductCartContext()
useEffect(() => {
if (!auth) return
@@ -115,7 +117,7 @@ const Cart = () => {
selected: true
}).then(() => {
getCart().then(() => {
- if(promotionActiveId){
+ if (promotionActiveId) {
setPromotionType(false)
}
})
@@ -438,7 +440,7 @@ const Cart = () => {
product.program.items &&
product.program.items.map((item) => (
<div key={item.id} className='flex mx-4 relative'>
- <ComponentCanBuy canBuy={product.canBuy} />
+ <ComponentCanBuy canBuy={product.canBuy} />
<input className='mr-2 accent-danger-500 w-4' />
<Link
href={createSlug(
@@ -530,254 +532,7 @@ const Cart = () => {
<div className='col-span-9 border border-gray_r-6 rounded bg-white p-4 pt-6'>
<h1 className='text-title-sm font-semibold mb-6'>Keranjang</h1>
- <table className='table-cart'>
- <thead>
- <tr>
- <th colSpan={2}>Nama Produk</th>
- <th>Jumlah</th>
- <th>Harga</th>
- <th>Subtotal</th>
- <th>Action</th>
- </tr>
- </thead>
- <tbody>
- {isLoading && (
- <tr>
- <td colSpan={6}>
- <div className='container flex justify-center my-4'>
- <LogoSpinner width={48} height={48} />
- </div>
- </td>
- </tr>
- )}
- {!isLoading && (!products || products?.length == 0) && (
- <tr>
- <td colSpan={6}>Keranjang belanja anda masih kosong</td>
- </tr>
- )}
- {products &&
- products?.map((product) => (
- <>
- {product.hasProgram && (
- <tr className='!border-b-0 pb-0'>
- <td colSpan={6}>
- <div className='flex gap-x-2 bg-yellow-100 p-2 items-center'>
- {product.program ? (
- <>
- <div className='flex border border-solid border-red-600 rounded-md p-1'>
- <span className='text-red-600'>
- {product.program.type.label}
- </span>
- </div>
- <div className='flex'>
- {product.program.type.value == 'merchandise' ? (
- <>Selamat anda mendapatkan merchandise indoteknik.com</>
- ) : (
- <>
- Selamat! Pembelian anda lebih hemat
- <span className='text-red-600 font-semibold ml-2'>
- {' '}
- {currencyFormat(product.program?.totalSavings)}
- </span>
- </>
- )}
- </div>
- </>
- ) : (
- <>
- <div className='flex border border-solid border-red-600 rounded-md p-1'>
- <span className='text-red-600'>Promo</span>
- </div>
- <div className='flex'>
- Pilih Promo Yang Tersedia Bisa lebih Hemat
- </div>
- </>
- )}
- <div
- onClick={() =>
- handlePopUpPromo(
- product.id,
- product.quantity,
- product.program?.id
- )
- }
- className='ml-auto text-red-500 flex gap-x-1 cursor-pointer'
- >
- <div className='font-semibold'> Cek Promo</div>
- <div>
- <svg
- aria-hidden='true'
- fill='none'
- stroke='currentColor'
- stroke-width='1.5'
- viewBox='0 0 20 24'
- className='h-5 w-5 font-semibold'
- >
- <path
- d='M8.25 4.5l7.5 7.5-7.5 7.5'
- stroke-linecap='round'
- stroke-linejoin='round'
- ></path>
- </svg>
- </div>
- </div>
- </div>
- </td>
- </tr>
- )}
- <tr
- key={product.id}
- className={`${product.hasProgram ? '!border-t-0 !border-b-0' : ''}`}
- >
- <td className='relative'>
- <ComponentCanBuy canBuy={product.canBuy} />
- <input
- type='checkbox'
- onClick={() => toggleSelected(product.id)}
- checked={product?.selected}
- className='accent-danger-500 w-4'
- />
- </td>
- <td className='flex relative'>
- <ComponentCanBuy canBuy={product.canBuy} />
- <Link
- href={createSlug(
- '/shop/product/',
- product?.parent.name,
- product?.parent.id
- )}
- className='w-[20%] flex-shrink-0'
- >
- <Image
- src={product?.parent?.image}
- alt={product?.name}
- className='object-contain object-center border border-gray_r-6 h-28 w-full rounded-md'
- />
- </Link>
- <div className='px-2 text-left'>
- <Link
- href={createSlug(
- '/shop/product/',
- product?.parent.name,
- product?.parent.id
- )}
- className='line-clamp-2 leading-6 !text-gray_r-12 font-normal'
- >
- {product?.parent?.name}
- </Link>
- <div className='text-gray_r-11 mt-2'>
- {product?.code}{' '}
- {product?.attributes.length > 0
- ? `| ${product?.attributes.join(', ')}`
- : ''}
- </div>
- </div>
- </td>
- <td className='relative'>
- <ComponentCanBuy canBuy={product.canBuy} />
- <input
- className='form-input w-16 py-2 text-center bg-gray_r-1'
- type='number'
- value={product?.quantity}
- onChange={(e) => updateQuantity(e.target.value, product?.id)}
- onBlur={(e) => updateQuantity(e.target.value, product?.id, 'BLUR')}
- />
- </td>
- <td className='relative'>
- <ComponentCanBuy canBuy={product.canBuy} />
- {product?.price?.discountPercentage > 0 && (
- <div className='flex gap-x-1 items-center justify-center mt-3'>
- <div className='text-gray_r-11 line-through text-caption-1'>
- {currencyFormat(product?.price?.price)}
- </div>
- <div className='badge-solid-red'>
- {product?.price?.discountPercentage}%
- </div>
- </div>
- )}
- <div className='font-normal mt-1'>
- {currencyFormat(product?.price?.priceDiscount)}
- </div>
- </td>
- <td className='relative'>
- <ComponentCanBuy canBuy={product.canBuy} />
- <div className='text-danger-500 font-medium'>
- {currencyFormat(product?.price?.priceDiscount * product?.quantity)}
- </div>
- </td>
- <td>
- <div className='flex justify-center items-center h-full'>
- <button
- className='btn-red p-1 ml-1'
- onClick={() => setDeleteConfirmation(product)}
- >
- <TrashIcon className='w-4' />
- </button>
- </div>
- </td>
- </tr>
- {product?.program?.items && (
- <tr key={product.program.id} className='!border-t-0'>
- {product.program.items.map((item) => (
- <>
- <td className='relative'>
- <ComponentCanBuy canBuy={product.canBuy} />
- </td>
- <td className='flex relative'>
- <ComponentCanBuy canBuy={product.canBuy} />
- <div className='w-[20%] flex-shrink-0'>
- <Image
- src={item.parent.image}
- alt={item.name}
- className='object-contain object-center border border-gray_r-6 h-28 w-full rounded-md'
- />
- </div>
- <div className='px-2 text-left'>
- <div className=''>
- <span className='border border-solid border-red-600 rounded-md p-1 text-red-600'>
- {product.program.type.label}
- </span>
- </div>
- <div className='mt-2 line-clamp-2 leading-6'>{item.name}</div>
- </div>
- </td>
- <td className='relative'>
- <ComponentCanBuy canBuy={product.canBuy} />
- <input
- className='form-input w-16 py-2 text-center bg-gray_r-1'
- type='number'
- value={1}
- disabled
- />
- </td>
- <td className='relative'>
- <ComponentCanBuy canBuy={product.canBuy} />
- {item?.price?.discountPercentage > 0 && (
- <div className='flex gap-x-1 items-center justify-center mt-3'>
- <div className='text-gray_r-11 line-through text-caption-1'>
- {currencyFormat(product?.price?.price)}
- </div>
- </div>
- )}
- <div className='font-normal mt-1'>
- {item?.price.priceDiscount > 0 ? 'Gratis' : ''}
- </div>
- </td>
- <td className='relative'>
- <ComponentCanBuy canBuy={product.canBuy} />
- <div className='text-danger-500 font-medium'>
- {item.price.priceDiscount > 0 ? 'Gratis' : ''}
- </div>
- </td>
- <td></td>
- </>
- ))}
- </tr>
- )}
- </>
- ))}
- </tbody>
- </table>
+ <CardProdcuctsList isLoading={isLoading} products={products} source='cart' handlePopUpPromo ={handlePopUpPromo} toggleSelected ={toggleSelected} updateQuantity ={updateQuantity} setDeleteConfirmation ={setDeleteConfirmation}/>
<div className='pt-2 pb-6 flex items-center gap-x-3'>
<NextImage
diff --git a/src/lib/cart/components/Cartheader.jsx b/src/lib/cart/components/Cartheader.jsx
index cbe7c7e1..901b1501 100644
--- a/src/lib/cart/components/Cartheader.jsx
+++ b/src/lib/cart/components/Cartheader.jsx
@@ -204,7 +204,7 @@ const Cardheader = (cartCount) => {
</p>
</Link>
- {product?.price?.discountPercentage > 0 && (
+ {product?.hasFlashsale && (
<div className='flex gap-x-1 items-center mb-2 mt-1'>
<div className='badge-solid-red'>
{product?.price?.discountPercentage}%
diff --git a/src/lib/checkout/components/Checkout.jsx b/src/lib/checkout/components/Checkout.jsx
index 6d2f62e0..e2c1a85b 100644
--- a/src/lib/checkout/components/Checkout.jsx
+++ b/src/lib/checkout/components/Checkout.jsx
@@ -32,6 +32,7 @@ import BottomPopup from '@/core/components/elements/Popup/BottomPopup'
import { useQuery } from 'react-query'
import { gtagPurchase } from '@/core/utils/googleTag'
import { findVoucher, getVoucher } from '../api/getVoucher'
+import CardProdcuctsList from '@/core/components/elements/Product/cartProductsList'
const SELF_PICKUP_ID = 32
@@ -633,8 +634,11 @@ const Checkout = () => {
Berakhir dalam{' '}
<span className='text-red-600'>{item.remainingTime}</span> lagi,{' '}
</div>
- <div className='text-sm ml-2 text-red-600' onClick={() => handlingTnC(item)} >
- Baca S&K
+ <div
+ className='text-sm ml-2 text-red-600'
+ onClick={() => handlingTnC(item)}
+ >
+ Baca S&K
</div>
</div>
</div>
@@ -985,7 +989,9 @@ const Checkout = () => {
<div className='p-4'>
<div className='font-medium'>Detail Pesanan</div>
- <table className='table-checkout'>
+ <CardProdcuctsList isLoading={isLoading} products={products} />
+
+ {/* <table className='table-checkout'>
<thead>
<tr>
<th>Nama Produk</th>
@@ -1045,21 +1051,27 @@ const Checkout = () => {
/>
</td>
<td>
- {product?.price?.discountPercentage > 0 && (
- <div className='flex gap-x-1 items-center justify-center mt-3'>
- <div className='text-gray_r-11 line-through text-caption-1'>
- {currencyFormat(product?.price?.price)}
+ {product?.hasFlashsale ? (
+ <>
+ <div className='flex gap-x-1 items-center justify-center mt-3'>
+ <div className='text-gray_r-11 line-through text-caption-1'>
+ {currencyFormat(product?.price?.price)}
+ </div>
+ <div className='badge-solid-red'>
+ {product?.price?.discountPercentage}%
+ </div>
</div>
- <div className='badge-solid-red'>
- {product?.price?.discountPercentage}%
+ <div className='font-normal mt-1'>
+ {currencyFormat(product?.price?.priceDiscount)}
</div>
+ </>
+ ) : (
+ <div className='font-normal mt-1'>
+ {product.price.priceDiscount > 0
+ ? currencyFormat(product?.price?.priceDiscount)
+ : 'Call For Price'}
</div>
)}
- <div className='font-normal mt-1'>
- {product.price.priceDiscount > 0
- ? currencyFormat(product?.price?.priceDiscount)
- : 'Call For Price'}
- </div>
</td>
<td>
<div className='text-danger-500 font-medium'>
@@ -1139,7 +1151,7 @@ const Checkout = () => {
))
)}
</tbody>
- </table>
+ </table> */}
</div>
</div>
<div className='w-1/4 pl-4'>
diff --git a/src/lib/product/components/Product/ProductDesktop.jsx b/src/lib/product/components/Product/ProductDesktop.jsx
index 5cc35df7..4c8c3ae9 100644
--- a/src/lib/product/components/Product/ProductDesktop.jsx
+++ b/src/lib/product/components/Product/ProductDesktop.jsx
@@ -44,7 +44,10 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => {
const { setRefreshCart, refreshCart } = useProductCartContext()
const getLowestPrice = useCallback(() => {
- const prices = product.variants.map((variant) => variant.price)
+ const prices = product.variants.map((variant) => ({
+ price: variant.price,
+ isFlashsale: variant.isFlashsale
+ }))
const lowest = prices.reduce((lowest, price) => {
return price.priceDiscount < lowest.priceDiscount ? price : lowest
}, prices[0])
@@ -413,13 +416,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'>
@@ -436,28 +439,56 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => {
</div>
)}
</div>
+ )} */}
+
+ {lowestPrice?.isFlashsale ? (
+ <>
+ <div className='flex gap-x-1 items-center mt-2'>
+ <div className='badge-solid-red text-caption-1'>
+ {lowestPrice?.price?.discountPercentage}%
+ </div>
+ <div className='text-gray_r-9 line-through text-caption-1'>
+ {currencyFormat(lowestPrice?.price?.price)}
+ </div>
+ <div className='text-danger-500 font-semibold text-xl'>
+ {currencyFormat(lowestPrice?.price?.priceDiscount)}
+ </div>
+ </div>
+ <div className='text-gray_r-9 text-base font-normal mt-1'>
+ Termasuk PPN:{' '}
+ {currencyFormat(lowestPrice?.price.priceDiscount * process.env.NEXT_PUBLIC_PPN)}
+ </div>
+ </>
+ ) : (
+ <h3 className='text-danger-500 font-semibold mt-1 text-title-md'>
+ {lowestPrice?.price.price > 0 ? (
+ <>
+ {currencyFormat(lowestPrice?.price.price)}
+ <div className='text-gray_r-9 text-base font-normal mt-1'>
+ Termasuk PPN:{' '}
+ {currencyFormat(lowestPrice?.price.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'
@@ -549,32 +580,65 @@ const ProductDesktop = ({ products, wishlist, toggleWishlist }) => {
<ColumnsSLA variant={variant} product={product} />
</LazyLoadComponent>
<td>
- {variant.price.discountPercentage > 0 &&
+ {variant.isFlashsale ? (
+ <>
+ <div className='flex items-center gap-x-1 justify-center'>
+ <div className='badge-solid-red text-caption-1'>
+ {variant?.price?.discountPercentage}%
+ </div>
+ <div className='line-through text-caption-1 text-gray_r-11'>
+ {currencyFormat(variant?.price?.price)}
+ </div>{' '}
+ <div className=' text-caption-1 text-red-600 font-semibold'>
+ {currencyFormat(variant?.price?.priceDiscount)}
+ </div>{' '}
+ </div>
+ <div className=' text-caption-1 text-gray_r-11 mb-1'>
+ Inc. PPN:{' '}
+ {currencyFormat(
+ variant.price.priceDiscount * process.env.NEXT_PUBLIC_PPN
+ )}
+ </div>
+ </>
+ ) : (
+ <div>
+ {variant?.price?.price > 0 ? (
+ <>
+ <div className=' text-caption-1 text-red-600 font-semibold'>
+ {currencyFormat(variant?.price?.price)}
+ </div>{' '}
+ <div className=' text-caption-1 text-gray_r-11 mb-1'>
+ Inc. PPN:{' '}
+ {currencyFormat(
+ variant?.price?.priceDiscount * process.env.NEXT_PUBLIC_PPN
+ )}
+ </div>
+ </>
+ ) : (
+ <a
+ href={whatsappUrl('product', {
+ name: variant.name,
+ manufacture: product.manufacture?.name,
+ url: createSlug('/shop/product/', product.name, product.id, true)
+ })}
+ className='text-red_r-11'
+ rel='noopener noreferrer'
+ target='_blank'
+ >
+ Call for price
+ </a>
+ )}
+ </div>
+ )}
+ {/* {variant.price.discountPercentage > 0 &&
variant.price.priceDiscount > 0 && (
<>
<div className='line-through text-caption-1 text-gray_r-11 mb-1'>
{currencyFormat(variant.price.price)}
</div>{' '}
</>
- )}
- <div>
- {variant.price.priceDiscount > 0 ? (
- currencyFormat(variant.price.priceDiscount)
- ) : (
- <a
- href={whatsappUrl('product', {
- name: variant.name,
- manufacture: product.manufacture?.name,
- url: createSlug('/shop/product/', product.name, product.id, true)
- })}
- className='text-red_r-11'
- rel='noopener noreferrer'
- target='_blank'
- >
- Call for price
- </a>
- )}
- </div>
+ )} */}
+
{/* <VariantPrice id={variant.id} /> */}
</td>
<td>
diff --git a/src/lib/product/components/Product/ProductDesktopVariant.jsx b/src/lib/product/components/Product/ProductDesktopVariant.jsx
index d64e70c2..51739bc9 100644
--- a/src/lib/product/components/Product/ProductDesktopVariant.jsx
+++ b/src/lib/product/components/Product/ProductDesktopVariant.jsx
@@ -203,7 +203,8 @@ const ProductDesktopVariant = ({ product, wishlist, toggleWishlist, isVariant })
<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'
>
@@ -269,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>
- <h3 className='text-danger-500 font-semibold text-title-sm'>
- {currencyFormat(lowestPrice?.priceDiscount * 1.11)}
- </h3>
+ <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>
</>
) : (
- <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 12c43727..20a1d3f4 100644
--- a/src/lib/product/components/Product/ProductMobile.jsx
+++ b/src/lib/product/components/Product/ProductMobile.jsx
@@ -100,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)
@@ -231,32 +232,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?.price > 0 ? (
+ <>
+ {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)}
+ </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 d0c209cc..8cdb631f 100644
--- a/src/lib/product/components/Product/ProductMobileVariant.jsx
+++ b/src/lib/product/components/Product/ProductMobileVariant.jsx
@@ -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])
@@ -139,47 +141,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>
diff --git a/src/lib/product/components/ProductCard.jsx b/src/lib/product/components/ProductCard.jsx
index 10ffdaec..6a5e29ab 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-[10px] font-normal mt-2'>
+ Inc. 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'>
+ Inc. 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/quotation/components/Quotation.jsx b/src/lib/quotation/components/Quotation.jsx
index cee35457..8c379ead 100644
--- a/src/lib/quotation/components/Quotation.jsx
+++ b/src/lib/quotation/components/Quotation.jsx
@@ -16,6 +16,7 @@ import MobileView from '@/core/components/views/MobileView'
import DesktopView from '@/core/components/views/DesktopView'
import Image from '@/core/components/elements/Image/Image'
import { useQuery } from 'react-query'
+import CardProdcuctsList from '@/core/components/elements/Product/cartProductsList'
const { checkoutApi } = require('@/lib/checkout/api/checkoutApi')
const { getProductsCheckout } = require('@/lib/checkout/api/checkoutApi')
@@ -174,70 +175,7 @@ const Quotation = () => {
<div className='container mx-auto py-10 flex'>
<div className='w-3/4 border border-gray_r-6 rounded bg-white p-4'>
<div className='font-medium'>Detail Barang</div>
- <table className='table-checkout'>
- <thead>
- <tr>
- <th>Nama Produk</th>
- <th>Jumlah</th>
- <th>Harga</th>
- <th>Subtotal</th>
- </tr>
- </thead>
- <tbody>
- {products?.map((product) => (
- <tr key={product.id}>
- <td className='flex'>
- <div className='w-[30%] flex-shrink-0'>
- <Image
- src={product?.parent?.image}
- alt={product?.name}
- className='object-contain object-center border border-gray_r-6 h-40 w-full rounded-md'
- />
- </div>
- <div className='px-2 text-left'>
- <div className='line-clamp-2 leading-6 !text-gray_r-12 font-normal'>
- {product?.parent?.name}
- </div>
- <div className='text-gray_r-11 mt-2'>
- {product?.code}{' '}
- {product?.attributes.length > 0
- ? `| ${product?.attributes.join(', ')}`
- : ''}
- </div>
- </div>
- </td>
- <td>
- <input
- className='form-input w-16 py-2 text-center bg-gray_r-1'
- type='number'
- value={product?.quantity}
- disabled
- />
- </td>
- <td>
- {product?.price?.discountPercentage > 0 && (
- <div className='flex gap-x-1 items-center justify-center mt-3'>
- <div className='text-gray_r-11 line-through text-caption-1'>
- {currencyFormat(product?.price?.price)}
- </div>
- <div className='badge-solid-red'>
- {product?.price?.discountPercentage}%
- </div>
- </div>
- )}
- <div className='font-normal mt-1'>
- {currencyFormat(product?.price?.priceDiscount)}
- </div>
- </td>
- <td>
- <div className='text-danger-500 font-medium'>
- {currencyFormat(product?.price?.priceDiscount * product?.quantity)}
- </div>
- </td>
- </tr>
- ))}
- </tbody>
- </table>
+ <CardProdcuctsList isLoading={isLoading} products={products} source='checkout' />
</div>
<div className='w-1/4 pl-4'>
diff --git a/src/lib/variant/components/VariantCard.jsx b/src/lib/variant/components/VariantCard.jsx
index 0f9f02f6..64b6d146 100644
--- a/src/lib/variant/components/VariantCard.jsx
+++ b/src/lib/variant/components/VariantCard.jsx
@@ -43,7 +43,7 @@ const VariantCard = ({ product, openOnClick = true, buyMore = false }) => {
Berat Item : {product?.weight} Kg
</p>
<div className='flex flex-wrap gap-x-1 items-center mt-auto'>
- {product.price.discountPercentage > 0 && (
+ {product.hasFlashsale && (
<>
<p className='text-caption-2 text-gray_r-11 line-through'>
{currencyFormat(product.price.price)}
diff --git a/src/lib/variant/components/VariantGroupCard.jsx b/src/lib/variant/components/VariantGroupCard.jsx
index dd5983a9..1e921546 100644
--- a/src/lib/variant/components/VariantGroupCard.jsx
+++ b/src/lib/variant/components/VariantGroupCard.jsx
@@ -4,7 +4,6 @@ import Image from '@/core/components/elements/Image/Image'
import currencyFormat from '@/core/utils/currencyFormat'
const VariantGroupCard = ({ variants, ...props }) => {
- console.log('variant', variants)
const [showAll, setShowAll] = useState(false)
const variantsToShow = showAll ? variants : variants.slice(0, 2)
diff --git a/src/pages/api/shop/product-detail.js b/src/pages/api/shop/product-detail.js
index 5c3a8231..22a53df2 100644
--- a/src/pages/api/shop/product-detail.js
+++ b/src/pages/api/shop/product-detail.js
@@ -1,3 +1,4 @@
+import { productMappingSolr, variantsMappingSolr } from '@/utils/solrMapping'
import axios from 'axios'
export default async function handler(req, res) {
@@ -9,13 +10,12 @@ export default async function handler(req, res) {
process.env.SOLR_HOST +
`/solr/variants/select?q=template_id_i:${req.query.id}&q.op=OR&indent=true&rows=100`
)
- let { auth } = req.cookies
- if (auth) auth = JSON.parse(auth)
- let result = productResponseMap(productTemplate.data.response.docs, auth?.pricelist || false)
- result[0].variants = productVariantsResponseMap(
+ let auth = req.query.auth === 'false' ? JSON.parse(req.query.auth) : req.query.auth
+ let result = productMappingSolr(productTemplate.data.response.docs, auth || false)
+ result[0].variants = variantsMappingSolr(
productTemplate.data.response.docs[0],
productVariants.data.response.docs,
- auth?.pricelist || false
+ auth || false
)
res.status(200).json(result)
} catch (error) {
@@ -24,19 +24,14 @@ export default async function handler(req, res) {
}
}
-const productResponseMap = (products, pricelist) => {
+/*const productResponseMap = (products, pricelist) => {
return products.map((product) => {
- let price = product.price_f || 0
+ let price = product.price_tier1_v2_f || 0
let priceDiscount = product.price_discount_f || 0
let discountPercentage = product.discount_f || 0
if (pricelist) {
- const pricelistDiscount = product?.[`price_${pricelist}_f`] || false
- const pricelistDiscountPerc = product?.[`discount_${pricelist}_f`] || false
-
- if (pricelistDiscount && pricelistDiscount > 0) priceDiscount = pricelistDiscount
- if (pricelistDiscountPerc && pricelistDiscountPerc > 0)
- discountPercentage = pricelistDiscountPerc
+ price = product?.[`price_${pricelist}_f`] || 0
}
if (product?.flashsale_id_i > 0) {
@@ -86,17 +81,12 @@ const productResponseMap = (products, pricelist) => {
}
const productVariantsResponseMap = (parent, products, pricelist) => {
return products.map((product) => {
- let price = product.price_f || 0
+ let price = product.price_tier1_v2_f || 0
let priceDiscount = product.price_discount_f || 0
let discountPercentage = product.discount_f || 0
if (pricelist) {
- const pricelistDiscount = product?.[`price_${pricelist}_f`] || false
- const pricelistDiscountPerc = product?.[`discount_${pricelist}_f`] || false
-
- if (pricelistDiscount && pricelistDiscount > 0) priceDiscount = pricelistDiscount
- if (pricelistDiscountPerc && pricelistDiscountPerc > 0)
- discountPercentage = pricelistDiscountPerc
+ price = product?.[`price_${pricelist}_f`] || 0
}
if (product?.flashsale_id_i > 0) {
@@ -144,4 +134,4 @@ const flashsaleTime = (endDate) => {
const timeDifferenceInSeconds = timeDifferenceInMillis / 1000
return { remainingTime: timeDifferenceInSeconds, isFlashSale: flashsaleEndDate > currentTime }
-}
+}*/
diff --git a/src/pages/api/shop/search.js b/src/pages/api/shop/search.js
index 57b16db8..2120a442 100644
--- a/src/pages/api/shop/search.js
+++ b/src/pages/api/shop/search.js
@@ -1,3 +1,4 @@
+import { productMappingSolr } from '@/utils/solrMapping'
import axios from 'axios'
import camelcaseObjectDeep from 'camelcase-object-deep'
@@ -73,7 +74,7 @@ export default async function handler(req, res) {
try {
let { auth } = req.cookies
if (auth) auth = JSON.parse(auth)
- result.data.response.products = productResponseMap(
+ result.data.response.products = productMappingSolr(
result.data.response.docs,
auth?.pricelist || false
)
@@ -102,19 +103,21 @@ const escapeSolrQuery = (query) => {
return escapedWords.join(' ')
}
-const productResponseMap = (products, pricelist) => {
+/*const productResponseMap = (products, pricelist) => {
return products.map((product) => {
- let price = product.price_f || 0
+ let price = product.price_tier1_v2_f || 0
let priceDiscount = product.price_discount_f || 0
let discountPercentage = product.discount_f || 0
if (pricelist) {
- const pricelistDiscount = product?.[`price_${pricelist}_f`] || false
- const pricelistDiscountPerc = product?.[`discount_${pricelist}_f`] || false
+ // const pricelistDiscount = product?.[`price_${pricelist}_f`] || false
+ // const pricelistDiscountPerc = product?.[`discount_${pricelist}_f`] || false
- if (pricelistDiscount && pricelistDiscount > 0) priceDiscount = pricelistDiscount
- if (pricelistDiscountPerc && pricelistDiscountPerc > 0)
- discountPercentage = pricelistDiscountPerc
+ // if (pricelistDiscount && pricelistDiscount > 0) priceDiscount = pricelistDiscount
+ // if (pricelistDiscountPerc && pricelistDiscountPerc > 0)
+ // discountPercentage = pricelistDiscountPerc
+
+ price = product?.[`price_${pricelist}_f`] || 0
}
if (product?.flashsale_id_i > 0) {
@@ -156,4 +159,4 @@ const productResponseMap = (products, pricelist) => {
]
return productMapped
})
-}
+}*/
diff --git a/src/pages/shop/product/[slug].jsx b/src/pages/shop/product/[slug].jsx
index 534aa8da..63fb2e7e 100644
--- a/src/pages/shop/product/[slug].jsx
+++ b/src/pages/shop/product/[slug].jsx
@@ -18,10 +18,11 @@ export async function getServerSideProps(context) {
const cookies = context.req.headers.cookie
const cookieObj = cookies ? cookie.parse(cookies) : {}
const auth = cookieObj.auth ? JSON.parse(cookieObj.auth) : {}
+ const tier = auth.pricelist ? auth.pricelist : false
const authToken = auth?.token || ''
let response = await axios(
- `${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/product-detail?id=` + getIdFromSlug(slug)
+ `${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/product-detail?id=` + getIdFromSlug(slug) +'&auth=' + tier
)
let product = response.data
// let productSolr = await productApi({ id: getIdFromSlug(slug), headers: { Token: authToken } })
diff --git a/src/utils/solrMapping.js b/src/utils/solrMapping.js
new file mode 100644
index 00000000..c8bd54ea
--- /dev/null
+++ b/src/utils/solrMapping.js
@@ -0,0 +1,113 @@
+export const productMappingSolr = (products, pricelist) => {
+ return products.map((product) => {
+ let price = product.price_tier1_v2_f || 0
+ let priceDiscount = product.price_discount_f || 0
+ let discountPercentage = product.discount_f || 0
+
+ if (pricelist) {
+ price = product?.[`price_${pricelist}_f`] || 0
+ }
+
+ if (product?.flashsale_id_i > 0) {
+ price = product?.flashsale_base_price_f || 0
+ priceDiscount = product?.flashsale_price_f || 0
+ discountPercentage = product?.flashsale_discount_f || 0
+ }
+
+ let productMapped = {
+ id: product.product_id_i || '',
+ image: product.image_s || '',
+ code: product.default_code_s || '',
+ description: product.description_t || '',
+ displayName: product.display_name_s || '',
+ name: product.name_s || '',
+ lowestPrice: { price, priceDiscount, discountPercentage },
+ variantTotal: product.variant_total_i || 0,
+ stockTotal: product.stock_total_f || 0,
+ weight: product.weight_f || 0,
+ manufacture: {},
+ categories: [],
+ flashSale: {
+ id: product?.flashsale_id_i,
+ remainingTime: flashsaleTime(product?.flashsale_end_date_s)?.remainingTime,
+ name: product?.product?.flashsale_name_s,
+ tag: product?.flashsale_tag_s || 'FLASH SALE'
+ }
+ }
+
+ if (product.manufacture_id_i && product.manufacture_name_s) {
+ productMapped.manufacture = {
+ id: product.manufacture_id_i || '',
+ name: product.manufacture_name_s || '',
+ imagePromotion1: product.image_promotion_1_s || '',
+ imagePromotion2: product.image_promotion_2_s || ''
+ }
+ }
+
+ productMapped.categories = [
+ {
+ id: product.category_id_i || '',
+ name: product.category_name_s || ''
+ }
+ ]
+ return productMapped
+ })
+}
+
+export const variantsMappingSolr = (parent, products, pricelist) => {
+ return products.map((product) => {
+ let price = product.price_tier1_v2_f || 0
+ let priceDiscount = product.price_discount_f || 0
+ let discountPercentage = product.discount_f || 0
+
+ if (pricelist) {
+ price = product?.[`price_${pricelist}_f`] || 0
+ }
+
+ if (product?.flashsale_id_i > 0) {
+ price = product?.flashsale_base_price_f || 0
+ priceDiscount = product?.flashsale_price_f || 0
+ discountPercentage = product?.flashsale_discount_f || 0
+ }
+
+ let productMapped = {
+ attributes: product.attributes || [],
+ id: product.product_id_i || '',
+ image: product.image_s || '',
+ code: product.default_code_s || '',
+ isFlashsale: flashsaleTime(product?.flashsale_end_date_s)?.isFlashSale,
+ isFlashsale: flashsaleTime(product?.flashsale_end_date_s)?.isFlashSale,
+ name: product.display_name_s || '',
+ price: { price, priceDiscount, discountPercentage },
+ variantTotal: product.variant_total_i || 0,
+ stockTotal: product.stock_total_f || 0,
+ weight: product.weight_f || 0,
+ manufacture: {},
+ parent: {}
+ }
+
+ if (product.manufacture_id_i && product.manufacture_name_s) {
+ productMapped.manufacture = {
+ id: product.manufacture_id_i || '',
+ name: product.manufacture_name_s || ''
+ }
+ }
+ productMapped.parent = {
+ id: parent.product_id_i || '',
+ image: parent.image_s || '',
+ name: parent.name_s || ''
+ }
+ return productMapped
+ })
+ }
+
+const flashsaleTime = (endDate) => {
+ const flashsaleEndDate = new Date(endDate)
+ const currentTime = new Date()
+
+ const timeDifferenceInMillis = flashsaleEndDate - currentTime
+ const timeDifferenceInSeconds = timeDifferenceInMillis / 1000
+
+ return { remainingTime: timeDifferenceInSeconds, isFlashSale: flashsaleEndDate > currentTime }
+ }
+