summaryrefslogtreecommitdiff
path: root/src-migrate/modules
diff options
context:
space:
mode:
Diffstat (limited to 'src-migrate/modules')
-rw-r--r--src-migrate/modules/product-detail/components/AddToCart.tsx9
-rw-r--r--src-migrate/modules/product-detail/components/AddToQuotation.tsx20
-rw-r--r--src-migrate/modules/product-detail/components/PriceAction.tsx34
-rw-r--r--src-migrate/modules/product-detail/components/ProductDetail.tsx126
4 files changed, 146 insertions, 43 deletions
diff --git a/src-migrate/modules/product-detail/components/AddToCart.tsx b/src-migrate/modules/product-detail/components/AddToCart.tsx
index 147fd6d2..0dc39c1c 100644
--- a/src-migrate/modules/product-detail/components/AddToCart.tsx
+++ b/src-migrate/modules/product-detail/components/AddToCart.tsx
@@ -66,6 +66,8 @@ const AddToCart = ({
weight: '',
isFlashSale: false,
});
+ const hasPrice =
+ !!product?.lowest_price && Number(product.lowest_price.price) > 0;
useEffect(() => {
const fetchData = async () => {
@@ -183,6 +185,7 @@ const AddToCart = ({
colorScheme={btnConfig[source].colorScheme}
variant={btnConfig[source].variant}
className='w-full'
+ isDisabled={!hasPrice || status === 'loading'}
>
{btnConfig[source].text}
</Button>
@@ -194,6 +197,7 @@ const AddToCart = ({
colorScheme={btnConfig[source].colorScheme}
variant={btnConfig[source].variant}
className='w-full'
+ isDisabled={!hasPrice || status === 'loading'}
>
{btnConfig[source].text}
</Button>
@@ -208,7 +212,10 @@ const AddToCart = ({
{/* ===== MOBILE LAYOUT: konten scroll + footer fixed di dalam popup ===== */}
<div className='md:hidden flex flex-col max-h-[75vh]'>
{/* area scroll */}
- <div className='flex-1 overflow-y-auto' style={{ scrollbarWidth: 'none' }}>
+ <div
+ className='flex-1 overflow-y-auto'
+ style={{ scrollbarWidth: 'none' }}
+ >
{/* HEADER ITEM */}
<div className='flex mt-4'>
<div className='w-[25%]'>
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 ffc9ba40..d73ab5f6 100644
--- a/src-migrate/modules/product-detail/components/PriceAction.tsx
+++ b/src-migrate/modules/product-detail/components/PriceAction.tsx
@@ -37,6 +37,7 @@ const PriceAction = ({ product }: Props) => {
} = useProductDetail();
const [qtyPickUp, setQtyPickUp] = useState(0);
const { isDesktop, isMobile } = useDevice();
+
useEffect(() => {
setActive(selectedVariant);
if (product.variants.length > 2 && product.variants[0].price.price === 0) {
@@ -77,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
@@ -144,7 +146,7 @@ const PriceAction = ({ product }: Props) => {
</>
)}
- {!!activePrice && activePrice.price === 0 && (
+ {/* {!!activePrice && activePrice.price === 0 && (
<span>
Hubungi kami untuk dapatkan harga terbaik,{' '}
<Link
@@ -155,7 +157,7 @@ const PriceAction = ({ product }: Props) => {
klik disini
</Link>
</span>
- )}
+ )} */}
<DesktopView>
<div className='h-4' />
@@ -164,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>
@@ -195,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>
@@ -218,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 ===== */}
@@ -255,11 +264,11 @@ const PriceAction = ({ product }: Props) => {
)}
</div>
- {qtyPickUp > 0 && (
+ {/* {qtyPickUp > 0 && (
<div className='text-[12px] mt-1 text-red-500 italic'>
* {qtyPickUp} barang bisa di pickup
</div>
- )}
+ )} */}
</div>
{/* Kanan: hanya qty, rata kanan */}
@@ -274,6 +283,7 @@ const PriceAction = ({ product }: Props) => {
)
}
aria-label='Kurangi'
+ disabled={!hasPrice}
>
<span className='text-2xl leading-none'>–</span>
</button>
@@ -288,6 +298,7 @@ const PriceAction = ({ product }: Props) => {
[appearance:textfield]
[&::-webkit-outer-spin-button]:appearance-none
[&::-webkit-inner-spin-button]:appearance-none'
+ disabled={!hasPrice}
/>
<button
@@ -297,6 +308,7 @@ const PriceAction = ({ product }: Props) => {
setQuantityInput(String(Number(quantityInput) + 1))
}
aria-label='Tambah'
+ disabled={!hasPrice}
>
<span className='text-2xl leading-none'>+</span>
</button>
diff --git a/src-migrate/modules/product-detail/components/ProductDetail.tsx b/src-migrate/modules/product-detail/components/ProductDetail.tsx
index f32bb38e..e4ba2b2f 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,9 +141,32 @@ const ProductDetail = ({ product }: Props) => {
setMainImage(allImages[i] || '');
};
-
return (
<>
+ <div className='relative'>
+ {isDesktop && !hasPrice && (
+ <div className='absolute inset-0 z-[20] flex items-center justify-center pointer-events-none select-none'>
+ <img
+ src='/images/produk_tidak_tersedia.svg'
+ alt='Produk tidak tersedia'
+ className='w-[47%] opacity-50 -translate-x-[3%] -translate-y-[-70%]'
+ />
+ </div>
+ )}
+ </div>
+
+ <div className='relative'>
+ {isMobile && !hasPrice && (
+ <div className='absolute inset-0 z-[50] flex items-center justify-center pointer-events-none select-none'>
+ <img
+ src='/images/produk_tidak_tersedia.svg'
+ alt='Produk tidak tersedia'
+ className='w-[100%] opacity-[1000%] -translate-x-[0%] -translate-y-[-197%]'
+ />
+ </div>
+ )}
+ </div>
+
<div className='md:flex md:flex-wrap'>
<div className='w-full mb-4 md:mb-0 px-4 md:px-0'>
<Breadcrumb id={product.id} name={product.name} />
@@ -165,7 +191,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 +225,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 +246,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
@@ -247,13 +274,45 @@ const ProductDetail = ({ product }: Props) => {
{/* <<=== TUTUP kolom kiri */}
{/* ===== Kolom kanan: info ===== */}
- <div className='md:w-8/12 px-4 md:pl-6'>
- <div className='h-6 md:h-0' />
- <h1 className={style['title']}>{product.name}</h1>
- <div className='h-3 md:h-0' />
- <Information product={product} />
- <div className='h-6' />
- </div>
+ {isDesktop && (
+ <div className='md:w-8/12 px-4 md:pl-6'>
+ {!hasPrice && (
+ <div className='bg-red-50 p-2 py-1.5 rounded-lg border border-red-500 flex gap-1 items-center '>
+ <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' />
+ <Information product={product} />
+ <div className='h-6' />
+ </div>
+ )}
+ {isMobile && (
+ <div className='md:w-8/12 px-4 md:pl-6 relative'>
+ {!hasPrice && (
+ <div className='bg-red-50 p-2 py-1.5 border-b border-red-500 flex gap-1 items-center w-screen relative left-1/2 right-1/2 -translate-x-1/2'>
+ <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>
+ )}
+ <h1 className={style['title']}>{product.name}</h1>
+ <div className='h-3 md:h-0' />
+ <Information product={product} />
+ <div className='h-6' />
+ </div>
+ )}
</div>
<div className='h-full'>
@@ -281,7 +340,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 +362,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 +380,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 +420,6 @@ const ProductDetail = ({ product }: Props) => {
</div>
</>
);
-
-
};
export default ProductDetail;