summaryrefslogtreecommitdiff
path: root/src/lib/product
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/product')
-rw-r--r--src/lib/product/api/productSearchApi.js31
-rw-r--r--src/lib/product/components/ProductSearch.jsx74
2 files changed, 94 insertions, 11 deletions
diff --git a/src/lib/product/api/productSearchApi.js b/src/lib/product/api/productSearchApi.js
index a84caa3c..1a6ad36a 100644
--- a/src/lib/product/api/productSearchApi.js
+++ b/src/lib/product/api/productSearchApi.js
@@ -2,8 +2,37 @@ import _ from 'lodash-contrib';
import axios from 'axios';
const productSearchApi = async ({ query, operation = 'OR' }) => {
+ // Use POST for large product ID arrays to avoid URL length limits
+ // GET request URL limit is typically 2KB-8KB; switch to POST if query string is large
+ const QUERY_SIZE_THRESHOLD = 2000; // Switch to POST if query > 2KB
+
+ if (query.length > QUERY_SIZE_THRESHOLD) {
+ console.log(
+ `[productSearchApi] Large query (${query.length} chars), using POST`,
+ );
+
+ // Parse query string into object for POST body
+ const params = new URLSearchParams(query);
+ const bodyData = {
+ ...Object.fromEntries(params),
+ operation,
+ };
+
+ const dataProductSearch = await axios.post(
+ `${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/search`,
+ bodyData,
+ {
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ },
+ );
+ return dataProductSearch.data;
+ }
+
+ // Small query, use standard GET request
const dataProductSearch = await axios(
- `${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/search?${query}&operation=${operation}`
+ `${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/search?${query}&operation=${operation}`,
);
return dataProductSearch.data;
};
diff --git a/src/lib/product/components/ProductSearch.jsx b/src/lib/product/components/ProductSearch.jsx
index c73c7036..3e667966 100644
--- a/src/lib/product/components/ProductSearch.jsx
+++ b/src/lib/product/components/ProductSearch.jsx
@@ -44,7 +44,7 @@ const ProductSearch = ({
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 [limit, setLimit] = useState(parseInt(router.query?.limit) || 30);
const [orderBy, setOrderBy] = useState(router.query?.orderBy);
const [finalQuery, setFinalQuery] = useState({});
const [queryFinal, setQueryFinal] = useState({});
@@ -86,6 +86,21 @@ const ProductSearch = ({
}
}, [router.isReady, router.pathname, router.query?.orderBy, prefixUrl]);
+ // 🔹 Sync limit state with router.query
+ useEffect(() => {
+ if (!router.isReady) return;
+ const newLimit = parseInt(router.query?.limit) || 30;
+ setLimit(newLimit);
+ }, [router.query?.limit, router.isReady]);
+
+ // 🔹 Sync orderBy state with router.query
+ useEffect(() => {
+ if (!router.isReady) return;
+ if (router.query?.orderBy) {
+ setOrderBy(router.query.orderBy);
+ }
+ }, [router.query?.orderBy, router.isReady]);
+
const dataIdCategories = [];
useEffect(() => {
if (prefixUrl.includes('category')) {
@@ -180,20 +195,55 @@ const ProductSearch = ({
}
};
fetchCategoryData();
+ } else if (query?.from === 'searchkey' && query?.ids) {
+ const newQuery = {
+ ids: query.ids,
+ from: 'searchkey',
+ page: router.query.page ? router.query.page : 1,
+ 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);
}
- }, [dataCategoriesProduct, dataLob]);
+ }, [dataCategoriesProduct, dataLob, query?.from, query?.ids, router.query]);
useEffect(() => {
if (
prefixUrl.includes('category') ||
prefixUrl.includes('lob') ||
+ query?.from === 'searchkey' ||
router.asPath.includes('penawaran')
) {
- setQueryFinal({ ...finalQuery, q, limit, orderBy });
+ setQueryFinal({
+ ...finalQuery,
+ q,
+ limit,
+ orderBy,
+ page: router.query.page || 1,
+ });
} else {
- setQueryFinal({ ...query, q, limit, orderBy });
+ setQueryFinal({
+ ...query,
+ q,
+ limit,
+ orderBy,
+ page: router.query.page || 1,
+ });
}
- }, [prefixUrl, dataCategoriesProduct, query, finalQuery]);
+ }, [
+ prefixUrl,
+ dataCategoriesProduct,
+ query,
+ finalQuery,
+ router.query,
+ router.query.page,
+ limit,
+ orderBy,
+ q,
+ ]);
const { productSearch } = useProductSearch({
query: queryFinal,
@@ -339,6 +389,7 @@ const ProductSearch = ({
let params = {
...router.query,
limit: e.target.value,
+ page: 1, // Reset to page 1 when limit changes
};
params = _.pickBy(params, _.identity);
params = toQuery(params);
@@ -541,8 +592,10 @@ const ProductSearch = ({
<Pagination
pageCount={pageCount}
- currentPage={parseInt(page)}
- url={`${prefixUrl}?${toQuery(_.omit(query, ['page', 'fq']))}`}
+ currentPage={
+ router.query.page ? parseInt(router.query.page, 10) : 1
+ }
+ url={`${prefixUrl}?${toQuery(_.omit(router.query, ['page', 'ids', 'from']))}`}
className='mt-6 mb-2'
/>
@@ -729,9 +782,10 @@ const ProductSearch = ({
<Pagination
pageCount={pageCount}
- currentPage={parseInt(page)}
- url={`${prefixUrl}?${toQuery(_.omit(query, ['page', 'fq']))}`}
- // url={prefixUrl.includes('category') || prefixUrl.includes('lob')? `${prefixUrl}?${toQuery(_.omit(finalQuery, ['page']))}` : `${prefixUrl}?${toQuery(_.omit(query, ['page']))}`}
+ currentPage={
+ router.query.page ? parseInt(router.query.page, 10) : 1
+ }
+ url={`${prefixUrl}?${toQuery(_.omit(router.query, ['page', 'ids', 'from']))}`}
className='!justify-end'
/>
</div>