diff --git a/public/locales/de.json b/public/locales/de.json index 896e14f..382cbcf 100644 --- a/public/locales/de.json +++ b/public/locales/de.json @@ -319,7 +319,9 @@ "savedRecipePlaceholder": "Rezept auswählen", "saveAsRecipe": "Als Rezept speichern", "recipeScaleLabel": "Zutaten skalieren", - "deletedToast": "Mahlzeit gelöscht" + "deletedToast": "Mahlzeit gelöscht", + "cookLabel": "Koch/Köchin", + "cookNone": "Keine Koch-Zuweisung" }, "calendar": { "title": "Kalender", diff --git a/public/locales/en.json b/public/locales/en.json index ee436b7..596ff06 100644 --- a/public/locales/en.json +++ b/public/locales/en.json @@ -313,7 +313,9 @@ "savedRecipePlaceholder": "Select recipe", "saveAsRecipe": "Save as recipe", "recipeScaleLabel": "Scale ingredients", - "deletedToast": "Meal deleted" + "deletedToast": "Meal deleted", + "cookLabel": "Cook", + "cookNone": "No assigned cook" }, "calendar": { "title": "Calendar", diff --git a/public/pages/meals.js b/public/pages/meals.js index b2ebb6a..167cd1c 100644 --- a/public/pages/meals.js +++ b/public/pages/meals.js @@ -38,6 +38,7 @@ let state = { currentWeek: null, // YYYY-MM-DD (Montag) meals: [], recipes: [], + familyMembers: [], // Familienmitglieder für Koch-Zuweisung lists: [], // Einkaufslisten für Transfer-Dropdown categories: [], // Einkaufskategorien für Zutaten modal: null, @@ -126,6 +127,15 @@ async function loadRecipes() { } } +async function loadFamilyMembers() { + try { + const res = await api.get('/family/members'); + state.familyMembers = res.data; + } catch { + state.familyMembers = []; + } +} + async function loadPreferences() { try { const res = await api.get('/preferences'); @@ -169,7 +179,7 @@ export async function render(container, { user }) { const today = new Date().toISOString().slice(0, 10); const monday = getMondayOf(today); - await Promise.all([loadWeek(monday), loadLists(), loadPreferences(), loadCategories(), loadRecipes()]); + await Promise.all([loadWeek(monday), loadLists(), loadPreferences(), loadCategories(), loadRecipes(), loadFamilyMembers()]); renderWeekGrid(); wireNav(); @@ -252,6 +262,7 @@ function renderSlot(date, type, mealsForDay) { const ingLabel = ingCount > 0 ? (ingCount !== 1 ? t('meals.ingredientCountPlural', { count: ingCount }) : t('meals.ingredientCount', { count: ingCount })) : ''; const ingDoneLabel = ingCount > 0 && ingDone === ingCount ? ' ✓' : ''; const canTransfer = ingCount > 0 && ingDone < ingCount; + const cookName = meal.cook_assignment?.cook_name; return `
@@ -261,8 +272,9 @@ function renderSlot(date, type, mealsForDay) { data-meal-id="${meal.id}" role="button" tabindex="0">
${esc(meal.title)}
- ${ingLabel ? `
- ${ingLabel}${esc(ingDoneLabel)} + ${(ingLabel || cookName) ? `
+ ${ingLabel ? `${ingLabel}${esc(ingDoneLabel)}` : ''} + ${cookName ? `${esc(cookName)}` : ''}
` : ''}
${meal.recipe_url ? ` ``), ].join(''); + const selectedCookId = isEdit && meal.cook_assignment?.user_id ? String(meal.cook_assignment.user_id) : ''; + const cookOptions = [ + ``, + ...state.familyMembers.map((member) => ``), + ].join(''); + return ` +
+ + +
+
i.id)); diff --git a/public/styles/meals.css b/public/styles/meals.css index 8c714f5..bf40a20 100644 --- a/public/styles/meals.css +++ b/public/styles/meals.css @@ -461,3 +461,11 @@ transform: none; } } + +.meal-card__cook { + display: inline-flex; + align-items: center; + gap: 0.25rem; + color: var(--color-text-secondary); + font-weight: 600; +} diff --git a/server/routes/meals.js b/server/routes/meals.js index c4aa75c..8ddec35 100644 --- a/server/routes/meals.js +++ b/server/routes/meals.js @@ -87,6 +87,14 @@ function saveCookAssignment(meal, cookUserId, sourcePlanId, createdBy) { `).run(meal.id, cookUserId, meal.date, meal.meal_type, sourcePlanId || null, createdBy); } +function syncCookAssignmentSlot(meal) { + db.get().prepare(` + UPDATE planned_meal_cooks + SET planned_for_date = ?, meal_type = ?, updated_at = strftime('%Y-%m-%dT%H:%M:%SZ', 'now') + WHERE meal_id = ? + `).run(meal.date, meal.meal_type, meal.id); +} + // -------------------------------------------------------- // Routen - Mahlzeiten-Vorschläge (vor dynamischen Routen!) // -------------------------------------------------------- @@ -321,6 +329,8 @@ router.put('/:id', (req, res) => { if (vCookUserId.present) { saveCookAssignment(updated, vCookUserId.value, vSourcePlanId.value, req.session.userId); + } else { + syncCookAssignmentSlot(updated); } const ings = db.get().prepare(