Skip to content

Commit

Permalink
add food collection
Browse files Browse the repository at this point in the history
  • Loading branch information
Reed Nelson committed Nov 14, 2023
1 parent 28bf3cf commit 8ffa0f1
Show file tree
Hide file tree
Showing 13 changed files with 452 additions and 11 deletions.
Binary file added src/assets/food/pad-thai.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/food/placeholder.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 4 additions & 2 deletions src/config/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@
"default_theme": "system",
"blog_pagination": 4,
"drink_pagination": 6,
"food_pagination": 6,
"puzzle_pagination": 6,
"summary_length": 200,
"blog_folder": "blog",
"puzzle_folder": "puzzles",
"drink_folder": "drinks"
"drink_folder": "drinks",
"food_folder": "food",
"puzzle_folder": "puzzles"
},

"metadata": {
Expand Down
38 changes: 29 additions & 9 deletions src/content/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,40 +15,60 @@ const blogCollection = defineCollection({
}),
});

// Puzzle collection schema
const puzzleCollection = defineCollection({
schema: z.object({
// Drink collection schema
const drinkCollection = defineCollection({
schema: ({ image }) => z.object({
title: z.string(),
meta_title: z.string().optional(),
description: z.string().optional(),
date: z.date().optional(),
cover: image().optional(),
author: z.string().default("none"),
spirits: z.array(z.string()).default(["none"]),
bottles: z.array(z.string()).default(["none"]),
tags: z.array(z.string()).default(["none"]),
draft: z.boolean().optional(),
ingredients: z.object({
list: z.array(z.string()).optional(),
qty: z.array(z.string()).optional(),
}).optional(),
instructions: z.array(z.string()).optional(),
}),
});

// Drink collection schema
const drinkCollection = defineCollection({
// Food collection schema
const foodCollection = defineCollection({
schema: ({ image }) => z.object({
title: z.string(),
meta_title: z.string().optional(),
description: z.string().optional(),
date: z.date().optional(),
cover: image().optional(),
author: z.string().default("none"),
spirits: z.array(z.string()).default(["none"]),
bottles: z.array(z.string()).default(["none"]),
tags: z.array(z.string()).default(["none"]),
draft: z.boolean().optional(),
ingredients: z.object({
list: z.array(z.string()).optional(),
qty: z.array(z.string()).optional(),
}).optional(),
instructions: z.array(z.string()).optional(),
notes: z.array(z.string()).optional(),
}),
});

// Puzzle collection schema
const puzzleCollection = defineCollection({
schema: z.object({
title: z.string(),
meta_title: z.string().optional(),
description: z.string().optional(),
draft: z.boolean().optional(),
}),
});

// Export collections
export const collections = {
blog: blogCollection,
puzzles: puzzleCollection,
drinks: drinkCollection,
food: foodCollection,
puzzles: puzzleCollection,
};
5 changes: 5 additions & 0 deletions src/content/food/-index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
title: Food
meta_title: Food
description: A modest recipe book.
---
20 changes: 20 additions & 0 deletions src/content/food/_food.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
title: Food
meta_title: Food
author: Reed Nelson
draft: true
description: recipe.
cover: "@assets/food/.jpg"

ingredients:
list:
- Ingredient
qty:
- qty

instructions:
- Step

notes:
- Note
---
52 changes: 52 additions & 0 deletions src/content/food/pad-thai.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
title: Pad Thai
meta_title: Pad Thai
author: Reed Nelson
draft: false
description: Pad Thai recipe.
cover: "@assets/food/pad-thai.jpg"

ingredients:
list:
- Wide rice noodles
- Fresh cilantro
- Green onion
- Garlic (minced)
- Ginger (grated)
- Brown sugar
- Soy sauce (low sodium)
- Peanut butter
- Lime juice
- Sriracha
- Roasted peanuts
qty:
- 14 oz
- 1 bunch
- 6 stalks
- 4 cloves
- 4 tbsp
- 1⁄3 cup
- 1⁄2 cup
- 3 tbsp
- 1⁄4 cup
- 1 tbsp
- 1⁄4 cup

instructions:
- "Stir fry prep: chop and combine garlic, ginger, cilantro, green onion, and any other desired ingredients*"
- "Noodle prep: cook noodles al dente; rinse and drain well"
- "Sauce prep: combine brown sugar, peanut butter, soy sauce, lime juice, and sriracha in a bowl"
- "Garnish prep: optionally chop peanuts/limes/cilantro and set aside for serving"
- Saute stir fry ingredients in a large pan; account for differences in cook time among ingredients
- Add noodles to the pan, combine thoroughly
- Add sauce, combine thoroughly
- Remove from heat when sauce is cooked in to your liking
- Serve

notes:
- "*Other desired ingredients may include spinach, broccoli, bell pepper, baby corn, etc."
- Steps 1-4 can be parallelized, and that's where most of the work is.
- Cilantro is really great.
- I recommend dividing the veggies that will saute quickly from those that will slowly.
- Keep the soy sauce and lime juice handy, you may want more flavor toward the end.
---
44 changes: 44 additions & 0 deletions src/content/food/tofu-burritos.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
---
title: Tofu Burritos
meta_title: Tofu Burritos
author: Reed Nelson
draft: false
description: Tofu Burrito recipe.
cover: "@assets/food/placeholder.jpg"

ingredients:
list:
- Tofu
- Taco seasoning
- Romaine
- Tortillas
- Mexican cheese blend
- Spanish style rice (Trader Joe's)
- Roma tomatoes
- Sweet onion
- cilantro
- Lime juice
qty:
- 1 slab (pressed)
- some
- 2 hearts
- "8"
- some
- 1 bag
- "4"
- 1⁄4 cup
- 1⁄2 bunch
- some
- some

instructions:
- Dice the tofu into ~ 1⁄2 cm cubes; fry dry until crispy
- "Prepare pico: chop tomatoes, onion, and cilantro, add lime juice and salt"
- Cook rice according to its instructions
- Chop lettuce
- Wrap everything together

notes:
- I recommend storing leftover tofu and rice together, pico in another container, then cheese, lettuce, and tortillas separately.
- All ingredients can be acquired at Trader Joe's, the rice must be, and the rice does a lot here.
---
119 changes: 119 additions & 0 deletions src/layouts/FoodSingle.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
---
import Share from "@/components/Share.astro";
import config from "@/config/config.json";
import { Image } from "astro:assets";
interface Recipe {
ingredients: {
list: string[];
qty: string[];
};
instructions: string[];
notes: string[];
}
const { food_folder } = config.settings;
const { post } = Astro.props;
const { title, description, cover } = post.data;
const { ingredients, instructions, notes }: Recipe = post.data;
---

<section class="section pt-7">
<div class="container">
<div class="row justify-center">
<article class="lg:col-10">
<h1 set:html={title} class="mb-4" />

<div class="row">
<div class="lg:col-8 mb-8">
{
cover && (
<Image
src={cover}
width={1920}
height={1080}
alt={title}
class="w-full rounded-lg"
format="webp"
/>
)
}
</div>
</div>

<!-- Ingredients -->
<section class="section-sm bg-theme-light dark:bg-darkmode-theme-light rounded-lg mb-4">
<div class="container -my-10">
<div class="row items-center justify-between">
<div class="md:col-6 lg:col-6 md:order-1">
<h2 set:html="Ingredients" class="mb-4" />
<div class="row mx-4">
{ingredients.list.map((it: string, index: number) => (
<div class="row my-1">
<div class="col-7" set:html={ingredients.list[index]} />
<div class="col-5 text-right" set:html={ingredients.qty[index]} />
<hr class="my-1">
</div>
))}
</div>
</div>
</div>
</div>
</section>

<!-- Instructions -->
<section class="section-sm bg-theme-light dark:bg-darkmode-theme-light rounded-lg mb-4">
<div class="container -my-10">
<div class="row items-center justify-between">
<div class="md:order-1">
<h2 set:html="Instructions" class="mb-4" />
<div class="row mx-4">
{instructions.map((it: string, index: number) => (
<div class="row my-1">
<div class="col">
{index + 1}.{" "}{it}
</div>
<hr class="my-1">
</div>
))}
</div>
</div>
</div>
</div>
</section>

<!-- Notes -->
<section class="section-sm bg-theme-light dark:bg-darkmode-theme-light rounded-lg mb-4">
<div class="container -my-10">
<div class="row items-center justify-between">
<div class="md:order-1">
<h2 set:html="Notes" class="mb-4" />
<div class="row mx-4">
{notes.map((it: string, index: number) => (
<div class="row my-1">
<div class="col">
{it}
</div>
<hr class="my-1">
</div>
))}
</div>
</div>
</div>
</div>
</section>

<!-- Share -->
<div class="flex items-center justify-center lg:justify-end">
<Share
className="social-icons"
title={title}
description={description}
folder={food_folder}
slug={post.slug}
/>
</div>
</article>
</div>
</div>
</section>
34 changes: 34 additions & 0 deletions src/layouts/components/FoodCard.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---
import config from "@/config/config.json";
import { Image } from "astro:assets";
const {
food_folder,
}: { food_folder: string } = config.settings;
const { data } = Astro.props;
const { title, cover } = data.data;
---

<div class="bg-body dark:bg-darkmode-body">
<a href={`/${food_folder}/${data.slug}`}>
<div class="relative">
{
cover && (
<Image
class="mb-2 w-full rounded"
src={cover}
alt={title}
width={1280}
height={720}
format="webp"
/>
)
}
<div class="bg-theme-light bg-opacity-50 dark:bg-darkmode-theme-light dark:bg-opacity-60 rounded absolute bottom-0 px-2 py-1">
<h4 class="opacity-70 dark:opacity-70 font-normal">
{title}
</h4>
</div>
</div>
</a>
</div>
30 changes: 30 additions & 0 deletions src/pages/food/[single].astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
import config from "@/config/config.json";
import Base from "@/layouts/Base.astro";
import FoodSingle from "@/layouts/FoodSingle.astro";
import { getSinglePage } from "@/lib/contentParser.astro";
export async function getStaticPaths() {
const posts = await getSinglePage(config.settings.food_folder);
const paths = posts.map((post) => ({
params: {
single: post.slug,
},
props: { post },
}));
return paths;
}
const { post } = Astro.props;
const { title, meta_title, description, image } = post.data;
---

<Base
title={title}
meta_title={meta_title}
description={description}
image={image}
>
<FoodSingle post={post} />
</Base>
Loading

0 comments on commit 8ffa0f1

Please sign in to comment.