summaryrefslogtreecommitdiff
path: root/src/lib/product
diff options
context:
space:
mode:
authortrisusilo <tri.susilo@altama.co.id>2023-10-24 03:07:57 +0000
committertrisusilo <tri.susilo@altama.co.id>2023-10-24 03:07:57 +0000
commite6c0f277f47b6aeaa55a19216615840f61bfeb1e (patch)
treeebaef18f5b7d6925f8eddd029df336fe408f6261 /src/lib/product
parentbf33b9a9493aeab84e72647fad384bed43feabd5 (diff)
parent7c08e60acc68f4fbd3ff6af756aeae7c1e7b866c (diff)
Merged in CR/UI (pull request #110)
CR/UI
Diffstat (limited to 'src/lib/product')
-rw-r--r--src/lib/product/components/ProductFilterDesktop.jsx10
-rw-r--r--src/lib/product/components/ProductSearch.jsx162
-rw-r--r--src/lib/product/hooks/useProductSearch.js4
3 files changed, 141 insertions, 35 deletions
diff --git a/src/lib/product/components/ProductFilterDesktop.jsx b/src/lib/product/components/ProductFilterDesktop.jsx
index 6118ed6b..e4a62abb 100644
--- a/src/lib/product/components/ProductFilterDesktop.jsx
+++ b/src/lib/product/components/ProductFilterDesktop.jsx
@@ -18,6 +18,7 @@ import {
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()
@@ -104,14 +105,7 @@ const ProductFilterDesktop = ({ brands, categories, prefixUrl, defaultBrand = nu
router.push(`${prefixUrl}?${params}`)
}
- const formatCurrency = (value) => {
- if (value >= 1000) {
- const thousands = Math.floor(value / 1000) // Menghitung ribuan
- return `Rp${thousands}k`
- } else {
- return `Rp${value}`
- }
- }
+
/*const handleIndexAccordion = async () => {
if (brandValues) {
diff --git a/src/lib/product/components/ProductSearch.jsx b/src/lib/product/components/ProductSearch.jsx
index 9d59b305..3740d264 100644
--- a/src/lib/product/components/ProductSearch.jsx
+++ b/src/lib/product/components/ProductSearch.jsx
@@ -15,23 +15,33 @@ import { useRouter } from 'next/router'
import searchSpellApi from '@/core/api/searchSpellApi'
import Link from '@/core/components/elements/Link/Link'
import whatsappUrl from '@/core/utils/whatsappUrl'
-import { Image } from '@chakra-ui/react'
+import { HStack, Image, Tag, TagCloseButton, TagLabel } from '@chakra-ui/react'
import odooApi from '@/core/api/odooApi'
+import { formatCurrency } from '@/core/utils/formatValue'
-const ProductSearch = ({ query, prefixUrl, defaultBrand = null }) => {
+const ProductSearch = ({ query, prefixUrl, defaultBrand = null, brand = null }) => {
const router = useRouter()
const { page = 1 } = query
const [q, setQ] = useState(query?.q || '*')
const [limit, setLimit] = useState(query?.limit || 30)
const [orderBy, setOrderBy] = useState(router.query?.orderBy || 'popular')
if (defaultBrand) query.brand = defaultBrand.toLowerCase()
- const { productSearch } = useProductSearch({ query: { ...query, q, limit, orderBy } })
+ const { productSearch } = useProductSearch({
+ query: { ...query, q, limit, orderBy },
+ operation: 'AND'
+ })
const [products, setProducts] = useState(null)
const [spellings, setSpellings] = useState(null)
const [bannerPromotionHeader, setBannerPromotionHeader] = useState(null)
const [bannerPromotionFooter, setBannerPromotionFooter] = useState(null)
const popup = useActive()
const numRows = [30, 50, 80, 100]
+ const [brandValues, setBrand] = useState(
+ !router.pathname.includes('brands') ? (query.brand ? query.brand.split(',') : []) : []
+ )
+ const [categoryValues, setCategory] = useState(query?.category?.split(',') || [])
+ const [priceFrom, setPriceFrom] = useState(query?.priceFrom || null)
+ const [priceTo, setPriceTo] = useState(query?.priceTo || null)
const pageCount = Math.ceil(productSearch.data?.response.numFound / limit)
const productStart = productSearch.data?.responseHeader.params.start
@@ -80,15 +90,6 @@ const ProductSearch = ({ query, prefixUrl, defaultBrand = null }) => {
brands.push({ brand, qty })
}
}
- /*const brandsList = productSearch.data?.facetCounts?.facetFields?.manufactureName?.filter(
- (value, index) => {
- if (index % 2 === 0) {
- const brand = value
- const qty = index + 1
- brands.push({ brand, qty })
- }
- }
- )*/
const categories = []
for (let i = 0; i < productSearch.data?.facetCounts?.facetFields?.categoryName.length; i += 2) {
@@ -98,14 +99,6 @@ const ProductSearch = ({ query, prefixUrl, defaultBrand = null }) => {
categories.push({ name, qty })
}
}
-
- /*const categories = productSearch.data?.facetCounts?.facetFields?.categoryName?.filter(
- (value, index) => {
- if (index % 2 === 0) {
- return true
- }
- }
- )*/
const orderOptions = [
{ value: 'price-asc', label: 'Harga Terendah' },
@@ -155,7 +148,7 @@ const ProductSearch = ({ query, prefixUrl, defaultBrand = null }) => {
const SpellingComponent = useMemo(() => {
return (
<>
- Mungkin yang anda cari{' '}
+ {spellings?.length > 0 ? <>Mungkin yang anda cari </> : <>Produk yang cari anda tidak ada</>}
{spellings?.map((spelling, i) => (
<Link href={`/shop/search?q=${spelling}`} key={i} className='inline'>
{spelling}
@@ -166,12 +159,62 @@ const ProductSearch = ({ query, prefixUrl, defaultBrand = null }) => {
)
}, [spellings])
+ const handleDeleteFilter = async (source, value) => {
+ let params = {
+ q: router.query.q,
+ orderBy: orderBy,
+ brand: brandValues.join(','),
+ category: categoryValues.join(','),
+ priceFrom,
+ priceTo
+ }
+
+ let brands = brandValues
+ let catagories = categoryValues
+ switch (source) {
+ case 'brands':
+ brands = brandValues.filter((item) => item !== value)
+ params.brand = brands.join(',')
+ await setBrand(brands)
+ break
+ case 'category':
+ catagories = categoryValues.filter((item) => item !== value)
+ params.category = catagories.join(',')
+ await setCategory(catagories)
+ break
+ case 'price':
+ params.priceFrom = null
+ params.priceTo = null
+ break
+ case 'delete':
+ params = {
+ q: router.query.q,
+ orderBy: orderBy
+ }
+ break
+ }
+
+ handleSubmitFilter(params)
+ }
+ const handleSubmitFilter = (params) => {
+ params = _.pickBy(params, _.identity)
+ params = toQuery(params)
+ router.push(`${prefixUrl}?${params}`)
+ }
+
return (
<>
<MobileView>
{productSearch.isLoading && <ProductSearchSkeleton />}
<div className='p-4 pt-0'>
<h1 className='mb-2 font-semibold text-h-sm'>Produk</h1>
+ <FilterChoicesComponent
+ brandValues={brandValues}
+ categoryValues={categoryValues}
+ priceFrom={priceFrom}
+ priceTo={priceTo}
+ handleDeleteFilter={handleDeleteFilter}
+ />
<div className='mb-2 leading-6 text-gray_r-11'>
{!spellings ? (
@@ -252,6 +295,24 @@ const ProductSearch = ({ query, prefixUrl, defaultBrand = null }) => {
<DesktopView>
<div className='container mx-auto flex mb-3'>
<div className='w-3/12'>
+ {brand && (
+ <div className='p-4'>
+ <div className='text-caption-1 text-gray_r-11 mb-2'>Produk dari brand:</div>
+ {brand?.data?.logo && (
+ <Image
+ src={brand?.data?.logo}
+ alt={brand?.data?.name}
+ className='w-32 p-2 border borde-gray_r-6 rounded'
+ />
+ )}
+ {!brand?.data?.logo && (
+ <div className='bg-danger-500 text-white text-center text-body-1 py-2 px-4 rounded w-fit'>
+ {brand?.data?.name}
+ </div>
+ )}
+ </div>
+ )}
+
<ProductFilterDesktop
brands={brands || []}
categories={categories || []}
@@ -271,8 +332,15 @@ const ProductSearch = ({ query, prefixUrl, defaultBrand = null }) => {
)}
<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'>
+ <FilterChoicesComponent
+ brandValues={brandValues}
+ categoryValues={categoryValues}
+ priceFrom={priceFrom}
+ priceTo={priceTo}
+ handleDeleteFilter={handleDeleteFilter}
+ />
+ <div className='flex justify-between items-center mb-5'>
+ <div className='leading-6 text-gray_r-11'>
{!spellings ? (
<>
Menampilkan&nbsp;
@@ -303,7 +371,7 @@ const ProductSearch = ({ query, prefixUrl, defaultBrand = null }) => {
<div className='ml-3'>
<select
name='urutan'
- className='form-input mt-2'
+ className='form-input'
value={orderBy}
onChange={(e) => handleOrderBy(e)}
>
@@ -318,7 +386,7 @@ const ProductSearch = ({ query, prefixUrl, defaultBrand = null }) => {
<div className='ml-3'>
<select
name='limit'
- className='form-input mt-2'
+ className='form-input'
value={router.query?.limit || ''}
onChange={(e) => handleLimit(e)}
>
@@ -388,3 +456,47 @@ const ProductSearch = ({ query, prefixUrl, defaultBrand = null }) => {
}
export default ProductSearch
+
+const FilterChoicesComponent = ({
+ brandValues,
+ categoryValues,
+ priceFrom,
+ priceTo,
+ handleDeleteFilter
+}) => (
+ <div className='flex items-center'>
+ <HStack spacing={2} className='flex-wrap'>
+ {brandValues.map((value, index) => (
+ <Tag size='lg' key={index} borderRadius='lg' variant='outline' colorScheme='gray'>
+ <TagLabel>{value}</TagLabel>
+ <TagCloseButton onClick={() => handleDeleteFilter('brands', value)} />
+ </Tag>
+ ))}
+
+ {categoryValues.map((value, index) => (
+ <Tag size='lg' key={index} borderRadius='lg' variant='outline' colorScheme='gray'>
+ <TagLabel>{value}</TagLabel>
+ <TagCloseButton onClick={() => handleDeleteFilter('category', value)} />
+ </Tag>
+ ))}
+ {priceFrom && priceTo && (
+ <Tag size='lg' borderRadius='lg' variant='outline' colorScheme='gray'>
+ <TagLabel>{formatCurrency(priceFrom) + '-' + formatCurrency(priceTo)}</TagLabel>
+ <TagCloseButton onClick={() => handleDeleteFilter('price', priceFrom)} />
+ </Tag>
+ )}
+ {brandValues.length > 0 || categoryValues.length > 0 || priceFrom || priceTo ? (
+ <span>
+ <button
+ className='btn-transparent py-2 px-5 h-[40px] text-red-700'
+ onClick={() => handleDeleteFilter('delete')}
+ >
+ Hapus Semua
+ </button>
+ </span>
+ ) : (
+ ''
+ )}
+ </HStack>
+ </div>
+)
diff --git a/src/lib/product/hooks/useProductSearch.js b/src/lib/product/hooks/useProductSearch.js
index 4c9272f1..f3b7530a 100644
--- a/src/lib/product/hooks/useProductSearch.js
+++ b/src/lib/product/hooks/useProductSearch.js
@@ -2,9 +2,9 @@ import { useQuery } from 'react-query'
import productSearchApi from '../api/productSearchApi'
import _ from 'lodash-contrib'
-const useProductSearch = ({ query }) => {
+const useProductSearch = ({ query, operation }) => {
const queryString = _.toQuery(query)
- const fetchProductSearch = async () => await productSearchApi({ query: queryString })
+ const fetchProductSearch = async () => await productSearchApi({ query: queryString , operation : operation})
const productSearch = useQuery(`productSearch-${queryString}`, fetchProductSearch)
return {