"use client"; import { cloneElement, isValidElement, useState, type ReactElement } from "react"; import { useTranslations } from "next-intl"; import { toast } from "sonner"; import { ChefHat } from "lucide-react"; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Switch } from "@/components/ui/switch"; function todayIso(): string { return new Date().toISOString().slice(0, 10); } interface MarkCookedDialogProps { recipeId: string; baseServings: number; batchDishId?: string; trigger: React.ReactNode; onLogged?: (cookedAt: string) => void; } /** Logs a cook event — date, servings, and whether to deduct matching * ingredients from the pantry (default on). A recipe can be logged as * cooked any number of times; each submission is a new row, never an * update. */ export function MarkCookedDialog({ recipeId, baseServings, batchDishId, trigger, onLogged }: MarkCookedDialogProps) { const t = useTranslations("recipe"); const tCommon = useTranslations("common"); const [open, setOpen] = useState(false); const [date, setDate] = useState(todayIso()); const [servings, setServings] = useState(baseServings); const [deductFromPantry, setDeductFromPantry] = useState(true); const [submitting, setSubmitting] = useState(false); async function handleSubmit() { setSubmitting(true); try { const res = await fetch(`/api/v1/recipes/${recipeId}/cooked`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ servings, cookedAt: date, deductFromPantry, ...(batchDishId ? { batchDishId } : {}), }), }); if (!res.ok) throw new Error(); toast.success(t("markCookedSuccess")); setOpen(false); onLogged?.(date); } catch { toast.error(t("markCookedFailed")); } finally { setSubmitting(false); } } const triggerElement = isValidElement(trigger) ? cloneElement(trigger as ReactElement<{ onClick?: () => void }>, { onClick: () => setOpen(true) }) : trigger; return ( <> {triggerElement} {t("markCookedTitle")} {t("markCookedDescription")}
setDate(e.target.value || todayIso())} />
setServings(Math.max(1, Number(e.target.value) || baseServings))} />

{t("markCookedDeductDescription")}

); }