/* ags 92 – B2B: filter dostupnosti + „skladom najprv" v zoznamoch produktov (SK/CZ/HU/PL/EN)
* Súbor: /buxus/docs/skladom5.js.txt · verzia 2026-10-15f
* Nastavenie (riadok pred skriptom v Container 22 Content after):
* window.agsSkladom = { mode: 'preview', allow: ['Fiktívna firma pre OZ'], def: 'sklad', markets: ['sk','cz','hu'] };
* mode: 'preview' (len účty z allow) | 'live' (všetci prihlásení) | 'off'
* def: predvolený výber pri prvej návšteve: 'all' | 'sklad' | 'cesta' | 'bez'
* Čo robí:
* - nad každým zoznamom produktov (kategória, značka, vyhľadávanie, kampaň, výpredaj) pridá prepínač
* Všetko · Skladom · Na ceste · Bez termínu; voľbu si pamätá (localStorage ags_skl_f).
* - „Všetko": preusporiada kartičky na zobrazenej strane – skladom, potom s termínom (od najbližšieho), potom bez termínu.
* - Filter: zobrazí len vyhovujúce kartičky; keď ich je na strane málo, dočíta ďalšie produkty zo zoznamu na pozadí
* (1 požiadavka = 96 produktov, automaticky najviac 1), tlačidlo „Zobraziť ďalšie" pokračuje (opäť najviac 1 dávka).
* - Bez počtov na tlačidlách (prehliadač pozná len načítanú časť zoznamu).
* - Stav berie z kartičky (žltý riadok = nie je skladom; dátum v ňom = na ceste). Ceny partnera dočíta len pre viditeľné
* dočítané kartičky (API webu, po 2 naraz); naraz ukáže najviac toľko kartičiek, koľko je nastavené na stranu.
* - Iba zobrazenie. Nič neukladá na server, nemení košík ani nastavenie počtu položiek.
*/
(function () {
'use strict';
if (window.__agsSkladomLoaded) { return; }
window.__agsSkladomLoaded = true;
var VER = '2026-10-15f';
var CFG = window.agsSkladom || {};
var MODE = CFG.mode || 'preview';
if (MODE === 'off') { return; }
var ALLOW = CFG.allow || ['Fiktívna firma pre OZ'];
var MARKETS = CFG.markets || ['sk', 'cz', 'hu'];
var DEF = CFG.def || 'all';
var CHUNK = 96, MAX_CHUNKS = 1; /* automaticky najviac 1 dávka; ďalšie len po kliknutí partnera */
var LS_KEY = 'ags_skl_f';
var m = (location.pathname.match(/^\/(sk|cz|hu|pl|com|en)(\/|$)/i) || [])[1];
m = m ? m.toLowerCase() : 'sk';
if (m === 'com') { m = 'en'; }
if (MARKETS.indexOf(m) < 0) { return; }
var T = {
sk: { lbl: 'Dostupnosť:', all: 'Všetko', sklad: 'Skladom', cesta: 'Na ceste', bez: 'Bez termínu', page: 'na tejto strane', more: 'Zobraziť ďalšie', loading: 'Hľadám ďalšie produkty…', scanned: 'Prehľadaných {n} produktov', done: 'Prehľadaný celý zoznam', none: 'V tomto výbere nie sú žiadne produkty.', sorted: 'Zoradené: skladom najprv', prev: 'NÁHĽAD' },
cz: { lbl: 'Dostupnost:', all: 'Vše', sklad: 'Skladem', cesta: 'Na cestě', bez: 'Bez termínu', page: 'na této stránce', more: 'Zobrazit další', loading: 'Hledám další produkty…', scanned: 'Prohledáno {n} produktů', done: 'Prohledán celý seznam', none: 'V tomto výběru nejsou žádné produkty.', sorted: 'Seřazeno: skladem nejdřív', prev: 'NÁHLED' },
hu: { lbl: 'Elérhetőség:', all: 'Összes', sklad: 'Raktáron', cesta: 'Úton', bez: 'Nincs szállítási idő', page: 'ezen az oldalon', more: 'Továbbiak', loading: 'További termékek keresése…', scanned: '{n} termék átnézve', done: 'A teljes lista átnézve', none: 'Ebben a szűrésben nincs termék.', sorted: 'Rendezés: raktáron lévők elöl', prev: 'ELŐNÉZET' },
pl: { lbl: 'Dostępność:', all: 'Wszystkie', sklad: 'Na stanie', cesta: 'W drodze', bez: 'Bez terminu', page: 'na tej stronie', more: 'Pokaż więcej', loading: 'Szukam kolejnych produktów…', scanned: 'Przejrzano {n} produktów', done: 'Przejrzano całą listę', none: 'Brak produktów w tym wyborze.', sorted: 'Sortowanie: najpierw na stanie', prev: 'PODGLĄD' },
en: { lbl: 'Availability:', all: 'All', sklad: 'In stock', cesta: 'On the way', bez: 'No delivery date', page: 'on this page', more: 'Show more', loading: 'Looking for more products…', scanned: '{n} products checked', done: 'Whole list checked', none: 'No products in this selection.', sorted: 'Sorted: in stock first', prev: 'PREVIEW' }
}[m];
function txt(s) { return (s || '').replace(/\s+/g, ' ').trim(); }
function lsGet(k) { try { return localStorage.getItem(k); } catch (e) { return null; } }
function lsSet(k, v) { try { localStorage.setItem(k, v); } catch (e) {} }
function track(ev, data) { try { (window.dataLayer = window.dataLayer || []).push(Object.assign({ event: ev, ags_skl_trh: m }, data || {})); } catch (e) {} }
function firmName() { var h = document.querySelector('.header-basic-info h3'); return h ? txt(h.textContent) : ''; }
function allowed() {
var f = firmName();
if (!f) { return false; }
if (MODE === 'live') { return true; }
for (var i = 0; i < ALLOW.length; i++) { if (f.toLowerCase().indexOf(String(ALLOW[i]).toLowerCase()) >= 0) { return true; } }
return false;
}
/* ---- stav kartičky ---- */
function parseDate(s) {
var a = s.match(/(\d{4})\s*\.\s*(\d{1,2})\s*\.\s*(\d{1,2})/); /* 2026. 10. 05 (HU) */
if (a) { return new Date(+a[1], +a[2] - 1, +a[3]).getTime(); }
var b = s.match(/(\d{1,2})\s*\.\s*(\d{1,2})\s*\.\s*(\d{4})/); /* 1.11.2026 */
if (b) { return new Date(+b[3], +b[2] - 1, +b[1]).getTime(); }
var c = s.match(/(\d{4})-(\d{2})-(\d{2})/);
if (c) { return new Date(+c[1], +c[2] - 1, +c[3]).getTime(); }
return null;
}
function status(card) {
if (card.__aggSt) { return card.__aggSt; }
var y = card.querySelector('.yellow-background');
var st;
if (!y) { st = { k: 'sklad', d: 0 }; }
else {
var d = parseDate(txt(y.textContent));
st = d ? { k: 'cesta', d: d } : { k: 'bez', d: 0 };
}
card.__aggSt = st;
return st;
}
var RANK = { sklad: 0, cesta: 1, bez: 2 };
function cmp(a, b) {
var sa = status(a.card), sb = status(b.card);
if (RANK[sa.k] !== RANK[sb.k]) { return RANK[sa.k] - RANK[sb.k]; }
if (sa.k === 'cesta' && sa.d !== sb.d) { return sa.d - sb.d; }
return a.i - b.i;
}
/* ---- DOM zoznamu ---- */
function grid() {
var c = document.querySelector('.row.eq-height .product-card');
return c ? c.closest('.row.eq-height') : null;
}
function items(g) {
var out = [];
var ch = g.children;
for (var i = 0; i < ch.length; i++) {
var card = ch[i].querySelector('.product-card');
if (card) { out.push({ el: ch[i], card: card, i: i }); }
}
return out;
}
function isListing() {
return !!(grid() && document.querySelector('.fs_results_count, .pagination'));
}
/* ---- štýl ---- */
function css() {
if (document.getElementById('ags-skl-css')) { return; }
var s = document.createElement('style');
s.id = 'ags-skl-css';
s.textContent =
'#ags-skl{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin:4px 0 14px;padding:10px 12px;background:#fff;border:1px solid #d6e6f2;border-radius:6px;font-size:13px}' +
'#ags-skl .lbl{font-weight:700;color:#1b3a57;margin-right:2px}' +
'#ags-skl button{border:1px solid #1c84c6;background:#fff;color:#1c84c6;border-radius:16px;padding:5px 12px;font-weight:600;cursor:pointer;line-height:1.2}' +
'#ags-skl button.on{background:#1c84c6;color:#fff}' +
'#ags-skl button[data-f=sklad]:not(.on){border-color:#2e9e5b;color:#237a46}' +
'#ags-skl button[data-f=sklad].on{background:#2e9e5b;border-color:#2e9e5b}' +
'#ags-skl .info{color:#5a6b7b;margin-left:auto;font-size:12px}' +
'#ags-skl .prev{background:#f0ad4e;color:#fff;border-radius:3px;padding:1px 6px;font-size:10px;font-weight:700}' +
'#ags-skl-more{display:block;margin:6px auto 22px;border:1px solid #1c84c6;background:#1c84c6;color:#fff;border-radius:4px;padding:9px 22px;font-weight:700;cursor:pointer}' +
'#ags-skl-more[disabled]{opacity:.6;cursor:default}' +
'#ags-skl-msg{text-align:center;color:#5a6b7b;margin:4px 0 20px}' +
'.ags-skl-hide{display:none!important}';
document.head.appendChild(s);
}
/* ---- stav prepínača ---- */
var filter = lsGet(LS_KEY) || DEF;
if (!/^(all|sklad|cesta|bez)$/.test(filter)) { filter = 'all'; }
var run = 0; /* poradové číslo behu – zruší staré načítavanie po zmene */
var state = null; /* stav dočítavania pre aktuálny zoznam */
function bar(g) {
var b = document.getElementById('ags-skl');
if (b && b.nextElementSibling === g) { return b; }
if (b) { b.parentNode.removeChild(b); }
b = document.createElement('div');
b.id = 'ags-skl';
b.innerHTML = '' + T.lbl + '' +
['all', 'sklad', 'cesta', 'bez'].map(function (k) { return ''; }).join('') +
'' + (MODE === 'preview' ? ' ' + T.prev + '' : '');
g.parentNode.insertBefore(b, g);
b.addEventListener('click', function (e) {
var t = e.target.closest('button[data-f]');
if (!t) { return; }
var f = t.getAttribute('data-f');
if (f === filter && f === 'all') { return; }
filter = f;
lsSet(LS_KEY, f);
track('ags_skl_filter', { ags_skl_f: f });
apply(true);
});
return b;
}
/* bez počtov: prehliadač pozná len načítanú časť zoznamu, číslo by klamalo (rozhodnutie Petra 15. 10.) */
function paint(b, info) {
var btns = b.querySelectorAll('button[data-f]');
for (var i = 0; i < btns.length; i++) { btns[i].classList.toggle('on', btns[i].getAttribute('data-f') === filter); }
b.querySelector('.info').textContent = info || '';
}
function nativePager(show) {
var els = document.querySelectorAll('.pagination');
for (var i = 0; i < els.length; i++) {
var w = els[i].closest('.row') || els[i];
if (w.contains(grid())) { w = els[i]; }
w.classList.toggle('ags-skl-hide', !show);
}
}
function clearExtras() {
['ags-skl-more', 'ags-skl-msg'].forEach(function (id) { var e = document.getElementById(id); if (e) { e.parentNode.removeChild(e); } });
}
/* ---- hlavná logika ---- */
var applying = false;
function apply(userClick) {
var g = grid();
if (!g) { return; }
applying = true;
run++;
var b = bar(g);
var list = items(g);
if (filter === 'all') {
/* návrat po filtri: ak sú v zozname dočítané kartičky, obnovíme pôvodnú stranu */
if (state && state.orig && state.g === g) {
g.innerHTML = state.orig;
state = null;
list = items(g);
list.forEach(function (it) { it.card.__agsOwn = true; });
}
list.forEach(function (it) { it.el.classList.remove('ags-skl-hide'); });
list.slice().sort(cmp).forEach(function (it) { it.el.__agsSeen = true; g.appendChild(it.el); });
clearExtras();
nativePager(true);
paint(b, T.sorted + ' · ' + T.page);
applying = false;
prices();
return;
}
/* filter: zoznam prevezmeme od začiatku, aby sa nič nepreskočilo */
if (!state || state.g !== g || state.href !== location.href) {
state = { g: g, href: location.href, orig: g.innerHTML, page: 0, end: false, seen: {}, scanned: 0, target: 0 };
list.forEach(function (it) { state.seen[it.card.getAttribute('data-lazy-product-id')] = 1; });
}
state.target = perPage();
list.slice().sort(cmp).forEach(function (it) { it.el.__agsSeen = true; g.appendChild(it.el); });
nativePager(false);
var vis = show();
applying = false;
if (vis < state.target && !state.end) { loadMore(); } else { moreButton(); }
}
/* zobrazí najviac state.target vyhovujúcich kartičiek (ostatné načítané čakajú skryté na „Zobraziť ďalšie“) */
function show() {
var g = grid();
if (!g || !state) { return 0; }
var n = 0, list = items(g);
list.forEach(function (it) {
var on = status(it.card).k === filter && n < state.target;
if (on) { n++; }
it.el.classList.toggle('ags-skl-hide', !on);
});
paint(document.getElementById('ags-skl'), '');
prices();
return n;
}
function matching() {
var g = grid();
return g ? items(g).filter(function (it) { return status(it.card).k === filter; }).length : 0;
}
function perPage() {
/* aktívny počet je jediné číslo v .fs_results_count, ktoré nie je odkaz */
var box = document.querySelector('.fs_results_count');
if (box) {
var w = document.createTreeWalker(box, NodeFilter.SHOW_TEXT, null, false), n;
while ((n = w.nextNode())) {
if (n.parentElement.closest('a')) { continue; }
var mm = txt(n.textContent).match(/\b(12|24|48|96)\b/);
if (mm) { return +mm[1]; }
}
}
return 24;
}
function chunkUrl(p) {
var u = new URL(location.href);
u.searchParams.delete('page');
u.searchParams.set('results_per_page', String(CHUNK));
// BUXUS FS: 1. strana = BEZ parametra page (page=1 vráti chybný výsek, overené 15. 10.)
if (p > 1) { u.searchParams.set('page', String(p)); }
u.hash = '';
return u.toString();
}
function moreButton(loading) {
var g = grid();
if (!g || !state) { return; }
var btn = document.getElementById('ags-skl-more');
var msg = document.getElementById('ags-skl-msg');
if (!msg) { msg = document.createElement('div'); msg.id = 'ags-skl-msg'; g.parentNode.insertBefore(msg, g.nextSibling); }
if (!btn) {
btn = document.createElement('button'); btn.id = 'ags-skl-more'; btn.type = 'button';
btn.addEventListener('click', function () {
if (!state || btn.disabled) { return; }
track('ags_skl_more', { ags_skl_f: filter });
state.target += perPage();
var vis = show();
if (vis < state.target && !state.end) { loadMore(); } else { moreButton(); }
});
msg.parentNode.insertBefore(btn, msg);
}
var visible = items(g).filter(function (it) { return !it.el.classList.contains('ags-skl-hide'); }).length;
var waiting = matching() - visible;
btn.textContent = loading ? T.loading : T.more;
btn.disabled = !!loading;
btn.style.display = (!loading && state.end && waiting <= 0) ? 'none' : '';
msg.textContent = (visible === 0 && state.end) ? T.none : '';
}
function loadMore() {
var myRun = run;
var g = grid();
if (!g || !state || state.end) { moreButton(); return; }
var chunks = 0;
moreButton(true);
(function next() {
if (myRun !== run || !state) { return; }
if (matching() >= state.target || chunks >= MAX_CHUNKS || state.end) { done(); return; }
state.page++; chunks++;
fetch(chunkUrl(state.page), { credentials: 'same-origin' })
.then(function (r) { return r.text(); })
.then(function (h) {
if (myRun !== run || !state) { return; }
var d = new DOMParser().parseFromString(h, 'text/html');
var cards = d.querySelectorAll('.row.eq-height .product-card');
if (!cards.length) { state.end = true; next(); return; }
state.scanned = (state.page - 1) * CHUNK + cards.length;
if (cards.length < CHUNK) { state.end = true; }
for (var i = 0; i < cards.length; i++) {
var id = cards[i].getAttribute('data-lazy-product-id');
if (state.seen[id]) { continue; }
state.seen[id] = 1;
var wrap = cards[i].closest('.item') || cards[i].parentElement;
var node = document.importNode(wrap, true);
node.classList.add('ags-skl-hide'); node.__agsSeen = true;
node.querySelector('.product-card').__agsOwn = true;
g.appendChild(node);
}
show();
next();
})
.catch(function () { if (state) { state.end = true; } done(); });
})();
function done() { if (myRun === run) { show(); moreButton(false); } }
}
/* ceny partnera v dočítaných kartičkách: rovnaké API ako web (/{trh}/api/product/{id}), ale len pre VIDITEĽNÉ
kartičky, ktoré pridal tento skript, postupne po 2 (server spracúva požiadavky jednej relácie za sebou –
hromadné volanie by zdržalo aj pridanie do košíka). */
var pq = [], pActive = 0, P_PAR = 2;
var DOM_SEG = location.pathname.split('/')[1] || 'sk';
function prices() {
var g = grid();
if (!g) { return; }
items(g).forEach(function (it) {
var c = it.card;
if (!c.__agsOwn || c.__agsReq || it.el.classList.contains('ags-skl-hide')) { return; }
if (!c.querySelector('[data-lazy-property]')) { return; }
c.__agsReq = true;
pq.push(c);
});
pump();
}
function pump() {
while (pActive < P_PAR && pq.length) {
var c = pq.shift();
if (!c.isConnected || (c.closest('.item') && c.closest('.item').classList.contains('ags-skl-hide'))) { c.__agsReq = false; continue; }
pActive++;
(function (c) {
fetch('/' + DOM_SEG + '/api/product/' + encodeURIComponent(c.getAttribute('data-lazy-product-id')), { credentials: 'same-origin' })
.then(function (r) { return r.json(); })
.then(function (data) {
var props = c.querySelectorAll('[data-lazy-property]');
for (var i = 0; i < props.length; i++) {
var v = data[props[i].getAttribute('data-lazy-property')];
if (v === undefined) { continue; }
var t = document.createElement('template');
t.innerHTML = String(v);
props[i].replaceWith(t.content);
}
})
.catch(function () { c.__agsReq = false; })
.then(function () { pActive--; pump(); });
})(c);
}
}
/* ---- štart + sledovanie AJAX zmien (filter kategórie/výrobcu, stránkovanie) ---- */
function start() {
if (!allowed() || !isListing()) { return; }
css();
apply(false);
var host = grid().parentNode;
var mo = new MutationObserver(function () {
if (applying) { return; }
var g = grid();
if (!g) { return; }
/* FS (AJAX stránkovanie, filter výrobcu, zoradenie) vymení kartičky v tom istom kontajneri → nové kartičky nemajú značku */
var fresh = false;
for (var i = 0; i < g.children.length; i++) { if (!g.children[i].__agsSeen && g.children[i].querySelector('.product-card')) { fresh = true; break; } }
if (fresh || !document.getElementById('ags-skl') || document.getElementById('ags-skl').nextElementSibling !== g || (state && state.g !== g)) {
state = null;
clearTimeout(start.t);
start.t = setTimeout(function () { apply(false); }, 80);
}
});
mo.observe(host.parentNode || host, { childList: true, subtree: true });
track('ags_skl_view', { ags_skl_f: filter });
}
if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', start); } else { start(); }
window.agsSkladomInfo = { ver: VER, market: m, mode: MODE };
})();