<script>console.log('[T] Wywołanie:', {text: Torba na zakupy" class="icon"> Koszyk <script>console.log('[T] Wywołanie:', {text: Ulubione" class="icon"> Ulubione <script>console.log('[T] Wywołanie:', {text: Zamówienia" class="icon"> Moje zamówienia <script>console.log('[T] Wywołanie:', {text: Upraszanie" class="icon"> Moje prośby <script>console.log('[T] Wywołanie:', {text: Pogawędzić" class="icon"> Pomoc w czacie

Koszyk

Twój koszyk jest pusty.

'; setBadge(0); if (totalValueEl) totalValueEl.textContent = fmtPrice(0); return; } setBadge(items.length); cartContent.innerHTML = items.map(it => `
${it.size ? `
Rozmiar: ${it.size}
` : ''}
Usuń
${fmtPrice(it.price)}
`).join(''); const total = items.reduce((sum, it) => sum + (it.price * it.quantity), 0); if (totalValueEl) totalValueEl.textContent = fmtPrice(total); } // >>> ZMIANA: przy braku zalogowania pokazujemy pusty koszyk, bez redirectu async function loadCart(open = true){ try{ // przekaż aktualny język do API, aby T_PL wiedziało jaki język zwrócić const lang = (location.pathname.split('/')[1] || 'pl').slice(0,2); const data = await fetchJSON('/api/cart_list.php?lang=' + encodeURIComponent(lang)); if (data && data.ok) { renderCart(data.items); } else if (data && data.error === 'AUTH_REQUIRED') { // niezalogowany → pokaż pusty koszyk renderCart([]); } else { // inne błędy → pokaż choć pusty, nie krzycz renderCart([]); console.warn('cart_list fallback:', data); } }catch(e){ console.error(e); renderCart([]); // fallback } finally { if (open) openCart(); } } async function addToCart(productId, quantity=1){ try{ const data = await fetchJSON('/api/cart_add.php', { method:'POST', headers:{'Content-Type':'application/json','Accept':'application/json'}, body: JSON.stringify({product_id: productId, quantity}) }); if(data.ok){ setBadge(data.count); await loadCart(true); // === NOWE: efekt highlight na produkcie === const productEl = document.querySelector(`[data-product-id="${productId}"]`); if (productEl) { productEl.classList.add('product-highlight'); setTimeout(() => productEl.classList.remove('product-highlight'), 2000); } } else if(data.error==='AUTH_REQUIRED'){ window.location.href = '/pl/login_choose.php'; } }catch(e){ console.error('addToCart failed', e); } } async function removeFromCart(productId, size = null){ try{ const body = { product_id: productId }; if (size) body.size = size; const data = await fetchJSON('/api/cart_remove.php', { method:'POST', headers:{'Content-Type':'application/json','Accept':'application/json'}, body: JSON.stringify(body) }); if(data.ok){ setBadge(data.count); await loadCart(false); } else if(data.error==='AUTH_REQUIRED'){ renderCart([]); } }catch(e){ console.error('removeFromCart failed', e); } } let isEditingQty = false; async function getStockMax(pid){ try{ const r = await fetchJSON(`/api/stock_quantity.php?product_id=${encodeURIComponent(pid)}`); return r && r.ok ? (r.stock ?? r.quantity ?? 9999) : 9999; }catch{ return 9999; } } async function setCartQty(pid, newQty, size = null){ const removeBody = { product_id: pid }; if (size) removeBody.size = size; await fetchJSON('/api/cart_remove.php', { method:'POST', headers:{'Content-Type':'application/json','Accept':'application/json'}, body: JSON.stringify(removeBody) }); if (newQty > 0){ const addBody = { product_id: pid, quantity: newQty }; if (size) addBody.size = size; await fetchJSON('/api/cart_add.php', { method:'POST', headers:{'Content-Type':'application/json','Accept':'application/json'}, body: JSON.stringify(addBody) }); } } async function applyQtyFromInput(inputEl){ const pid = parseInt(inputEl.dataset.pid,10); const size = inputEl.dataset.size || null; if(!pid) return; isEditingQty = true; try{ const stockMax = await getStockMax(pid); let val = parseInt(inputEl.value,10); if (Number.isNaN(val)) val = 1; val = Math.max(1, Math.min(stockMax, val)); const itemEl = inputEl.closest('.cart-item'); const current = parseInt(itemEl?.dataset.qty || '1',10); if (val !== current){ await setCartQty(pid, val, size); if (itemEl) itemEl.dataset.qty = String(val); await loadCart(false); } inputEl.value = val; }catch(e){ console.error(e); }finally{ setTimeout(()=>{ isEditingQty = false; }, 300); } } // === Triggery if (cartBtn) { cartBtn.addEventListener('click', function(e){ e.preventDefault(); // Zawsze otwórz panel; zawartość wg zalogowania loadCart(true); }); } closeBtn.addEventListener('click', closeCart); cartOverlay.addEventListener('click', closeCart); // Delegacja: add-to-cart document.body.addEventListener('click', function(e) { const btn = e.target.closest('.add-to-cart,[data-add-to-cart]'); if (!btn) return; // Zawsze wysuń koszyk loadCart(true); // Nie dodawaj jeszcze raz, jeśli to #add-to-cart z product.php if (btn.id === 'add-to-cart') return; e.preventDefault(); const rawId = btn.dataset.productId || btn.getAttribute('data-product-id') || btn.dataset.id; const pid = parseInt(rawId, 10); if (!pid) return; addToCart(pid, 1); }); // Delegacja: remove cartContent.addEventListener('click', function(e){ const rem = e.target.closest('.cart-remove[data-remove]'); if(!rem) return; const pid = parseInt(rem.dataset.remove,10); const size = rem.dataset.size || null; if(pid){ removeFromCart(pid, size); } }); // Delegacja dla ± i inputa cartContent.addEventListener('click', async (e)=>{ const incBtn = e.target.closest('[data-qty-inc]'); const decBtn = e.target.closest('[data-qty-dec]'); if (!incBtn && !decBtn) return; const btn = incBtn || decBtn; const pid = parseInt(btn.dataset.pid,10); const size = btn.dataset.size || null; if(!pid) return; // Znajdź input z tym samym pid i size const inputs = cartContent.querySelectorAll(`.cart-qty-input[data-pid="${pid}"]`); let input = null; for (const inp of inputs) { if ((inp.dataset.size || null) === size) { input = inp; break; } } if(!input) return; const step = incBtn ? +1 : -1; let next = parseInt(input.value,10); if(Number.isNaN(next)) next = 1; next += step; const stockMax = await getStockMax(pid); next = Math.max(1, Math.min(stockMax, next)); input.value = next; await applyQtyFromInput(input); }); cartContent.addEventListener('keydown', (e)=>{ const inp = e.target.closest('.cart-qty-input'); if(!inp) return; if (e.key === 'Enter'){ e.preventDefault(); inp.blur(); } }); cartContent.addEventListener('blur', (e)=>{ const inp = e.target.closest('.cart-qty-input'); if(!inp) return; applyQtyFromInput(inp); }, true); // Checkout → checkout.php (link już ma href) if (checkoutBtn && checkoutBtn.tagName === 'BUTTON') { checkoutBtn.addEventListener('click', function(e){ e.preventDefault(); window.location.href = '/checkout.php'; }); } // Badge na starcie (bez redirectu dla niezalogowanych) (async ()=>{ try{ const d = await fetchJSON('/api/cart_count.php'); if (d && d.ok) setBadge(d.count); else if (d && d.error === 'AUTH_REQUIRED') setBadge(0); }catch(_){ /* cicho */ } })(); // Auto-odświeżanie zawartości, jeśli panel otwarty i nie edytujemy ilości setInterval(() => { if (cartSidebar.classList.contains('open') && !isEditingQty) { loadCart(false); } }, 700); }); <script>console.log('[T_PL] Wywołanie:', {text: "Bransoletka ze z\u0142oconej stali z okr\u0105g\u0142ym kamieniem", langCode: 'pl'});</script><script>console.log('[T_PL] ⏭️ Język PL lub pusty - zwracam bez tłumaczenia');</script>Bransoletka ze złoconej stali z okrągłym kamieniem

Bransoletka ze złoconej stali z okrągłym kamieniem

Zaloguj się, aby zobaczyć ceny

Podkreśl swój styl tą wykwintną bransoletką ze złoconej stali. Ten delikatny element zdobi okrągły kamień, który doda Twojej stylizacji odrobinę wyrafinowania. Idealna na co dzień lub na specjalne okazje, ta bransoletka to ponadczasowy dodatek do każdej kolekcji biżuterii.

NASZE PRODUKTY
Nasza biżuteria ze stali nierdzewnej jest trwała i stylowa. Odporna na matowienie, korozję i zużycie, idealnie nadaje się do codziennego użytku, nie rezygnując z elegancji.
WYSYŁKA
Wysyłka na cały świat
Proszę wybrać rozmiar'); return; } } let qty = parseInt(input.value, 10) || 1; if (available > 0) qty = Math.min(Math.max(qty, 1), available); addToCart(pid, qty, selectedSize); }); } (async () => { try { const resp = await fetch('/api/cart_count.php', { headers: { 'Accept': 'application/json' } }); const json = await resp.json(); if (json.ok) setBadge(json.count); } catch (_) {} })(); });