meal planning

This commit is contained in:
jableader 2024-01-17 22:31:45 +11:00
parent b6d2ac0cbc
commit ca5a9616be
4 changed files with 78 additions and 40 deletions

View file

@ -22,8 +22,8 @@
</div> </div>
<div class="ingredients"> <div class="ingredients">
<h2>Additional Ingredients</h2> <h2>Additional Ingredients</h2>
<ul v-if="meal.ingredients && meal.ingredients.length"> <ul v-if="meal.extra_ingredients && meal.extra_ingredients.length">
<li v-for="ingredient in meal.ingredients" :key="ingredient" class="saved-ingredient"> <li v-for="ingredient in meal.extra_ingredients" :key="ingredient" class="saved-ingredient">
<p> <p>
<compact-parsed-ingredient :ingredient="ingredient" /> <compact-parsed-ingredient :ingredient="ingredient" />
</p> </p>
@ -35,6 +35,7 @@
</div> </div>
<ingredient-add-box @add-ingredient="addIngredient" /> <ingredient-add-box @add-ingredient="addIngredient" />
</div> </div>
<button @click="saveMeal">Save</button>
</div> </div>
</template> </template>
@ -52,17 +53,18 @@ export default {
data() { data() {
return { return {
meal: { meal: {
id: 0,
date: new Date(), date: new Date(),
recipes: [], recipes: [],
ingredients: [], extra_ingredients: [],
chefs: [{ name: 'Ryan' }], chefs: [],
consumers: [{ name: 'Ryan' }, { name: 'Jacob' }], consumers: [],
} }
}; };
}, },
beforeMount() { async beforeMount() {
if (this.id) { if (this.id) {
this.meal = data.getMeal(this.id); this.meal = await data.getMeal(this.id);
} }
}, },
methods: { methods: {
@ -70,18 +72,26 @@ export default {
this.meal.recipes.push(recipe); this.meal.recipes.push(recipe);
}, },
selectDate(date) { selectDate(date) {
console.log("selectDate", date);
this.meal.date = date; this.meal.date = date;
}, },
removeRecipe(recipe) { removeRecipe(recipe) {
this.meal.recipes = this.meal.recipes.filter(r => r.id !== recipe.id); this.meal.recipes = this.meal.recipes.filter(r => r.id !== recipe.id);
}, },
addIngredient(ingredient) { addIngredient(ingredient) {
this.meal.ingredients.push(ingredient); this.meal.extra_ingredients.push(ingredient);
}, },
deleteIngredient(ingredient) { deleteIngredient(ingredient) {
this.meal.ingredients = this.meal.ingredients.filter(i => i != ingredient); this.meal.extra_ingredients = this.meal.extra_ingredients.filter(i => i != ingredient);
}, },
async saveMeal() {
const meal = await data.saveMeal(this.meal);
if (meal?.id) {
this.$router.push(`/meals/${meal.id}`);
return;
}
alert('Failed to save meal');
}
} }
} }
</script> </script>

View file

