Ajouter reconcile.html
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / PHP Syntax Check (push) Has been cancelled
CI / JavaScript Lint (push) Has been cancelled
CI / Docker Build Test (push) Has been cancelled
CI / Validate Translation Files (push) Has been cancelled
CI / Auto-merge develop → main (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
This commit is contained in:
+123
@@ -0,0 +1,123 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>EverShelf - Réconciliation</title>
|
||||
<style>
|
||||
:root { --bg: #111827; --card: #1f2937; --text: #f3f4f6; --accent: #3b82f6; }
|
||||
body { font-family: 'Segoe UI', sans-serif; background: var(--bg); color: var(--text); margin: 0; padding: 20px; }
|
||||
|
||||
/* Formulaire de modification (fixé en haut) */
|
||||
.edit-zone {
|
||||
position: sticky; top: 0; background: var(--card); padding: 20px;
|
||||
border-radius: 12px; box-shadow: 0 4px 20px rgba(0,0,0,0.5); z-index: 100;
|
||||
display: grid; grid-template-columns: 1fr 1fr 1fr auto; gap: 10px; margin-bottom: 30px;
|
||||
}
|
||||
|
||||
/* Grille de produits */
|
||||
.inventory-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 15px; }
|
||||
.product-card {
|
||||
background: var(--card); padding: 15px; border-radius: 8px; cursor: pointer;
|
||||
border: 1px solid #374151; transition: 0.2s;
|
||||
}
|
||||
.product-card:hover { border-color: var(--accent); transform: translateY(-2px); }
|
||||
.product-card h4 { margin: 0 0 10px 0; font-size: 14px; }
|
||||
.badge { background: #374151; padding: 3px 8px; border-radius: 4px; font-size: 11px; color: #9ca3af; }
|
||||
|
||||
input, select { background: #374151; color: white; border: 1px solid #4b5563; padding: 10px; border-radius: 6px; }
|
||||
button { background: var(--accent); color: white; border: none; padding: 10px 20px; border-radius: 6px; cursor: pointer; font-weight: bold; }
|
||||
button:hover { background: #2563eb; }
|
||||
.status { font-size: 12px; margin-top: 5px; color: #10b981; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="edit-zone">
|
||||
<input type="hidden" id="edit-id">
|
||||
<input type="text" id="edit-name" placeholder="Nom du produit">
|
||||
<select id="edit-category">
|
||||
<option value="">-- Catégorie --</option>
|
||||
</select>
|
||||
<button onclick="saveChanges()">ENREGISTRER</button>
|
||||
<div id="save-status" class="status" style="grid-column: span 4; display:none;">Modification enregistrée !</div>
|
||||
</div>
|
||||
|
||||
<div id="loader" style="text-align:center;">Chargement de l'inventaire...</div>
|
||||
<div class="inventory-grid" id="inventory"></div>
|
||||
|
||||
<script>
|
||||
let categories = {};
|
||||
|
||||
// 1. Charger les catégories FR
|
||||
fetch('translations/fr.json')
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
categories = data.categories;
|
||||
const sel = document.getElementById('edit-category');
|
||||
Object.entries(categories).forEach(([key, val]) => {
|
||||
const opt = document.createElement('option');
|
||||
opt.value = key; opt.textContent = val;
|
||||
sel.appendChild(opt);
|
||||
});
|
||||
loadInventory(); // Charger les produits après les catégories
|
||||
});
|
||||
|
||||
// 2. Charger les produits via app_bootstrap
|
||||
function loadInventory() {
|
||||
fetch('api/index.php?action=app_bootstrap')
|
||||
.then(r => r.json())
|
||||
.then(data => {
|
||||
document.getElementById('loader').style.display = 'none';
|
||||
const container = document.getElementById('inventory');
|
||||
|
||||
// Dans app_bootstrap, les produits sont souvent dans data.inventory ou data.products
|
||||
const products = data.inventory || data.products || [];
|
||||
|
||||
container.innerHTML = "";
|
||||
products.forEach(p => {
|
||||
const card = document.createElement('div');
|
||||
card.className = 'product-card';
|
||||
const catLabel = categories[p.category] || p.category;
|
||||
card.innerHTML = `
|
||||
<h4>${p.name}</h4>
|
||||
<span class="badge">${catLabel}</span>
|
||||
`;
|
||||
card.onclick = () => prepareEdit(p);
|
||||
container.appendChild(card);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 3. Remplir le formulaire au clic
|
||||
function prepareEdit(p) {
|
||||
document.getElementById('edit-id').value = p.id;
|
||||
document.getElementById('edit-name').value = p.name;
|
||||
document.getElementById('edit-category').value = p.category;
|
||||
window.scrollTo({top: 0, behavior: 'smooth'});
|
||||
}
|
||||
|
||||
// 4. Sauvegarder
|
||||
function saveChanges() {
|
||||
const data = {
|
||||
id: document.getElementById('edit-id').value,
|
||||
name: document.getElementById('edit-name').value,
|
||||
category: document.getElementById('edit-category').value
|
||||
};
|
||||
|
||||
fetch('api/index.php?action=product_edit', {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify(data)
|
||||
})
|
||||
.then(r => r.json())
|
||||
.then(res => {
|
||||
const st = document.getElementById('save-status');
|
||||
st.style.display = 'block';
|
||||
setTimeout(() => st.style.display = 'none', 3000);
|
||||
loadInventory(); // Recharger pour voir le changement
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user