Squashed commit of the following:
commit c5461420e7f1022019b79517d853a26301add9e9
Author: jableader <jacobdunk@gmail.com>
Date: Sat Sep 28 14:55:18 2024 +1000
meal scaling improvements
commit 37a444ff1fb5cbd1942161a8097a44fa7483b14c
Author: jableader <jacobdunk@gmail.com>
Date: Sat Sep 28 13:13:06 2024 +1000
Implementation
This commit is contained in:
parent
e59d4aa0ed
commit
531e4f057f
5 changed files with 85 additions and 21 deletions
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"name": "doof-front",
|
"name": "doof",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
|
||||||
|
|
@ -11,11 +11,17 @@
|
||||||
<div class="recipes">
|
<div class="recipes">
|
||||||
<h2>Recipes</h2>
|
<h2>Recipes</h2>
|
||||||
<ul v-if="meal.recipes && meal.recipes.length">
|
<ul v-if="meal.recipes && meal.recipes.length">
|
||||||
<li v-for="recipe in meal.recipes" :key="recipe.id" class="saved-recipe">
|
<li v-for="meal_recipe in meal.recipes" :key="meal_recipe.recipe.id" class="saved-recipe">
|
||||||
<p class="recipe-card">
|
<p class="recipe-card">
|
||||||
<recipe-card :recipe="recipe" />
|
<recipe-card :recipe="meal_recipe.recipe" />
|
||||||
</p>
|
</p>
|
||||||
<button @click="removeRecipe(recipe)">
|
|
||||||
|
<p class="servings">
|
||||||
|
<input type="number" v-model="meal_recipe.servings" min="1" />
|
||||||
|
<small><em>servings</em></small>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<button class="delete-button" @click="removeRecipe(meal_recipe)">
|
||||||
<img class="icon" :src="require('@/assets/trash.svg')" />
|
<img class="icon" :src="require('@/assets/trash.svg')" />
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
|
|
@ -31,7 +37,10 @@
|
||||||
<h2>Sides & Additional Ingredients</h2>
|
<h2>Sides & Additional Ingredients</h2>
|
||||||
<editable-ingredients-panel :ingredients="meal.extra_ingredients" @on-add="addIngredient" @on-delete="deleteIngredient" @on-update-ingredient="updateIngredient" @on-editing="onEditAdditionalIngredients" />
|
<editable-ingredients-panel :ingredients="meal.extra_ingredients" @on-add="addIngredient" @on-delete="deleteIngredient" @on-update-ingredient="updateIngredient" @on-editing="onEditAdditionalIngredients" />
|
||||||
</div>
|
</div>
|
||||||
<button @click="saveMeal" v-if="!meal.purchase_date">Save</button>
|
|
||||||
|
<button @click="saveMeal">Save</button>
|
||||||
|
<p v-if="meal.purchase_date"><em>Purchased {{ formatDate(meal.purchase_date) }}</em></p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -90,13 +99,36 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.meal.recipes.push(recipe);
|
this.meal.recipes.push({ recipe, recipe_id: recipe.id, meal_id: this.meal.id, servings: recipe.serves });
|
||||||
},
|
},
|
||||||
selectDate(date) {
|
selectDate(date) {
|
||||||
this.meal.suggested_date = date;
|
this.meal.suggested_date = date;
|
||||||
},
|
},
|
||||||
removeRecipe(recipe) {
|
formatDate(date) {
|
||||||
this.meal.recipes = this.meal.recipes.filter(r => r.id !== recipe.id);
|
// If it's today, show 'x hours ago'
|
||||||
|
// If it's within the last week, show 'x days ago'
|
||||||
|
// If it's within the last month weeks, show 'x weeks ago'
|
||||||
|
// Otherwise, show the date as dd/mm
|
||||||
|
const now = new Date();
|
||||||
|
const diff = now - date;
|
||||||
|
const days = Math.floor(diff / (1000 * 60 * 60 * 24));
|
||||||
|
if (days === 0) {
|
||||||
|
const hours = Math.floor(diff / (1000 * 60 * 60));
|
||||||
|
return `${hours} hour${hours === 1 ? '' : 's'} ago`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (days < 7) {
|
||||||
|
return `${days} day${days === 1 ? '' : 's'} ago`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (days < 30) {
|
||||||
|
return `${Math.floor(days / 7)} week${days === 7 ? '' : 's'} ago`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return date.toLocaleDateString('en-au', { day: 'numeric', month: 'numeric' });
|
||||||
|
},
|
||||||
|
removeRecipe(mealRecipe) {
|
||||||
|
this.meal.recipes = this.meal.recipes.filter(r => r != mealRecipe);
|
||||||
},
|
},
|
||||||
addIngredient() {
|
addIngredient() {
|
||||||
this.meal.extra_ingredients = [{ line: '', product: null }, ...this.meal.extra_ingredients];
|
this.meal.extra_ingredients = [{ line: '', product: null }, ...this.meal.extra_ingredients];
|
||||||
|
|
@ -198,4 +230,35 @@ li {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.recipe-card {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.servings {
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.servings input {
|
||||||
|
width: 3em;
|
||||||
|
border: none;
|
||||||
|
border-bottom: 1px solid #000;
|
||||||
|
text-align: center;
|
||||||
|
font-size: large;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.delete-button {
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 1em;
|
||||||
|
padding: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.delete-button:hover {
|
||||||
|
/* Invert the colors of the trash icon */
|
||||||
|
filter: invert(1);
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
@ -3,8 +3,8 @@
|
||||||
<h3>{{ dayOfWeek }} <small>{{ date }}</small></h3>
|
<h3>{{ dayOfWeek }} <small>{{ date }}</small></h3>
|
||||||
|
|
||||||
<p v-if="meal.recipes.length && meal.extra_ingredients.length">
|
<p v-if="meal.recipes.length && meal.extra_ingredients.length">
|
||||||
<span v-for="(recipe, index) in meal.recipes" :key="recipe.id">
|
<span v-for="(meal_recipe, index) in meal.recipes" :key="meal_recipe.recipe.id">
|
||||||
{{ recipe.name }}{{ seperator(index, meal.recipes) }}
|
{{ meal_recipe.recipe.name }}{{ seperator(index, meal.recipes) }}
|
||||||
</span>
|
</span>
|
||||||
with
|
with
|
||||||
<span v-for="(ingredient, index) in meal.extra_ingredients" :key="ingredient.id">
|
<span v-for="(ingredient, index) in meal.extra_ingredients" :key="ingredient.id">
|
||||||
|
|
@ -12,8 +12,8 @@
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
<p v-else-if="meal.recipes.length">
|
<p v-else-if="meal.recipes.length">
|
||||||
<span v-for="(recipe, index) in meal.recipes" :key="recipe.id">
|
<span v-for="(meal_recipe, index) in meal.recipes" :key="meal_recipe.recipe.id">
|
||||||
{{ recipe.name }}{{ seperator(index, meal.recipes) }}
|
{{ meal_recipe.recipe.name }}{{ seperator(index, meal.recipes) }}
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
<p v-else-if="meal.extra_ingredients.length">
|
<p v-else-if="meal.extra_ingredients.length">
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,8 @@ const formatDate = (date) => {
|
||||||
|
|
||||||
const getUrl = (meal) => {
|
const getUrl = (meal) => {
|
||||||
// First non empty value in meal.recipe/image_urls
|
// First non empty value in meal.recipe/image_urls
|
||||||
for (const recipe of meal.recipes) {
|
for (const mr of meal.recipes) {
|
||||||
|
const recipe = mr.recipe;
|
||||||
if (recipe.image_urls.length && recipe.image_urls[0]) {
|
if (recipe.image_urls.length && recipe.image_urls[0]) {
|
||||||
return recipe.image_urls[0];
|
return recipe.image_urls[0];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,19 @@
|
||||||
import units from '@/units.js';
|
import units from '@/units.js';
|
||||||
|
|
||||||
function scaleFactor(meal, recipe) {
|
function scaleFactor(mealRecipe) {
|
||||||
const numYield = recipe.serves;
|
const numRecipe = mealRecipe.recipe.serves;
|
||||||
const numConsumers = meal.consumers.length;
|
const numRequested = mealRecipe.servings;
|
||||||
|
|
||||||
return numConsumers / numYield;
|
return numRequested / numRecipe;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function mealToShoppingListSources(meal) {
|
export function mealToShoppingListSources(meal) {
|
||||||
const sources = [];
|
const sources = [];
|
||||||
for (const recipe of meal.recipes) {
|
for (const mealRecipe of meal.recipes) {
|
||||||
const scale = scaleFactor(meal, recipe);
|
const scale = scaleFactor(mealRecipe);
|
||||||
for (const ingredient of recipe.ingredients) {
|
for (const ingredient of mealRecipe.recipe.ingredients) {
|
||||||
const quantity = ingredient.quantity * scale;
|
const quantity = ingredient.quantity * scale;
|
||||||
sources.push({ meal, recipe, ingredient: { ...ingredient, quantity, }, });
|
sources.push({ meal, mealRecipe, recipe: mealRecipe.recipe, ingredient: { ...ingredient, quantity, }, });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue