<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: "Stylowy pier\u015bcionek w kolorze niebiesko-posrebrzanym", langCode: 'pl'});</script><script>console.log('[T_PL] ⏭️ Język PL lub pusty - zwracam bez tłumaczenia');</script>Stylowy pierścionek w kolorze niebiesko-posrebrzanym

Stylowy pierścionek w kolorze niebiesko-posrebrzanym

Zaloguj się, aby zobaczyć ceny

Ten efektowny, niebiesko-posrebrzany pierścionek łączy nowoczesny design z nutą elegancji. Żywa, niebieska obrączka uzupełniona jest eleganckim posrebrzanym akcentem, dzięki czemu stanowi idealny dodatek na każdą okazję. Niezależnie od tego, czy wybierasz się na wieczorne wyjście, czy chcesz dodać elegancji swojej codziennej stylizacji, ten pierścionek z pewnością zwróci na siebie uwagę.

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 (_) {} })(); });