const ProductPage = ({ product, setPage, onAddToCart, lang }) => { const [selectedColor, setSelectedColor] = React.useState(product?.colors?.[0] || null); const [mainImg, setMainImg] = React.useState(null); const [selectedSize, setSelectedSize] = React.useState(product?.sizes?.[0] || null); const [variantName, setVariantName] = React.useState(product?.variants?.[0]?.name || null); const [qty, setQty] = React.useState(1); const [added, setAdded] = React.useState(false); const [reviews, setReviews] = React.useState([]); const [reviewStats, setReviewStats] = React.useState({ total:0, avg:0 }); const [canReview, setCanReview] = React.useState(false); const [alreadyReviewed, setAlreadyReviewed] = React.useState(false); const [myRating, setMyRating] = React.useState(5); const [myReview, setMyReview] = React.useState(""); const [submitting, setSubmitting] = React.useState(false); const [reviewMsg, setReviewMsg] = React.useState(""); const t = (en, id) => lang === "id" ? id : en; React.useEffect(() => { setSelectedColor(null); // jangan paksa pilih warna saat load setSelectedSize(product?.sizes?.[0] || null); const _vs = Array.isArray(product?.variants) ? product.variants : []; // Default varian = yang termurah biar harga awal = "mulai dari"; cover foto TIDAK ikut warna let _cheap = null; _vs.forEach(v => { if (!_cheap || (v.price || 0) < (_cheap.price || 0)) _cheap = v; }); setVariantName(_cheap ? _cheap.name : null); // Cover awal = foto utama produk (pilihan admin), BUKAN foto warna. Ganti hanya saat user klik warna. setMainImg( (product?.images && product.images[0]) || product?.image || (_cheap && _cheap.image) || null ); setQty(1); setAdded(false); window.scrollTo({ top: 0, behavior: "smooth" }); if (product?.id && typeof fbq === 'function') { fbq('track', 'ViewContent', { content_ids: [String(product.id)], content_name: product.name, content_category: product.category || '', content_type: 'product', value: product.price, currency: 'IDR' }); } // Load reviews if (product?.id) { fetch("api/reviews.php?product_id=" + product.id, { credentials:"include" }) .then(r => r.json()) .then(d => { setReviews(d.reviews || []); setReviewStats({ total: d.total || 0, avg: d.avg_rating || 0 }); setCanReview(d.can_review || false); setAlreadyReviewed(d.already_reviewed || false); }).catch(() => {}); setMyRating(5); setMyReview(""); setReviewMsg(""); } }, [product]); const submitReview = async () => { if (myReview.length < 10) { setReviewMsg("❌ Ulasan minimal 10 karakter"); return; } setSubmitting(true); try { const res = await fetch("api/reviews.php", { method:"POST", credentials:"include", headers:{"Content-Type":"application/json"}, body: JSON.stringify({ product_id: product.id, rating: myRating, review: myReview }) }); const data = await res.json(); if (data.success) { setReviewMsg("✓ Ulasan berhasil dikirim!"); setCanReview(false); setAlreadyReviewed(true); // Reload reviews fetch("api/reviews.php?product_id=" + product.id, { credentials:"include" }) .then(r => r.json()).then(d => { setReviews(d.reviews||[]); setReviewStats({ total:d.total||0, avg:d.avg_rating||0 }); }); } else { setReviewMsg("❌ " + (data.error||"Gagal mengirim")); } } catch { setReviewMsg("❌ Gagal terhubung"); } finally { setSubmitting(false); } }; const StarRating = ({ value, onChange, size=20 }) => (
{product.categoryLabel}
{t("Variant", "Varian")}: {curVariant ? curVariant.name : ""}
⏳ Pre-Order — {product.preorderDays || 14} Hari
{t( `This product is made-to-order. It will be processed and shipped approximately ${product.preorderDays || 14} days after payment.`, `Produk ini dibuat berdasarkan pesanan. Akan diproses & dikirim ±${product.preorderDays || 14} hari setelah pembayaran lunas.` )}
{t("Color", "Warna")}: {selectedColor || t("— Choose", "— Pilih")}
{t("Size", "Ukuran")}: {selectedSize}
{t("Quantity", "Jumlah")}
🔥 {t(`Only ${curStock} left — order soon`, `Sisa ${curStock} stok — buruan sebelum kehabisan`)}
)} {/* Add to cart — inline */} {/* Sticky bottom CTA — mobile only */}{product.name}
{formatPrice(curPrice)}
{product.description}
{/* Details */}{t("Details", "Detail")}
Tulis Ulasanmu
Rating
💬
Belum ada ulasan
Jadilah yang pertama mengulas produk ini