From 33ee63af39d27062a9d5f296640c88cf5ff74334 Mon Sep 17 00:00:00 2001
From: Miqdad <ahmadmiqdad27@gmail.com>
Date: Mon, 29 Sep 2025 10:09:22 +0700
Subject: <Miqdad> try fix crawl

---
 .../product-detail/components/ProductDetail.tsx    | 241 +++++++++++++++------
 1 file changed, 180 insertions(+), 61 deletions(-)

(limited to 'src-migrate/modules/product-detail/components/ProductDetail.tsx')

diff --git a/src-migrate/modules/product-detail/components/ProductDetail.tsx b/src-migrate/modules/product-detail/components/ProductDetail.tsx
index 39011620..f32bb38e 100644
--- a/src-migrate/modules/product-detail/components/ProductDetail.tsx
+++ b/src-migrate/modules/product-detail/components/ProductDetail.tsx
@@ -1,18 +1,13 @@
 import style from '../styles/product-detail.module.css';
+
 import Link from 'next/link';
 import { useRouter } from 'next/router';
-import { useEffect, useMemo, useState } from 'react';
-import dynamic from 'next/dynamic';
+import { useEffect, useRef, useState, UIEvent } from 'react';
 
 import { Button } from '@chakra-ui/react';
 import { MessageCircleIcon, Share2Icon } from 'lucide-react';
 import { LazyLoadComponent } from 'react-lazy-load-image-component';
 
-const RWebShare = dynamic(
-  () => import('react-web-share').then(m => m.RWebShare),
-  { ssr: false }
-);
-
 import useDevice from '@/core/hooks/useDevice';
 import { getAuth } from '~/libs/auth';
 import { whatsappUrl } from '~/libs/whatsappUrl';
@@ -26,23 +21,34 @@ import Information from './Information';
 import PriceAction from './PriceAction';
 import SimilarBottom from './SimilarBottom';
 import SimilarSide from './SimilarSide';
+import dynamic from 'next/dynamic';
+
+
 import { gtagProductDetail } from '@/core/utils/googleTag';
 
-type Props = { product: IProductDetail };
+type Props = {
+  product: IProductDetail;
+};
+
+const RWebShare = dynamic(
+  () => import('react-web-share').then(m => m.RWebShare),
+  { ssr: false }
+);
 
-const SELF_HOST = process.env.NEXT_PUBLIC_SELF_HOST || '';
+const SELF_HOST = process.env.NEXT_PUBLIC_SELF_HOST;
 
 const ProductDetail = ({ product }: Props) => {
   const { isDesktop, isMobile } = useDevice();
   const router = useRouter();
-
   const [auth, setAuth] = useState<any>(null);
   useEffect(() => {
-    try {
-      setAuth(getAuth() ?? null);
-    } catch {}
+    try { setAuth(getAuth() ?? null); } catch { }
   }, []);
 
+  const canShare =
+    typeof navigator !== 'undefined' &&
+    typeof (navigator as any).share === 'function';
+
   const {
     setAskAdminUrl,
     askAdminUrl,
@@ -50,51 +56,88 @@ const ProductDetail = ({ product }: Props) => {
     setIsApproval,
     isApproval,
     setSelectedVariant,
+    setSla,
   } = useProductDetail();
 
   useEffect(() => {
-    try {
-      gtagProductDetail(product);
-    } catch {}
+    gtagProductDetail(product);
   }, [product]);
 
-  const currentPath = router?.asPath || '/';
   useEffect(() => {
     const createdAskUrl = whatsappUrl({
       template: 'product',
       payload: {
-        manufacture: product.manufacture?.name ?? '',
-        productName: product.name ?? '',
-        url: SELF_HOST + currentPath,
+        manufacture: product.manufacture.name,
+        productName: product.name,
+        url: process.env.NEXT_PUBLIC_SELF_HOST + router.asPath,
       },
-      fallbackUrl: currentPath,
+      fallbackUrl: router.asPath,
     });
+
     setAskAdminUrl(createdAskUrl);
-  }, [currentPath, product.manufacture?.name, product.name, setAskAdminUrl]);
+  }, [router.asPath, product.manufacture.name, product.name, setAskAdminUrl]);
 
   useEffect(() => {
-    if (auth && typeof auth === 'object') {
-      setIsApproval(!!auth?.feature?.soApproval);
+    if (typeof auth === 'object') {
+      setIsApproval(auth?.feature?.soApproval);
     }
     const selectedVariant =
-      product?.variants?.find(v => v.is_in_bu) || product?.variants?.[0] || null;
+      product?.variants?.find((variant) => variant.is_in_bu) ||
+      product?.variants?.[0];
     setSelectedVariant(selectedVariant);
-  }, [auth, product?.variants, setIsApproval, setSelectedVariant]);
+  }, []);
+
 
