/* Blog: topic filter + client-side pagination (they work together). Chips toggle the visible topic; the pager pages through the matches. */ (function () { var list = document.querySelector('.blog-list'); if (!list) return; var chips = [].slice.call(list.querySelectorAll('.blog-chip')); var cards = [].slice.call(list.querySelectorAll('.blog-card')); var pager = list.querySelector('.blog-pagination'); var numbers = pager ? pager.querySelector('.pagination-numbers') : null; var prevBtn = pager ? pager.querySelector('[data-nav="prev"]') : null; var nextBtn = pager ? pager.querySelector('[data-nav="next"]') : null; var pageSize = pager ? (parseInt(pager.getAttribute('data-page-size'), 10) || 6) : 6; var state = { topic: 'all', page: 1 }; function matching() { return cards.filter(function (c) { return state.topic === 'all' || c.getAttribute('data-topic') === state.topic; }); } // Compact list of page tokens: numbers and 'dots'. function tokens(total, cur) { if (total <= 7) { var all = []; for (var i = 1; i <= total; i++) all.push(i); return all; } var set = { 1: 1, 2: 1 }; set[total] = 1; set[total - 1] = 1; set[cur] = 1; set[cur - 1] = 1; set[cur + 1] = 1; var pages = Object.keys(set).map(Number).filter(function (n) { return n >= 1 && n <= total; }).sort(function (a, b) { return a - b; }); var out = []; for (var j = 0; j < pages.length; j++) { if (j > 0 && pages[j] - pages[j - 1] > 1) out.push('dots'); out.push(pages[j]); } return out; } function buildPager(total) { if (!pager) return; if (total <= 1) { pager.hidden = true; return; } pager.hidden = false; numbers.innerHTML = ''; tokens(total, state.page).forEach(function (t) { if (t === 'dots') { var s = document.createElement('span'); s.className = 'page-dots'; s.textContent = '...'; numbers.appendChild(s); return; } var b = document.createElement('button'); b.type = 'button'; b.className = 'page-number' + (t === state.page ? ' active' : ''); b.textContent = t; b.addEventListener('click', function () { state.page = t; render(true); }); numbers.appendChild(b); }); prevBtn.classList.toggle('disabled', state.page <= 1); nextBtn.classList.toggle('disabled', state.page >= total); } function render(scroll) { var m = matching(); var total = Math.max(1, Math.ceil(m.length / pageSize)); if (state.page > total) state.page = total; if (state.page < 1) state.page = 1; var start = (state.page - 1) * pageSize; var end = start + pageSize; cards.forEach(function (c) { c.hidden = true; }); m.slice(start, end).forEach(function (c) { c.hidden = false; }); buildPager(total); if (scroll) list.scrollIntoView({ behavior: 'smooth', block: 'start' }); } chips.forEach(function (chip) { chip.addEventListener('click', function () { chips.forEach(function (c) { c.classList.remove('is-active'); }); chip.classList.add('is-active'); state.topic = chip.getAttribute('data-topic'); state.page = 1; render(false); }); }); if (prevBtn) prevBtn.addEventListener('click', function () { if (state.page > 1) { state.page--; render(true); } }); if (nextBtn) nextBtn.addEventListener('click', function () { state.page++; render(true); }); render(false); })();