recipe view timer

This commit is contained in:
vabene1111
2024-02-28 21:04:43 +01:00
parent b7533457de
commit c0c26a5a20
6 changed files with 95 additions and 48 deletions

View File

@@ -10,6 +10,8 @@
}, },
"dependencies": { "dependencies": {
"@mdi/font": "7.2.96", "@mdi/font": "7.2.96",
"@types/luxon": "^3.4.2",
"luxon": "^3.4.4",
"pinia": "^2.1.7", "pinia": "^2.1.7",
"vue": "^3.4.15", "vue": "^3.4.15",
"vue-router": "4", "vue-router": "4",

View File

@@ -10,6 +10,7 @@ import vuetify from "@/vuetify";
import ShoppingListPage from "@/pages/ShoppingListPage.vue"; import ShoppingListPage from "@/pages/ShoppingListPage.vue";
import RecipeSearchPage from "@/pages/RecipeSearchPage.vue"; import RecipeSearchPage from "@/pages/RecipeSearchPage.vue";
import RecipeViewPage from "@/pages/RecipeViewPage.vue"; import RecipeViewPage from "@/pages/RecipeViewPage.vue";
import luxonPlugin from "@/plugins/luxonPlugin";
const routes = [ const routes = [
{path: '/', redirect: '/search', name: 'index'}, {path: '/', redirect: '/search', name: 'index'},
@@ -33,5 +34,6 @@ const app = createApp(App)
app.use(createPinia()) app.use(createPinia())
app.use(vuetify) app.use(vuetify)
app.use(router) app.use(router)
app.use(luxonPlugin)
app.mount('#app') app.mount('#app')

View File

@@ -1,16 +1,19 @@
<template> <template>
<tr> <tr>
<template v-if="ingredient.isHeader"> <template v-if="ingredient.isHeader">
<td colspan="4">{{ ingredient.note }}</td> <td colspan="4"><b>{{ ingredient.note }}</b></td>
</template> </template>
<td>{{ ingredient.amount }}</td> <template v-else>
<td><span v-if="ingredient.unit != null">{{ ingredient.unit.name }}</span></td> <td>{{ ingredient.amount }}</td>
<td ><span v-if="ingredient.food != null">{{ ingredient.food.name }}</span></td> <td><span v-if="ingredient.unit != null">{{ ingredient.unit.name }}</span></td>
<td> <td><span v-if="ingredient.food != null">{{ ingredient.food.name }}</span></td>
<v-icon class="far fa-comment" v-if="ingredient.note != ''" @click="show_tooltip = !show_tooltip"> <td>
<v-tooltip v-model="show_tooltip" activator="parent" location="start">{{ ingredient.note }}</v-tooltip> <v-icon class="far fa-comment" v-if="ingredient.note != ''" @click="show_tooltip = !show_tooltip">
</v-icon> <v-tooltip v-model="show_tooltip" activator="parent" location="start">{{ ingredient.note }}</v-tooltip>
</td> </v-icon>
</td>
</template>
</tr> </tr>
</template> </template>
@@ -26,10 +29,10 @@ export default defineComponent({
required: true required: true
} }
}, },
data(){ data() {
return { return {
show_tooltip: false, show_tooltip: false,
} }
}, },
}) })
</script> </script>

View File

