-
{{ step.title }}
-
-
{{ $t("recipe.step-index", { step: index + 1 }) }}
-
+
+
+
+
+ {{ ingredient.title }}
+
+
+
+
+
+ {{ $t("recipe.instructions") }}
+
+
+
+
+ {{ step.title }}
+
+ {{ $t("recipe.step-index", { step: stepIndex + instructionSection.stepOffset + 1 }) }}
+
+
+
+
+
+
+
-
{{ note.title }}
-
+
+
{{ note.title }}
+
+
@@ -52,9 +72,20 @@ import { defineComponent, computed } from "@nuxtjs/composition-api";
// @ts-ignore vue-markdown has no types
import VueMarkdown from "@adapttive/vue-markdown";
import RecipeTimeCard from "~/components/Domain/Recipe/RecipeTimeCard.vue";
-import { Recipe, RecipeIngredient } from "~/types/api-types/recipe";
+import { Recipe, RecipeIngredient, RecipeStep } from "~/types/api-types/recipe";
import { parseIngredientText } from "~/composables/recipes";
+type IngredientSection = {
+ sectionName: string;
+ ingredients: RecipeIngredient[];
+};
+
+type InstructionSection = {
+ sectionName: string;
+ stepOffset: number;
+ instructions: RecipeStep[];
+};
+
export default defineComponent({
components: {
RecipeTimeCard,
@@ -67,6 +98,84 @@ export default defineComponent({
},
},
setup(props) {
+ // Group ingredients by section so we can style them independently
+ const ingredientSections = computed
(() => {
+ if (!props.recipe.recipeIngredient) {
+ return [];
+ }
+
+ return props.recipe.recipeIngredient.reduce((sections, ingredient) => {
+ // if title append new section to the end of the array
+ if (ingredient.title) {
+ sections.push({
+ sectionName: ingredient.title,
+ ingredients: [ingredient],
+ });
+
+ return sections;
+ }
+
+ // append new section if first
+ if (sections.length === 0) {
+ sections.push({
+ sectionName: "",
+ ingredients: [ingredient],
+ });
+
+ return sections;
+ }
+
+ // otherwise add ingredient to last section in the array
+ sections[sections.length - 1].ingredients.push(ingredient);
+ return sections;
+ }, [] as IngredientSection[]);
+ });
+
+ // Group instructions by section so we can style them independently
+ const instructionSections = computed(() => {
+ if (!props.recipe.recipeInstructions) {
+ return [];
+ }
+
+ return props.recipe.recipeInstructions.reduce((sections, step) => {
+ const offset = (() => {
+ if (sections.length === 0) {
+ return 0;
+ }
+
+ const lastOffset = sections[sections.length - 1].stepOffset;
+ const lastNumSteps = sections[sections.length - 1].instructions.length;
+ return lastOffset + lastNumSteps;
+ })();
+
+ // if title append new section to the end of the array
+ if (step.title) {
+ sections.push({
+ sectionName: step.title,
+ stepOffset: offset,
+ instructions: [step],
+ });
+
+ return sections;
+ }
+
+ // append if first element
+ if (sections.length === 0) {
+ sections.push({
+ sectionName: "",
+ stepOffset: offset,
+ instructions: [step],
+ });
+
+ return sections;
+ }
+
+ // otherwise add step to last section in the array
+ sections[sections.length - 1].instructions.push(step);
+ return sections;
+ }, [] as InstructionSection[]);
+ });
+
const hasNotes = computed(() => {
return props.recipe.notes && props.recipe.notes.length > 0;
});
@@ -79,6 +188,8 @@ export default defineComponent({
hasNotes,
parseText,
parseIngredientText,
+ ingredientSections,
+ instructionSections,
};
},
});
@@ -108,18 +219,23 @@ export default defineComponent({