feat: one-click shopping list from meal plan, fix ingredient merge bug

- Meal-plan page now has a direct "Add to shopping list" action for the
  currently-viewed week, instead of requiring a trip to Shopping Lists and
  manually typing the week's Monday date.
- Fixed a real under-shopping bug in shopping-lists/route.ts: when
  generating from a meal-plan week, ingredients appearing in more than one
  recipe were merged by keeping only the FIRST occurrence's quantity and
  silently dropping the rest. New mergeIngredients() (pantry-shopping-match.ts)
  groups by ingredientId (or normalized name+unit) and sums quantities
  across every recipe in the week; incompatible/unparseable units are kept
  as separate line items rather than guessed at.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Arnaud
2026-07-10 09:45:51 +02:00
parent 9c545a5bb3
commit d62e2a6383
6 changed files with 104 additions and 28 deletions
+5
View File
@@ -7,6 +7,7 @@ import { db, mealPlans, mealPlanMembers, recipes, userNutritionGoals, eq, and, d
import { buttonVariants } from "@/components/ui/button";
import { MealPlanner } from "@/components/meal-plan/meal-planner";
import { ShareMealPlanButton } from "@/components/meal-plan/share-meal-plan-button";
import { NewShoppingListButton } from "@/components/meal-plan/new-shopping-list-button";
import { WeeklyNutritionBar } from "@/components/nutrition/weekly-nutrition-bar";
import { cn } from "@/lib/utils";
import { ExportMarkdownButton } from "@/components/shared/export-markdown-button";
@@ -100,6 +101,10 @@ export default async function MealPlanPage({
</div>
<div className="flex flex-wrap items-center gap-2">
<ShareMealPlanButton weekStart={weekStart} />
<NewShoppingListButton
defaultWeekStart={weekStart}
defaultName={formatMessage(msgs.mealPlan.shoppingListWeekName, { week: label })}
/>
<Link href="/shopping-lists" className={cn(buttonVariants({ variant: "outline", size: "sm" }))}>
<ShoppingCart className="h-4 w-4" />
{msgs.mealPlan.shoppingLists}