@@ -1,12 +1,21 @@
<template> <template>
<v-img cover lazy :src="recipe.image"></v-img>
<v-card> <v-card>
<v-card-title>{{ recipe.name }}</v-card-title> <v-card-title>{{ recipe.name }}</v-card-title>
<v-img max-height="25vh" cover lazy :src="recipe.image">
<!-- TODO placement in image -->
<KeywordsBar :keywords="recipe?.keywords"></KeywordsBar>
<v-chip size="small" color="primary" label>
<v-icon icon="fas fa-calendar" class="mr-2"></v-icon>
{{ recipe.lastCooked }}
</v-chip>
<v-rating v-model="recipe.rating" color="tandoor"></v-rating>
</v-img>
<v-container> <v-container>
<v-row class="text-center text-body-2"> <v-row class="text-center text-body-2">
<v-col class="pt-1 pb-1"> <v-col class="pt-1 pb-1">
@@ -24,36 +33,11 @@
<div class="text-grey"><span v-if="recipe?.servingsText">{{ recipe.servingsText }}</span><span v-else>Servings</span></div> <div class="text-grey"><span v-if="recipe?.servingsText">{{ recipe.servingsText }}</span><span v-else>Servings</span></div>
</template> </template>
</NumberScalerDialog> </NumberScalerDialog>
</v-col> </v-col>
</v-row> </v-row>
</v-container> </v-container>
<v-card-subtitle v-if="recipe?.description"> {{ recipe.description }}</v-card-subtitle>
<v-card-subtitle>
<KeywordsBar :keywords="recipe?.keywords"></KeywordsBar>
</v-card-subtitle>
<v-card-text>
<v-chip size="small" color="primary" label>
<v-icon icon="fa fa-clock" class="mr-2"></v-icon>
{{ recipe.workingTime }} min
</v-chip>
<v-chip size="small" color="primary" label>
<v-icon icon="fas fa-hourglass-half" class="mr-2"></v-icon>
{{ recipe.waitingTime }} min
</v-chip>
<v-chip size="small" color="primary" label>
<v-icon icon="fas fa-calendar" class="mr-2"></v-icon>
{{ recipe.lastCooked }}
</v-chip>
<v-rating v-model="recipe.rating" color="tandoor"></v-rating>
</v-card-text>
</v-card> </v-card>
<v-card class="mt-1"> <v-card class="mt-1">
@@ -65,7 +49,7 @@
<Step :step="s"></Step> <Step :step="s"></Step>
</v-card> </v-card>
<!-- <RecipeActivity :recipe="recipe"></RecipeActivity>--> <!-- <RecipeActivity :recipe="recipe"></RecipeActivity>-->
</template> </template>
@@ -85,9 +69,7 @@ export default defineComponent({
components: {RecipeActivity, Step, StepsOverview, IngredientsTable, NumberScalerDialog, KeywordsBar}, components: {RecipeActivity, Step, StepsOverview, IngredientsTable, NumberScalerDialog, KeywordsBar},
computed: {}, computed: {},
data() { data() {
return { return {}
}
}, },
props: { props: {
recipe: { recipe: {

View File

@@ -5,13 +5,18 @@
<v-col>{{ step.name }}</v-col> <v-col>{{ step.name }}</v-col>
<v-col class="text-right"> <v-col class="text-right">
<v-btn-group density="compact" variant="tonal"> <v-btn-group density="compact" variant="tonal">
<v-btn size="small" color="info" v-if="step.time > 0"><i class="fas fa-stopwatch mr-1"></i> {{ step.time }}</v-btn> <v-btn size="small" color="info" v-if="step.time > 0" @click="startTimer(step.time)"><i class="fas fa-stopwatch mr-1"></i> {{ step.time }}</v-btn>
<v-btn size="small" color="success" ><i class="fas fa-check"></i></v-btn> <v-btn size="small" color="success"><i class="fas fa-check"></i></v-btn>
</v-btn-group> </v-btn-group>
</v-col> </v-col>
</v-row> </v-row>
</v-card-title> </v-card-title>
<v-alert v-if="timer_end != null" :color="timer_color" closable @click:close="timer_end = null">
<v-alert-title><i class="fas fa-stopwatch mr-1"></i> {{ remaining_time }}</v-alert-title>
Finished at {{ finished_at }}
</v-alert>
<IngredientsTable :ingredients="step.ingredients"></IngredientsTable> <IngredientsTable :ingredients="step.ingredients"></IngredientsTable>
<v-card-text v-if="step.instruction?.length > 0"> <v-card-text v-if="step.instruction?.length > 0">
@@ -24,15 +29,58 @@
import {defineComponent, PropType} from 'vue' import {defineComponent, PropType} from 'vue'
import IngredientsTable from "@/components/display/IngredientsTable.vue"; import IngredientsTable from "@/components/display/IngredientsTable.vue";
import {Step} from "@/openapi"; import {Step} from "@/openapi";
import {DateTime, Duration, Interval} from "luxon";
export default defineComponent({ export default defineComponent({
name: "Step", name: "Step",
computed: {
timer_color: function () {
if (this.timer_end != null) {
if (this.time_now > this.timer_end) {
return 'warning'
}
}
return ''
},
remaining_time: function () {
if (this.timer_end != null) {
if (Interval.fromDateTimes(this.time_now, this.timer_end).length() > 0){
return Duration.fromMillis(Interval.fromDateTimes(this.time_now, this.timer_end).length()).toFormat('hh:mm:ss')
} else {
return '00:00:00'
}
}
return ''
},
finished_at: function () {
if (this.timer_end != null) {
return this.timer_end.toLocaleString(DateTime.TIME_SIMPLE)
}
return ''
}
},
components: {IngredientsTable}, components: {IngredientsTable},
props: { props: {
step: { step: {
type: {} as PropType<Step>, type: {} as PropType<Step>,
required: true, required: true,
} }
},
data() {
return {
timer_end: null as null | DateTime,
time_now: DateTime.now(),
}
},
mounted() {
setInterval(() => {
this.time_now = DateTime.now()
}, 500)
},
methods: {
startTimer(minutes: number) {
this.timer_end = DateTime.now().plus({minutes: minutes})
}
} }
}) })
</script> </script>

View File

@@ -226,6 +226,11 @@
"@types/tough-cookie" "*" "@types/tough-cookie" "*"
parse5 "^7.0.0" parse5 "^7.0.0"
"@types/luxon@^3.4.2":
version "3.4.2"
resolved "https://registry.yarnpkg.com/@types/luxon/-/luxon-3.4.2.tgz#e4fc7214a420173cea47739c33cdf10874694db7"
integrity sha512-TifLZlFudklWlMBfhubvgqTXRzLDI5pCbGa4P8a3wPyUQSW+1xQ5eDsreP9DWHX3tjq1ke96uYG/nwundroWcA==
"@types/node@*": "@types/node@*":
version "20.11.19" version "20.11.19"
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.19.tgz#b466de054e9cb5b3831bee38938de64ac7f81195" resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.19.tgz#b466de054e9cb5b3831bee38938de64ac7f81195"
@@ -604,6 +609,11 @@ lru-cache@^6.0.0:
dependencies: dependencies:
yallist "^4.0.0" yallist "^4.0.0"
luxon@^3.4.4:
version "3.4.4"
resolved "https://registry.yarnpkg.com/luxon/-/luxon-3.4.4.tgz#cf20dc27dc532ba41a169c43fdcc0063601577af"
integrity sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA==
magic-string@^0.30.6: magic-string@^0.30.6:
version "0.30.7" version "0.30.7"
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.7.tgz#0cecd0527d473298679da95a2d7aeb8c64048505" resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.7.tgz#0cecd0527d473298679da95a2d7aeb8c64048505"