diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/components/elements/CountDown/CountDown.jsx | 18 | ||||
| -rw-r--r-- | src/lib/flashSale/components/FlashSale.jsx | 48 | ||||
| -rw-r--r-- | src/lib/product/api/productSearchApi.js | 4 | ||||
| -rw-r--r-- | src/pages/api/shop/search.js | 37 | ||||
| -rw-r--r-- | src/pages/index.jsx | 1 |
5 files changed, 72 insertions, 36 deletions
diff --git a/src/core/components/elements/CountDown/CountDown.jsx b/src/core/components/elements/CountDown/CountDown.jsx index 49a33d77..877f7998 100644 --- a/src/core/components/elements/CountDown/CountDown.jsx +++ b/src/core/components/elements/CountDown/CountDown.jsx @@ -31,22 +31,22 @@ const CountDown = ({ initialTime }) => { }, [timeLeft]) return ( - <div className='flex gap-x-3 w-fit'> + <div className='flex gap-x-2.5 w-fit'> <div className='flex flex-col items-center'> - <span className='bg-red-600 text-white font-semibold w-10 h-10 flex items-center justify-center rounded'>{timeLeft.day}</span> - <span className='text-caption-1 text-gray-807'>Hari</span> + <span className='bg-red-600 text-white font-semibold w-10 h-10 flex items-center justify-center rounded'>{timeLeft.day.toString().padStart(2, '0')}</span> + <span className='text-caption-1 text-gray-700 mt-1'>Hari</span> </div> <div className='flex flex-col items-center'> - <span className='bg-red-600 text-white font-semibold w-10 h-10 flex items-center justify-center rounded'>{timeLeft.hour}</span> - <span className='text-caption-1 text-gray-807'>Jam</span> + <span className='bg-red-600 text-white font-semibold w-10 h-10 flex items-center justify-center rounded'>{timeLeft.hour.toString().padStart(2, '0')}</span> + <span className='text-caption-1 text-gray-700 mt-1'>Jam</span> </div> <div className='flex flex-col items-center'> - <span className='bg-red-600 text-white font-semibold w-10 h-10 flex items-center justify-center rounded'>{timeLeft.minute}</span> - <span className='text-caption-1 text-gray-700'>Menit</span> + <span className='bg-red-600 text-white font-semibold w-10 h-10 flex items-center justify-center rounded'>{timeLeft.minute.toString().padStart(2, '0')}</span> + <span className='text-caption-1 text-gray-700 mt-1'>Menit</span> </div> <div className='flex flex-col items-center'> - <span className='bg-red-600 text-white font-semibold w-10 h-10 flex items-center justify-center rounded'>{timeLeft.second}</span> - <span className='text-caption-1 text-gray-700'>Detik</span> + <span className='bg-red-600 text-white font-semibold w-10 h-10 flex items-center justify-center rounded'>{timeLeft.second.toString().padStart(2, '0')}</span> + <span className='text-caption-1 text-gray-700 mt-1'>Detik</span> </div> </div> ) diff --git a/src/lib/flashSale/components/FlashSale.jsx b/src/lib/flashSale/components/FlashSale.jsx index 0167dc57..91248c12 100644 --- a/src/lib/flashSale/components/FlashSale.jsx +++ b/src/lib/flashSale/components/FlashSale.jsx @@ -2,6 +2,8 @@ import { useEffect, useState } from 'react' import flashSaleApi from '../api/flashSaleApi' import Image from '@/core/components/elements/Image/Image' import CountDown from '@/core/components/elements/CountDown/CountDown' +import productSearchApi from '@/lib/product/api/productSearchApi' +import ProductSlider from '@/lib/product/components/ProductSlider' const FlashSale = () => { const [flashSales, setFlashSales] = useState(null) @@ -14,24 +16,42 @@ const FlashSale = () => { loadFlashSales() }, []) - return flashSales?.length > 0 && ( - <div className='px-4 sm:px-0'> - - {flashSales.map((flashSale, index) => ( - <div key={index}> - <div className='font-medium sm:text-h-lg mb-4'>{flashSale.name}</div> - - <div className='relative'> - <div className='absolute top-0 left-0 p-4'> + return ( + flashSales?.length > 0 && ( + <div className='px-4 sm:px-0 grid grid-cols-1 gap-y-8'> + {flashSales.map((flashSale, index) => ( + <div key={index}> + <div className='flex gap-x-3 mb-4 justify-between sm:justify-start'> + <div className='font-medium sm:text-h-lg mt-1.5'>{flashSale.name}</div> <CountDown initialTime={flashSale.duration} /> </div> - <Image src={flashSale.banner} alt={flashSale.name} className='w-full rounded' /> - </div> - </div> - ))} - </div> + <div className='relative'> + <Image src={flashSale.banner} alt={flashSale.name} className='w-full rounded mb-4' /> + <FlashSaleProduct flashSaleId={flashSale.pricelistId} /> + </div> + </div> + ))} + </div> + ) ) } +const FlashSaleProduct = ({ flashSaleId }) => { + const [products, setProducts] = useState(null) + + useEffect(() => { + const loadProducts = async () => { + const dataProducts = await productSearchApi({ + query: `fq=flashsale_id_i:${flashSaleId}&fq=flashsale_price_f:[1 TO *]&limit=500`, + operation: 'AND' + }) + setProducts(dataProducts.response) + } + loadProducts() + }, [flashSaleId]) + + return <ProductSlider products={products} /> +} + export default FlashSale diff --git a/src/lib/product/api/productSearchApi.js b/src/lib/product/api/productSearchApi.js index 71fb72e6..8ff8e57d 100644 --- a/src/lib/product/api/productSearchApi.js +++ b/src/lib/product/api/productSearchApi.js @@ -1,9 +1,9 @@ import _ from 'lodash-contrib' import axios from 'axios' -const productSearchApi = async ({ query }) => { +const productSearchApi = async ({ query, operation = 'OR' }) => { const dataProductSearch = await axios( - `${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/search?${query}&operation=OR` + `${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/search?${query}&operation=${operation}` ) return dataProductSearch.data } diff --git a/src/pages/api/shop/search.js b/src/pages/api/shop/search.js index 4a237d47..404da1b3 100644 --- a/src/pages/api/shop/search.js +++ b/src/pages/api/shop/search.js @@ -43,10 +43,17 @@ export default async function handler(req, res) { 'qf=name_s', `start=${offset}`, `rows=${limit}`, - `sort=${paramOrderBy}`, - `fq=price_discount_f:[${priceFrom == '' ? '*' : priceFrom} TO ${priceTo == '' ? '*' : priceTo}]` + `sort=${paramOrderBy}` ] + if (priceFrom > 0 || priceTo > 0) { + parameter.push( + `fq=price_discount_f:[${priceFrom == '' ? '*' : priceFrom} TO ${ + priceTo == '' ? '*' : priceTo + }]` + ) + } + if (brand) parameter.push(`fq=manufacture_name:${brand}`) if (category) parameter.push(`fq=category_name:${category}`) @@ -90,15 +97,23 @@ const escapeSolrQuery = (query) => { const productResponseMap = (products, pricelist) => { return products.map((product) => { + let price = product.price_f || 0 let priceDiscount = product.price_discount_f || 0 - let discount = product.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) discount = pricelistDiscountPerc + if (pricelistDiscountPerc && pricelistDiscountPerc > 0) + discountPercentage = pricelistDiscountPerc + } + + 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 = { @@ -106,16 +121,16 @@ const productResponseMap = (products, pricelist) => { image: product.image_s || '', code: product.default_code_s || '', name: product.name_s || '', - lowestPrice: { - price: product.price_f || 0, - priceDiscount: priceDiscount, - discountPercentage: discount - }, + lowestPrice: { price, priceDiscount, discountPercentage }, variantTotal: product.variant_total_i || 0, stockTotal: product.stock_total_f || 0, weight: product.weight_f || 0, manufacture: {}, - categories: [] + categories: [], + flashSale: { + id: product?.flashsale_id_i, + name: product?.product?.flashsale_name_s + } } if (product.manufacture_id_i && product.manufacture_name_s) { diff --git a/src/pages/index.jsx b/src/pages/index.jsx index a98fb6b3..f1df4e13 100644 --- a/src/pages/index.jsx +++ b/src/pages/index.jsx @@ -83,6 +83,7 @@ export default function Home() { <HeroBanner /> <div className='flex flex-col gap-y-6 my-6'> <PreferredBrand /> + <FlashSale /> <PopularProduct /> <CategoryHomeId /> </div> |
