summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorMqdd <ahmadmiqdad27@gmail.com>2026-02-18 15:05:34 +0700
committerMqdd <ahmadmiqdad27@gmail.com>2026-02-18 15:05:34 +0700
commit9118c586d2c4fdab43c11409db91cf7b51839261 (patch)
treef2c2c9415e613c153a51f8ed2760933f4ebd8bc9 /src/lib
parent8c4d73ff159cb7b5df4f83f1eb76e8a06c7179ce (diff)
parent7ef19bc5b5dc64fc0fb8126cec02943f06a4237a (diff)
Merge branch 'new-release' of https://bitbucket.org/altafixco/next-indoteknik into cr_renca_keyword
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/category/components/Breadcrumb.jsx58
-rw-r--r--src/lib/category/components/styles/breadcrumb.module.css3
-rw-r--r--src/lib/checkout/api/getRatesCourier.js3
-rw-r--r--src/lib/checkout/components/SectionExpedition.jsx2
-rw-r--r--src/lib/checkout/components/SectionQuotationExpedition.jsx3
-rw-r--r--src/lib/product/components/ProductSearch.jsx76
6 files changed, 98 insertions, 47 deletions
diff --git a/src/lib/category/components/Breadcrumb.jsx b/src/lib/category/components/Breadcrumb.jsx
index acd2cbff..fa2846e4 100644
--- a/src/lib/category/components/Breadcrumb.jsx
+++ b/src/lib/category/components/Breadcrumb.jsx
@@ -11,11 +11,14 @@ import React from 'react';
import { useQuery } from 'react-query';
import useDevice from '@/core/hooks/useDevice';
-const Breadcrumb = ({ categoryId, currentLabel }) => {
+const Breadcrumb = ({ categoryId, shortDesc }) => {
const breadcrumbs = useQuery(
['category-breadcrumbs', categoryId],
async () =>
- await odooApi('GET', `/api/v1/category/${categoryId}/category-breadcrumb`)
+ await odooApi(
+ 'GET',
+ `/api/v1/category/${categoryId}/category-breadcrumb`,
+ ),
);
const { isDesktop, isMobile } = useDevice();
@@ -23,7 +26,7 @@ const Breadcrumb = ({ categoryId, currentLabel }) => {
/* =========================
DESKTOP
- ========================== */
+ ========================= */
if (isDesktop) {
return (
<div className='container mx-auto py-4 md:py-6'>
@@ -67,7 +70,7 @@ const Breadcrumb = ({ categoryId, currentLabel }) => {
href={createSlug(
'/shop/category/',
category.name,
- category.id
+ category.id,
)}
className='!text-danger-500'
>
@@ -92,13 +95,28 @@ const Breadcrumb = ({ categoryId, currentLabel }) => {
)}
</ChakraBreadcrumb>
</Skeleton>
+ {shortDesc && (
+ <div
+ className='
+ w-full mt-2
+ text-sm text-neutral-600
+ leading-7
+ text-justify
+ break-words
+ [hyphens:auto]
+ max-w-none
+ '
+ >
+ {shortDesc}
+ </div>
+ )}
</div>
);
}
/* =========================
MOBILE
- ========================== */
+ ========================= */
if (isMobile) {
const n = items.length;
const lastCat = n >= 1 ? items[n - 1] : null;
@@ -148,7 +166,7 @@ const Breadcrumb = ({ categoryId, currentLabel }) => {
</BreadcrumbLink>
</BreadcrumbItem>
- {/* Ellipsis */}
+ {/* Jika ada kategori sebelum secondLast, tampilkan '..' (link ke beforeSecond) */}
{beforeSecond && (
<BreadcrumbItem>
<BreadcrumbLink
@@ -156,10 +174,9 @@ const Breadcrumb = ({ categoryId, currentLabel }) => {
href={createSlug(
'/shop/category/',
beforeSecond.name,
- beforeSecond.id
+ beforeSecond.id,
)}
title={hiddenText}
- aria-label={`Kembali ke ${beforeSecond.name}`}
className='!text-danger-500'
>
..
@@ -167,7 +184,6 @@ const Breadcrumb = ({ categoryId, currentLabel }) => {
</BreadcrumbItem>
)}
- {/* Second last category */}
{secondLast && (
<BreadcrumbItem>
<BreadcrumbLink
@@ -175,7 +191,7 @@ const Breadcrumb = ({ categoryId, currentLabel }) => {
href={createSlug(
'/shop/category/',
secondLast.name,
- secondLast.id
+ secondLast.id,
)}
className='!text-danger-500'
>
@@ -184,13 +200,13 @@ const Breadcrumb = ({ categoryId, currentLabel }) => {
</BreadcrumbItem>
)}
- {/* Current */}
- {finalLabel && (
+ {/* lastCat (current) dengan truncate & lebar dibatasi */}
+ {lastCat && (
<BreadcrumbItem isCurrentPage>
<span
className='inline-block truncate align-bottom'
style={{ maxWidth: '60vw' }}
- title={finalLabel}
+ title={lastCat.name}
>
{finalLabel}
</span>
@@ -198,6 +214,22 @@ const Breadcrumb = ({ categoryId, currentLabel }) => {
)}
</ChakraBreadcrumb>
</Skeleton>
+
+ {shortDesc && (
+ <div
+ className='
+ w-full mt-2
+ text-sm text-neutral-600
+ leading-7
+ text-justify
+ break-words
+ [hyphens:auto]
+ max-w-none
+ '
+ >
+ {shortDesc}
+ </div>
+ )}
</div>
);
}
diff --git a/src/lib/category/components/styles/breadcrumb.module.css b/src/lib/category/components/styles/breadcrumb.module.css
new file mode 100644
index 00000000..dee4e1b4
--- /dev/null
+++ b/src/lib/category/components/styles/breadcrumb.module.css
@@ -0,0 +1,3 @@
+.category-short-desc {
+ flex: 0 0 100%;
+}
diff --git a/src/lib/checkout/api/getRatesCourier.js b/src/lib/checkout/api/getRatesCourier.js
index 30cfe6e1..0108a3b8 100644
--- a/src/lib/checkout/api/getRatesCourier.js
+++ b/src/lib/checkout/api/getRatesCourier.js
@@ -5,8 +5,7 @@ const GetRatesCourierBiteship = async ({ destination, items }) => {
const couriers = process.env.NEXT_PUBLIC_BITESHIP_CODE_COURIERS;
let body = {
...destination,
- couriers:
- 'gojek, grab, deliveree, lalamove, jne, tiki, ninja, lion, rara, sicepat, jnt, pos, idexpress, rpx, wahana, jdl, pos, anteraja, sap, paxel, borzo',
+ couriers: couriers,
items: items,
};
diff --git a/src/lib/checkout/components/SectionExpedition.jsx b/src/lib/checkout/components/SectionExpedition.jsx
index 66182589..16a2c664 100644
--- a/src/lib/checkout/components/SectionExpedition.jsx
+++ b/src/lib/checkout/components/SectionExpedition.jsx
@@ -250,7 +250,7 @@ export default function SectionExpedition({ products }) {
let body = {
...destination,
couriers:
- 'gojek,grab,deliveree,lalamove,jne,tiki,ninja,lion,rara,sicepat,jnt,pos,idexpress,rpx,wahana,jdl,pos,anteraja,sap,paxel,borzo',
+ 'gojek,grab,deliveree,lalamove,jne,ninja,lion,rara,sicepat,jnt,idexpress,rpx,wahana,jdl,pos,anteraja,sap,paxel,borzo',
items: items,
};
try {
diff --git a/src/lib/checkout/components/SectionQuotationExpedition.jsx b/src/lib/checkout/components/SectionQuotationExpedition.jsx
index 817cd21b..718e096c 100644
--- a/src/lib/checkout/components/SectionQuotationExpedition.jsx
+++ b/src/lib/checkout/components/SectionQuotationExpedition.jsx
@@ -155,8 +155,7 @@ export default function SectionExpeditionQuotation({ products }) {
const fetchExpedition = async () => {
const body = {
...destination,
- couriers:
- 'gojek,grab,deliveree,lalamove,jne,tiki,ninja,lion,rara,sicepat,jnt,pos,idexpress,rpx,wahana,jdl,pos,anteraja,sap,paxel,borzo',
+ couriers: 'gojek,grab,deliveree,lalamove,jne,ninja,lion,rara,sicepat,jnt,idexpress,rpx,wahana,jdl,pos,anteraja,sap,paxel,borzo',
items,
};
const response = await axios.get(`/api/biteship-service`, {
diff --git a/src/lib/product/components/ProductSearch.jsx b/src/lib/product/components/ProductSearch.jsx
index 850d00cc..c73c7036 100644
--- a/src/lib/product/components/ProductSearch.jsx
+++ b/src/lib/product/components/ProductSearch.jsx
@@ -6,7 +6,10 @@ 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 {
+ 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';
@@ -57,9 +60,15 @@ const ProductSearch = ({
if (!router.isReady) return;
const onBrandsPage = router.pathname.includes('brands');
- const hasOrder = typeof router.query?.orderBy === 'string' && router.query.orderBy !== '';
-
- if (onBrandsPage && !hasOrder && !appliedDefaultBrandOrder.current) {
+ 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',
@@ -83,7 +92,7 @@ const ProductSearch = ({
const loadProduct = async () => {
const getCategoriesId = await odooApi(
'GET',
- `/api/v1/category/numFound?parent_id=${categoryId}`
+ `/api/v1/category/numFound?parent_id=${categoryId}`,
);
if (getCategoriesId) {
setDataCategoriesProduct(getCategoriesId);
@@ -94,7 +103,7 @@ const ProductSearch = ({
const loadProduct = async () => {
const lobData = await odooApi(
'GET',
- `/api/v1/lob_homepage/${categoryId}/category_id`
+ `/api/v1/lob_homepage/${categoryId}/category_id`,
);
if (lobData) {
@@ -175,7 +184,11 @@ const ProductSearch = ({
}, [dataCategoriesProduct, dataLob]);
useEffect(() => {
- if (prefixUrl.includes('category') || prefixUrl.includes('lob') || router.asPath.includes('penawaran')) {
+ if (
+ prefixUrl.includes('category') ||
+ prefixUrl.includes('lob') ||
+ router.asPath.includes('penawaran')
+ ) {
setQueryFinal({ ...finalQuery, q, limit, orderBy });
} else {
setQueryFinal({ ...query, q, limit, orderBy });
@@ -198,10 +211,10 @@ const ProductSearch = ({
? router.query.brand
? router.query.brand.split(',')
: []
- : []
+ : [],
);
const [categoryValues, setCategory] = useState(
- router.query?.category?.split(',') || router.query?.category?.split(',')
+ router.query?.category?.split(',') || router.query?.category?.split(','),
);
const [priceFrom, setPriceFrom] = useState(router.query?.priceFrom || null);
@@ -217,11 +230,11 @@ const ProductSearch = ({
if (productFound == 0 && query.q && !spellings) {
searchSpellApi({ query: query.q }).then((response) => {
const oddIndexSuggestions = response.data.spellcheck.suggestions.filter(
- (_, index) => index % 2 === 1
+ (_, index) => index % 2 === 1,
);
const oddIndexCollations = response.data.spellcheck.collations.filter(
- (_, index) => index % 2 === 1
+ (_, index) => index % 2 === 1,
);
const dataSpellings = oddIndexSuggestions.reduce((acc, curr) => {
@@ -246,7 +259,7 @@ const ProductSearch = ({
useEffect(() => {
const checkIfBrand = async () => {
const brand = await axios(
- `${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/brands?params=search&q=${search}`
+ `${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/brands?params=search&q=${search}`,
);
if (brand.data.length > 0) {
@@ -265,7 +278,7 @@ const ProductSearch = ({
const loadCategories = async () => {
const getCategories = await odooApi(
'GET',
- `/api/v1/category/child?parent_id=${categoryId}`
+ `/api/v1/category/child?parent_id=${categoryId}`,
);
if (getCategories) {
setDataCategories(getCategories);
@@ -335,15 +348,15 @@ const ProductSearch = ({
if (router.pathname.includes('search')) {
const getBannerHeader = await odooApi(
'GET',
- '/api/v1/banner?type=promotion-header'
+ '/api/v1/banner?type=promotion-header',
);
const getBannerFooter = await odooApi(
'GET',
- '/api/v1/banner?type=promotion-footer'
+ '/api/v1/banner?type=promotion-footer',
);
var randomIndex = Math.floor(Math.random() * getBannerHeader.length);
var randomIndexFooter = Math.floor(
- Math.random() * getBannerFooter.length
+ Math.random() * getBannerFooter.length,
);
setBannerPromotionHeader(getBannerHeader[randomIndex]);
setBannerPromotionFooter(getBannerFooter[randomIndexFooter]);
@@ -430,7 +443,9 @@ const ProductSearch = ({
<div className='p-4 pt-0'>
{isNotReadyStockPage && isBrand && isBrand.logo && (
<div className='mb-3'>
- <h1 className='mb-2 font-semibold text-h-sm'>Brand Pencarian {q}</h1>
+ <h1 className='mb-2 font-semibold text-h-sm'>
+ Brand Pencarian {q}
+ </h1>
<Link
href={createSlug('/shop/brands/', isBrand.name, isBrand.id)}
className='inline'
@@ -462,7 +477,8 @@ const ProductSearch = ({
{pageCount > 1 ? (
<>
{productStart + 1}-
- {parseInt(productStart) + parseInt(productRows) > productFound
+ {parseInt(productStart) + parseInt(productRows) >
+ productFound
? productFound
: parseInt(productStart) + parseInt(productRows)}
&nbsp;dari&nbsp;
@@ -474,7 +490,8 @@ const ProductSearch = ({
&nbsp;produk{' '}
{query.q && (
<>
- untuk pencarian <span className='font-semibold'>{query.q}</span>
+ untuk pencarian{' '}
+ <span className='font-semibold'>{query.q}</span>
</>
)}
</>
@@ -512,7 +529,9 @@ const ProductSearch = ({
</div>
)}
{!!dataLob?.length && <LobSectionCategory categories={dataLob} />}
- {!!dataCategories?.length && <CategorySection categories={dataCategories} />}
+ {!!dataCategories?.length && (
+ <CategorySection categories={dataCategories} />
+ )}
<div className='grid grid-cols-2 gap-3'>
{products &&
products.map((product) => (
@@ -621,7 +640,7 @@ const ProductSearch = ({
<>
{productStart + 1}-
{parseInt(productStart) + parseInt(productRows) >
- productFound
+ productFound
? productFound
: parseInt(productStart) + parseInt(productRows)}
&nbsp;dari&nbsp;
@@ -629,12 +648,11 @@ const ProductSearch = ({
) : (
''
)}
- {productFound}
+ <strong>{productFound}</strong>
&nbsp;produk{' '}
{query.q && (
<>
- untuk pencarian{' '}
- <span className='font-semibold'>{query.q}</span>
+ untuk pencarian <strong>{query.q}</strong>
</>
)}
</>
@@ -697,8 +715,8 @@ const ProductSearch = ({
href={
query?.q
? whatsappUrl('productSearch', {
- name: query.q,
- })
+ name: query.q,
+ })
: whatsappUrl()
}
className='text-danger-500'
@@ -783,9 +801,9 @@ const FilterChoicesComponent = ({
</Tag>
)}
{brandValues?.length > 0 ||
- categoryValues?.length > 0 ||
- priceFrom ||
- priceTo ? (
+ categoryValues?.length > 0 ||
+ priceFrom ||
+ priceTo ? (
<span>
<button
className='btn-transparent py-2 px-5 h-[40px] text-red-700'