diff --git a/frontend/components/Domain/Recipe/RecipePage/RecipePageParts/RecipePageInstructions.vue b/frontend/components/Domain/Recipe/RecipePage/RecipePageParts/RecipePageInstructions.vue
index 2867b9d62..9b2076b3f 100644
--- a/frontend/components/Domain/Recipe/RecipePage/RecipePageParts/RecipePageInstructions.vue
+++ b/frontend/components/Domain/Recipe/RecipePage/RecipePageParts/RecipePageInstructions.vue
@@ -29,32 +29,49 @@
{{ activeText }}
-
-
-
-
-
-
-
+
- {{ $t("recipe.linked-to-other-step") }}
+ {{ $t("recipe.unlinked") }}
+
+
+
+ {{ title }}
+
+
+
+
+ {{ $t("recipe.linked-to-other-step") }}
+
+
+
+ {{ title }}
+
+
+
+
+
+
+
+
@@ -563,6 +580,71 @@ const ingredientLookup = computed(() => {
}, results);
});
+// Map each ingredient's referenceId to its section title
+const ingredientSectionTitles = computed(() => {
+ const titleMap: { [key: string]: string } = {};
+ let currentTitle = "";
+
+ // Go through all ingredients in order
+ props.recipe.recipeIngredient.forEach((ingredient) => {
+ if (ingredient.referenceId === undefined) {
+ return;
+ }
+
+ // If this ingredient has a title, update the current title
+ if (ingredient.title) {
+ currentTitle = ingredient.title;
+ }
+
+ // Assign the current title to this ingredient
+ titleMap[ingredient.referenceId] = currentTitle;
+ });
+
+ return titleMap;
+});
+
+const groupedUnusedIngredients = computed(() => {
+ const groups: { [key: string]: RecipeIngredient[] } = {};
+
+ // Group ingredients by section title
+ unusedIngredients.value.forEach((ingredient) => {
+ if (ingredient.referenceId === undefined) {
+ return;
+ }
+
+ // Use the section title from the mapping, or fallback to the ingredient's own title
+ const title = ingredientSectionTitles.value[ingredient.referenceId] || ingredient.title || "";
+
+ if (!groups[title]) {
+ groups[title] = [];
+ }
+ groups[title].push(ingredient);
+ });
+
+ return groups;
+});
+
+const groupedUsedIngredients = computed(() => {
+ const groups: { [key: string]: RecipeIngredient[] } = {};
+
+ // Group ingredients by section title
+ usedIngredients.value.forEach((ingredient) => {
+ if (ingredient.referenceId === undefined) {
+ return;
+ }
+
+ // Use the section title from the mapping, or fallback to the ingredient's own title
+ const title = ingredientSectionTitles.value[ingredient.referenceId] || ingredient.title || "";
+
+ if (!groups[title]) {
+ groups[title] = [];
+ }
+ groups[title].push(ingredient);
+ });
+
+ return groups;
+});
+
function getIngredientByRefId(refId: string | undefined) {
if (refId === undefined) {
return "";
diff --git a/frontend/composables/recipes/use-recipe-ingredients.ts b/frontend/composables/recipes/use-recipe-ingredients.ts
index 867fed639..00ee9f55b 100644
--- a/frontend/composables/recipes/use-recipe-ingredients.ts
+++ b/frontend/composables/recipes/use-recipe-ingredients.ts
@@ -37,7 +37,7 @@ function useUnitName(unit: CreateIngredientUnit | IngredientUnit | undefined, us
}
export function useParsedIngredientText(ingredient: RecipeIngredient, scale = 1, includeFormating = true) {
- const { quantity, food, unit, note } = ingredient;
+ const { quantity, food, unit, note, title } = ingredient;
const usePluralUnit = quantity !== undefined && ((quantity || 0) * scale > 1 || (quantity || 0) * scale === 0);
const usePluralFood = (!quantity) || quantity * scale > 1;
@@ -66,6 +66,7 @@ export function useParsedIngredientText(ingredient: RecipeIngredient, scale = 1,
const foodName = useFoodName(food || undefined, usePluralFood);
return {
+ title: title ? sanitizeIngredientHTML(title) : undefined,
quantity: returnQty ? sanitizeIngredientHTML(returnQty) : undefined,
unit: unitName && quantity ? sanitizeIngredientHTML(unitName) : undefined,
name: foodName ? sanitizeIngredientHTML(foodName) : undefined,
diff --git a/frontend/lang/messages/en-US.json b/frontend/lang/messages/en-US.json
index 08b98b58c..4193f54e2 100644
--- a/frontend/lang/messages/en-US.json
+++ b/frontend/lang/messages/en-US.json
@@ -561,6 +561,7 @@
"see-original-text": "See Original Text",
"original-text-with-value": "Original Text: {originalText}",
"ingredient-linker": "Ingredient Linker",
+ "unlinked": "Not linked yet",
"linked-to-other-step": "Linked to other step",
"auto": "Auto",
"cook-mode": "Cook Mode",