import NextImage from 'next/image';
import { useRouter } from 'next/router';
import { useEffect, useMemo, useState, useRef } 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 {
FunnelIcon,
AdjustmentsHorizontalIcon,
} from '@heroicons/react/24/outline';
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);
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([]);
const appliedDefaultBrandOrder = useRef(false);
if (defaultBrand) query.brand = defaultBrand.toLowerCase();
useEffect(() => {
if (!router.isReady) return;
const onBrandsPage = router.pathname.includes('brands');
const onSearchPage = prefixUrl === '/shop/search';
const hasOrder =
typeof router.query?.orderBy === 'string' && router.query.orderBy !== '';
if (
(onBrandsPage || onSearchPage) &&
!hasOrder &&
!appliedDefaultBrandOrder.current
) {
let params = {
...router.query,
orderBy: 'popular',
};
params = _.pickBy(params, _.identity);
const qs = toQuery(params);
// ganti URL tanpa nambah history & tanpa full reload
router.replace(`${prefixUrl}?${qs}`, undefined, { shallow: true });
// sinkronkan state lokal
setOrderBy('popular');
appliedDefaultBrandOrder.current = true;
}
}, [router.isReady, router.pathname, router.query?.orderBy, prefixUrl]);
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]);
useEffect(() => {
const checkIfPenawaran = async () => {
if (router.asPath.includes('penawaran')) {
query = {
...query,
fq: `flashsale_id_i:${router.query.penawaran} AND 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) {
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') ||
router.asPath.includes('penawaran')
) {
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: '', label: 'Pilih Filter' },
{ 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 = {
penawaran: router.query.penawaran,
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 = {
penawaran: router.query.penawaran,
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 (
<>
Brand Pencarian {q}
Produk
Brand Pencarian {q}
Hasil Pencarian