"use client"; import { useState } from "react"; import { useRouter } from "next/navigation"; import { Wand2, Loader2, X } from "lucide-react"; import { toast } from "sonner"; import { Button } from "@/components/ui/button"; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, } from "@/components/ui/dialog"; import { Textarea } from "@/components/ui/textarea"; import { Label } from "@/components/ui/label"; import { cn } from "@/lib/utils"; type Ingredient = { rawName: string }; export function AdaptRecipeButton({ recipeId, ingredients, }: { recipeId: string; ingredients: Ingredient[]; }) { const router = useRouter(); const [open, setOpen] = useState(false); const [excluded, setExcluded] = useState>(new Set()); const [extraConstraints, setExtraConstraints] = useState(""); const [adapting, setAdapting] = useState(false); const [adaptationNotes, setAdaptationNotes] = useState(""); function toggleExclude(name: string) { setExcluded((prev) => { const next = new Set(prev); if (next.has(name)) next.delete(name); else next.add(name); return next; }); } function reset() { setExcluded(new Set()); setExtraConstraints(""); setAdaptationNotes(""); } async function handleAdapt() { if (excluded.size === 0 && !extraConstraints.trim()) { toast.error("Select at least one ingredient to exclude or add a constraint"); return; } setAdapting(true); setAdaptationNotes(""); try { const res = await fetch(`/api/v1/ai/adapt/${recipeId}`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ excludeIngredients: Array.from(excluded), extraConstraints: extraConstraints.trim() || undefined, }), }); if (!res.ok) { const err = await res.json() as { error?: string }; toast.error(err.error ?? "Failed to adapt recipe"); return; } const { id, adaptationNotes: notes } = await res.json() as { id: string; adaptationNotes: string }; setAdaptationNotes(notes); toast.success("Adapted recipe saved as draft"); setOpen(false); reset(); router.push(`/recipes/${id}/edit`); } finally { setAdapting(false); } } const hasConstraints = excluded.size > 0 || extraConstraints.trim().length > 0; return ( <> { setOpen(v); if (!v) reset(); }}> Adapt this recipe Tap ingredients to exclude them. AI will find the best substitutes while preserving the dish.
{/* Ingredient chips */}
{ingredients.map((ing, idx) => { const isExcluded = excluded.has(ing.rawName); return ( ); })}
{/* Free-text constraints */}