238 lines
6.2 KiB
Vue
238 lines
6.2 KiB
Vue
<template>
|
|
<div>
|
|
<div v-if="recipe === null">
|
|
Loading...
|
|
</div>
|
|
<div v-else>
|
|
<div class="level is-mobile">
|
|
|
|
<div class="level-item has-text-centered">
|
|
<div>
|
|
<p class="heading">Time</p>
|
|
<p class="title is-6">{{timeDisplay}}</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="level-item has-text-centered">
|
|
<div>
|
|
<p class="heading">Yields</p>
|
|
<p class="title is-6">{{recipe.yields}}</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="level-item has-text-centered">
|
|
<div>
|
|
<p class="heading">Source</p>
|
|
<p class="title is-6">{{recipe.source}}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="columns">
|
|
<div class="column is-one-third-desktop">
|
|
<div class="message">
|
|
<div class="message-header">
|
|
Ingredients
|
|
<button class="button is-small is-primary" type="button" @click="showConvertDialog = true">Convert</button>
|
|
</div>
|
|
<div class="message-body content">
|
|
<ul v-if="recipe.ingredients.length > 0" v-click-strike>
|
|
<li v-for="i in recipe.ingredients">
|
|
{{i.display_name}}
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="column">
|
|
<div class="message">
|
|
<div class="message-header">Directions</div>
|
|
<div class="message-body content" v-html="recipe.rendered_steps" v-click-strike>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="message">
|
|
<div class="message-header" @click="showNutrition = !showNutrition">Nutrition Data</div>
|
|
<div class="message-body" v-show="showNutrition">
|
|
<table class="table">
|
|
<tr>
|
|
<th>Item</th>
|
|
<th>Value</th>
|
|
</tr>
|
|
<tr v-for="nutrient in recipe.nutrition_data.nutrients" :key="nutrient.name">
|
|
<td>{{nutrient.label}}</td>
|
|
<td>{{nutrient.value}}</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<h3 class="title is-5">Nutrition Calculation Warnings</h3>
|
|
<ul>
|
|
<li v-for="warn in recipe.nutrition_data.errors" :key="warn">
|
|
{{warn}}
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<app-modal :open="showConvertDialog" @dismiss="showConvertDialog = false" title="Convert Recipe">
|
|
<div class="field">
|
|
<label class="label">Scale</label>
|
|
<div class="control">
|
|
<div class="select">
|
|
<select v-model="scaleValue">
|
|
<option v-for="s in scaleOptions" :key="s" :value="s">{{s}}</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="field">
|
|
<label class="label">System</label>
|
|
<div class="control">
|
|
<label class="radio">
|
|
<input type="radio" value="" v-model="systemConvertValue" />
|
|
No System Conversion
|
|
</label>
|
|
|
|
<label class="radio">
|
|
<input type="radio" value="standard" v-model="systemConvertValue" />
|
|
Convert to Standard Units
|
|
</label>
|
|
|
|
<label class="radio">
|
|
<input type="radio" value="metric" v-model="systemConvertValue" />
|
|
Convert to Metric Units
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="field">
|
|
<label class="label">Unit</label>
|
|
<div class="control">
|
|
<label class="radio">
|
|
<input type="radio" value="" v-model="unitConvertValue" />
|
|
No Unit Conversion
|
|
</label>
|
|
|
|
<label class="radio">
|
|
<input type="radio" value="volume" v-model="unitConvertValue" />
|
|
Convert to Volume Units
|
|
</label>
|
|
|
|
<label class="radio">
|
|
<input type="radio" value="mass" v-model="unitConvertValue" />
|
|
Convert to Mass Units
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="buttons">
|
|
<button type="button" class="button is-primary" @click="convert">Convert</button>
|
|
<button type="button" class="button" @click="showConvertDialog = false">Close</button>
|
|
</div>
|
|
</app-modal>
|
|
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
|
|
export default {
|
|
props: {
|
|
recipe: {
|
|
required: true,
|
|
type: Object
|
|
}
|
|
},
|
|
|
|
data() {
|
|
return {
|
|
showNutrition: false,
|
|
showConvertDialog: false,
|
|
|
|
scaleValue: '1',
|
|
systemConvertValue: "",
|
|
unitConvertValue: "",
|
|
|
|
scaleOptions: [
|
|
'1/4',
|
|
'1/3',
|
|
'1/2',
|
|
'2/3',
|
|
'3/4',
|
|
'1',
|
|
'1 1/2',
|
|
'2',
|
|
'3',
|
|
'4'
|
|
]
|
|
};
|
|
},
|
|
|
|
computed: {
|
|
timeDisplay() {
|
|
let a = this.formatMinutes(this.recipe.active_time);
|
|
const t = this.formatMinutes(this.recipe.total_time);
|
|
|
|
if (a) {
|
|
a = ` (${a} active)`;
|
|
}
|
|
|
|
return t + a;
|
|
}
|
|
},
|
|
|
|
watch: {
|
|
recipe: {
|
|
handler: function(r) {
|
|
if (r) {
|
|
this.scaleValue = r.converted_scale || '1';
|
|
this.systemConvertValue = r.converted_system;
|
|
this.unitConvertValue = r.converted_unit;
|
|
}
|
|
},
|
|
immediate: true
|
|
}
|
|
},
|
|
|
|
methods: {
|
|
convert() {
|
|
this.showConvertDialog = false;
|
|
this.$router.push({name: 'recipe', query: { scale: this.scaleValue, system: this.systemConvertValue, unit: this.unitConvertValue }});
|
|
},
|
|
|
|
formatMinutes(min) {
|
|
if (min) {
|
|
const partUnits = [
|
|
{unit: "d", minutes: 60 * 24},
|
|
{unit: "h", minutes: 60},
|
|
{unit: "m", minutes: 1}
|
|
];
|
|
|
|
const parts = [];
|
|
let remaining = min;
|
|
|
|
for (let unit of partUnits) {
|
|
let val = Math.floor(remaining / unit.minutes);
|
|
remaining = remaining % unit.minutes;
|
|
|
|
if (val > 0) {
|
|
parts.push(`${val} ${unit.unit}`);
|
|
}
|
|
}
|
|
|
|
return parts.join(" ");
|
|
} else {
|
|
return "";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
</style> |