import BottomPopup from '@/core/components/elements/Popup/BottomPopup'; import style from '../styles/price-action.module.css'; import { Button, ButtonProps, Link, useToast } from '@chakra-ui/react'; import product from 'next-seo/lib/jsonld/product'; import { useRouter } from 'next/router'; import { useEffect, useState } from 'react'; import Image from '~/components/ui/image'; import { getAuth } from '~/libs/auth'; import { upsertUserCart } from '~/services/cart'; import LazyLoad from 'react-lazy-load'; import ProductSimilar from '../../../../src/lib/product/components/ProductSimilar'; import { IProductDetail } from '~/types/product'; import ImageNext from 'next/image'; import { useProductCartContext } from '@/contexts/ProductCartContext'; import { createSlug } from '~/libs/slug'; import formatCurrency from '~/libs/formatCurrency'; import { useProductDetail } from '../stores/useProductDetail'; import { gtagAddToCart } from '@/core/utils/googleTag'; import axios from 'axios'; import useDevice from '@/core/hooks/useDevice'; import MobileView from '@/core/components/views/MobileView'; import DesktopView from '@/core/components/views/DesktopView'; import ProductPromoSection from '~/modules/product-promo/components/Section'; type Props = { variantId: number | null; quantity?: number; source?: 'buy' | 'add_to_cart'; products: IProductDetail; buttonProps?: ButtonProps; children?: (props: { onClick: () => Promise; isLoading: boolean }) => React.ReactNode; }; type Status = 'idle' | 'loading' | 'success'; const AddToCart = ({ variantId, quantity = 1, source = 'add_to_cart', products, buttonProps, children, }: Props) => { let auth = getAuth(); const router = useRouter(); const toast = useToast({ position: 'top', isClosable: true, }); const { isMobile, isDesktop } = useDevice(); const { askAdminUrl } = useProductDetail(); const [product, setProducts] = useState(products); const [status, setStatus] = useState('idle'); const { productCart, setRefreshCart, setProductCart, refreshCart, isLoading, setIsloading, } = useProductCartContext(); const [activeVariant, setActiveVariant] = useState({ id: 0, code: '', name: '', price: '', stock: '', weight: '', isFlashSale: false, }); const hasPrice = !!product?.lowest_price && Number(product.lowest_price.price) > 0; useEffect(() => { const fetchData = async () => { if (variantId) { let response = await axios( `${process.env.NEXT_PUBLIC_SELF_HOST}/api/shop/variant-detail?id=${variantId}` ); let productVariant = response.data; if (productVariant) { setActiveVariant({ id: productVariant[0].id, code: productVariant[0].code, name: productVariant[0].name, price: productVariant[0].price.price, stock: productVariant[0].stockTotal, weight: productVariant[0].weight, isFlashSale: productVariant[0].isFlashsale, }); } } }; fetchData(); }, [variantId]); const productSimilarQuery = [ product?.name, `fq=-product_id_i:${product.id}`, `fq=-manufacture_id_i:${product.manufacture?.id || 0}`, ].join('&'); const [addCartAlert, setAddCartAlert] = useState(false); const handleButton = async () => { let isLoggedIn = typeof auth === 'object'; if (!isLoggedIn) { const currentUrl = encodeURIComponent(router.asPath); await router.push(`/login?next=${currentUrl}`); // Tunggu login berhasil, misalnya dengan memantau perubahan status auth. const authCheckInterval = setInterval(() => { const newAuth = getAuth(); if (typeof newAuth === 'object') { isLoggedIn = true; auth = newAuth; // Update nilai auth setelah login clearInterval(authCheckInterval); } }, 500); // Periksa status login setiap 500ms await new Promise((resolve) => { const checkLogin = setInterval(() => { if (isLoggedIn) { clearInterval(checkLogin); resolve(null); } }, 500); }); } if (!variantId || isNaN(quantity) || typeof auth !== 'object') return; if (status === 'success') return; setStatus('loading'); await upsertUserCart({ userId: auth.id, type: 'product', id: variantId, qty: quantity, selected: true, source: source, qtyAppend: true, }); setStatus('idle'); setRefreshCart(true); if (!children) { setAddCartAlert(true); } gtagAddToCart(activeVariant, quantity); toast({ title: 'Tambah ke keranjang', description: 'Berhasil menambahkan barang ke keranjang belanja', status: 'success', duration: 3000, isClosable: true, position: 'top', }); if (source === 'buy') { router.push('/shop/checkout?source=buy'); } }; useEffect(() => { if (status === 'success') setTimeout(() => { setStatus('idle'); }, 3000); }, [status]); if (children) { return (
{children({ onClick: handleButton, isLoading: status === 'loading' })}
); } const btnConfig = { add_to_cart: { colorScheme: 'red', variant: 'outline', text: 'Keranjang', }, buy: { colorScheme: 'red', variant: 'solid', text: isDesktop ? 'Beli' : 'Beli Sekarang', }, }; return (
setAddCartAlert(false)} > {/* ===== MOBILE LAYOUT: konten scroll + footer fixed di dalam popup ===== */}
{/* area scroll */}
{/* HEADER ITEM */}
{!!product.manufacture.name ? ( {product.manufacture.name} ) : ( '-' )}

{product.name}

{product.code}

{!!product.lowest_price && product.lowest_price.price > 0 && ( <>
{product.lowest_price.discount_percentage > 0 && ( <>
{Math.floor( product.lowest_price.discount_percentage )} %
Rp {formatCurrency(product.lowest_price.price || 0)}
)}
Rp{' '} {formatCurrency( product.lowest_price.price_discount || 0 )}
)} {!!product.lowest_price && product.lowest_price.price === 0 && ( Hubungi kami untuk dapatkan harga terbaik,{' '} klik disini )}
{/* sembunyikan link header di mobile agar tidak dobel */}
Lihat Keranjang
{/* PROMO KHUSUS MOBILE */}
{/* PRODUCT SIMILAR */}
Kamu Mungkin Juga Suka
{/* footer tombol: selalu terlihat di bawah popup mobile */}
Lihat Keranjang
{/* ===== DESKTOP LAYOUT: tetap seperti semula ===== */}
{/* HEADER ITEM */}
{!!product.manufacture.name ? ( {product.manufacture.name} ) : ( '-' )}

{product.name}

{product.code}

{!!product.lowest_price && product.lowest_price.price > 0 && ( <>
{product.lowest_price.discount_percentage > 0 && ( <>
{Math.floor(product.lowest_price.discount_percentage)} %
Rp {formatCurrency(product.lowest_price.price || 0)}
)}
Rp{' '} {formatCurrency(product.lowest_price.price_discount || 0)}
)} {!!product.lowest_price && product.lowest_price.price === 0 && ( Hubungi kami untuk dapatkan harga terbaik,{' '} klik disini )}
Lihat Keranjang
{/* PROMO (desktop biarkan sama posisinya) */}
{/* PRODUCT SIMILAR */}
Kamu Mungkin Juga Suka
); }; export default AddToCart;