// ===== Données exemple (contexte terrain / chantier) =====
let products = [
{ id: 1, name: "Gants de manutention", unit: "paire", qty: 3 },
{ id: 2, name: "Vis autoperceuse 4.8×38", unit: "boîte", qty: 2 },
{ id: 3, name: "Marteau de coffreur 700g", unit: "pièce", qty: 1 },
{ id: 4, name: "Chaussures de sécurité S3", unit: "paire", qty: 1 },
{ id: 5, name: "Niveau à bulle 40 cm", unit: "pièce", qty: 1 },
{ id: 6, name: "Ruban de mesure 5 m", unit: "pièce", qty: 2 },
{ id: 7, name: "Bobine de fil de tension", unit: "pièce", qty: 1 },
{ id: 8, name: "Serre-joints 80 cm", unit: "pièce", qty: 2 },
{ id: 9, name: "Cutter lame 18 mm", unit: "pièce", qty: 3 },
{ id: 10, name: "Lunettes de protection", unit: "pièce", qty: 5 },
{ id: 11, name: "Coffret forets béton SDS", unit: "boîte", qty: 1 },
{ id: 12, name: "Gilet haute visibilité Classe 2", unit: "pièce", qty: 4 },
];
let activeId = null;
const listEl = document.getElementById('product-list');
const headerCountEl = document.getElementById('header-count');
const totalQtyEl = document.getElementById('total-qty');
// ===== Rendu initial =====
function init() {
renderList();
updateSummary();
lucide.createIcons();
}
function renderList() {
listEl.innerHTML = products.map(p => `
`).join('');
lucide.createIcons();
}
function escapeHtml(str) {
const div = document.createElement('div');
div.textContent = str;
return div.innerHTML;
}
// ===== Mise à jour du résumé =====
function updateSummary() {
const total = products.reduce((sum, p) => sum + p.qty, 0);
const count = products.length;
headerCountEl.textContent = `${count} article${count > 1 ? 's' : ''}`;
totalQtyEl.textContent = total;
}
// ===== Gestion du focus / activation =====
function setActiveId(id) {
// Désactiver l’ancien
if (activeId !== null) {
const oldRow = document.querySelector(`.product-row[data-id="${activeId}"]`);
if (oldRow) oldRow.classList.remove('active');
}
activeId = id;
// Activer le nouveau
if (activeId !== null) {
const newRow = document.querySelector(`.product-row[data-id="${activeId}"]`);
if (newRow) newRow.classList.add('active');
}
}
// ===== Actions quantité / suppression =====
function updateQty(id, delta) {
const product = products.find(p => p.id === id);
if (!product) return;
const newQty = product.qty + delta;
if (newQty < 1) return; // empêche de descendre sous 1 (utiliser la poubelle)
product.qty = newQty;
// Mise à jour DOM ciblée (pas de re-render complet pour garder l’état visuel)
const badge = document.querySelector(`.qty-badge[data-qty-id="${id}"]`);
if (badge) badge.textContent = product.qty;
updateSummary();
}
function deleteProduct(id) {
const row = document.querySelector(`.product-row[data-id="${id}"]`);
if (row) {
// Animation rapide de sortie
row.style.transition = "opacity 0.2s ease, transform 0.2s ease, max-height 0.25s ease";
row.style.opacity = "0";
row.style.transform = "translateX(-1rem)";
row.style.maxHeight = row.offsetHeight + "px";
requestAnimationFrame(() => {
row.style.maxHeight = "0px";
row.style.padding = "0px";
row.style.margin = "0px";
row.style.overflow = "hidden";
});
}
setTimeout(() => {
products = products.filter(p => p.id !== id);
if (activeId === id) activeId = null;
renderList();
updateSummary();
// Ré-applique l’état actif si un autre était déjà sélectionné (théoriquement impossible ici car 1 seul actif)
if (activeId !== null) {
const remain = document.querySelector(`.product-row[data-id="${activeId}"]`);
if (remain) remain.classList.add('active');
}
}, 220);
}
// ===== Écouteurs d’événements =====
// Clics sur les lignes et boutons (délégation)
listEl.addEventListener('click', (e) => {
const btn = e.target.closest('[data-action]');
// 1. Bouton d’action (+, –, poubelle)
if (btn) {
e.stopPropagation();
const row = btn.closest('.product-row');
const id = parseInt(row.dataset.id, 10);
const action = btn.dataset.action;
if (action === 'plus') updateQty(id, 1);
else if (action === 'minus') updateQty(id, -1);
else if (action === 'delete') deleteProduct(id);
return;
}
// 2. Ligne produit (hors bouton)
const row = e.target.closest('.product-row');
if (row) {
const id = parseInt(row.dataset.id, 10);
// Si on tape la ligne déjà active → on la referme
// Sinon on active la nouvelle
setActiveId(activeId === id ? null : id);
}
});
// Clic en dehors des lignes (zone vide, header, footer…) → désactive tout
document.getElementById('app').addEventListener('click', (e) => {
const row = e.target.closest('.product-row');
const btn = e.target.closest('[data-action]');
if (!row && !btn) {
setActiveId(null);
}
});
// Démarrage
init();