Skip to content

Commit

Permalink
feat: generic grouping of steps and mobile view
Browse files Browse the repository at this point in the history
  • Loading branch information
AleksandrSl committed Jan 16, 2025
1 parent 7b07a62 commit fab9e9b
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 42 deletions.
108 changes: 68 additions & 40 deletions src/components/Recipe.astro
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const recipeMessages = getRecipeMessages(locale)
const { time, weight } = createPropertyFormatters(Astro.currentLocale)
const href = getRelativeLocaleUrl(locale, `/recipes/${recipe.method}`)
const DEFAULT_GROUP = Symbol('default')
const formattedSteps = recipe.steps
?.reduce<({ endTime: number; startTime: number; totalWater: number } & Exclude<Entry['data']['steps'], undefined>[number])[]>((acc, step, index) => {
Expand All @@ -43,6 +44,19 @@ const formattedSteps = recipe.steps
totalWater: weight(step.totalWater),
water: weight(step.water)
}))
const groupedSteps = formattedSteps
?.reduce((acc, step) => {
const lastGroup = acc[acc.length - 1]
const group = step.group ?? DEFAULT_GROUP
if (lastGroup && lastGroup[0] === group) {
lastGroup[1].push(step)
} else {
acc.push([group, [step]])
}
return acc
}, [] as [string | typeof DEFAULT_GROUP, typeof formattedSteps][])
---

<div class="root">
Expand All @@ -52,39 +66,29 @@ const formattedSteps = recipe.steps
<RecipeProperties properties={recipe.properties} />
<div>
{
formattedSteps
groupedSteps
? (
<>
<h2>Recipe</h2>
<table>
<tbody>
<tr>
<td colspan="3">
<span class="recipe-steps-subheader">{recipeMessages.prewetting}</span>
</td>
</tr>
<tr>
<td>{formattedSteps[0].startTime} &rArr; {formattedSteps[0].endTime}</td>
<td>{formattedSteps[0].totalWater}</td>
<td>{formattedSteps[0].description}</td>
</tr>
<tr>
<td colspan="3">
<span class="recipe-steps-subheader">{recipeMessages.infusions}</span>
</td>
</tr>
{formattedSteps.slice(1).map(it => {
return (
<tr>
<td>{it.startTime} &rArr; {it.endTime}</td>
<td>{it.totalWater}</td>
<td>{it.description}</td>
</tr>
)
})}
</tbody>
</table>
</>
<div class="recipe-steps">
<div class="cell cell--header cell--first">{recipeMessages.startTime}</div>
<div class="cell cell--header cell--last">{recipeMessages.totalWeight}</div>
{groupedSteps.map(([group, steps]) =>
(
<>
{group !== DEFAULT_GROUP
? <div class="recipe-steps-subheader">{group}</div>
: null}
{steps.map(step => (
<>
<div class="cell cell--first">{step.startTime}</div>
<div class="cell">{step.totalWater}</div>
<div class="cell cell--description">{step.description}</div>
</>))}
</>
))}
</div>
</>
)
: null
}
Expand Down Expand Up @@ -124,30 +128,54 @@ const formattedSteps = recipe.steps
color: inherit;
}

.recipe-steps {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
margin-block-end: 32px;
}

.recipe-steps-subheader {
margin-block-start: 24px;
color: var(--text-secondary);
font-size: 14px;
text-transform: uppercase;
font-weight: 600;
grid-column: 1 / -1;
}

table {
margin-block-end: 24px;
.cell {
padding: 6px 12px;
}

th,
td {
padding: 6px 12px;
.cell--header {
font-weight: 600;
}

th:first-child,
td:first-child {
.cell--first {
padding-inline-start: 0;
}

th:last-child,
td:last-child {
padding-inline-end: 0;
/* Special case required only for the header of the last column to take the place of description column header if there are 3 columns. */
.cell--header.cell--last {
grid-column: 2 / -1;
}

/* These classes grouped under one query since changes are highly coupled */
@media screen and (max-width: 600px) {

.recipe-steps {
grid-template-columns: 1fr 1fr;
}

.cell--description {
grid-column: 1 / -1;
padding-inline: 0;
margin-block-end: 24px;
}

.cell--description:empty {
display: none;
}
}

.source {
Expand Down
3 changes: 2 additions & 1 deletion src/content/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import { defineCollection, z } from 'astro:content'
const recipeStep = z.object({
description: z.string().optional(),
time: z.string(),
water: z.number()
water: z.number(),
group: z.string().optional()
})

const recipesCollection = defineCollection({
Expand Down
5 changes: 5 additions & 0 deletions src/content/recipes/en/pourover/barn-01.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,19 @@ properties:
steps:
- water: 35
time: '0:30'
group: Pre-wetting
- water: 65
time: '0:30'
group: Infusions
- water: 50
time: '0:20'
group: Infusions
- water: 50
time: '0:25'
group: Infusions
- water: 50
time: '0:25'
group: Infusions

author: The Barn
authorImg: barn
Expand Down
4 changes: 3 additions & 1 deletion src/i18n/locales/recipe/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { t } from '../../utils'
export const getRecipeMessages = (locale?: string) => {
return t(locale, 'recipe', {
infusions: 'Infusions',
prewetting: 'Pre-wetting'
prewetting: 'Pre-wetting',
startTime: 'Start at',
totalWeight: 'Total weight'
})
}

0 comments on commit fab9e9b

Please sign in to comment.