mirror of
https://github.com/rjNemo/meal_planner
synced 2026-06-12 13:26:45 +00:00
refactor
This commit is contained in:
parent
1539a03084
commit
884095b0e0
5 changed files with 75 additions and 12 deletions
1
.env.example
Normal file
1
.env.example
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
NUXT_API_URL=https://www.themealdb.com/api/json/v1/1/
|
||||||
BIN
bun.lockb
BIN
bun.lockb
Binary file not shown.
|
|
@ -18,7 +18,8 @@
|
||||||
"nuxt": "^3.11.2",
|
"nuxt": "^3.11.2",
|
||||||
"nuxt-icon": "^0.6.10",
|
"nuxt-icon": "^0.6.10",
|
||||||
"vue": "^3.4.21",
|
"vue": "^3.4.21",
|
||||||
"vue-router": "^4.3.0"
|
"vue-router": "^4.3.0",
|
||||||
|
"zod": "^3.23.8"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tailwindcss/typography": "^0.5.13",
|
"@tailwindcss/typography": "^0.5.13",
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
export type Recipe = {
|
export type Recipe = {
|
||||||
title: string;
|
title: string;
|
||||||
pictureUrl: string;
|
pictureUrl: string;
|
||||||
|
|
@ -7,3 +9,66 @@ export type Recipe = {
|
||||||
ingredients: { name: string; quantity: string }[];
|
ingredients: { name: string; quantity: string }[];
|
||||||
instructions: string;
|
instructions: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const mealSchema = z.object({
|
||||||
|
idMeal: z.string(),
|
||||||
|
strMeal: z.string(),
|
||||||
|
strDrinkAlternate: z.string().nullable(),
|
||||||
|
strCategory: z.string(),
|
||||||
|
strArea: z.string(),
|
||||||
|
strInstructions: z.string(),
|
||||||
|
strMealThumb: z.string().url(),
|
||||||
|
strTags: z.string().nullable(),
|
||||||
|
strYoutube: z.string(),
|
||||||
|
strIngredient1: z.string().optional(),
|
||||||
|
strIngredient2: z.string().optional(),
|
||||||
|
strIngredient3: z.string().optional(),
|
||||||
|
strIngredient4: z.string().optional(),
|
||||||
|
strIngredient5: z.string().optional(),
|
||||||
|
strIngredient6: z.string().optional(),
|
||||||
|
strIngredient7: z.string().optional(),
|
||||||
|
strIngredient8: z.string().optional(),
|
||||||
|
strIngredient9: z.string().optional(),
|
||||||
|
strIngredient10: z.string().optional(),
|
||||||
|
strIngredient11: z.string().optional(),
|
||||||
|
strIngredient12: z.string().optional(),
|
||||||
|
strIngredient13: z.string().optional(),
|
||||||
|
strIngredient14: z.string().optional(),
|
||||||
|
strIngredient15: z.string().optional(),
|
||||||
|
strIngredient16: z.string().optional(),
|
||||||
|
strIngredient17: z.string().optional(),
|
||||||
|
strIngredient18: z.string().optional(),
|
||||||
|
strIngredient19: z.string().optional(),
|
||||||
|
strIngredient20: z.string().optional(),
|
||||||
|
strMeasure1: z.string().optional(),
|
||||||
|
strMeasure2: z.string().optional(),
|
||||||
|
strMeasure3: z.string().optional(),
|
||||||
|
strMeasure4: z.string().optional(),
|
||||||
|
strMeasure5: z.string().optional(),
|
||||||
|
strMeasure6: z.string().optional(),
|
||||||
|
strMeasure7: z.string().optional(),
|
||||||
|
strMeasure8: z.string().optional(),
|
||||||
|
strMeasure9: z.string().optional(),
|
||||||
|
strMeasure10: z.string().optional(),
|
||||||
|
strMeasure11: z.string().optional(),
|
||||||
|
strMeasure12: z.string().optional(),
|
||||||
|
strMeasure13: z.string().optional(),
|
||||||
|
strMeasure14: z.string().optional(),
|
||||||
|
strMeasure15: z.string().optional(),
|
||||||
|
strMeasure16: z.string().optional(),
|
||||||
|
strMeasure17: z.string().optional(),
|
||||||
|
strMeasure18: z.string().optional(),
|
||||||
|
strMeasure19: z.string().optional(),
|
||||||
|
strMeasure20: z.string().optional(),
|
||||||
|
strSource: z.string().optional(),
|
||||||
|
strImageSource: z.string().nullable(),
|
||||||
|
strCreativeCommonsConfirmed: z.string().nullable(),
|
||||||
|
dateModified: z.string().optional().nullable(),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const apiResponseSchema = z.object({
|
||||||
|
meals: z.array(mealSchema),
|
||||||
|
});
|
||||||
|
|
||||||
|
export type Meal = z.infer<typeof mealSchema>;
|
||||||
|
export type ApiResponse = z.infer<typeof apiResponseSchema>;
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,14 @@
|
||||||
import type { Recipe } from "~/types/recipe";
|
import type { ApiResponse, Meal, Recipe } from "~/types/recipe";
|
||||||
|
import { apiResponseSchema } from "~/types/recipe";
|
||||||
|
|
||||||
export function parseRecipeData(data: { meals: unknown }): Recipe[] {
|
export function parseRecipeData(data: ApiResponse): Recipe[] {
|
||||||
return data.meals.map((meal: unknown) => {
|
return apiResponseSchema.parse(data).meals.map((meal: Meal) => {
|
||||||
// Extract ingredients and measurements
|
|
||||||
const ingredients: { name: string; quantity: string }[] = [];
|
const ingredients: { name: string; quantity: string }[] = [];
|
||||||
for (let i = 1; i <= 20; i++) {
|
for (let i = 1; i <= 20; i++) {
|
||||||
const ingredientName = meal[`strIngredient${i}`];
|
const ingredientName = meal[`strIngredient${i}`];
|
||||||
const ingredientQuantity = meal[`strMeasure${i}`];
|
const ingredientQuantity = meal[`strMeasure${i}`];
|
||||||
if (
|
|
||||||
ingredientName &&
|
if (ingredientName?.trim() && ingredientQuantity?.trim()) {
|
||||||
ingredientName.trim() &&
|
|
||||||
ingredientQuantity &&
|
|
||||||
ingredientQuantity.trim()
|
|
||||||
) {
|
|
||||||
ingredients.push({
|
ingredients.push({
|
||||||
name: ingredientName.trim(),
|
name: ingredientName.trim(),
|
||||||
quantity: ingredientQuantity.trim(),
|
quantity: ingredientQuantity.trim(),
|
||||||
|
|
@ -26,7 +22,7 @@ export function parseRecipeData(data: { meals: unknown }): Recipe[] {
|
||||||
videoUrl: meal.strYoutube,
|
videoUrl: meal.strYoutube,
|
||||||
category: meal.strCategory,
|
category: meal.strCategory,
|
||||||
origin: meal.strArea,
|
origin: meal.strArea,
|
||||||
ingredients: ingredients,
|
ingredients,
|
||||||
instructions: meal.strInstructions,
|
instructions: meal.strInstructions,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue