`;
}).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();