diff --git a/public/pages/meals.js b/public/pages/meals.js index 1e5a0bf..3f3bfa6 100644 --- a/public/pages/meals.js +++ b/public/pages/meals.js @@ -9,6 +9,7 @@ import { openModal as openSharedModal, closeModal as closeSharedModal, selectMod import { stagger } from '/utils/ux.js'; import { t, formatDate } from '/i18n.js'; import { esc } from '/utils/html.js'; +import { DEFAULT_CATEGORY_NAME, categoryLabel } from '/utils/shopping-categories.js'; // -------------------------------------------------------- // Konstanten @@ -26,6 +27,8 @@ const DAY_NAMES = () => [ t('meals.dayFr'), t('meals.daySa'), t('meals.daySo'), ]; +const EXCLUDED_MEAL_CATEGORY_NAMES = new Set(['Haushalt', 'Drogerie', 'Sonstiges']); + // -------------------------------------------------------- // State // -------------------------------------------------------- @@ -73,6 +76,10 @@ function formatDayDate(dateStr) { return formatDate(dateStr); } +function mealCategories() { + return state.categories.filter((c) => !EXCLUDED_MEAL_CATEGORY_NAMES.has(c.name)); +} + // -------------------------------------------------------- // API-Wrapper // -------------------------------------------------------- @@ -564,7 +571,7 @@ function buildModalContent({ mode, date, mealType, meal }) { : ``; const ingRows = isEdit && meal.ingredients?.length - ? meal.ingredients.map((ing) => ingredientRowHTML(ing.name, ing.quantity ?? '', ing.id, ing.category ?? 'Sonstiges')).join('') + ? meal.ingredients.map((ing) => ingredientRowHTML(ing.name, ing.quantity ?? '', ing.id, ing.category ?? DEFAULT_CATEGORY_NAME)).join('') : ''; const hasIngOpen = isEdit && meal.ingredients?.some((i) => !i.on_shopping_list); @@ -630,10 +637,14 @@ function buildModalContent({ mode, date, mealType, meal }) { `; } -function ingredientRowHTML(name, qty, id, category = 'Sonstiges') { - const catOptions = state.categories.length - ? state.categories.map((c) => ``).join('') - : ``; +function ingredientRowHTML(name, qty, id, category = DEFAULT_CATEGORY_NAME) { + const availableCategories = mealCategories(); + const resolvedCategory = availableCategories.some((c) => c.name === category) + ? category + : (availableCategories[0]?.name ?? DEFAULT_CATEGORY_NAME); + const catOptions = availableCategories.length + ? availableCategories.map((c) => ``).join('') + : ``; return `
@@ -669,7 +680,7 @@ async function saveModal(overlay) { overlay.querySelectorAll('.ingredient-row').forEach((row) => { const name = row.querySelector('.ingredient-row__name').value.trim(); const qty = row.querySelector('.ingredient-row__qty').value.trim() || null; - const category = row.querySelector('.ingredient-row__cat')?.value || 'Sonstiges'; + const category = row.querySelector('.ingredient-row__cat')?.value || DEFAULT_CATEGORY_NAME; if (name) ingredients.push({ name, quantity: qty, category, id: row.dataset.ingId || null }); }); diff --git a/public/pages/shopping.js b/public/pages/shopping.js index 1cd43b3..4c7379b 100644 --- a/public/pages/shopping.js +++ b/public/pages/shopping.js @@ -9,6 +9,7 @@ import { stagger, vibrate } from '/utils/ux.js'; import { t } from '/i18n.js'; import { esc } from '/utils/html.js'; import { promptModal, confirmModal } from '/components/modal.js'; +import { DEFAULT_CATEGORY_NAME, categoryLabel } from '/utils/shopping-categories.js'; // -------------------------------------------------------- // Konstanten @@ -19,25 +20,6 @@ const SWIPE_THRESHOLD = 80; // px - Mindestweg für Aktion const SWIPE_MAX_VERT = 12; // px - vertikaler Toleranzbereich const SWIPE_LOCK_VERT = 30; // px - ab diesem Weg gilt es als Scroll -// Übersetzungs-Map für die Standard-Kategorien (DB-Name → i18n-Key) -const DEFAULT_CATEGORY_I18N = { - 'Obst & Gemüse': 'shopping.catFruitVeg', - 'Backwaren': 'shopping.catBakery', - 'Milchprodukte': 'shopping.catDairy', - 'Fleisch & Fisch': 'shopping.catMeatFish', - 'Tiefkühl': 'shopping.catFrozen', - 'Getränke': 'shopping.catDrinks', - 'Haushalt': 'shopping.catHousehold', - 'Drogerie': 'shopping.catDrugstore', - 'Sonstiges': 'shopping.catMisc', -}; - -/** Übersetzten Label für eine Kategorie zurückgeben. */ -function catLabel(name) { - const key = DEFAULT_CATEGORY_I18N[name]; - return key ? t(key) : name; -} - /** Icon für eine Kategorie (aus state.categories, Fallback 'tag'). */ function catIcon(name) { return state.categories.find((c) => c.name === name)?.icon ?? 'tag'; @@ -67,7 +49,7 @@ const state = { function groupItemsByCategory(items) { const grouped = {}; for (const item of items) { - const cat = item.category || (state.categories[0]?.name ?? 'Sonstiges'); + const cat = item.category || (state.categories[0]?.name ?? DEFAULT_CATEGORY_NAME); (grouped[cat] = grouped[cat] || []).push(item); } // In DB-Reihenfolge zurückgeben; unbekannte Kategorien ans Ende @@ -157,7 +139,7 @@ function renderListContent(container) {