munch-ease-frontend/src/components/recipes/EditRecipePage.vue

153 lines
4.8 KiB
Vue
Raw Normal View History

2024-01-13 02:00:15 +00:00
<template>
<div>
2024-01-13 08:43:15 +00:00
<div v-if="!id && !recipe">
2024-05-04 01:52:31 +00:00
<input class="recipe-link" type="text" v-model="link" placeholder="Link to Recipe" /> <br />
2024-01-13 02:00:15 +00:00
<button @click="parseLink">Parse</button>
2024-05-04 01:52:31 +00:00
<button @click="createFromScratch">Create from Scratch</button>
2024-01-13 02:00:15 +00:00
</div>
2024-01-13 08:43:15 +00:00
2024-01-13 03:22:10 +00:00
<div v-if="parse_failed">
2024-01-13 02:00:15 +00:00
<p>Recipe not found</p>
</div>
2024-01-13 03:22:10 +00:00
<div v-if="!parse_failed && recipe">
2024-01-13 08:43:15 +00:00
<div class="image-container" v-if="image_styling" :style="image_styling" ></div>
2024-05-04 02:24:22 +00:00
<h1><input class="recipe-name" type="text" v-model="recipe.name" /></h1>
2024-05-19 11:22:58 +00:00
<label for="recipe-serves">Number of serves: </label>
<input type="number" v-model="recipe.serves" />
2024-01-13 08:43:15 +00:00
<h3 class="recipe-link"><a :href="recipe.link">View Recipe</a></h3>
<h2>Ingredients</h2>
2024-05-12 07:00:26 +00:00
<editable-ingredients-panel
:ingredients="recipe.ingredients"
:edit-only="true"
@on-add="addIngredient" @on-delete="deleteIngredient" @on-update-ingredient="updateIngredient"
/>
2024-05-04 02:00:05 +00:00
2024-05-04 02:24:22 +00:00
<div>
<button v-if="recipe.id" class="delete-btn" @click="deleteRecipe">Delete</button>
<button class="submit-btn" @click="saveRecipe">{{ recipe.id ? "Save" : "Create" }}</button>
</div>
2024-01-13 02:00:15 +00:00
</div>
</div>
</template>
<style scoped>
input {
border: 0;
border-bottom: 1px solid #ccc;
font-size: large;
}
input.recipe-link {
width: 80%;
}
2024-01-13 08:43:15 +00:00
.image-container {
max-height: 20vh;
min-height: 20vh;
display: flex;
flex-direction: column;
}
2024-01-13 02:00:15 +00:00
input.recipe-name {
width: 100%;
2024-01-13 08:43:15 +00:00
font-weight: bold;
font-size: larger;
}
.recipe-link {
color: #0000EE;
text-decoration: none;
2024-01-13 02:00:15 +00:00
}
</style>
<script>
2024-09-22 02:58:25 +00:00
import alert from '@/alert.js'
2024-01-13 02:00:15 +00:00
import data from '@/data.js'
2024-05-12 07:00:26 +00:00
import EditableIngredientsPanel from '@/components/ingredients/EditableIngredientsPanel.vue'
2024-01-13 02:00:15 +00:00
export default {
props: {
id: { type: Number, optional: true }
},
2024-05-12 07:00:26 +00:00
components: { EditableIngredientsPanel },
2024-01-13 02:00:15 +00:00
data() {
return {
2024-01-13 03:22:10 +00:00
link: this.$route.query.url ?? "",
parse_failed: false,
2024-01-13 02:00:15 +00:00
recipe: null,
2024-01-13 08:43:15 +00:00
chefs: [],
2024-01-13 02:00:15 +00:00
}
},
mounted() {
2024-01-13 03:22:10 +00:00
this.refreshRecipe();
},
2024-01-13 08:43:15 +00:00
computed: {
image_styling() {
if (this.recipe?.image_urls && this.recipe.image_urls[0]) {
const image = this.recipe.image_urls[0];
// linear-gradient(to bottom, rgba(255, 255, 255, 0.8) 0%, rgba(255, 255, 255, 0) 100%), url('https://i2.wp.com/www.downshiftology.com/wp-content/uploads/2019/04/steamed-broccoli-4.jpg') center/cover no-repeat;
return {background: `linear-gradient(to bottom, rgba(255, 255, 255, 0.8) 0%, rgba(255, 255, 255, 0) 100%), url('${image}') center/cover no-repeat` }
}
return null;
}
},
2024-01-13 03:22:10 +00:00
methods: {
parseLink() {
this.$router.push({ path: '/recipes/add', query: { url: this.link }})
this.refreshRecipe();
},
2024-01-17 09:17:22 +00:00
async refreshRecipe() {
2024-05-20 12:16:39 +00:00
if (this.id >= 0) {
2024-01-17 09:17:22 +00:00
this.recipe = await data.getRecipe(this.id);
this.link = this.recipe.link;
2024-01-13 07:00:55 +00:00
return;
}
else if (this.link) {
2024-01-17 09:17:22 +00:00
this.recipe = await data.parseRecipe(this.link);
this.parse_failed = !this.recipe;
2024-01-13 07:00:55 +00:00
}
else {
2024-01-13 03:22:10 +00:00
this.recipe = null;
}
2024-01-13 02:00:15 +00:00
},
2024-05-12 07:00:26 +00:00
async updateIngredient(ingredient, newIngredient) {
this.recipe.ingredients = this.recipe.ingredients.map(i => i == ingredient ? newIngredient : i);
2024-01-13 02:00:15 +00:00
},
2024-01-13 06:36:02 +00:00
deleteIngredient(ingredient) {
this.recipe.ingredients = this.recipe.ingredients.filter(i => i != ingredient);
},
2024-01-17 09:17:22 +00:00
async saveRecipe() {
const recipe = await data.saveRecipe(this.recipe);
2024-05-20 12:16:39 +00:00
if (recipe?.id >= 0) {
2024-09-22 02:58:25 +00:00
alert.show({ heading: 'Recipe saved', message: 'Your recipe has been saved', type: 'success' });
2024-01-17 09:17:22 +00:00
this.$router.push(`/recipes/${recipe.id}`);
return;
}
2024-09-22 02:58:25 +00:00
alert.show({ heading: 'Error saving recipe', message: 'There was an error saving your recipe', type: 'error' });
2024-05-04 01:52:31 +00:00
},
async createFromScratch() {
this.recipe = {
2024-05-20 12:16:39 +00:00
id: -1,
2024-05-04 01:52:31 +00:00
name: 'My new recipe',
2024-05-20 12:16:39 +00:00
created_by_id: -1,
2024-05-04 01:52:31 +00:00
link: '',
ingredients: [],
image_urls: []
}
2024-05-04 02:00:05 +00:00
},
addIngredient() {
2024-05-12 07:00:26 +00:00
this.recipe.ingredients = [{ line: '', product: null }, ...this.recipe.ingredients];
2024-05-04 02:24:22 +00:00
},
async deleteRecipe() {
if (confirm('Are you sure you want to delete this recipe?')) {
await data.deleteRecipe(this.recipe.id);
this.$router.push('/recipes');
2024-05-04 02:24:22 +00:00
}
2024-01-13 03:22:10 +00:00
}
2024-01-13 02:00:15 +00:00
},
}
</script>