-  const allImages = useMemo(() => {
+  const allImages = (() => {
     const arr: string[] = [];
-    if (Array.isArray(product?.image_carousel)) arr.push(...product.image_carousel);
-    if (product?.image) arr.unshift(product.image);
+    if (product?.image) arr.push(product.image);
+    if (
+      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)) {
+          arr.push(img);
+          set.add(img);
+        }
+      }
+    }
     return arr;
-  }, [product?.image, product?.image_carousel]);
+  })();
 
   const [mainImage, setMainImage] = useState(allImages[0] || '');
+
   useEffect(() => {
-    if (!allImages.includes(mainImage)) setMainImage(allImages[0] || '');
-  }, [allImages, mainImage]);
 
-  const canShare =
-    typeof navigator !== 'undefined' && typeof (navigator as any).share === 'function';
+    if (!allImages.includes(mainImage)) {
+      setMainImage(allImages[0] || '');
+    }
+  }, [allImages]);
+
+
+  const sliderRef = useRef<HTMLDivElement | null>(null);
+  const [currentIdx, setCurrentIdx] = useState(0);
+
+  const handleMobileScroll = (e: UIEvent<HTMLDivElement>) => {
+    const el = e.currentTarget;
+    if (!el) return;
+    const idx = Math.round(el.scrollLeft / el.clientWidth);
+    if (idx !== currentIdx) {
+      setCurrentIdx(idx);
+      setMainImage(allImages[idx] || '');
+    }
+  };
+
+  const scrollToIndex = (i: number) => {
+    const el = sliderRef.current;
+    if (!el) return;
+    el.scrollTo({ left: i * el.clientWidth, behavior: 'smooth' });
+    setCurrentIdx(i);
+    setMainImage(allImages[i] || '');
+  };
+
 
   return (
     <>
@@ -105,38 +148,105 @@ const ProductDetail = ({ product }: Props) => {
 
         <div className='md:w-9/12 md:flex md:flex-col md:pr-4 md:pt-6'>
           <div className='md:flex md:flex-wrap'>
+            {/* ===== Kolom kiri: gambar ===== */}
             <div className='md:w-4/12'>
-              <ProductImage product={{ ...product, image: mainImage }} />
-
-              {allImages.length > 0 && (
-                <div className='mt-4 overflow-x-auto'>
-                  <div className='flex space-x-3 pb-3'>
-                    {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'
-                        }`}
-                        onClick={() => setMainImage(img)}
-                      >
+              {/* === MOBILE: Slider swipeable, tanpa thumbnail carousel === */}
+              {isMobile ? (
+                <div className='relative'>
+                  <div
+                    ref={sliderRef}
+                    onScroll={handleMobileScroll}
+                    className='flex overflow-x-auto snap-x snap-mandatory scroll-smooth no-scrollbar'
+                    style={{
+                      scrollBehavior: 'smooth',
+                      msOverflowStyle: 'none',
+                      scrollbarWidth: 'none',
+                    }}
+                  >
+                    {allImages.length > 0 ? (
+                      allImages.map((img, i) => (
+
+                        <div
+                          key={i}
+                          className='w-full flex-shrink-0 snap-center flex justify-center items-center'
+                        >
+                          {/* gambar diperkecil */}
+                          <img
+                            src={img}
+                            alt={`Gambar ${i + 1}`}
+                            className='w-[85%] aspect-square object-contain'
+                            onError={(e) => {
+                              (e.target as HTMLImageElement).src =
+                                '/images/noimage.jpeg';
+                            }}
+                          />
+                        </div>
+                      ))
+                    ) : (
+                      <div className='w-full flex-shrink-0 snap-center flex justify-center items-center'>
                         <img
-                          src={img}
-                          alt={`Thumbnail ${index + 1}`}
-                          className='w-full h-full object-cover rounded-sm'
-                          loading='lazy'
-                          onError={e => {
-                            (e.target as HTMLImageElement).src = '/images/noimage.jpeg';
-                          }}
+                          src={mainImage || '/images/noimage.jpeg'}
+                          alt='Gambar produk'
+                          className='w-[85%] aspect-square object-contain'
                         />
                       </div>
-                    ))}
+                    )}
                   </div>
+
+                  {/* Dots indicator */}
+                  {allImages.length > 1 && (
+                    <div className='absolute bottom-2 left-0 right-0 flex justify-center gap-2'>
+                      {allImages.map((_, i) => (
+                        <button
+                          key={i}
+                          aria-label={`Ke slide ${i + 1}`}
+                          className={`w-2 h-2 rounded-full ${currentIdx === i ? 'bg-gray-800' : 'bg-gray-300'
+                            }`}
+                          onClick={() => scrollToIndex(i)}
+                        />
+                      ))}
+                    </div>
+                  )}
                 </div>
+              ) : (
+                <>
+                  {/* === DESKTOP: Tetap seperti sebelumnya === */}
+                  <ProductImage product={{ ...product, image: mainImage }} />
+
+                  {/* Carousel horizontal (thumbnail) – hanya desktop */}
+                  {allImages.length > 0 && (
+                    <div className='mt-4 overflow-x-auto'>
+                      <div className='flex space-x-3 pb-3'>
+                        {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'
+                              }`}
+                            onClick={() => setMainImage(img)}
+                          >
+                            <img
+                              src={img}
+                              alt={`Thumbnail ${index + 1}`}
+                              className='w-full h-full object-cover rounded-sm'
+                              loading='lazy'
+                              onError={(e) => {
+                                (e.target as HTMLImageElement).src =
+                                  '/images/noimage.jpeg';
+                              }}
+                            />
+                          </div>
+                        ))}
+                      </div>
+                    </div>
+                  )}
+                </>
               )}
             </div>
