import style from '../styles/product-detail.module.css'; import Link from 'next/link'; 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 { LazyLoadComponent } from 'react-lazy-load-image-component'; import useDevice from '@/core/hooks/useDevice'; import { getAuth } from '~/libs/auth'; import { whatsappUrl } from '~/libs/whatsappUrl'; import ProductPromoSection from '~/modules/product-promo/components/Section'; import { IProductDetail } from '~/types/product'; import { useProductDetail } from '../stores/useProductDetail'; import AddToWishlist from './AddToWishlist'; import Breadcrumb from './Breadcrumb'; import ProductImage from './Image'; import Information from './Information'; import PriceAction from './PriceAction'; import SimilarBottom from './SimilarBottom'; import SimilarSide from './SimilarSide'; import dynamic from 'next/dynamic'; import { TicketIcon } from '@heroicons/react/24/solid'; import { gtagProductDetail } from '@/core/utils/googleTag'; import currencyFormat from '@/core/utils/currencyFormat'; 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 ProductDetail = ({ product }: Props) => { const { isDesktop, isMobile } = useDevice(); const router = useRouter(); const [auth, setAuth] = useState(null); useEffect(() => { try { setAuth(getAuth() ?? null); } catch {} }, []); const canShare = typeof navigator !== 'undefined' && typeof (navigator as any).share === 'function'; const { setAskAdminUrl, askAdminUrl, activeVariantId, setIsApproval, isApproval, setSelectedVariant, setSla, selectedVariant, } = useProductDetail(); useEffect(() => { gtagProductDetail(product); }, [product]); useEffect(() => { const createdAskUrl = whatsappUrl({ template: 'product', payload: { manufacture: product.manufacture.name, productName: product.name, url: process.env.NEXT_PUBLIC_SELF_HOST + router.asPath, }, fallbackUrl: router.asPath, }); setAskAdminUrl(createdAskUrl); }, [router.asPath, product.manufacture.name, product.name, setAskAdminUrl]); useEffect(() => { if (typeof auth === 'object') { setIsApproval(auth?.feature?.soApproval); } const selectedVariant = product?.variants?.find((variant) => variant.is_in_bu) || product?.variants?.[0]; setSelectedVariant(selectedVariant); }, []); const allImages = (() => { const arr: string[] = []; 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; })(); const [mainImage, setMainImage] = useState(allImages[0] || ''); const [discount, setDiscount] = useState(0); const [voucherDiscount, setVoucherDiscount] = useState(0); useEffect(() => { if (!allImages.includes(mainImage)) { setMainImage(allImages[0] || ''); } }, [allImages]); const sliderRef = useRef(null); const [currentIdx, setCurrentIdx] = useState(0); const handleMobileScroll = (e: UIEvent) => { 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] || ''); }; useEffect(() => { // ambil voucher dari PRODUCT (bukan variant) const voucherRaw = Array.isArray(product?.new_voucher_pasti_hemat) ? product.new_voucher_pasti_hemat[0] : product?.new_voucher_pasti_hemat; if (!voucherRaw) { setVoucherDiscount(0); return; } // ambil harga dari VARIANT aktif // kalau belum ada selectedVariant, fallback ke product.lowest_price const basePriceObj = selectedVariant?.price || { price: product?.lowest_price?.price ?? 0, priceDiscount: product?.lowest_price?.price_discount ?? 0, }; const { discount_type = '', discount_amount = 0, max_discount = 0, min_purchase = 0, } = voucherRaw; // harga dasar dipakai priceDiscount dulu, kalau kosong pakai price const basePrice = Number(basePriceObj.priceDiscount ?? 0) || Number(basePriceObj.price ?? 0); if (!basePrice) { setVoucherDiscount(0); return; } // cek minimum belanja if (Number(min_purchase) > 0 && basePrice < Number(min_purchase)) { setVoucherDiscount(0); return; } // hitung potongan let cut = 0; if (discount_type === 'percentage') { // contoh: 8.33 (%) const pct = Number(discount_amount) || 0; cut = basePrice * (pct / 100); } else { // fixed amount cut = Number(discount_amount) || 0; } // batas maksimal diskon if (Number(max_discount) > 0 && cut > Number(max_discount)) { cut = Number(max_discount); } // final clamp cut = cut > 0 ? Math.floor(cut) : 0; setVoucherDiscount(cut); }, [product, selectedVariant]); return ( <>
{/* ===== Kolom kiri: gambar ===== */}
{/* === MOBILE: Slider swipeable, tanpa thumbnail carousel === */} {isMobile ? (
{allImages.length > 0 ? ( allImages.map((img, i) => (
{`Gambar { (e.target as HTMLImageElement).src = '/images/noimage.jpeg'; }} />
)) ) : (
Gambar produk
)}
{/* Dots indicator */} {allImages.length > 1 && (
{allImages.map((_, i) => (
)}
) : ( <> {/* === DESKTOP: Tetap seperti sebelumnya === */} {/* Carousel horizontal (thumbnail) – hanya desktop */} {allImages.length > 0 && (
{allImages.map((img, index) => (
setMainImage(img)} > {`Thumbnail { (e.target as HTMLImageElement).src = '/images/noimage.jpeg'; }} />
))}
)} )}
{/* <<=== TUTUP kolom kiri */} {/* ===== Kolom kanan: info ===== */}
{/*
{isMobile && voucherDiscount > 0 && (
{' '} Pakai{' '} {' '} Voucher belanja hemat {currencyFormat(voucherDiscount)} {' '} saat checkout
)} */}

{product.name}

{isMobile && (
)}
{!!activeVariantId && !isApproval && ( )}

Informasi Produk


' ? 'Belum ada deskripsi' : product.description, }} />
{isDesktop && (
| | {canShare && ( )}
Produk Serupa
)}
Kamu Mungkin Juga Suka
); }; export default ProductDetail;