diff --git a/assets/js/app.js b/assets/js/app.js
index 630a50a..56c62fa 100644
--- a/assets/js/app.js
+++ b/assets/js/app.js
@@ -1352,16 +1352,7 @@ async function loadCustomLocations() {
console.warn('[EverShelf] Could not load custom locations:', e);
}
}
-function renderLocationButtons(containerId, activeKey, onClickFnName) {
- const container = document.getElementById(containerId);
- if (!container) return;
- const keys = Object.keys(LOCATIONS);
- container.innerHTML = keys.map(key => {
- const info = LOCATIONS[key];
- const isActive = key === activeKey ? 'active' : '';
- return ``;
- }).join('');
-}
+
/**
* Render location selector buttons dynamically into a container.
* @param {string} containerId - DOM id of the container holding the buttons
@@ -1379,6 +1370,123 @@ function renderLocationButtons(containerId, activeKey, onClickFnName) {
}).join('');
}
+async function _loadConfigPage() {
+ const container = document.getElementById('locations-list-container');
+ if (!container) return;
+ container.innerHTML = `
Chargement…
`;
+ try {
+ const result = await api('locations_list', {}, 'GET');
+ if (!result.success) {
+ container.innerHTML = `Erreur de chargement.
`;
+ return;
+ }
+ renderLocationsList(result.locations);
+ } catch (e) {
+ container.innerHTML = `Erreur de chargement.
`;
+ }
+}
+
+function renderLocationsList(locations) {
+ const container = document.getElementById('locations-list-container');
+ if (!container) return;
+ if (!locations || locations.length === 0) {
+ container.innerHTML = `Aucun emplacement.
`;
+ return;
+ }
+ container.innerHTML = locations.map(loc => {
+ const builtinBadge = loc.is_builtin
+ ? `natif`
+ : '';
+ const deleteBtn = loc.is_builtin
+ ? ''
+ : ``;
+ return `
+
+
+
+ ${builtinBadge}
+
+ ${deleteBtn}
+
+ `;
+ }).join('');
+}
+
+async function addLocation() {
+ const iconInput = document.getElementById('new-location-icon');
+ const labelInput = document.getElementById('new-location-label');
+ const icon = iconInput.value.trim() || '📦';
+ const label = labelInput.value.trim();
+
+ if (!label) {
+ showToast('Indique un nom pour le nouvel emplacement', 'warning');
+ return;
+ }
+
+ showLoading(true);
+ try {
+ const result = await api('locations_add', {}, 'POST', { label, icon });
+ showLoading(false);
+ if (result.success) {
+ showToast(`Emplacement "${label}" ajouté`, 'success');
+ iconInput.value = '';
+ labelInput.value = '';
+ LOCATIONS[result.key] = { icon, label };
+ _loadConfigPage();
+ } else {
+ showToast(result.error || 'Erreur lors de l\'ajout', 'error');
+ }
+ } catch (e) {
+ showLoading(false);
+ showToast('Erreur lors de l\'ajout', 'error');
+ }
+}
+
+async function updateLocation(key) {
+ const icon = document.getElementById(`loc-icon-${key}`).value.trim() || '📦';
+ const label = document.getElementById(`loc-label-${key}`).value.trim();
+
+ if (!label) {
+ showToast('Le nom ne peut pas être vide', 'warning');
+ return;
+ }
+
+ showLoading(true);
+ try {
+ const result = await api('locations_update', {}, 'POST', { key, label, icon });
+ showLoading(false);
+ if (result.success) {
+ showToast('Emplacement mis à jour', 'success');
+ LOCATIONS[key] = { icon, label };
+ } else {
+ showToast(result.error || 'Erreur', 'error');
+ }
+ } catch (e) {
+ showLoading(false);
+ showToast('Erreur', 'error');
+ }
+}
+
+async function removeLocation(key) {
+ if (!confirm(`Supprimer l'emplacement "${LOCATIONS[key]?.label || key}" ?`)) return;
+
+ showLoading(true);
+ try {
+ const result = await api('locations_remove', {}, 'POST', { key });
+ showLoading(false);
+ if (result.success) {
+ showToast('Emplacement supprimé', 'success');
+ delete LOCATIONS[key];
+ _loadConfigPage();
+ } else {
+ showToast(result.error || 'Impossible de supprimer', 'error');
+ }
+ } catch (e) {
+ showLoading(false);
+ showToast('Erreur lors de la suppression', 'error');
+ }
+}
+
const CATEGORY_ICONS = {
'latticini': '🥛', 'carne': '🥩', 'pesce': '🐟', 'frutta': '🍎',
'verdura': '🥬', 'pasta': '🍝', 'pane': '🍞', 'surgelati': '🧊',