"use client"; import { useState } from "react"; import { Shuffle, Loader2 } from "lucide-react"; import { Popover, PopoverContent, PopoverTrigger, } from "@/components/ui/popover"; import { Badge } from "@/components/ui/badge"; type Substitution = { name: string; ratio: string; note: string; flavorImpact: "minimal" | "moderate" | "significant"; }; const IMPACT_VARIANT = { minimal: "default", moderate: "secondary", significant: "destructive", } as const; export function SubstituteIngredientPopover({ ingredient, recipeTitle, }: { ingredient: string; recipeTitle: string; }) { const [open, setOpen] = useState(false); const [loading, setLoading] = useState(false); const [substitutions, setSubstitutions] = useState([]); const [fetched, setFetched] = useState(false); const [error, setError] = useState(null); async function fetchSubstitutions() { if (fetched) return; setLoading(true); setError(null); try { const res = await fetch("/api/v1/ai/substitute", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ ingredient, recipeTitle }), }); if (!res.ok) { const body = await res.json().catch(() => null) as { error?: string } | null; setError(body?.error ?? "Couldn't fetch substitutes."); return; } const data = await res.json() as { substitutions: Substitution[] }; setSubstitutions(data.substitutions); setFetched(true); } catch { setError("Couldn't fetch substitutes."); } finally { setLoading(false); } } function handleOpen(v: boolean) { setOpen(v); if (v && !fetched) fetchSubstitutions(); } return (

Substitutes for {ingredient}

{loading && (
Finding substitutes…
)} {!loading && substitutions.length > 0 && (
{substitutions.map((sub, i) => (
{sub.name} {sub.ratio} {sub.flavorImpact}

{sub.note}

))}
)} {!loading && error && (

{error}

)} {!loading && fetched && substitutions.length === 0 && (

No substitutions found.

)}
); }