<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: "Kolczyki ze posrebrzanej stali z tekstur\u0105", langCode: 'pl'});</script><script>console.log('[T_PL] ⏭️ Język PL lub pusty - zwracam bez tłumaczenia');</script>Kolczyki ze posrebrzanej stali z teksturą

Kolczyki ze posrebrzanej stali z teksturą

Zaloguj się, aby zobaczyć ceny

Podkreśl swój codzienny styl tymi eleganckimi srebrnymi kolczykami-sztyftami. Dzięki unikalnemu, teksturowanemu wzorowi, kolczyki te stanowią nowoczesną interpretację klasycznego dodatku. Ich polerowane wykończenie dodaje odrobinę wyrafinowania, dzięki czemu idealnie nadają się na każdą okazję.

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