fix recalculating ingredients

This commit is contained in:
Anika Raemer 2025-09-08 18:58:48 +02:00
parent f23aab4b3f
commit 3eefa41a28
3 changed files with 26 additions and 10 deletions

View file

@ -18,17 +18,23 @@ export default function RecipeDetailView() {
return <p className="p-6">Recipe not found.</p> return <p className="p-6">Recipe not found.</p>
} }
// Working copy for re-calculating ingredients // Working copy for re-calculating ingredients
const [recipeWorkingCopy, updateRecipeWorkingCopy] = useState<Recipe>(recipe) const [recipeWorkingCopy, updateRecipeWorkingCopy] = useState<Recipe>(recipe)
// Keep original immutable for scaling
const [originalRecipe] = useState<Recipe>(recipe)
/** recalculate ingredients based on the amount of servings */
const recalculateIngredients = (newAmount: number) => { const recalculateIngredients = (newAmount: number) => {
// Always calculate factor from the *original recipe*, not the working copy // Always calculate factor from the *original recipe*, not the working copy
const factor = newAmount / recipe.servings.amount const factor = newAmount / originalRecipe.servings.amount
// Create a new ingredient list with updated amounts // Create a new ingredient list with updated amounts
const updatedIngredients = recipe.ingredients.map((ing) => ({ const updatedIngredientGroupList = recipe.ingredientGroupList.map((ingGrp) => ({
...ing, ...ingGrp,
amount: ing.amount * factor, ingredientList: ingGrp.ingredientList.map((ing) => ({
...ing,
amount: ing.amount * factor,
}))
})) }))
// Update working copy with new servings + recalculated ingredients // Update working copy with new servings + recalculated ingredients
@ -38,10 +44,10 @@ export default function RecipeDetailView() {
...recipeWorkingCopy.servings, ...recipeWorkingCopy.servings,
amount: newAmount, amount: newAmount,
}, },
ingredients: updatedIngredients, ingredientGroupList: updatedIngredientGroupList,
}) })
} }
// @todo add a feature to recalculate ingredients based on servings
return ( return (
<div className="p-6 max-w-2xl mx-auto"> <div className="p-6 max-w-2xl mx-auto">
<h1 className="content-title">{recipeWorkingCopy.title}</h1> <h1 className="content-title">{recipeWorkingCopy.title}</h1>
@ -72,8 +78,9 @@ export default function RecipeDetailView() {
{/* Ingredients */} {/* Ingredients */}
<h2 className="section-heading">Zutaten</h2> <h2 className="section-heading">Zutaten</h2>
<ul> <ul>
{recipe.ingredientGroupList.map((group,i) => ( {recipeWorkingCopy.ingredientGroupList.map((group,i) => (
<div key={i}> <div key={i}>
{/* the title is optional, only print if present */}
{group.title && group.title.trim() !== "" && ( {group.title && group.title.trim() !== "" && (
<h3 className="subsection-heading">{group.title}</h3> <h3 className="subsection-heading">{group.title}</h3>
)} )}

View file

@ -53,7 +53,6 @@ export default function RecipeEditor({ recipe, onSave, onCancel }: RecipeEditorP
return !ingGrp.ingredientList || ingGrp.ingredientList.length === 0 return !ingGrp.ingredientList || ingGrp.ingredientList.length === 0
} }
) )
console.log(isAnyIngredientListEmpty)
if(isAnyIngredientListEmpty){ if(isAnyIngredientListEmpty){
newErrors.ingredients = true newErrors.ingredients = true
} }

View file

@ -3,5 +3,15 @@
"references": [ "references": [
{ "path": "./tsconfig.app.json" }, { "path": "./tsconfig.app.json" },
{ "path": "./tsconfig.node.json" } { "path": "./tsconfig.node.json" }
] ],
"compilerOptions": {
"strict": true,
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "Node",
"jsx": "react-jsx",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"skipLibCheck": true
}
} }