>(new Set());
const [adding, setAdding] = useState<{ day: Day; mealType: MealType } | null>(null);
const [showAiModal, setShowAiModal] = useState(false);
const [aiGenerating, setAiGenerating] = useState(false);
@@ -236,6 +239,32 @@ export function MealPlanner({
}
}
+ async function markCooked(entry: Entry) {
+ if (!entry.recipe || markingCookedIds.has(entry.id)) return;
+ setMarkingCookedIds((prev) => new Set(prev).add(entry.id));
+ try {
+ const res = await fetch(`/api/v1/recipes/${entry.recipe.id}/cooked`, {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify({ servings: entry.servings, deductFromPantry: false }),
+ });
+ if (!res.ok) {
+ toast.error(t("markCookedFailed"));
+ return;
+ }
+ setCookedIds((prev) => new Set(prev).add(entry.id));
+ toast.success(t("markCookedSuccess"));
+ } catch {
+ toast.error(t("markCookedFailed"));
+ } finally {
+ setMarkingCookedIds((prev) => {
+ const next = new Set(prev);
+ next.delete(entry.id);
+ return next;
+ });
+ }
+ }
+
const addingDay = adding ? DAYS.find((d) => d.key === adding.day) : null;
const addingMeal = adding ? MEAL_TYPES.find((m) => m.key === adding.mealType) : null;
@@ -277,14 +306,35 @@ export function MealPlanner({
{entry?.recipe ? (
- {entry.recipe.title}
- {t("servingsAbbrev", { count: entry.servings })}
-
+ {entry.recipe.title}
+
+ {t("servingsAbbrev", { count: entry.servings })}
+ {cookedIds.has(entry.id) && (
+
+ )}
+
+
+
+
+
+
) : (
|