`; }).join(''); // wire qty + add grid.querySelectorAll('[data-qtyinput]').forEach(inp => { inp.addEventListener('input', () => { const id = inp.getAttribute('data-qtyinput'); qty[id] = inp.value; }); }); grid.querySelectorAll('[data-add]').forEach(btn => { btn.addEventListener('click', () => { const id = btn.getAttribute('data-add'); const p = PRODUCTS_SOURCE.find(x => x.id === id); if (p) addToCart(p); }); }); // pagination UI pageInfo.textContent = `Page ${page} of ${totalPages} • ${products.length} products`; prevBtn.disabled = page === 1; nextBtn.disabled = page === totalPages; } prevBtn.addEventListener('click', () => { page = Math.max(1, page - 1); renderGrid(); }); nextBtn.addEventListener('click', () => { const totalPages = Math.max(1, Math.ceil(getFilteredProducts().length / PER_PAGE)); page = Math.min(totalPages, page + 1); renderGrid(); }); // search document.getElementById('searchInput').addEventListener('input', (e) => { q = e.target.value || ''; page = 1; renderGrid(); }); // --- Setup dropdowns --- const catDD = setupDropdown({ rootId: 'catDropdown', btnId: 'catBtn', listId: 'catList', labelId: 'catLabel', chevronId: 'catChevron', getOptions: categoriesList, getValue: () => cat, setValue: (v) => { cat = v; page = 1; renderGrid(); } }); const sortDD = setupDropdown({ rootId: 'sortDropdown', btnId: 'sortBtn', listId: 'sortList', labelId: 'sortLabel', chevronId: 'sortChevron', getOptions: () => sortOptions, getValue: () => sort, setValue: (v) => { sort = v; page = 1; renderGrid(); } }); const curDD = setupDropdown({ rootId: 'curDropdown', btnId: 'curBtn', listId: 'curList', labelId: 'curLabel', chevronId: 'curChevron', getOptions: () => [ { value: 'USD', label: 'USD $' }, { value: 'EUR', label: 'EUR €' }, { value: 'GBP', label: 'GBP £' }, { value: 'JPY', label: 'JPY ¥' }, ], getValue: () => currency, setValue: (v) => { currency = v; renderGrid(); renderCart(); } }); // Initial render renderGrid(); renderCart(); renderCartBadge();