From 4eeb34f8c885f349b8a4ae7fbf11040a96b5026e Mon Sep 17 00:00:00 2001 From: June Date: Mon, 17 Nov 2025 15:07:34 +1300 Subject: [PATCH] Adapt step views! --- .../detail/StepIngredientSideView.astro | 11 ++++ web/src/components/detail/StepView.astro | 60 +++++++++++++++++++ web/src/pages/recipe/[id].astro | 26 +++++--- 3 files changed, 88 insertions(+), 9 deletions(-) create mode 100644 web/src/components/detail/StepIngredientSideView.astro create mode 100644 web/src/components/detail/StepView.astro diff --git a/web/src/components/detail/StepIngredientSideView.astro b/web/src/components/detail/StepIngredientSideView.astro new file mode 100644 index 0000000..c4272ee --- /dev/null +++ b/web/src/components/detail/StepIngredientSideView.astro @@ -0,0 +1,11 @@ +--- +const { ingredients, class: className } = Astro.props; +--- + +
+ {ingredients.map(i => ( +
+

• {i.quantity.value.value} {i.unit || ""} {i.name}

+
+ ))} +
\ No newline at end of file diff --git a/web/src/components/detail/StepView.astro b/web/src/components/detail/StepView.astro new file mode 100644 index 0000000..f79de88 --- /dev/null +++ b/web/src/components/detail/StepView.astro @@ -0,0 +1,60 @@ +--- +import StepIngredientSideView from "@component/detail/StepIngredientSideView" + +const { sections, allIngredients, cookware, timers, class: className } = Astro.props + +// Helper function to render step items +function renderStepText(items, allIngredients, cookware, timers) { + return items.map(item => { + if (item.type === 'text') { + return item.value; + } else if (item.type === 'ingredient') { + const ing = allIngredients[item.index]; + return `${ing.quantity.value.value} ${ing.unit || ''} ${ing.name}`.trim(); + } else if (item.type === 'cookware') { + return cookware[item.index].name; + } else if (item.type === 'timer') { + const timer = timers[item.index]; + return `${timer.duration.value.value} ${timer.unit}`; + } + return ''; + }).join(''); +} + +// Extract ingredients used in each step +function getStepIngredients(items, allIngredients) { + return items + .filter(item => item.type === 'ingredient') + .map(item => allIngredients[item.index]); +} +--- + +
+

Steps

+ {sections.map((section, sectionIndex) => ( +
+ {section.name && ( +

{section.name}

+ )} + {section.content.map((step, stepIndex) => { + const stepIngredients = getStepIngredients(step.items, allIngredients); + const stepText = renderStepText(step.items, allIngredients, cookware, timers); + + return ( +
+

Step {stepIndex + 1}

+ +
+

{stepText}

+ {stepIngredients.length > 0 && ( +
+ +
+ )} +
+
+ ); + })} +
+ ))} +
\ No newline at end of file diff --git a/web/src/pages/recipe/[id].astro b/web/src/pages/recipe/[id].astro index fc78255..bc20368 100644 --- a/web/src/pages/recipe/[id].astro +++ b/web/src/pages/recipe/[id].astro @@ -2,6 +2,7 @@ import Base from "@layout/Base"; import ImageCarousel from "@component/detail/ImageCarousel"; import InfoView from "@component/detail/InfoView"; +import StepView from "@component/detail/StepView"; import IngredientTableView from '@component/detail/IngredientTableView' import { Recipe } from "@tmlmt/cooklang-parser"; @@ -11,7 +12,8 @@ const { id } = Astro.params const pb = await authPB() const re = await pb.collection('recipes').getOne(id as string) -const recipe = new Recipe(re.cooklang) + +let recipeData = new Recipe(re.cooklang) const images = await Promise.all( re.images.map(r => pb.files.getURL(re, r)) @@ -22,24 +24,30 @@ const images = await Promise.all(
-

{recipe.metadata.title ?? "Untitled Recipe"}

+

{recipeData.metadata.title ?? "Untitled Recipe"}

Ingredients

- +
- +