import NextImage from 'next/image'; import { useRouter } from 'next/router'; import { useEffect, useMemo, useState } from 'react'; import { HStack, Image, Tag, TagCloseButton, TagLabel } from '@chakra-ui/react'; import axios from 'axios'; import _ from 'lodash'; import { toQuery } from 'lodash-contrib'; import odooApi from '@/core/api/odooApi'; import searchSpellApi from '@/core/api/searchSpellApi'; import Link from '@/core/components/elements/Link/Link'; import Pagination from '@/core/components/elements/Pagination/Pagination'; import DesktopView from '@/core/components/views/DesktopView'; import MobileView from '@/core/components/views/MobileView'; import useActive from '@/core/hooks/useActive'; import { formatCurrency } from '@/core/utils/formatValue'; import { createSlug } from '@/core/utils/slug'; import whatsappUrl from '@/core/utils/whatsappUrl'; import useProductSearch from '../hooks/useProductSearch'; import ProductCard from './ProductCard'; import ProductFilter from './ProductFilter'; import ProductFilterDesktop from './ProductFilterDesktop'; import ProductSearchSkeleton from './Skeleton/ProductSearchSkeleton'; import SideBanner from '~/modules/side-banner'; import FooterBanner from '~/modules/footer-banner'; import CategorySection from './CategorySection'; import LobSectionCategory from './LobSectionCategory'; import { getIdFromSlug } from '@/core/utils/slug' import { data } from 'autoprefixer'; const ProductSearch = ({ query, prefixUrl, defaultBrand = null, brand = null, }) => { const router = useRouter(); const { page = 1 } = query; const [q, setQ] = useState(query?.q || '*'); const [search, setSearch] = useState(query?.q || '*'); const [limit, setLimit] = useState(router.query?.limit || 30); const [orderBy, setOrderBy] = useState(router.query?.orderBy || 'popular'); const [finalQuery, setFinalQuery] = useState({}); const [queryFinal, setQueryFinal] = useState({}); const [dataCategoriesProduct, setDataCategoriesProduct] = useState([]) const [dataCategoriesLob, setDataCategoriesLob] = useState([]) const categoryId = getIdFromSlug(prefixUrl) const [data, setData] = useState([]) const [dataLob, setDataLob] = useState([]); if (defaultBrand) query.brand = defaultBrand.toLowerCase(); const dataIdCategories = [] useEffect(() => { if(prefixUrl.includes('category')){ const loadProduct = async () => { const getCategoriesId = await odooApi('GET', `/api/v1/category/numFound?parent_id=${categoryId}`); if (getCategoriesId) { setDataCategoriesProduct(getCategoriesId); } }; loadProduct(); }else if(prefixUrl.includes('lob')){ const loadProduct = async () => { const lobData = await odooApi('GET', `/api/v1/lob_homepage/${categoryId}/category_id`); if (lobData) { setDataLob(lobData); } }; loadProduct(); } }, [categoryId]); const collectIds = (category) => { const ids = []; function recurse(cat) { if (cat && cat.id) { ids.push(cat.id); } if (Array.isArray(cat.children)) { cat.children.forEach(recurse); } } recurse(category); return ids; }; useEffect(() => { if(prefixUrl.includes('category')){ const ids = collectIds(dataCategoriesProduct); const newQuery = { fq: `category_id_ids:(${ids.join(' OR ')})`, page : router.query.page? router.query.page : 1, brand : router.query.brand? router.query.brand : '', category : router.query.category? router.query.category : '', priceFrom : router.query.priceFrom? router.query.priceFrom : '', priceTo : router.query.priceTo? router.query.priceTo : '', limit : router.query.limit? router.query.limit : '', orderBy : router.query.orderBy? router.query.orderBy : '' }; setFinalQuery(newQuery); } else if (prefixUrl.includes('lob')){ const fetchCategoryData = async () => { if (dataLob[0]?.categoryIds) { for (const cate of dataLob[0].categoryIds) { dataIdCategories.push(cate.childId) } const mergedArray = dataIdCategories.flat(); const newQuery = { fq: `category_id_ids:(${mergedArray.join(' OR ')})`, category : router.query.category? router.query.category : '', page : router.query.page? router.query.page : 1, brand : router.query.brand? router.query.brand : '', priceFrom : router.query.priceFrom? router.query.priceFrom : '', priceTo : router.query.priceTo? router.query.priceTo : '', limit : router.query.limit? router.query.limit : '', orderBy : router.query.orderBy? router.query.orderBy : '' }; setFinalQuery(newQuery); } }; fetchCategoryData(); } }, [dataCategoriesProduct, dataLob]); useEffect(() => { if (prefixUrl.includes('category') || prefixUrl.includes('lob')) { setQueryFinal({ ...finalQuery, q, limit, orderBy }); } else { setQueryFinal({ ...query, q, limit, orderBy }); } }, [prefixUrl,dataCategoriesProduct, query, finalQuery]); const { productSearch } = useProductSearch({ query: queryFinal, operation: 'AND', }); const [products, setProducts] = useState(null); const [spellings, setSpellings] = useState(null); const [bannerPromotionHeader, setBannerPromotionHeader] = useState(null); const [bannerPromotionFooter, setBannerPromotionFooter] = useState(null); const [isBrand, setIsBrand] = useState(null); const popup = useActive(); const numRows = [30, 50, 80, 100]; const [brandValues, setBrand] = useState( !router.pathname.includes('brands') ? router.query.brand ? router.query.brand.split(',') : [] : [] ); const [categoryValues, setCategory] = useState( router.query?.category?.split(',') || router.query?.category?.split(',') ); const [priceFrom, setPriceFrom] = useState(router.query?.priceFrom || null); const [priceTo, setPriceTo] = useState(router.query?.priceTo || null); const pageCount = Math.ceil(productSearch.data?.response.numFound / limit); const productStart = productSearch.data?.responseHeader.params.start; const productRows = limit; const productFound = productSearch.data?.response.numFound; const [dataCategories, setDataCategories] = useState([]) useEffect(() => { if (productFound == 0 && query.q && !spellings) { searchSpellApi({ query: query.q }).then((response) => { 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); }); curr.suggestion.forEach((s) => { if (!acc.includes(s.word)) acc.push(s.word); }); return acc; }, []); if (dataSpellings.length > 0) { setQ(dataSpellings[0]); } setSpellings(dataSpellings); }); } }, [productFound, query, spellings]); let id = [] useEffect(() => { const checkIfBrand = async () => { const brand = await axios( `${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/brands?params=search&q=${search}` ); if (brand.data.length > 0) { setIsBrand(brand?.data[0]); } else { setIsBrand(null); } }; if (router.pathname.includes('search') && q !== '*') { checkIfBrand(); } }, [q]); useEffect(() => { if(prefixUrl.includes('category')){ const loadCategories = async () => { const getCategories = await odooApi('GET', `/api/v1/category/child?parent_id=${categoryId}`) if(getCategories){ setDataCategories(getCategories) } } loadCategories() } }, []) const brands = []; for ( let i = 0; i < productSearch.data?.facetCounts?.facetFields?.manufactureNameS.length; i += 2 ) { const brand = productSearch.data?.facetCounts?.facetFields?.manufactureNameS[i]; const qty = productSearch.data?.facetCounts?.facetFields?.manufactureNameS[i + 1]; if (qty > 0) { brands.push({ brand, qty }); } } const categories = []; for ( let i = 0; i < productSearch.data?.facetCounts?.facetFields?.categoryName.length; i += 2 ) { const name = productSearch.data?.facetCounts?.facetFields?.categoryName[i]; const qty = productSearch.data?.facetCounts?.facetFields?.categoryName[i + 1]; if (qty > 0) { categories.push({ name, qty }); } } const orderOptions = [ { value: 'price-asc', label: 'Harga Terendah' }, { value: 'price-desc', label: 'Harga Tertinggi' }, { value: 'popular', label: 'Populer' }, { value: 'stock', label: 'Ready Stock' }, ]; const handleOrderBy = (e) => { let params = { ...router.query, orderBy: e.target.value, }; params = _.pickBy(params, _.identity); params = toQuery(params); router.push(`${prefixUrl}?${params}`); }; const handleLimit = (e) => { let params = { ...router.query, limit: e.target.value, }; params = _.pickBy(params, _.identity); params = toQuery(params); router.push(`${prefixUrl}?${params}`); }; const getBanner = async () => { if (router.pathname.includes('search')) { const getBannerHeader = await odooApi( 'GET', '/api/v1/banner?type=promotion-header' ); const getBannerFooter = await odooApi( 'GET', '/api/v1/banner?type=promotion-footer' ); var randomIndex = Math.floor(Math.random() * getBannerHeader.length); var randomIndexFooter = Math.floor( Math.random() * getBannerFooter.length ); setBannerPromotionHeader(getBannerHeader[randomIndex]); setBannerPromotionFooter(getBannerFooter[randomIndexFooter]); } }; useEffect(() => { getBanner(); }, []); useEffect(() => { setProducts(productSearch.data?.response?.products); }, [productSearch]); const SpellingComponent = useMemo(() => { return ( <> {spellings?.length > 0 ? ( <>Mungkin yang anda cari ) : ( <>Produk yang cari anda tidak ada )} {spellings?.map((spelling, i) => ( {spelling} {i + 1 < spellings.length ? ', ' : ''} ))} ); }, [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}`); }; const isNotReadyStockPage = router.asPath !== '/shop/search?orderBy=stock'; return ( <> {productSearch.isLoading && }
{isNotReadyStockPage && isBrand && isBrand.logo && (

Brand Pencarian {q}

)}

Produk

{!spellings ? ( <> Menampilkan  {pageCount > 1 ? ( <> {productStart + 1}- {parseInt(productStart) + parseInt(productRows) > productFound ? productFound : parseInt(productStart) + parseInt(productRows)}  dari  ) : ( '' )} {productFound}  produk{' '} {query.q && ( <> untuk pencarian{' '} {query.q} )} ) : ( SpellingComponent )}
{productFound > 0 && (
)}
{products && products.map((product) => ( ))}
{brand && (
Produk dari brand:
{brand?.data?.logo && ( {brand?.data?.name} )} {!brand?.data?.logo && (
{brand?.data?.name}
)}
)}
{bannerPromotionHeader && bannerPromotionHeader?.image && (
)} {isNotReadyStockPage && isBrand && isBrand.logo && (

Brand Pencarian {q}

)}

Hasil Pencarian

{!spellings ? ( <> Menampilkan  {pageCount > 1 ? ( <> {productStart + 1}- {parseInt(productStart) + parseInt(productRows) > productFound ? productFound : parseInt(productStart) + parseInt(productRows)}  dari  ) : ( '' )} {productFound}  produk{' '} {query.q && ( <> untuk pencarian{' '} {query.q} )} ) : ( SpellingComponent )}
{productSearch.isLoading && }
{products && products.map((product) => ( ))}
Barang yang anda cari tidak ada?{' '} Hubungi Kami
{bannerPromotionFooter && bannerPromotionFooter?.image && (
)}
); }; export default ProductSearch; const FilterChoicesComponent = ({ brandValues, categoryValues, priceFrom, priceTo, handleDeleteFilter, }) => (
{brandValues?.map((value, index) => ( {value} handleDeleteFilter('brands', value)} /> ))} {categoryValues?.map((value, index) => ( {value} handleDeleteFilter('category', value)} /> ))} {priceFrom && priceTo && ( {formatCurrency(priceFrom) + '-' + formatCurrency(priceTo)} handleDeleteFilter('price', priceFrom)} /> )} {brandValues?.length > 0 || categoryValues?.length > 0 || priceFrom || priceTo ? ( ) : ( '' )}
);