From ba807d9b16d6e0cdd005f3ab749b124c40512f48 Mon Sep 17 00:00:00 2001 From: patrick-ouano Date: Sun, 25 Jan 2026 02:24:48 -0500 Subject: [PATCH 1/5] Add cost fields to recipe generation prompt --- src/app/api/generate/route.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/app/api/generate/route.ts b/src/app/api/generate/route.ts index d77d5d6..921f948 100644 --- a/src/app/api/generate/route.ts +++ b/src/app/api/generate/route.ts @@ -110,12 +110,16 @@ Use this exact structure: "protein": 30, "carbs": 45, "fat": 20 - } + }, + "estimatedCost": 12.50, + "takeoutEquivalent": 25.00 } ] } -Generate 5 diverse recipes with realistic nutritional information. Make them practical and delicious.`, +Generate 5 diverse recipes with realistic nutritional information. Make them practical and delicious. + +For each recipe, include estimatedCost (realistic total grocery cost for ingredients in USD) and takeoutEquivalent (what a similar meal would cost at a restaurant or delivery service in USD). Be realistic with pricing.`, }, ], }, From 1c9f2bc2102cd139c3fd0a74fc279889d2f74296 Mon Sep 17 00:00:00 2001 From: patrick-ouano Date: Sun, 25 Jan 2026 02:27:22 -0500 Subject: [PATCH 2/5] Add estimatedCost and takeoutEquivalent to Recipe Interface --- src/app/generate/page.tsx | 2 ++ src/components/RecipeCard.tsx | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/app/generate/page.tsx b/src/app/generate/page.tsx index 6afca5b..0c7d4af 100644 --- a/src/app/generate/page.tsx +++ b/src/app/generate/page.tsx @@ -21,6 +21,8 @@ interface Recipe { carbs: number; fat: number; }; + estimatedCost: number; + takeoutEquivalent: number; } export default function GeneratePage() { diff --git a/src/components/RecipeCard.tsx b/src/components/RecipeCard.tsx index 423f5f1..792195a 100644 --- a/src/components/RecipeCard.tsx +++ b/src/components/RecipeCard.tsx @@ -18,6 +18,8 @@ interface Recipe { carbs: number; fat: number; }; + estimatedCost: number; + takeoutEquivalent: number; } interface RecipeCardProps { From 27c51e96e0eeeeddf4d802b61d38c1dd4e46ed92 Mon Sep 17 00:00:00 2001 From: patrick-ouano Date: Sun, 25 Jan 2026 02:30:53 -0500 Subject: [PATCH 3/5] Display cost savings on recipe cards and update copy function --- src/components/RecipeCard.tsx | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/components/RecipeCard.tsx b/src/components/RecipeCard.tsx index 792195a..3ad150b 100644 --- a/src/components/RecipeCard.tsx +++ b/src/components/RecipeCard.tsx @@ -35,6 +35,7 @@ export default function RecipeCard({ recipe }: RecipeCardProps) { const playPageBack = usePageBackSound(); const handleCopy = async () => { + const savings = recipe.takeoutEquivalent - recipe.estimatedCost; const recipeText = ` ${recipe.name} @@ -42,6 +43,8 @@ ${recipe.description} Nutrition: ${recipe.macros.calories} cal | ${recipe.macros.protein}g protein | ${recipe.macros.carbs}g carbs | ${recipe.macros.fat}g fat +Cost: ~$${recipe.estimatedCost.toFixed(2)} | Takeout: ~$${recipe.takeoutEquivalent.toFixed(2)} | You save: $${savings.toFixed(2)} + Ingredients: ${recipe.ingredients.map((ing) => `• ${ing}`).join("\n")} @@ -107,6 +110,19 @@ ${recipe.instructions.map((step, i) => `${i + 1}. ${step}`).join("\n")} ))} + {/* Cost Savings */} +
+ + 💰 Cost: ~${recipe.estimatedCost.toFixed(2)} + + + 🍔 Takeout: ~${recipe.takeoutEquivalent.toFixed(2)} + + + ✅ You save: ${(recipe.takeoutEquivalent - recipe.estimatedCost).toFixed(2)} + +
+ {/* Ingredients */}

- Ingredients -

From e8d3205f4c379fe62c891bc9c6fc80cdfa469577 Mon Sep 17 00:00:00 2001 From: patrick-ouano Date: Sun, 25 Jan 2026 02:41:41 -0500 Subject: [PATCH 4/5] Implemented cost breakdown button --- src/components/RecipeCard.tsx | 42 ++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/src/components/RecipeCard.tsx b/src/components/RecipeCard.tsx index 3ad150b..3c79e51 100644 --- a/src/components/RecipeCard.tsx +++ b/src/components/RecipeCard.tsx @@ -30,6 +30,7 @@ export default function RecipeCard({ recipe }: RecipeCardProps) { const [isOpen, setIsOpen] = useState(false); const [copied, setCopied] = useState(false); const [detailedInstructions, setDetailedInstructions] = useState(null); + const [showCostBreakdown, setShowCostBreakdown] = useState(false); const playClick = useClickSound(); const playPageTurn = usePageTurnSound(); const playPageBack = usePageBackSound(); @@ -110,19 +111,6 @@ ${recipe.instructions.map((step, i) => `${i + 1}. ${step}`).join("\n")} ))}
- {/* Cost Savings */} -
- - 💰 Cost: ~${recipe.estimatedCost.toFixed(2)} - - - 🍔 Takeout: ~${recipe.takeoutEquivalent.toFixed(2)} - - - ✅ You save: ${(recipe.takeoutEquivalent - recipe.estimatedCost).toFixed(2)} - -
- {/* Ingredients */}

- Ingredients -

@@ -141,6 +129,34 @@ ${recipe.instructions.map((step, i) => `${i + 1}. ${step}`).join("\n")} detailedInstructions={detailedInstructions} onDetailedInstructionsLoaded={setDetailedInstructions} /> + + {/* Cost Breakdown */} +
+ + + {showCostBreakdown && ( +
+ + 🛒 Grocery Cost: ~${recipe.estimatedCost.toFixed(2)} + + + 🍔 Takeout Equivalent: ~${recipe.takeoutEquivalent.toFixed(2)} + + + ✅ You Save: ${(recipe.takeoutEquivalent - recipe.estimatedCost).toFixed(2)} + +
+ )} +
)}
From e7762f2102f28b6832e3fef1afee2d8e3abea1ef Mon Sep 17 00:00:00 2001 From: patrick-ouano Date: Sun, 25 Jan 2026 02:43:59 -0500 Subject: [PATCH 5/5] Fixed placement of cost breakdown button --- src/components/InstructionsSection.tsx | 44 ++++++++++++--------- src/components/RecipeCard.tsx | 53 +++++++++++++------------- 2 files changed, 52 insertions(+), 45 deletions(-) diff --git a/src/components/InstructionsSection.tsx b/src/components/InstructionsSection.tsx index d2cbe69..17f712d 100644 --- a/src/components/InstructionsSection.tsx +++ b/src/components/InstructionsSection.tsx @@ -1,6 +1,6 @@ "use client"; -import { useState } from "react"; +import { useState, ReactNode } from "react"; interface InstructionsSectionProps { recipeName: string; @@ -8,6 +8,7 @@ interface InstructionsSectionProps { instructions: string[]; detailedInstructions: string[] | null; onDetailedInstructionsLoaded: (instructions: string[]) => void; + additionalButtons?: ReactNode; } export default function InstructionsSection({ @@ -16,6 +17,7 @@ export default function InstructionsSection({ instructions, detailedInstructions, onDetailedInstructionsLoaded, + additionalButtons, }: InstructionsSectionProps) { const [isLoadingDetails, setIsLoadingDetails] = useState(false); const [detailsError, setDetailsError] = useState(null); @@ -61,24 +63,30 @@ export default function InstructionsSection({ ))} - {/* Detailed Instructions Button */} - {!detailedInstructions && ( - - )} + {/* Action Buttons Row */} +
+ {/* Detailed Instructions Button */} + {!detailedInstructions && ( + + )} - {/* Show label when detailed instructions are displayed */} - {detailedInstructions && ( -

✓ Showing detailed instructions

- )} + {/* Show label when detailed instructions are displayed */} + {detailedInstructions && ( +

✓ Showing detailed instructions

+ )} + + {/* Additional buttons passed from parent */} + {additionalButtons} +
{/* Error message */} {detailsError &&

{detailsError}

} diff --git a/src/components/RecipeCard.tsx b/src/components/RecipeCard.tsx index 3c79e51..6697d72 100644 --- a/src/components/RecipeCard.tsx +++ b/src/components/RecipeCard.tsx @@ -128,35 +128,34 @@ ${recipe.instructions.map((step, i) => `${i + 1}. ${step}`).join("\n")} instructions={recipe.instructions} detailedInstructions={detailedInstructions} onDetailedInstructionsLoaded={setDetailedInstructions} + additionalButtons={ + + } /> - {/* Cost Breakdown */} -
- - - {showCostBreakdown && ( -
- - 🛒 Grocery Cost: ~${recipe.estimatedCost.toFixed(2)} - - - 🍔 Takeout Equivalent: ~${recipe.takeoutEquivalent.toFixed(2)} - - - ✅ You Save: ${(recipe.takeoutEquivalent - recipe.estimatedCost).toFixed(2)} - -
- )} -
+ {/* Cost Breakdown Content */} + {showCostBreakdown && ( +
+ + 🛒 Grocery Cost: ~${recipe.estimatedCost.toFixed(2)} + + + 🍔 Takeout Equivalent: ~${recipe.takeoutEquivalent.toFixed(2)} + + + ✅ You Save: ${(recipe.takeoutEquivalent - recipe.estimatedCost).toFixed(2)} + +
+ )} )}