127 lines
3.2 KiB
Vue
127 lines
3.2 KiB
Vue
|
|
<template>
|
||
|
|
|
||
|
|
<ul>
|
||
|
|
<li v-for="meal in meals" :key="meal.id">
|
||
|
|
<!-- Have a checkbox and card for each meal, show the image and name -->
|
||
|
|
<!-- Emit meal-selected event on checked and meal-unselected on unchecked -->
|
||
|
|
<input type="checkbox" :id="meal.id" @change="$emit('meal-selected', meal)" />
|
||
|
|
<label :for="meal.id" :style="getImageStyling(meal)">
|
||
|
|
{{ meal.meal_date.toLocaleDateString('en-AU', { weekday: 'long', day: 'numeric', month: 'long' }) }}
|
||
|
|
</label>
|
||
|
|
</li>
|
||
|
|
</ul>
|
||
|
|
|
||
|
|
</template>
|
||
|
|
|
||
|
|
<style scoped>
|
||
|
|
|
||
|
|
ul {
|
||
|
|
padding: 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
li {
|
||
|
|
display: inline-block;
|
||
|
|
list-style-type: none;
|
||
|
|
border: 1px solid #ccc;
|
||
|
|
border-radius: 0.5em;
|
||
|
|
margin-bottom: 1em;
|
||
|
|
padding: none;
|
||
|
|
overflow: hidden;
|
||
|
|
text-align: center;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Hide the default checkbox formatting, and format the card instead */
|
||
|
|
input[type="checkbox"] {
|
||
|
|
display: none;
|
||
|
|
}
|
||
|
|
|
||
|
|
label {
|
||
|
|
display: inline-block;
|
||
|
|
padding: 1em;
|
||
|
|
width: 10em;
|
||
|
|
height: 10em;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Give the card a thick pastel green stroke when checked */
|
||
|
|
input[type="checkbox"]:checked + label {
|
||
|
|
border: 0.5em solid #8FBC8F;
|
||
|
|
/* Reduce the size to account for the border */
|
||
|
|
width: 9em;
|
||
|
|
height: 9em;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Show the image as the background image of the card */
|
||
|
|
.meal-image {
|
||
|
|
width: 100%;
|
||
|
|
height: 100%;
|
||
|
|
object-fit: cover;
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Position the text in the center of the card */
|
||
|
|
label {
|
||
|
|
display: flex;
|
||
|
|
justify-content: center;
|
||
|
|
align-items: center;
|
||
|
|
font-size: larger;
|
||
|
|
font-weight: bold;
|
||
|
|
}
|
||
|
|
|
||
|
|
</style>
|
||
|
|
|
||
|
|
<script>
|
||
|
|
|
||
|
|
import data from '@/data.js'
|
||
|
|
|
||
|
|
export default {
|
||
|
|
name: 'MealSelectionList',
|
||
|
|
data() {
|
||
|
|
const from = new Date();
|
||
|
|
from.setTime(0);
|
||
|
|
|
||
|
|
const to = new Date();
|
||
|
|
to.setDate(to.getDate() + 7);
|
||
|
|
|
||
|
|
return { from, to, meals: [], }
|
||
|
|
},
|
||
|
|
async beforeMount() {
|
||
|
|
const meals = await data.getMeals(this.from, this.to)
|
||
|
|
this.meals = meals;
|
||
|
|
},
|
||
|
|
methods: {
|
||
|
|
getImageStyling(meal) {
|
||
|
|
let image = null;
|
||
|
|
// First non empty value in meal.recipe/image_urls
|
||
|
|
for (const recipe of meal.recipes) {
|
||
|
|
if (recipe.image_urls.length && recipe.image_urls[0]) {
|
||
|
|
image = recipe.image_urls[0];
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!image) {
|
||
|
|
// First meal.extra_ingredient with a product with an image
|
||
|
|
for (const ingredient of meal.extra_ingredients) {
|
||
|
|
if (ingredient.product) {
|
||
|
|
if (ingredient.product.img_large) {
|
||
|
|
image = ingredient.product.img_large;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (ingredient.product.img_small) {
|
||
|
|
image = ingredient.product.img_small;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!image) {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
return {background: `linear-gradient(to bottom, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 50%, rgba(255, 255, 255, 0) 100%), url('${image}') center/cover no-repeat` }
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
</script>
|