summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorIT Fixcomart <it@fixcomart.co.id>2024-10-07 06:08:39 +0000
committerIT Fixcomart <it@fixcomart.co.id>2024-10-07 06:08:39 +0000
commit154f70e23f9aaced5b210b4f27161f70999ae9cb (patch)
tree5de6b0e48df5267f0bd0fd99397157e7e57ee9fb /src/lib
parent79e1000887b6326475251624575655bb65c296db (diff)
parent41a12de37fff3f716de77bb18c50073336f69ab4 (diff)
Merged in iman/flashsaleNonDisplay (pull request #345)
Iman/flashsaleNonDisplay Approved-by: trisusilo
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/flashSale/components/FlashSale.jsx60
-rw-r--r--src/lib/flashSale/components/FlashSaleNonDisplay.jsx68
-rw-r--r--src/lib/product/components/ProductFilter.jsx127
-rw-r--r--src/lib/product/components/ProductFilterDesktop.jsx165
-rw-r--r--src/lib/product/components/ProductSearch.jsx20
5 files changed, 286 insertions, 154 deletions
diff --git a/src/lib/flashSale/components/FlashSale.jsx b/src/lib/flashSale/components/FlashSale.jsx
index 5be6d4e3..89c46de4 100644
--- a/src/lib/flashSale/components/FlashSale.jsx
+++ b/src/lib/flashSale/components/FlashSale.jsx
@@ -26,38 +26,40 @@ const FlashSale = () => {
}
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 className='sm:mt-4'>
+ {flashSales?.length > 0 && (
+ <div className='px-4 sm:px-0 grid grid-cols-1 gap-y-8 sm:mt-4'>
+ {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>
- <CountDown initialTime={flashSale.duration} />
- </div>
- <div className='relative'>
- <Image
- src={flashSale.banner}
- alt={flashSale.name}
- width={1080}
- height={192}
- className='w-full rounded mb-4 hidden sm:block'
- />
- <Image
- src={flashSale.bannerMobile}
- alt={flashSale.name}
- width={256}
- height={48}
- className='w-full rounded mb-4 block sm:hidden'
- />
- <FlashSaleProduct flashSaleId={flashSale.pricelistId} />
+ <div className='relative'>
+ <Image
+ src={flashSale.banner}
+ alt={flashSale.name}
+ width={1080}
+ height={192}
+ className='w-full rounded mb-4 hidden sm:block'
+ />
+ <Image
+ src={flashSale.bannerMobile}
+ alt={flashSale.name}
+ width={256}
+ height={48}
+ className='w-full rounded mb-4 block sm:hidden'
+ />
+ <FlashSaleProduct flashSaleId={flashSale.pricelistId} />
+ </div>
</div>
- </div>
- ))}
- </div>
- )
+ ))}
+ </div>
+ )}
+ </div>
);
};
diff --git a/src/lib/flashSale/components/FlashSaleNonDisplay.jsx b/src/lib/flashSale/components/FlashSaleNonDisplay.jsx
new file mode 100644
index 00000000..c91de2be
--- /dev/null
+++ b/src/lib/flashSale/components/FlashSaleNonDisplay.jsx
@@ -0,0 +1,68 @@
+import Image from 'next/image';
+import { useEffect, useState } from 'react';
+import CountDown from '@/core/components/elements/CountDown/CountDown';
+import productSearchApi from '@/lib/product/api/productSearchApi';
+import ProductSlider from '@/lib/product/components/ProductSlider';
+import flashSaleApi from '../api/flashSaleApi';
+import { FlashSaleSkeleton } from '../skeleton/FlashSaleSkeleton';
+import Link from 'next/link';
+import { useRouter } from 'next/router';
+const FlashSaleNonDisplay = () => {
+ const [flashSales, setFlashSales] = useState(null);
+ const [isLoading, setIsLoading] = useState(true);
+ const router = useRouter();
+ useEffect(() => {
+ const loadFlashSales = async () => {
+ const dataFlashSales = await flashSaleApi();
+ setFlashSales(dataFlashSales);
+ setIsLoading(false);
+ };
+ loadFlashSales();
+ }, []);
+ const handleSubmit = () => {
+ router.push(`/shop/search?penawaran=${flashSales[0]?.pricelistId}`);
+ };
+ if (isLoading) {
+ return <FlashSaleSkeleton />;
+ }
+
+ 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 items-center mb-4 justify-between '>
+ <div className='font-medium sm:text-h-lg mt-1.5'>
+ Penawaran Terbatas
+ </div>
+ <div
+ onClick={handleSubmit}
+ className='!text-red-500 font-semibold cursor-pointer'
+ >
+ Lihat Semua
+ </div>
+ </div>
+ <div className='relative'>
+ <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=25&orderBy=flashsale-discount-desc`,
+ operation: 'AND',
+ });
+ setProducts(dataProducts.response);
+ };
+ loadProducts();
+ }, [flashSaleId]);
+ return <ProductSlider products={products} />;
+};
+export default FlashSaleNonDisplay;
diff --git a/src/lib/product/components/ProductFilter.jsx b/src/lib/product/components/ProductFilter.jsx
index d52fcb90..947550b7 100644
--- a/src/lib/product/components/ProductFilter.jsx
+++ b/src/lib/product/components/ProductFilter.jsx
@@ -1,88 +1,96 @@
-import BottomPopup from '@/core/components/elements/Popup/BottomPopup'
-import { useRouter } from 'next/router'
-import { useState } from 'react'
-import _ from 'lodash'
-import { toQuery } from 'lodash-contrib'
-import { Checkbox } from '@chakra-ui/react'
+import BottomPopup from '@/core/components/elements/Popup/BottomPopup';
+import { useRouter } from 'next/router';
+import { useState } from 'react';
+import _ from 'lodash';
+import { toQuery } from 'lodash-contrib';
+import { Checkbox } from '@chakra-ui/react';
const orderOptions = [
{ value: 'price-asc', label: 'Harga Terendah' },
{ value: 'price-desc', label: 'Harga Tertinggi' },
{ value: 'popular', label: 'Populer' },
- { value: 'stock', label: 'Ready Stock' }
-]
+ { value: 'stock', label: 'Ready Stock' },
+];
-const ProductFilter = ({ active, close, brands, categories, prefixUrl, defaultBrand = null }) => {
- const router = useRouter()
- const { query } = router
- const [order, setOrder] = useState(query?.orderBy || 'popular')
- const [brand, setBrand] = useState(query?.brand)
- const [category, setCategory] = useState(query?.category)
- const [priceFrom, setPriceFrom] = useState(query?.priceFrom)
- const [priceTo, setPriceTo] = useState(query?.priceTo)
+const ProductFilter = ({
+ active,
+ close,
+ brands,
+ categories,
+ prefixUrl,
+ defaultBrand = null,
+}) => {
+ const router = useRouter();
+ const { query } = router;
+ const [order, setOrder] = useState(query?.orderBy || 'popular');
+ const [brand, setBrand] = useState(query?.brand);
+ const [category, setCategory] = useState(query?.category);
+ const [priceFrom, setPriceFrom] = useState(query?.priceFrom);
+ const [priceTo, setPriceTo] = useState(query?.priceTo);
- const [stock, setStock] = useState(query?.stock)
+ const [stock, setStock] = useState(query?.stock);
- const [activeRange, setActiveRange] = useState(null)
+ const [activeRange, setActiveRange] = useState(null);
const priceRange = [
{
priceFrom: 100000,
- priceTo: 200000
+ priceTo: 200000,
},
{
priceFrom: 200000,
- priceTo: 300000
+ priceTo: 300000,
},
{
priceFrom: 300000,
- priceTo: 400000
+ priceTo: 400000,
},
{
priceFrom: 400000,
- priceTo: 500000
- }
- ]
+ priceTo: 500000,
+ },
+ ];
const handlePriceFromChange = async (priceFromr, priceTor, index) => {
- await setPriceFrom(priceFromr)
- await setPriceTo(priceTor)
- setActiveRange(index)
- }
+ await setPriceFrom(priceFromr);
+ await setPriceTo(priceTor);
+ setActiveRange(index);
+ };
const handleReadyStockChange = (event) => {
- const value = event.target.value
- const isChecked = event.target.checked
+ const value = event.target.value;
+ const isChecked = event.target.checked;
if (isChecked) {
- setStock(value)
+ setStock(value);
} else {
- setStock(null)
+ setStock(null);
}
- }
+ };
const handleSubmit = () => {
let params = {
+ penawaran: router.query.penawaran,
q: router.query.q,
orderBy: order,
brand,
category,
priceFrom,
priceTo,
- stock: stock
- }
- params = _.pickBy(params, _.identity)
- params = toQuery(params)
- router.push(`${prefixUrl}?${params}`)
- }
+ stock: stock,
+ };
+ params = _.pickBy(params, _.identity);
+ params = toQuery(params);
+ router.push(`${prefixUrl}?${params}`);
+ };
const formatCurrency = (value) => {
if (value >= 1000) {
- const thousands = Math.floor(value / 1000) // Menghitung ribuan
- return `Rp${thousands}k`
+ const thousands = Math.floor(value / 1000); // Menghitung ribuan
+ return `Rp${thousands}k`;
} else {
- return `Rp${value}`
+ return `Rp${value}`;
}
- }
+ };
return (
<BottomPopup active={active} close={close} title='Filter Produk'>
@@ -101,7 +109,10 @@ const ProductFilter = ({ active, close, brands, categories, prefixUrl, defaultBr
<option value=''>Pilih Brand...</option>
{brands.map((brand, index) => (
<option value={brand.brand} key={index}>
- {brand.brand} <span className='text-sm text-gray-200'>({brand.qty})</span>
+ {brand.brand}{' '}
+ <span className='text-sm text-gray-200'>
+ ({brand.qty})
+ </span>
</option>
))}
</>
@@ -125,7 +136,10 @@ const ProductFilter = ({ active, close, brands, categories, prefixUrl, defaultBr
<option value=''>Pilih Kategori...</option>
{categories.map((category, index) => (
<option value={category.name} key={index}>
- {category.name} <span className='text-sm text-gray-200'>({category.qty})</span>
+ {category.name}{' '}
+ <span className='text-sm text-gray-200'>
+ ({category.qty})
+ </span>
</option>
))}
</>
@@ -141,7 +155,9 @@ const ProductFilter = ({ active, close, brands, categories, prefixUrl, defaultBr
<button
key={orderOption.value}
className={`btn-light px-3 font-normal flex-shrink-0 ${
- order == orderOption.value ? 'bg-warning-500' : 'bg-transparent'
+ order == orderOption.value
+ ? 'bg-warning-500'
+ : 'bg-transparent'
}`}
onClick={() => setOrder(orderOption.value)}
>
@@ -173,13 +189,16 @@ const ProductFilter = ({ active, close, brands, categories, prefixUrl, defaultBr
{priceRange.map((price, i) => (
<button
key={i}
- onClick={() => handlePriceFromChange(price.priceFrom, price.priceTo, i)}
+ onClick={() =>
+ handlePriceFromChange(price.priceFrom, price.priceTo, i)
+ }
className={`w-full border ${
i === activeRange ? 'border-red-600' : 'border-gray-400'
}
py-2 p-3 rounded-full text-sm whitespace-nowrap`}
>
- {formatCurrency(price.priceFrom)} - {formatCurrency(price.priceTo)}
+ {formatCurrency(price.priceFrom)} -{' '}
+ {formatCurrency(price.priceTo)}
</button>
))}
</div>
@@ -197,12 +216,16 @@ const ProductFilter = ({ active, close, brands, categories, prefixUrl, defaultBr
</Checkbox>
</div>
</div> */}
- <button type='button' className='btn-solid-red w-full mt-2' onClick={handleSubmit}>
+ <button
+ type='button'
+ className='btn-solid-red w-full mt-2'
+ onClick={handleSubmit}
+ >
Terapkan Filter
</button>
</div>
</BottomPopup>
- )
-}
+ );
+};
-export default ProductFilter
+export default ProductFilter;
diff --git a/src/lib/product/components/ProductFilterDesktop.jsx b/src/lib/product/components/ProductFilterDesktop.jsx
index 73fecab5..d2ecb4d9 100644
--- a/src/lib/product/components/ProductFilterDesktop.jsx
+++ b/src/lib/product/components/ProductFilterDesktop.jsx
@@ -1,7 +1,7 @@
-import { useRouter } from 'next/router'
-import { useEffect, useState } from 'react'
-import _ from 'lodash'
-import { toQuery } from 'lodash-contrib'
+import { useRouter } from 'next/router';
+import { useEffect, useState } from 'react';
+import _ from 'lodash';
+import { toQuery } from 'lodash-contrib';
import {
Accordion,
AccordionButton,
@@ -15,110 +15,119 @@ import {
InputGroup,
InputLeftAddon,
Stack,
- VStack
-} from '@chakra-ui/react'
-import Image from '@/core/components/elements/Image/Image'
-import { formatCurrency } from '@/core/utils/formatValue'
+ VStack,
+} from '@chakra-ui/react';
+import Image from '@/core/components/elements/Image/Image';
+import { formatCurrency } from '@/core/utils/formatValue';
-const ProductFilterDesktop = ({ brands, categories, prefixUrl, defaultBrand = null }) => {
-
-
- const router = useRouter()
- const { query } = router
- const [order, setOrder] = useState(query?.orderBy)
- const [brandValues, setBrand] = useState(query?.brand?.split(',') || [])
- const [categoryValues, setCategory] = useState(query?.category?.split(',') || [])
- const [priceFrom, setPriceFrom] = useState(query?.priceFrom)
- const [priceTo, setPriceTo] = useState(query?.priceTo)
- const [stock, setStock] = useState(query?.stock)
- const [activeRange, setActiveRange] = useState(null)
- const [activeIndeces, setActiveIndeces] = useState([])
+const ProductFilterDesktop = ({
+ brands,
+ categories,
+ prefixUrl,
+ defaultBrand = null,
+}) => {
+ const router = useRouter();
+ const { query } = router;
+ const [order, setOrder] = useState(query?.orderBy);
+ const [brandValues, setBrand] = useState(query?.brand?.split(',') || []);
+ const [categoryValues, setCategory] = useState(
+ query?.category?.split(',') || []
+ );
+ const [priceFrom, setPriceFrom] = useState(query?.priceFrom);
+ const [priceTo, setPriceTo] = useState(query?.priceTo);
+ const [stock, setStock] = useState(query?.stock);
+ const [activeRange, setActiveRange] = useState(null);
+ const [activeIndeces, setActiveIndeces] = useState([]);
const priceRange = [
{
priceFrom: 100000,
- priceTo: 200000
+ priceTo: 200000,
},
{
priceFrom: 200000,
- priceTo: 300000
+ priceTo: 300000,
},
{
priceFrom: 300000,
- priceTo: 400000
+ priceTo: 400000,
},
{
priceFrom: 400000,
- priceTo: 500000
- }
- ]
+ priceTo: 500000,
+ },
+ ];
const indexRange = priceRange.findIndex((range) => {
- return range.priceFrom === parseInt(priceFrom) && range.priceTo == parseInt(priceTo)
- })
+ return (
+ range.priceFrom === parseInt(priceFrom) &&
+ range.priceTo == parseInt(priceTo)
+ );
+ });
const handleCategoriesChange = (event) => {
- const value = event.target.value
- const isChecked = event.target.checked
+ const value = event.target.value;
+ const isChecked = event.target.checked;
if (isChecked) {
- setCategory([...categoryValues, value])
+ setCategory([...categoryValues, value]);
} else {
- setCategory(categoryValues.filter((val) => val !== value))
+ setCategory(categoryValues.filter((val) => val !== value));
}
- }
+ };
const handleBrandsChange = (event) => {
- const value = event.target.value
- const isChecked = event.target.checked
+ const value = event.target.value;
+ const isChecked = event.target.checked;
if (isChecked) {
- setBrand([...brandValues, value])
+ setBrand([...brandValues, value]);
} else {
- setBrand(brandValues.filter((val) => val !== value))
+ setBrand(brandValues.filter((val) => val !== value));
}
- }
+ };
const handleReadyStockChange = (event) => {
- const value = event.target.value
- const isChecked = event.target.checked
+ const value = event.target.value;
+ const isChecked = event.target.checked;
if (isChecked) {
- setStock(value)
+ setStock(value);
} else {
- setStock(null)
+ setStock(null);
}
- }
+ };
const handlePriceFromChange = async (priceFromr, priceTor, index) => {
- await setPriceFrom(priceFromr)
- await setPriceTo(priceTor)
- setActiveRange(index)
- }
+ await setPriceFrom(priceFromr);
+ await setPriceTo(priceTor);
+ setActiveRange(index);
+ };
const handleSubmit = () => {
let params = {
+ penawaran: router.query.penawaran,
q: router.query.q,
orderBy: order,
brand: brandValues.join(','),
category: categoryValues.join(','),
priceFrom,
priceTo,
- stock: stock
- }
- params = _.pickBy(params, _.identity)
- params = toQuery(params)
+ stock: stock,
+ };
+ params = _.pickBy(params, _.identity);
+ params = toQuery(params);
- const slug = Array.isArray(router.query.slug) ? router.query.slug[0] : router.query.slug;
+ const slug = Array.isArray(router.query.slug)
+ ? router.query.slug[0]
+ : router.query.slug;
if (slug) {
- if(prefixUrl.includes('category') || prefixUrl.includes('lob')){
- router.push(`${prefixUrl}?${params}`)
- }else{
- router.push(`${prefixUrl}/${slug}?${params}`)
+ if (prefixUrl.includes('category') || prefixUrl.includes('lob')) {
+ router.push(`${prefixUrl}?${params}`);
+ } else {
+ router.push(`${prefixUrl}/${slug}?${params}`);
}
} else {
- router.push(`${prefixUrl}?${params}`)
+ router.push(`${prefixUrl}?${params}`);
}
- }
-
-
+ };
/*const handleIndexAccordion = async () => {
if (brandValues) {
@@ -136,9 +145,8 @@ const ProductFilterDesktop = ({ brands, categories, prefixUrl, defaultBrand = nu
}*/
useEffect(() => {
- setActiveRange(indexRange)
- }, [])
-
+ setActiveRange(indexRange);
+ }, []);
return (
<>
@@ -165,13 +173,17 @@ const ProductFilterDesktop = ({ brands, categories, prefixUrl, defaultBrand = nu
>
<div className='flex items-center gap-2'>
<span>{brand.brand} </span>
- <span className='text-sm text-gray-600'>({brand.qty})</span>
+ <span className='text-sm text-gray-600'>
+ ({brand.qty})
+ </span>
</div>
</Checkbox>
</div>
))
) : (
- <div className='flex items-center gap-2'>Brands tidak tersedia</div>
+ <div className='flex items-center gap-2'>
+ Brands tidak tersedia
+ </div>
)}
</Stack>
</AccordionPanel>
@@ -199,13 +211,17 @@ const ProductFilterDesktop = ({ brands, categories, prefixUrl, defaultBrand = nu
>
<div className='flex items-center gap-2'>
<span>{category.name} </span>
- <span className='text-sm text-gray-600'>({category.qty})</span>
+ <span className='text-sm text-gray-600'>
+ ({category.qty})
+ </span>
</div>
</Checkbox>
</div>
))
) : (
- <div className='flex items-center gap-2'>Kategori tidak tersedia</div>
+ <div className='flex items-center gap-2'>
+ Kategori tidak tersedia
+ </div>
)}
</Stack>
</AccordionPanel>
@@ -243,13 +259,16 @@ const ProductFilterDesktop = ({ brands, categories, prefixUrl, defaultBrand = nu
{priceRange.map((price, i) => (
<button
key={i}
- onClick={() => handlePriceFromChange(price.priceFrom, price.priceTo, i)}
+ onClick={() =>
+ handlePriceFromChange(price.priceFrom, price.priceTo, i)
+ }
className={`w-full border ${
i === activeRange ? 'border-red-600' : 'border-gray-400'
}
py-2 p-3 rounded-full text-sm whitespace-nowrap`}
>
- {formatCurrency(price.priceFrom)} - {formatCurrency(price.priceTo)}
+ {formatCurrency(price.priceFrom)} -{' '}
+ {formatCurrency(price.priceTo)}
</button>
))}
</div>
@@ -282,7 +301,7 @@ const ProductFilterDesktop = ({ brands, categories, prefixUrl, defaultBrand = nu
Terapkan
</Button>
</>
- )
-}
+ );
+};
-export default ProductFilterDesktop
+export default ProductFilterDesktop;
diff --git a/src/lib/product/components/ProductSearch.jsx b/src/lib/product/components/ProductSearch.jsx
index 26114acf..f7b044aa 100644
--- a/src/lib/product/components/ProductSearch.jsx
+++ b/src/lib/product/components/ProductSearch.jsx
@@ -79,6 +79,24 @@ const ProductSearch = ({
}
}, [categoryId]);
+ useEffect(() => {
+ const checkIfPenawaran = async () => {
+ if (router.asPath.includes('penawaran')) {
+ query = {
+ ...query,
+ fq: [
+ `-flashsale_id_i:${router.query.penawaran}`,
+ `flashsale_price_f:[1 TO *]`,
+ ],
+ orderBy: 'flashsale-discount-desc',
+ };
+ setFinalQuery(query);
+ setOrderBy('flashsale-discount-desc');
+ }
+ };
+ checkIfPenawaran();
+ }, [router.query]);
+
const collectIds = (category) => {
const ids = [];
function recurse(cat) {
@@ -337,6 +355,7 @@ const ProductSearch = ({
const handleDeleteFilter = async (source, value) => {
let params = {
+ penawaran: router.query.penawaran,
q: router.query.q,
orderBy: orderBy,
brand: brandValues.join(','),
@@ -364,6 +383,7 @@ const ProductSearch = ({
break;
case 'delete':
params = {
+ penawaran: router.query.penawaran,
q: router.query.q,
orderBy: orderBy,
};