summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src-migrate/modules/product-detail/components/AddToQuotation.tsx20
-rw-r--r--src-migrate/modules/product-detail/components/PriceAction.tsx26
-rw-r--r--src-migrate/modules/product-detail/components/ProductDetail.tsx67
3 files changed, 80 insertions, 33 deletions
diff --git a/src-migrate/modules/product-detail/components/AddToQuotation.tsx b/src-migrate/modules/product-detail/components/AddToQuotation.tsx
index ebfcef32..3e811330 100644
--- a/src-migrate/modules/product-detail/components/AddToQuotation.tsx
+++ b/src-migrate/modules/product-detail/components/AddToQuotation.tsx
@@ -60,6 +60,8 @@ const AddToQuotation = ({
`fq=-manufacture_id_i:${product.manufacture?.id || 0}`,
].join('&');
const [addCartAlert, setAddCartAlert] = useState(false);
+ const hasPrice =
+ !!product?.lowest_price && Number(product.lowest_price.price) > 0;
const handleButton = async () => {
if (typeof auth !== 'object') {
@@ -124,9 +126,10 @@ const AddToQuotation = ({
color={'red'}
colorScheme='white'
className='w-full border-2 p-2 gap-1 hover:bg-slate-100 flex items-center'
+ isDisabled={!hasPrice}
>
<ImageNext
- src= {isDesktop ? '/images/doc_red.svg' : '/images/doc.svg'}
+ src={isDesktop ? '/images/doc_red.svg' : '/images/doc.svg'}
alt='penawaran instan'
className=''
width={25}
@@ -191,7 +194,20 @@ const AddToQuotation = ({
</>
)}
- {!!product.lowest_price && product.lowest_price.price === 0 && (
+ {(!!product.lowest_price && product.lowest_price.price === 0) ||
+ product.lowest_price.price < 0 ? (
+ <span>
+ Hubungi kami untuk dapatkan harga terbaik,{' '}
+ <Link
+ href={askAdminUrl}
+ target='_blank'
+ className='font-medium underline'
+ color={'red'}
+ >
+ klik disini
+ </Link>
+ </span>
+ ) : (
<span>
Hubungi kami untuk dapatkan harga terbaik,{' '}
<Link
diff --git a/src-migrate/modules/product-detail/components/PriceAction.tsx b/src-migrate/modules/product-detail/components/PriceAction.tsx
index a329d2cc..510dd6a9 100644
--- a/src-migrate/modules/product-detail/components/PriceAction.tsx
+++ b/src-migrate/modules/product-detail/components/PriceAction.tsx
@@ -78,6 +78,7 @@ const PriceAction = ({ product }: Props) => {
const validJsonString = stringVoucher.replace(/'/g, '"');
voucherPastiHemat = JSON.parse(validJsonString);
}
+ const hasPrice = Number(product?.lowest_price?.price) > 0;
return (
<div
@@ -145,7 +146,7 @@ const PriceAction = ({ product }: Props) => {
</>
)}
- {!!activePrice && activePrice.price === 0 && (
+ {/* {!!activePrice && activePrice.price === 0 && (
<span>
Hubungi kami untuk dapatkan harga terbaik,{' '}
<Link
@@ -156,7 +157,7 @@ const PriceAction = ({ product }: Props) => {
klik disini
</Link>
</span>
- )}
+ )} */}
<DesktopView>
<div className='h-4' />
@@ -165,27 +166,32 @@ const PriceAction = ({ product }: Props) => {
<div className='relative flex items-center'>
<button
type='button'
- className='absolute left-0 px-2 py-1 h-full text-gray-500'
+ className='absolute left-0 px-2 py-1 h-full text-gray-500 disabled:opacity-40'
onClick={() =>
setQuantityInput(String(Math.max(1, Number(quantityInput) - 1)))
}
+ disabled={!hasPrice}
>
-
</button>
+
<input
type='number'
id='quantity'
min={1}
value={quantityInput}
onChange={(e) => setQuantityInput(e.target.value)}
- className={style['quantity-input']}
+ className={`${style['quantity-input']} disabled:bg-gray-100 disabled:text-gray-400`}
+ disabled={!hasPrice}
/>
+
<button
type='button'
- className='absolute right-0 px-2 py-1 h-full text-gray-500'
+ className='absolute right-0 px-2 py-1 h-full text-gray-500 disabled:opacity-40'
onClick={() =>
setQuantityInput(String(Number(quantityInput) + 1))
}
+ disabled={!hasPrice}
>
+
</button>
@@ -196,9 +202,11 @@ const PriceAction = ({ product }: Props) => {
<Skeleton
isLoaded={sla}
h='21px'
- className={sla?.qty < 10 ? 'text-red-600 font-medium' : ''}
+ className={
+ !hasPrice || sla?.qty < 10 ? 'text-red-600 font-medium' : ''
+ }
>
- Stock : {sla?.qty}{' '}
+ Stock : {hasPrice ? sla?.qty : 'Habis'}
</Skeleton>
</div>
@@ -219,9 +227,9 @@ const PriceAction = ({ product }: Props) => {
)}
</div>
</div>
- <span className='text-[12px] text-red-500 italic'>
+ {/* <span className='text-[12px] text-red-500 italic'>
* {qtyPickUp} barang bisa di pickup
- </span>
+ </span> */}
</DesktopView>
{/* ===== MOBILE: grid kiri-kanan, kanan hanya qty ===== */}
diff --git a/src-migrate/modules/product-detail/components/ProductDetail.tsx b/src-migrate/modules/product-detail/components/ProductDetail.tsx
index f32bb38e..c8c03300 100644
--- a/src-migrate/modules/product-detail/components/ProductDetail.tsx
+++ b/src-migrate/modules/product-detail/components/ProductDetail.tsx
@@ -5,7 +5,12 @@ import { useRouter } from 'next/router';
import { useEffect, useRef, useState, UIEvent } from 'react';
import { Button } from '@chakra-ui/react';
-import { MessageCircleIcon, Share2Icon } from 'lucide-react';
+import {
+ AlertCircle,
+ AlertTriangle,
+ MessageCircleIcon,
+ Share2Icon,
+} from 'lucide-react';
import { LazyLoadComponent } from 'react-lazy-load-image-component';
import useDevice from '@/core/hooks/useDevice';
@@ -23,7 +28,6 @@ import SimilarBottom from './SimilarBottom';
import SimilarSide from './SimilarSide';
import dynamic from 'next/dynamic';
-
import { gtagProductDetail } from '@/core/utils/googleTag';
type Props = {
@@ -31,7 +35,7 @@ type Props = {
};
const RWebShare = dynamic(
- () => import('react-web-share').then(m => m.RWebShare),
+ () => import('react-web-share').then((m) => m.RWebShare),
{ ssr: false }
);
@@ -42,7 +46,9 @@ const ProductDetail = ({ product }: Props) => {
const router = useRouter();
const [auth, setAuth] = useState<any>(null);
useEffect(() => {
- try { setAuth(getAuth() ?? null); } catch { }
+ try {
+ setAuth(getAuth() ?? null);
+ } catch {}
}, []);
const canShare =
@@ -87,7 +93,6 @@ const ProductDetail = ({ product }: Props) => {
setSelectedVariant(selectedVariant);
}, []);
-
const allImages = (() => {
const arr: string[] = [];
if (product?.image) arr.push(product.image);
@@ -95,7 +100,6 @@ const ProductDetail = ({ product }: Props) => {
Array.isArray(product?.image_carousel) &&
product.image_carousel.length
) {
-
const set = new Set(arr);
for (const img of product.image_carousel) {
if (!set.has(img)) {
@@ -108,15 +112,14 @@ const ProductDetail = ({ product }: Props) => {
})();
const [mainImage, setMainImage] = useState(allImages[0] || '');
+ const hasPrice = Number(product?.lowest_price?.price) > 0;
useEffect(() => {
-
if (!allImages.includes(mainImage)) {
setMainImage(allImages[0] || '');
}
}, [allImages]);
-
const sliderRef = useRef<HTMLDivElement | null>(null);
const [currentIdx, setCurrentIdx] = useState(0);
@@ -138,7 +141,6 @@ const ProductDetail = ({ product }: Props) => {
setMainImage(allImages[i] || '');
};
-
return (
<>
<div className='md:flex md:flex-wrap'>
@@ -165,7 +167,6 @@ const ProductDetail = ({ product }: Props) => {
>
{allImages.length > 0 ? (
allImages.map((img, i) => (
-
<div
key={i}
className='w-full flex-shrink-0 snap-center flex justify-center items-center'
@@ -200,8 +201,9 @@ const ProductDetail = ({ product }: Props) => {
<button
key={i}
aria-label={`Ke slide ${i + 1}`}
- className={`w-2 h-2 rounded-full ${currentIdx === i ? 'bg-gray-800' : 'bg-gray-300'
- }`}
+ className={`w-2 h-2 rounded-full ${
+ currentIdx === i ? 'bg-gray-800' : 'bg-gray-300'
+ }`}
onClick={() => scrollToIndex(i)}
/>
))}
@@ -220,10 +222,11 @@ const ProductDetail = ({ product }: Props) => {
{allImages.map((img, index) => (
<div
key={index}
- className={`flex-shrink-0 w-16 h-16 cursor-pointer border-2 rounded-md transition-colors ${mainImage === img
- ? 'border-red-500 ring-2 ring-red-200'
- : 'border-gray-200 hover:border-gray-300'
- }`}
+ className={`flex-shrink-0 w-16 h-16 cursor-pointer border-2 rounded-md transition-colors ${
+ mainImage === img
+ ? 'border-red-500 ring-2 ring-red-200'
+ : 'border-gray-200 hover:border-gray-300'
+ }`}
onClick={() => setMainImage(img)}
>
<img
@@ -248,6 +251,17 @@ const ProductDetail = ({ product }: Props) => {
{/* ===== Kolom kanan: info ===== */}
<div className='md:w-8/12 px-4 md:pl-6'>
+ {!hasPrice && (
+ <div className='bg-red-50 py-2 rounded-lg border border-red-500 flex gap-2 items-center mb-4'>
+ <AlertTriangle
+ size={18}
+ className='text-red-600 shrink-0 mx-2'
+ />
+ <h1 className='text-red-600 font-normal text-h-sm'>
+ Maaf untuk saat ini Produk yang anda cari tidak tersedia
+ </h1>
+ </div>
+ )}
<div className='h-6 md:h-0' />
<h1 className={style['title']}>{product.name}</h1>
<div className='h-3 md:h-0' />
@@ -281,7 +295,8 @@ const ProductDetail = ({ product }: Props) => {
className={style['description']}
dangerouslySetInnerHTML={{
__html:
- !product.description || product.description == '<p><br></p>'
+ !product.description ||
+ product.description == '<p><br></p>'
? 'Belum ada deskripsi'
: product.description,
}}
@@ -302,13 +317,16 @@ const ProductDetail = ({ product }: Props) => {
target='_blank'
colorScheme='gray'
leftIcon={<MessageCircleIcon size={18} />}
+ isDisabled={!hasPrice}
>
Ask Admin
</Button>
<span>|</span>
- <AddToWishlist productId={product.id} />
+ <div className={hasPrice ? '' : 'opacity-40 pointer-events-none'}>
+ <AddToWishlist productId={product.id} />
+ </div>
<span>|</span>
@@ -317,10 +335,17 @@ const ProductDetail = ({ product }: Props) => {
data={{
text: 'Check out this product',
title: `${product.name} - Indoteknik.com`,
- url: (process.env.NEXT_PUBLIC_SELF_HOST || '') + (router?.asPath || '/'),
+ url:
+ (process.env.NEXT_PUBLIC_SELF_HOST || '') +
+ (router?.asPath || '/'),
}}
>
- <Button variant='link' colorScheme='gray' leftIcon={<Share2Icon size={18} />}>
+ <Button
+ variant='link'
+ colorScheme='gray'
+ leftIcon={<Share2Icon size={18} />}
+ isDisabled={!hasPrice}
+ >
Share
</Button>
</RWebShare>
@@ -350,8 +375,6 @@ const ProductDetail = ({ product }: Props) => {
</div>
</>
);
-
-
};
export default ProductDetail;