@ -1,9 +1,44 @@
<template> <template>
<div class="meal-card"> <div class="meal-card">
<h3>{{ dayOfWeek }} <small>{{ date }}</small></h3> <h3>{{ dayOfWeek }} <small>{{ date }}</small></h3>
<h4>{{ meal.recipe.name }}</h4>
<p> Cooked by {{ chef_names }}</p> <p v-if="meal.recipes.length && meal.extra_ingredients.length">
<p> For {{ consumers_names }}</p> <span v-for="recipe in meal.recipes" :key="recipe.id">
{{ recipe.name }}
</span>
with
<span v-for="ingredient in meal.extra_ingredients" :key="ingredient.id">
{{ ingredient.name }}
</span>
</p>
<p v-else-if="meal.recipes.length">
<span v-for="recipe in meal.recipes" :key="recipe.id">
{{ recipe.name }}
</span>
</p>
<p v-else-if="meal.extra_ingredients.length">
<span v-for="ingredient in meal.extra_ingredients" :key="ingredient.id">
{{ ingredient.name }}
</span>
</p>
<p v-else>
Nothing planned
</p>
<p>
Cooked by
<span v-for="chef in meal.chefs" :key="chef.id">
{{ chef.name }}
</span>
<span v-if="!meal.chefs.length">somebody?</span>
</p>
<p>
For
<span v-for="consumer in meal.consumers" :key="consumer.id">
{{ consumer.name }}
</span>
<span v-if="!meal.consumers.length">somebody?</span>
</p>
<a @click="$emit('edit-meal', meal)">Edit</a> <a @click="$emit('edit-meal', meal)">Edit</a>
</div> </div>
</template> </template>
@ -22,12 +57,6 @@ export default {
name: 'MealCard', name: 'MealCard',
props: ['meal'], props: ['meal'],
computed: { computed: {
chef_names() {
return this.meal.chefs.map(chef => chef.name).join(', ')
},
consumers_names() {
return this.meal.consumers.map(consumer => consumer.name).join(', ')
},
date() { date() {
return this.meal.date.toLocaleDateString('en-au', { month: 'numeric', day: 'numeric' }) return this.meal.date.toLocaleDateString('en-au', { month: 'numeric', day: 'numeric' })
}, },

View file

@ -10,8 +10,8 @@
</ul> </ul>
<ul class="actions" v-if="selectedMeal"> <ul class="actions" v-if="selectedMeal">
<li><router-link class="nav-link" to="/meals/{{meal.id}}" active-class="active">Edit Meal</router-link></li> <li><router-link class="nav-link" :to="`/meals/${selectedMeal.id}`" active-class="active">Edit Meal</router-link></li>
<li><router-link class="nav-link" to="/meals/{{meal.id}}/swap" active-class="active">Swap Day</router-link></li> <li><router-link class="nav-link" :to="`/meals/${selectedMeal.id}/swap`" active-class="active">Swap Day</router-link></li>
<li><a @click="deleteSelectedMeal" class="button">Remove</a></li> <li><a @click="deleteSelectedMeal" class="button">Remove</a></li>
<li><a @click="selectedMeal = null">Cancel</a></li> <li><a @click="selectedMeal = null">Cancel</a></li>
</ul> </ul>
@ -59,18 +59,12 @@ export default {
}, },
data() { data() {
const from = new Date(); const from = new Date();
const to = new Date(from.getDate() + 7) const to = new Date();
to.setDate(to.getDate() + 7);
return { return {
from, to, from, to,
meals: [{ meals: [],
'date': new Date(),
'recipe': {'name': 'Sar Tay'},
'chefs': [{
'name': 'Ryan'
}],
'consumers': [{'name': 'Ryan'}, {'name': 'Jacob'}],
}],
selectedMeal: null selectedMeal: null
} }
}, },

View file

@ -2,24 +2,29 @@ const BASE_URL = "http://192.168.68.177:8000"
export default { export default {
async getMeals(from, to) { async getMeals(from, to) {
const response = fetch(BASE_URL + "/meals?from=" + from.toISOString() + "&to=" + to.toISOString()); const response = await fetch(BASE_URL + "/meals?from=" + from.toISOString() + "&to=" + to.toISOString());
return response.json(); const meals = await response.json();
for (const meal of meals) {
meal.date = new Date(meal.date);
}
return meals;
}, },
async getMeal(id) { async getMeal(id) {
var response = await fetch(BASE_URL + `/meals/${encodeURIComponent(id)}`); var response = await fetch(BASE_URL + `/meals/${encodeURIComponent(id)}`);
return response.json(); return await response.json();
}, },
async searchRecipes(query) { async searchRecipes(query) {
const response = await fetch(BASE_URL + "/recipes?q=" + encodeURIComponent(query)); const response = await fetch(BASE_URL + "/recipes?q=" + encodeURIComponent(query));
return response.json(); return await response.json();
}, },
async parseRecipe(url) { async parseRecipe(url) {
const response = await fetch(BASE_URL + `/recipes/parse?url=${encodeURIComponent(url)}`); const response = await fetch(BASE_URL + `/recipes/parse?url=${encodeURIComponent(url)}`);
return response.json(); return await response.json();
}, },
async getRecipe(id) { async getRecipe(id) {
const response = await fetch(BASE_URL + `/recipes/${encodeURIComponent(id)}`); const response = await fetch(BASE_URL + `/recipes/${encodeURIComponent(id)}`);
return response.json(); return await response.json();
}, },
async parseProduct(ingredient, url) { async parseProduct(ingredient, url) {
const body = { const body = {
@ -34,12 +39,12 @@ export default {
body: JSON.stringify(body), body: JSON.stringify(body),
}); });
return response.json(); return await response.json();
}, },
async parseIngredients(lines) { async parseIngredients(lines) {
const params = lines.map(line => "ingredients=" + encodeURIComponent(line)).join("&"); const params = lines.map(line => "ingredients=" + encodeURIComponent(line)).join("&");
const response = await fetch(BASE_URL + "/recipes/ingredients/parse?" + params); const response = await fetch(BASE_URL + "/recipes/ingredients/parse?" + params);
return response.json(); return await response.json();
}, },
async saveRecipe(recipe) { async saveRecipe(recipe) {
const response = await fetch(BASE_URL + "/recipes", { const response = await fetch(BASE_URL + "/recipes", {
@ -50,7 +55,7 @@ export default {
body: JSON.stringify(recipe), body: JSON.stringify(recipe),
}); });
return response.json(); return await response.json();
}, },
async saveMeal(meal) { async saveMeal(meal) {
const response = await fetch(BASE_URL + "/meals", { const response = await fetch(BASE_URL + "/meals", {
@ -61,6 +66,6 @@ export default {
body: JSON.stringify(meal), body: JSON.stringify(meal),
}); });
return response.json(); return await response.json();
}, },
} }