+            {/* <<=== 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>
@@ -155,7 +265,10 @@ const ProductDetail = ({ product }: Props) => {
 
             <div className='h-4 md:h-10' />
             {!!activeVariantId && !isApproval && (
-              <ProductPromoSection product={product} productId={activeVariantId} />
+              <ProductPromoSection
+                product={product}
+                productId={activeVariantId}
+              />
             )}
 
             <div className='h-0 md:h-6' />
@@ -168,7 +281,7 @@ 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,
                   }}
@@ -184,7 +297,7 @@ const ProductDetail = ({ product }: Props) => {
             <div className='flex gap-x-5 items-center justify-center'>
               <Button
                 as={Link}
-                href={/* askAdminUrl sudah di-set di effect */ askAdminUrl}
+                href={askAdminUrl}
                 variant='link'
                 target='_blank'
                 colorScheme='gray'
@@ -204,7 +317,7 @@ const ProductDetail = ({ product }: Props) => {
                   data={{
                     text: 'Check out this product',
                     title: `${product.name} - Indoteknik.com`,
-                    url: SELF_HOST + currentPath,
+                    url: (process.env.NEXT_PUBLIC_SELF_HOST || '') + (router?.asPath || '/'),
                   }}
                 >
                   <Button variant='link' colorScheme='gray' leftIcon={<Share2Icon size={18} />}>
@@ -216,14 +329,18 @@ const ProductDetail = ({ product }: Props) => {
 
             <div className='h-6' />
             <div className={style['heading']}>Produk Serupa</div>
+
             <div className='h-4' />
+
             <SimilarSide product={product} />
           </div>
         )}
 
         <div className='md:w-full pt-4 md:py-10 px-4 md:px-0'>
           <div className={style['heading']}>Kamu Mungkin Juga Suka</div>
+
           <div className='h-6' />
+
           <LazyLoadComponent>
             <SimilarBottom product={product} />
           </LazyLoadComponent>
@@ -233,6 +350,8 @@ const ProductDetail = ({ product }: Props) => {
       </div>
     </>
   );
+
+
 };
 
 export default ProductDetail;
-- 
cgit v1.2.3

