(function(){
function $(s,ctx=document){ return ctx.querySelector(s); }
function esc(s){ return String(s||'').replace(/[&<>"']/g, m=>({ '&':'&','<':'<','>':'>','"':'"',"'":''' }[m])); }
// CSRF token helper
function getCsrfToken() {
const metaTag = document.querySelector('meta[name="csrf-token"]');
return metaTag ? metaTag.getAttribute('content') : '';
}
function guessPdMeta(){
const name = (window.PD_NAME !== undefined) ? String(window.PD_NAME) : ($('#pd-title')?.textContent || '');
const sku = (function(){ const el=$('#pd-sku'); return el ? el.textContent.trim() : (window.PD_SKU||''); })();
// SECURITY FIX: Remove price from client-side metadata (will be validated server-side)
const imgEl = $('#pd-main-img');
const image_url = imgEl ? (imgEl.getAttribute('src') || '') : '';
return { name, sku, image_url }; // price removed for security
}
async function addToCart(productId, qty=1, variantId=0, metaOpt){
const meta = Object.assign(guessPdMeta(), metaOpt||{});
const payload = {
product_id: parseInt(productId||0,10) || 0,
qty: parseInt(qty||1,10) || 1,
variant_id: parseInt(variantId||0,10) || 0,
meta
};
// Check if user is logged in
const isLoggedIn = document.querySelector('meta[name="user-logged-in"]')?.content === 'true' ||
document.body.classList.contains('logged-in') ||
window.userLoggedIn === true ||
document.body.dataset.userLoggedIn === 'true';
// Skip localStorage untuk logged user - mereka pakai database
if (!isLoggedIn && window.guestCart) {
try {
window.guestCart.add(payload.product_id, payload.qty, payload.variant_id, meta);
} catch (e) {
console.warn('Failed to add to localStorage cart:', e);
}
}
const res = await fetch('/api/cart/add.php', {
method: 'POST',
headers: {
'Content-Type':'application/json',
'X-CSRF-Token': getCsrfToken()
},
credentials: 'same-origin',
body: JSON.stringify({
...payload,
csrf_token: getCsrfToken()
}),
});
const data = await res.json().catch(()=>({ ok:false, error:'Gagal menambahkan ke keranjang' }));
if (!res.ok || !data.ok) {
const msg = data && data.error ? data.error : 'Gagal menambahkan ke keranjang';
throw new Error(msg);
}
// Update badge di navbar dengan data dari response
try {
const el = document.querySelector('[data-role="cart-badge"]') || document.getElementById('cartCount');
if (el && data.cart && typeof data.cart.items_count === 'number') {
el.textContent = String(data.cart.items_count);
el.classList.toggle('is-empty', data.cart.items_count <= 0);
}
} catch(_){}
// Siarkan event global (dipakai cart-badge.js dan halaman lain)
try {
document.dispatchEvent(new CustomEvent('cart:updated', { detail: data.cart || {} }));
} catch(_){}
// Update CartBadge dengan data dari response (lebih reliable)
try {
if (window.CartBadge && window.CartBadge.set) {
window.CartBadge.set(data.cart.items_count||0);
}
} catch(_){}
// Tambahan: refresh cart counter setelah delay kecil untuk memastikan data tersinkronisasi
setTimeout(() => {
if (window.updateCartCounter) {
window.updateCartCounter();
}
}, 100);
return data;
}
// Function to update cart counter from server
async function updateCartCounter(){
try {
const res = await fetch('/api/cart/get.php', { credentials:'same-origin' });
const data = await res.json().catch(()=>({ok:false}));
if (data.ok && typeof data.items_count === 'number') {
const el = document.querySelector('[data-role="cart-badge"]') || document.getElementById('cartCount');
if (el) {
el.textContent = String(data.items_count);
el.classList.toggle('is-empty', data.items_count <= 0);
}
// Dispatch event
try {
document.dispatchEvent(new CustomEvent('cart:updated', { detail: { items_count: data.items_count } }));
} catch(_){}
}
} catch (err) {
console.log('Could not update cart counter:', err);
}
}
// Function to manually merge guest cart (if needed)
async function mergeGuestCart(){
try {
const res = await fetch('/api/cart/merge-guest.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-Token': getCsrfToken()
},
credentials: 'same-origin',
body: JSON.stringify({ csrf_token: getCsrfToken() })
});
const data = await res.json().catch(()=>({ok:false}));
if (data.ok && data.merged_items > 0) {
console.log(`Guest cart merged: ${data.merged_items} items`);
// Update cart counter after merge
await updateCartCounter();
return data;
}
return data;
} catch (err) {
console.log('Could not merge guest cart:', err);
return { ok: false, error: err.message };
}
}
window.addToCart = addToCart;
window.updateCartCounter = updateCartCounter;
window.mergeGuestCart = mergeGuestCart;
// Optional: auto-bind untuk tombol apapun yang punya data-addtocart
document.addEventListener('click', async (e)=>{
const btn = e.target.closest('[data-addtocart]');
if (!btn) return;
e.preventDefault();
if (btn.disabled) return;
const pid = parseInt(btn.getAttribute('data-pid')||'0',10);
const vid = parseInt(btn.getAttribute('data-vid')||'0',10);
const qty = parseInt(btn.getAttribute('data-qty')||'1',10) || 1;
try {
const data = await addToCart(pid, qty, vid);
if (window.showToast) {
const meta = guessPdMeta();
window.showToast({
type:'success',
title:'Berhasil ditambahkan',
message:`${esc(meta.name)}${meta.sku?` ยท SKU: ${esc(meta.sku)}`:''}
Qty: ${qty}`,
duration: 3800,
actions: [
{ label:'Lihat Keranjang', onClick: ()=> { window.location.href='/keranjang'; } },
{ label:'Lanjut Belanja', variant:'alt', onClick: ()=>{} }
]
});
}
} catch (err) {
if (window.showToast) {
window.showToast({ type:'warn', title:'Gagal', message: String(err?.message||'Gagal menambahkan'), duration: 4200 });
} else {
console.error(err);
}
}
});
})();