mirror of
https://github.com/rjNemo/meal_planner
synced 2026-06-06 02:26:49 +00:00
commit
b2680e7d22
31 changed files with 2286 additions and 121 deletions
1655
.aider.chat.history.md
Normal file
1655
.aider.chat.history.md
Normal file
File diff suppressed because it is too large
Load diff
276
.aider.input.history
Normal file
276
.aider.input.history
Normal file
|
|
@ -0,0 +1,276 @@
|
|||
|
||||
# 2024-12-13 21:39:55.512352
|
||||
+n
|
||||
|
||||
# 2024-12-13 21:40:09.266770
|
||||
+/add components/AppNavbar.vue
|
||||
|
||||
# 2024-12-13 21:41:08.087873
|
||||
+change the nuxt-link to random. It must be a button that triggers the useREcipeRandom composable. If the user is not on the /random url we must navigate to it
|
||||
|
||||
# 2024-12-13 21:41:57.546012
|
||||
+/add components/AppNavbar.vue
|
||||
|
||||
# 2024-12-13 22:37:21.637830
|
||||
+/add package.json
|
||||
|
||||
# 2024-12-13 22:38:15.345890
|
||||
+/add pages/[id].vue
|
||||
|
||||
# 2024-12-13 22:45:55.419537
|
||||
+/add pages/index.vue
|
||||
|
||||
# 2024-12-13 22:50:08.132910
|
||||
+/add app.vue
|
||||
|
||||
# 2024-12-13 22:57:55.838401
|
||||
+/add pages/[id].vue
|
||||
|
||||
# 2024-12-13 22:58:23.470174
|
||||
+/add components/recipe/card.vue components/recipe/index.vue components/recipe/ingredients.vue
|
||||
|
||||
# 2024-12-13 22:58:50.995437
|
||||
+I want to add a skeleton when the page loads that matches the card and ingredient list and content layout
|
||||
|
||||
# 2024-12-13 23:00:37.864463
|
||||
+/add pages/[id].vue
|
||||
|
||||
# 2024-12-13 23:10:51.785039
|
||||
+/add components/AppFooter.vue
|
||||
|
||||
# 2024-12-13 23:17:52.755408
|
||||
+/drop gitsigns:///Users/ruidy/Dev/node/meal_planner/.git//:0:components/AppFooter.vue
|
||||
|
||||
# 2024-12-13 23:29:25.130188
|
||||
+/add README.md
|
||||
|
||||
# 2024-12-14 10:11:48.291791
|
||||
+/add composables/useRecipeSearch.ts
|
||||
|
||||
# 2024-12-14 10:13:08.935799
|
||||
+create a research page on the /search url taking the search query as a query parameter. use daisyui for the layout
|
||||
|
||||
# 2024-12-14 10:14:09.451269
|
||||
+/add components/recipe/search.vue
|
||||
|
||||
# 2024-12-14 10:14:21.375661
|
||||
+/add server/trpc/routers/recipes.ts
|
||||
|
||||
# 2024-12-14 10:14:28.419016
|
||||
+now implement
|
||||
|
||||
# 2024-12-14 10:16:11.974208
|
||||
+/add pages/search.vue
|
||||
|
||||
# 2024-12-14 10:31:29.372232
|
||||
+/add components/recipe/search.vue
|
||||
|
||||
# 2024-12-14 10:40:24.170866
|
||||
+/add .nuxt/types/imports.d.ts
|
||||
|
||||
# 2024-12-14 10:42:09.952541
|
||||
+/add node_modules/nuxt/dist/app/composables/asyncData.d.ts
|
||||
|
||||
# 2024-12-14 10:46:07.185510
|
||||
+/add server/trpc/routers/recipes.ts
|
||||
|
||||
# 2024-12-14 10:46:11.532349
|
||||
+/add utils/recipes.ts
|
||||
|
||||
# 2024-12-14 10:46:15.907096
|
||||
+/add types/recipe.ts
|
||||
|
||||
# 2024-12-14 15:08:57.920043
|
||||
+/drop
|
||||
|
||||
# 2024-12-14 15:09:15.291578
|
||||
+create a categories page
|
||||
|
||||
# 2024-12-14 15:11:08.473107
|
||||
+/add server/trpc/routers/recipes.ts
|
||||
|
||||
# 2024-12-14 15:11:28.898754
|
||||
+/drop server/trpc/routers/recipes.ts
|
||||
|
||||
# 2024-12-14 15:11:28.976166
|
||||
+/add server/trpc/routers/recipes.ts
|
||||
|
||||
# 2024-12-14 15:11:32.962219
|
||||
+/drop neo-tree filesystem [1]
|
||||
|
||||
# 2024-12-14 15:11:46.767029
|
||||
+/add server/trpc/routers/categories.ts
|
||||
|
||||
# 2024-12-14 15:13:15.829646
|
||||
+create the category page calling the router you created
|
||||
|
||||
# 2024-12-14 15:14:00.601188
|
||||
+/add composables/useCategories.ts
|
||||
|
||||
# 2024-12-14 15:14:48.317381
|
||||
+/add server/trpc/trpc.ts
|
||||
|
||||
# 2024-12-14 15:14:55.169821
|
||||
+/add server/trpc/context.ts
|
||||
|
||||
# 2024-12-14 15:14:57.297636
|
||||
+/add server/trpc/routers/index.ts
|
||||
|
||||
# 2024-12-14 15:16:08.866486
|
||||
+/drop ~/Dev/node/meal_planner
|
||||
|
||||
# 2024-12-14 15:17:30.807622
|
||||
+/add pages/categories.vue
|
||||
|
||||
# 2024-12-14 15:19:32.874574
|
||||
+/add pages/search.vue
|
||||
|
||||
# 2024-12-14 15:19:44.835990
|
||||
+improve the layout by taking example on the search page
|
||||
|
||||
# 2024-12-14 15:20:10.531362
|
||||
+add pages/categories.vue
|
||||
|
||||
# 2024-12-14 15:20:56.212560
|
||||
+/add src/components/Navbar.tsx
|
||||
|
||||
# 2024-12-14 15:20:56.245090
|
||||
+/drop ~/Dev/node/meal_planner
|
||||
|
||||
# 2024-12-14 15:20:56.274982
|
||||
+/add ~/Dev/node/meal_planner
|
||||
|
||||
# 2024-12-14 15:20:56.287118
|
||||
+/add components/app/navbar.vue
|
||||
|
||||
# 2024-12-14 15:23:50.021356
|
||||
+/drop
|
||||
|
||||
# 2024-12-14 15:24:02.867277
|
||||
+/add pages/categories.vue
|
||||
|
||||
# 2024-12-14 15:24:35.057752
|
||||
+remove the header and set a fixed height the card. use ellipsis if the description is longer that the max allowed height. make it responseive
|
||||
|
||||
# 2024-12-14 15:25:28.155546
|
||||
+/add server/trpc/routers/categories.ts
|
||||
|
||||
# 2024-12-14 15:25:55.220084
|
||||
+/add types/recipe.ts
|
||||
|
||||
# 2024-12-14 15:27:09.955135
|
||||
+parse the categories fetch call response similarly to the recipes
|
||||
|
||||
# 2024-12-14 15:28:04.976045
|
||||
+parse the categories fetch call similarly to the recipes
|
||||
|
||||
# 2024-12-14 15:28:22.265520
|
||||
+/add types/recipe.ts
|
||||
|
||||
# 2024-12-14 15:28:32.201929
|
||||
+/add server/trpc/routers/categories.ts
|
||||
|
||||
# 2024-12-14 15:29:18.224388
|
||||
+/add server/trpc/routers/recipes.ts
|
||||
|
||||
# 2024-12-14 15:29:27.965664
|
||||
+/add utils/recipes.ts
|
||||
|
||||
# 2024-12-14 15:31:29.546270
|
||||
+/add pages/categories/index.vue
|
||||
|
||||
# 2024-12-14 15:31:29.727185
|
||||
+/drop pages/categories/index.vue
|
||||
|
||||
# 2024-12-14 15:31:29.775294
|
||||
+/add pages/categories/index.vue
|
||||
|
||||
# 2024-12-14 15:32:43.034734
|
||||
+/add composables/useCategories.ts
|
||||
|
||||
# 2024-12-14 15:32:52.855244
|
||||
+/add node_modules/zod/lib/types.d.ts
|
||||
|
||||
# 2024-12-14 15:33:24.249300
|
||||
+/add types/category.ts
|
||||
|
||||
# 2024-12-14 15:38:28.584427
|
||||
+/add ~/Dev/node/meal_planner
|
||||
|
||||
# 2024-12-14 15:38:28.657843
|
||||
+/drop ~/Dev/node/meal_planner
|
||||
|
||||
# 2024-12-14 15:38:28.663316
|
||||
+/add ~/Dev/node/meal_planner
|
||||
|
||||
# 2024-12-14 15:38:38.367339
|
||||
+/drop ~/Dev/node/meal_planner
|
||||
|
||||
# 2024-12-14 15:38:38.373518
|
||||
+/add ~/Dev/node/meal_planner
|
||||
|
||||
# 2024-12-14 15:38:49.446018
|
||||
+/add components/CategoryCard.vue
|
||||
|
||||
# 2024-12-14 15:44:12.403700
|
||||
+n
|
||||
|
||||
# 2024-12-14 15:45:04.918485
|
||||
+add a category details page use the image as a header background with the name inside. add the description below then cards with the related recipes
|
||||
|
||||
# 2024-12-14 15:46:47.445160
|
||||
+/add pages/category/[name].vue
|
||||
|
||||
# 2024-12-14 15:47:22.637607
|
||||
+/add server/trpc/routers/recipes.ts
|
||||
|
||||
# 2024-12-14 15:47:50.065673
|
||||
+/add composables/useCategoryRecipes.ts
|
||||
|
||||
# 2024-12-14 15:55:04.811952
|
||||
+/add src/containers/Category/index.tsx
|
||||
|
||||
# 2024-12-14 15:55:10.429945
|
||||
+/add src/services/api.ts
|
||||
|
||||
# 2024-12-14 18:53:11.975975
|
||||
+/drop types/recipe.ts
|
||||
|
||||
# 2024-12-14 18:53:14.326984
|
||||
+/drop utils/recipes.ts
|
||||
|
||||
# 2024-12-14 18:53:15.873485
|
||||
+/drop composables/useCategories.ts
|
||||
|
||||
# 2024-12-14 18:53:20.204915
|
||||
+/add composables/useCategories.ts
|
||||
|
||||
# 2024-12-14 18:53:43.120147
|
||||
+/add ~/Dev/node/meal_planner
|
||||
|
||||
# 2024-12-14 18:53:43.148579
|
||||
+/drop ~/Dev/node/meal_planner
|
||||
|
||||
# 2024-12-14 18:53:43.160247
|
||||
+/add ~/Dev/node/meal_planner
|
||||
|
||||
# 2024-12-14 18:53:57.723720
|
||||
+/add server/trpc/routers/index.ts
|
||||
|
||||
# 2024-12-14 19:19:40.694592
|
||||
+/add ~/Dev/node/meal_planner
|
||||
|
||||
# 2024-12-14 19:19:40.708960
|
||||
+/drop ~/Dev/node/meal_planner
|
||||
|
||||
# 2024-12-14 19:19:40.716279
|
||||
+/add ~/Dev/node/meal_planner
|
||||
|
||||
# 2024-12-14 23:44:44.873544
|
||||
+/drop ~/Dev/node/meal_planner
|
||||
|
||||
# 2024-12-14 23:46:59.255410
|
||||
+/add pages/categories/[name].vue
|
||||
|
||||
# 2024-12-14 23:46:59.262787
|
||||
+/drop pages/category/[name].vue
|
||||
BIN
.aider.tags.cache.v3/cache.db
Normal file
BIN
.aider.tags.cache.v3/cache.db
Normal file
Binary file not shown.
BIN
.aider.tags.cache.v3/cache.db-shm
Normal file
BIN
.aider.tags.cache.v3/cache.db-shm
Normal file
Binary file not shown.
BIN
.aider.tags.cache.v3/cache.db-wal
Normal file
BIN
.aider.tags.cache.v3/cache.db-wal
Normal file
Binary file not shown.
34
.gitignore
vendored
34
.gitignore
vendored
|
|
@ -1,12 +1,24 @@
|
|||
build/
|
||||
node_modules/
|
||||
.idea/
|
||||
.vscode/
|
||||
# Nuxt dev/build outputs
|
||||
.output
|
||||
.data
|
||||
.nuxt
|
||||
.nitro
|
||||
.cache
|
||||
dist
|
||||
|
||||
# Node dependencies
|
||||
node_modules
|
||||
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
|
||||
# Misc
|
||||
.DS_Store
|
||||
.fleet
|
||||
.idea
|
||||
|
||||
# Local env files
|
||||
.env
|
||||
.yarn/*
|
||||
!.yarn/cache
|
||||
!.yarn/patches
|
||||
!.yarn/plugins
|
||||
!.yarn/releases
|
||||
!.yarn/sdks
|
||||
!.yarn/versions
|
||||
.env.*
|
||||
!.env.example
|
||||
|
|
|
|||
7
.gitpod.Dockerfile
vendored
7
.gitpod.Dockerfile
vendored
|
|
@ -1,7 +0,0 @@
|
|||
FROM gitpod/workspace-full
|
||||
|
||||
# Install custom tools, runtimes, etc.
|
||||
# For example "bastet", a command-line tetris clone:
|
||||
# RUN brew install bastet
|
||||
#
|
||||
# More information: https://www.gitpod.io/docs/config-docker/
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
image:
|
||||
file: .gitpod.Dockerfile
|
||||
|
||||
tasks:
|
||||
- init: yarn install && yarn build
|
||||
command: yarn start
|
||||
1
.prettierignore
Normal file
1
.prettierignore
Normal file
|
|
@ -0,0 +1 @@
|
|||
src/
|
||||
24
TODO.md
24
TODO.md
|
|
@ -1,15 +1,13 @@
|
|||
# TO DO
|
||||
|
||||
- [ ] send message after contact form validation (confirm to sender and msg+info to admin)
|
||||
- [ ] Breadcrumb
|
||||
- [ ] Cookie bar
|
||||
- [x] code cleanup (props and refactoring)
|
||||
- [ ] Back to top button
|
||||
- [ ] Close Sidebar at outside click
|
||||
- [ ] Take a look at some components [here](http://react-materialize.github.io/react-materialize/?path=/story/css-grid--default)
|
||||
- [ ] Decoupled application and data layers. Abstract such that the front end does not know where the data comes from.
|
||||
- [x] Create PageLayout component
|
||||
- [ ] Use Css-in-Js
|
||||
- [x] Redirect to 404
|
||||
- [x] Typescript
|
||||
- [x] strict typing
|
||||
- [x] use bun package manager
|
||||
- [x] use nuxt framework
|
||||
- [x] rewrite the random page, the current landing page
|
||||
- [x] rewrite the recipe page
|
||||
- [ ] deploy
|
||||
- [ ] nuxt image
|
||||
- [x] prettier and eslint
|
||||
- [ ] transition
|
||||
- [ ] pwa
|
||||
- [ ] seo, robots.txt
|
||||
- [ ] update the README
|
||||
|
|
|
|||
9
app.vue
Normal file
9
app.vue
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<template>
|
||||
<div data-theme="cupcake" class="flex flex-col h-screen">
|
||||
<AppNavbar />
|
||||
<main class="flex-grow">
|
||||
<NuxtPage />
|
||||
</main>
|
||||
<AppFooter />
|
||||
</div>
|
||||
</template>
|
||||
3
assets/css/main.css
Normal file
3
assets/css/main.css
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
BIN
bun.lockb
Executable file
BIN
bun.lockb
Executable file
Binary file not shown.
7
components/AppFooter.vue
Normal file
7
components/AppFooter.vue
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<template>
|
||||
<footer class="footer footer-center p-4 bg-base-300 text-base-content">
|
||||
<aside>
|
||||
<p>Copyright © 2024 - Made with ❤️</p>
|
||||
</aside>
|
||||
</footer>
|
||||
</template>
|
||||
42
components/AppNavbar.vue
Normal file
42
components/AppNavbar.vue
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
<template>
|
||||
<nav class="navbar bg-base-300">
|
||||
<div class="navbar-start">
|
||||
<div class="dropdown">
|
||||
<div tabindex="0" role="button" class="btn btn-ghost lg:hidden">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-5 w-5"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M4 6h16M4 12h8m-8 6h16"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<ul
|
||||
tabindex="0"
|
||||
class="menu menu-sm dropdown-content mt-3 z-[1] p-2 shadow bg-base-200 rounded-box w-52"
|
||||
>
|
||||
<li><a>Categories</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<nuxt-link to="/" class="btn btn-ghost text-xl">
|
||||
<NuxtImg src="/logo192.png" width="50" />
|
||||
<span style="font-family: cursive"> Chefs </span>
|
||||
</nuxt-link>
|
||||
</div>
|
||||
<div class="navbar-center hidden lg:flex">
|
||||
<ul class="menu menu-horizontal px-1">
|
||||
<li><a>Categories</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="navbar-end">
|
||||
<nuxt-link to="/random" class="btn btn-primary">Random</nuxt-link>
|
||||
</div>
|
||||
</nav>
|
||||
</template>
|
||||
29
components/recipe/card.vue
Normal file
29
components/recipe/card.vue
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
<script setup lang="ts">
|
||||
defineProps<{
|
||||
title: string;
|
||||
pictureUrl: string;
|
||||
videoUrl: string;
|
||||
category: string;
|
||||
origin: string;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="card-body items-center text-center bg-base-200">
|
||||
<h2 class="card-title">{{ title }}</h2>
|
||||
<figure class="px-10 py-5">
|
||||
<NuxtImg :src="pictureUrl" alt="Shoes" class="rounded-xl" />
|
||||
</figure>
|
||||
<div class="card-actions space-between">
|
||||
<NuxtLink class="badge badge-outline" :to="videoUrl">
|
||||
<Icon name="cib:youtube" color="red" />
|
||||
</NuxtLink>
|
||||
<div class="badge badge-secondary">
|
||||
<Icon name="cil:apple" /> {{ category }}
|
||||
</div>
|
||||
<div class="badge badge-secondary">
|
||||
<Icon name="cil:location-pin" /> {{ origin }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
27
components/recipe/index.vue
Normal file
27
components/recipe/index.vue
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
<script setup lang="ts">
|
||||
import type { Recipe } from "~/types/recipe";
|
||||
|
||||
defineProps<{ recipe: Recipe }>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div class="lg:flex space-y-4 lg:justify-evenly py-4">
|
||||
<div class="card w-96 bg-base-100 shadow-xl mx-auto lg:mx-2 min-h-32">
|
||||
<RecipeCard
|
||||
:title="recipe.title"
|
||||
:picture-url="recipe.pictureUrl"
|
||||
:video-url="recipe.videoUrl"
|
||||
:category="recipe.category"
|
||||
:origin="recipe.origin"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<RecipeIngredients :ingredients="recipe.ingredients" />
|
||||
</div>
|
||||
<div class="flex flex-col items-center p-4">
|
||||
<h2 class="prose lg:prose-xl">Instructions</h2>
|
||||
<p class="prose">{{ recipe.instructions }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
26
components/recipe/ingredients.vue
Normal file
26
components/recipe/ingredients.vue
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
<script setup lang="ts">
|
||||
defineProps<{
|
||||
ingredients: { name: string; quantity: number }[];
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="overflow-x-auto">
|
||||
<table class="table table-s table-pin-rows table-pin-cols">
|
||||
<thead>
|
||||
<tr>
|
||||
<th />
|
||||
<td>Ingredient</td>
|
||||
<td>Quantity</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(ingredient, i) in ingredients" :key="i">
|
||||
<th>{{ i + 1 }}</th>
|
||||
<td>{{ ingredient.name }}</td>
|
||||
<td>{{ ingredient.quantity }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</template>
|
||||
61
composables/useRecipe.ts
Normal file
61
composables/useRecipe.ts
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
import type { Recipe } from "~/types/recipe";
|
||||
|
||||
type Keyword = "random" | "filter" | "lookup" | "search";
|
||||
|
||||
export default async function (keyword: Keyword, param?: string) {
|
||||
const { data, pending, error } = await useAsyncData(
|
||||
keyword,
|
||||
async () => {
|
||||
const config = useRuntimeConfig();
|
||||
|
||||
let url = "";
|
||||
|
||||
switch (keyword) {
|
||||
case "random":
|
||||
url = `${config.apiUrl}random.php`;
|
||||
break;
|
||||
case "filter":
|
||||
url = "";
|
||||
break;
|
||||
case "lookup":
|
||||
url = `${config.apiUrl}${keyword}.php?i=${param}`;
|
||||
break;
|
||||
case "search":
|
||||
url = "";
|
||||
break;
|
||||
default:
|
||||
throw Error("unexpected URI parameters");
|
||||
}
|
||||
return await $fetch(url);
|
||||
},
|
||||
{ lazy: true },
|
||||
);
|
||||
|
||||
const tmp = computed(() => data.value?.meals?.[0]);
|
||||
|
||||
const names: string[] = [];
|
||||
const quantities: number[] = [];
|
||||
for (const [k, v] of Object.entries(tmp.value)) {
|
||||
if (k.startsWith("strIngredient") && !!v) {
|
||||
names.push(v);
|
||||
} else if (k.startsWith("strMeasure") && !!v) {
|
||||
quantities.push(v);
|
||||
}
|
||||
}
|
||||
|
||||
const recipe = reactive<Recipe>({
|
||||
title: tmp.value.strMeal,
|
||||
pictureUrl: tmp.value.strMealThumb,
|
||||
videoUrl: tmp.value.strYoutube,
|
||||
category: tmp.value.strCategory,
|
||||
origin: tmp.value.strArea,
|
||||
ingredients: names.map((name, i) => ({ name, quantity: quantities[i] })),
|
||||
instructions: tmp.value.strInstructions,
|
||||
});
|
||||
|
||||
return {
|
||||
recipe,
|
||||
pending,
|
||||
error,
|
||||
};
|
||||
}
|
||||
6
eslint.config.mjs
Normal file
6
eslint.config.mjs
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
// @ts-check
|
||||
import withNuxt from "./.nuxt/eslint.config.mjs";
|
||||
|
||||
export default withNuxt({
|
||||
ignores: ["**/src/*"],
|
||||
});
|
||||
19
nuxt.config.ts
Normal file
19
nuxt.config.ts
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
// https://nuxt.com/docs/api/configuration/nuxt-config
|
||||
export default defineNuxtConfig({
|
||||
devtools: { enabled: true },
|
||||
css: ["~/assets/css/main.css"],
|
||||
modules: ["@nuxt/eslint", "@nuxt/image", "nuxt-icon"],
|
||||
postcss: {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
},
|
||||
runtimeConfig: {
|
||||
// The private keys which are only available server-side
|
||||
apiUrl: "",
|
||||
// Keys within public are also exposed client-side
|
||||
public: {},
|
||||
},
|
||||
ssr: true,
|
||||
});
|
||||
58
package.json
58
package.json
|
|
@ -1,42 +1,32 @@
|
|||
{
|
||||
"name": "meal-planner",
|
||||
"version": "0.1.0",
|
||||
"name": "chefs",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@testing-library/jest-dom": "^5.11.9",
|
||||
"@testing-library/react": "^11.2.5",
|
||||
"@testing-library/user-event": "^13.0.10",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-router-dom": "^6.1.1",
|
||||
"react-scripts": "^5.0.0"
|
||||
},
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject"
|
||||
"build": "nuxt build",
|
||||
"dev": "nuxt dev --port=3009",
|
||||
"generate": "nuxt generate",
|
||||
"preview": "nuxt preview",
|
||||
"postinstall": "nuxt prepare",
|
||||
"format": "bun prettier . --write",
|
||||
"lint": "eslint .",
|
||||
"lint:fix": "eslint . --fix"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": "react-app"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
"dependencies": {
|
||||
"@nuxt/eslint": "^0.3.10",
|
||||
"@nuxt/image": "^1.6.0",
|
||||
"nuxt": "^3.11.2",
|
||||
"nuxt-icon": "^0.6.10",
|
||||
"vue": "^3.4.21",
|
||||
"vue-router": "^4.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^14.14.37",
|
||||
"@types/react": "^17.0.3",
|
||||
"@types/react-router-dom": "^5.1.7",
|
||||
"prettier": "^2.5.1",
|
||||
"typescript": "^4.2.3"
|
||||
"@tailwindcss/typography": "^0.5.13",
|
||||
"autoprefixer": "^10.4.19",
|
||||
"daisyui": "^4.10.2",
|
||||
"postcss": "^8.4.38",
|
||||
"prettier": "3.2.5",
|
||||
"prettier-plugin-tailwindcss": "^0.5.14",
|
||||
"tailwindcss": "^3.4.3"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
12
pages/[id].vue
Normal file
12
pages/[id].vue
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
<script setup lang="ts">
|
||||
const { params } = useRoute();
|
||||
const { recipe, pending, error } = await useRecipe("lookup", params.id);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="pending">Loading</div>
|
||||
<div v-else-if="error">Failed: {{ error }}</div>
|
||||
<section v-else>
|
||||
<Recipe :recipe="recipe" />
|
||||
</section>
|
||||
</template>
|
||||
14
pages/index.vue
Normal file
14
pages/index.vue
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<template>
|
||||
<div class="hero min-h-screen bg-base-200">
|
||||
<div class="hero-content flex-col lg:flex-row-reverse">
|
||||
<NuxtImg src="/chef.svg" class="max-w-sm rounded-lg shadow-2xl" />
|
||||
<div>
|
||||
<h1 class="text-5xl font-bold prose">Eat Something New</h1>
|
||||
<p class="py-6 prose">Generate a random recipe.</p>
|
||||
<NuxtLink to="/random" class="btn btn-primary" external>
|
||||
Random Recipe Now
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
11
pages/random.vue
Normal file
11
pages/random.vue
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
<script setup lang="ts">
|
||||
const { recipe, pending, error } = await useRecipe("random");
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="pending">Loading</div>
|
||||
<div v-else-if="error">Failed: {{ error }}</div>
|
||||
<section v-else>
|
||||
<Recipe :recipe="recipe" />
|
||||
</section>
|
||||
</template>
|
||||
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
|
|
@ -1,22 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel="icon" href="%PUBLIC_URL%/favicon.ico"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<meta name="theme-color" content="#ff6d00"/>
|
||||
<meta name="description" content="Online Meal Planner | Chef's"/>
|
||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png"/>
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json"/>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"/>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons"/>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Marck+Script&display=swap"/>
|
||||
<title>Online Meal Planner | Chef's</title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -27,4 +27,4 @@
|
|||
"display": "standalone",
|
||||
"theme_color": "#ff6d00",
|
||||
"background_color": "#ffffff"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
18
tailwind.config.js
Normal file
18
tailwind.config.js
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/** @type {import('tailwindcss').Config} */
|
||||
export default {
|
||||
content: [
|
||||
"./components/**/*.{js,vue,ts}",
|
||||
"./layouts/**/*.vue",
|
||||
"./pages/**/*.vue",
|
||||
"./plugins/**/*.{js,ts}",
|
||||
"./app.vue",
|
||||
"./error.vue",
|
||||
],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [require("@tailwindcss/typography"), require("daisyui")],
|
||||
daisyui: {
|
||||
themes: ["cupcake"],
|
||||
},
|
||||
};
|
||||
|
|
@ -1,29 +1,4 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "es6",
|
||||
"lib": [
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"esnext"
|
||||
],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"strict": true,
|
||||
"noUnusedParameters": true,
|
||||
"noUnusedLocals": true,
|
||||
"noImplicitReturns": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"noEmit": true,
|
||||
"jsx": "react-jsx"
|
||||
},
|
||||
"include": [
|
||||
"src"
|
||||
]
|
||||
// https://nuxt.com/docs/guide/concepts/typescript
|
||||
"extends": "./.nuxt/tsconfig.json"
|
||||
}
|
||||
|
|
|
|||
9
types/recipe.ts
Normal file
9
types/recipe.ts
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
export type Recipe = {
|
||||
title: string;
|
||||
pictureUrl: string;
|
||||
videoUrl: string;
|
||||
category: string;
|
||||
origin: string;
|
||||
ingredients: { name: string; quantity: number }[];
|
||||
instructions: string;
|
||||
};
|
||||
Loading…
Reference in a new issue