feat(ui): infinite scroll, saved filters, product timeline, image comparator, customers bulk toolbar, dark mode refinements

This commit is contained in:
2026-05-26 09:37:35 +00:00
parent 5c815bc2f5
commit c5fc8c5ec6
5 changed files with 159 additions and 1 deletions

View File

@@ -94,6 +94,8 @@ const Customers = (() => {
}
}
var selectedCustomers = new Set();
function renderCustomerRow(c) {
const tier = tierMap[c.price_tier] || 'Mostrador';
const tClass = tierClass[c.price_tier] || 'mostrador';
@@ -104,7 +106,9 @@ const Customers = (() => {
const creditClass = usedPct >= 80 ? 'none' : usedPct >= 60 ? 'low' : '';
const num = String(c.id).padStart(5, '0');
const selClass = (currentCustomer && currentCustomer.id === c.id) ? 'selected' : '';
return '<tr class="' + selClass + '" onclick="Customers.selectCustomer(' + c.id + ')">' +
const isChecked = selectedCustomers.has(c.id) ? 'checked' : '';
return '<tr class="' + selClass + '">' +
'<td onclick="event.stopPropagation();"><input type="checkbox" ' + isChecked + ' onchange="Customers.toggleCustomerSelection(' + c.id + ')"></td>' +
'<td class="cell-num">' + num + '</td>' +
'<td>' +
'<div class="cell-name">' + (c.name || '') + '</div>' +
@@ -801,6 +805,41 @@ const Customers = (() => {
showPaymentModal, closePayment, recordPayment,
};
// Bulk selection
publicApi.toggleCustomerSelection = function(id) {
if (selectedCustomers.has(id)) selectedCustomers.delete(id);
else selectedCustomers.add(id);
updateBulkToolbar();
};
publicApi.toggleSelectAll = function() {
var cb = document.getElementById('selectAllCustomers');
var allChecked = cb.checked;
if (customersVS && customersVS.data) {
customersVS.data.forEach(function(c) {
if (allChecked) selectedCustomers.add(c.id);
else selectedCustomers.delete(c.id);
});
customersVS.refresh();
}
updateBulkToolbar();
};
function updateBulkToolbar() {
var container = document.getElementById('customersBulkToolbar');
if (!container) return;
var count = selectedCustomers.size;
if (count === 0) { container.innerHTML = ''; return; }
container.innerHTML = renderBulkToolbar(count,
'<button class="btn btn--primary btn--sm" onclick="Customers.featureProximamente(\'Exportar seleccionados\')">📥 Exportar</button>' +
'<button class="btn btn--ghost btn--sm" onclick="Customers.clearSelection()">Limpiar</button>'
);
}
publicApi.clearSelection = function() {
selectedCustomers.clear();
document.getElementById('selectAllCustomers').checked = false;
if (customersVS) customersVS.refresh();
updateBulkToolbar();
};
// Expose globally for inline HTML onclick handlers
window.Customers = publicApi;
return publicApi;