"use client" import { useState } from "react" import Link from "next/link" import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" import { Badge } from "@/components/ui/badge" import { Button } from "@/components/ui/button" import { Check, X, ChevronDown, ChevronUp, Bookmark, Trash2, GlassWater, Loader2, Star, Clock, } from "lucide-react" import { cn } from "@/lib/utils" import type { RecipeIngredient } from "@/hooks/use-bartender" export interface RecipeCardData { id?: string title: string ingredients: RecipeIngredient[] steps: string[] garnish?: string | null glassware?: string | null notes?: string | null missingCount?: number sourceDrink?: { id: string; name: string; type: string } | null } export type PromoteTarget = "drink" | "wishlist" interface RecipeCardProps { recipe: RecipeCardData onSave?: (recipe: RecipeCardData) => void onDelete?: (id: string) => void onPromote?: (id: string, target: PromoteTarget) => void isSaving?: boolean isDeleting?: boolean /** Which promotion is in flight for this card, if any. */ promoting?: PromoteTarget | null saved?: boolean } export function RecipeCard({ recipe, onSave, onDelete, onPromote, isSaving, isDeleting, promoting, saved, }: RecipeCardProps) { const [expanded, setExpanded] = useState(false) const availableCount = recipe.ingredients.filter((i) => i.available).length const totalCount = recipe.ingredients.length return (
{recipe.title}
{recipe.missingCount !== undefined && ( {recipe.missingCount === 0 ? "Ready" : `Missing ${recipe.missingCount}`} )} {!saved && onSave && ( )} {saved && recipe.id && onDelete && ( )}
{recipe.glassware && (
{recipe.glassware}
)}
{/* Ingredients */}

Ingredients

{availableCount}/{totalCount} available
    {recipe.ingredients.map((ing, i) => (
  • {ing.available ? ( ) : ( )} {ing.amount} {ing.name}
  • ))}
{/* Garnish */} {recipe.garnish && (

Garnish:{" "} {recipe.garnish}

)} {/* Expandable Steps */}
{expanded && (
    {recipe.steps.map((step, i) => (
  1. {i + 1} {step}
  2. ))}
)}
{/* Notes */} {expanded && recipe.notes && (

{recipe.notes}

)} {/* A recipe is instructions; a drink is the thing you have an opinion about. Promoting links the two rather than converting, so the recipe stays here and also shows on the drink's page. */} {saved && recipe.id && onPromote && (
{recipe.sourceDrink ? ( ) : ( )}
)} {recipe.sourceDrink && (

In your drinks as{" "} {recipe.sourceDrink.name}

)}
) }