mirror of
https://github.com/TandoorRecipes/recipes.git
synced 2026-01-01 04:10:06 -05:00
start page
This commit is contained in:
9
cookbook/static/vue3/assets/main-C0cQ5WeY.css
Normal file
9
cookbook/static/vue3/assets/main-C0cQ5WeY.css
Normal file
File diff suppressed because one or more lines are too long
29
cookbook/static/vue3/assets/main-Dn7LZ1Sm.js
Normal file
29
cookbook/static/vue3/assets/main-Dn7LZ1Sm.js
Normal file
File diff suppressed because one or more lines are too long
@@ -32,11 +32,11 @@
|
|||||||
"src": "node_modules/@fortawesome/fontawesome-free/webfonts/fa-v4compatibility.woff2"
|
"src": "node_modules/@fortawesome/fontawesome-free/webfonts/fa-v4compatibility.woff2"
|
||||||
},
|
},
|
||||||
"src/apps/tandoor/main.ts": {
|
"src/apps/tandoor/main.ts": {
|
||||||
"file": "assets/main-OseOyQb7.js",
|
"file": "assets/main-Dn7LZ1Sm.js",
|
||||||
"src": "src/apps/tandoor/main.ts",
|
"src": "src/apps/tandoor/main.ts",
|
||||||
"isEntry": true,
|
"isEntry": true,
|
||||||
"css": [
|
"css": [
|
||||||
"assets/main-DFkSTGyd.css"
|
"assets/main-C0cQ5WeY.css"
|
||||||
],
|
],
|
||||||
"assets": [
|
"assets": [
|
||||||
"assets/brand_logo-D4X97p3N.svg",
|
"assets/brand_logo-D4X97p3N.svg",
|
||||||
|
|||||||
@@ -2,44 +2,43 @@
|
|||||||
<v-app>
|
<v-app>
|
||||||
|
|
||||||
|
|
||||||
<v-app-bar color="tandoor" flat density="comfortable" >
|
<v-app-bar color="tandoor" flat density="comfortable">
|
||||||
<v-img class="ms-2" src="../../assets/brand_logo.svg"></v-img>
|
<v-img class="ms-2" src="../../assets/brand_logo.svg"></v-img>
|
||||||
<global-search-dialog></global-search-dialog>
|
<global-search-dialog></global-search-dialog>
|
||||||
<v-spacer></v-spacer>
|
<v-spacer></v-spacer>
|
||||||
<v-btn density="compact" icon="fas fa-ellipsis-v"></v-btn>
|
<v-btn density="compact" icon="fas fa-ellipsis-v"></v-btn>
|
||||||
</v-app-bar>
|
</v-app-bar>
|
||||||
|
|
||||||
|
|
||||||
<v-main>
|
<v-main>
|
||||||
<v-container class="pa-0 ma-0 mb-2">
|
<v-container class="pa-0 ma-0 mb-2">
|
||||||
<router-view></router-view>
|
<router-view></router-view>
|
||||||
</v-container>
|
</v-container>
|
||||||
</v-main>
|
</v-main>
|
||||||
|
|
||||||
<v-bottom-navigation>
|
<v-bottom-navigation>
|
||||||
<v-btn value="recent" to="/search">
|
<v-btn value="recent" to="/search">
|
||||||
<v-icon icon="fas fa-book"/>
|
<v-icon icon="fas fa-book"/>
|
||||||
<span>Recipes</span>
|
<span>Recipes</span>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
|
|
||||||
<v-btn value="favorites" to="/mealplan">
|
<v-btn value="favorites" to="/mealplan">
|
||||||
<v-icon icon="fas fa-calendar-alt"></v-icon>
|
<v-icon icon="fas fa-calendar-alt"></v-icon>
|
||||||
|
|
||||||
<span>MealPlan</span>
|
<span>MealPlan</span>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
|
|
||||||
<v-btn value="nearby" to="/shopping">
|
<v-btn value="nearby" to="/shopping">
|
||||||
<v-icon icon="fas fa-shopping-cart"></v-icon>
|
<v-icon icon="fas fa-shopping-cart"></v-icon>
|
||||||
|
|
||||||
<span>Shopping</span>
|
<span>Shopping</span>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
<v-btn value="nearby" to="/books">
|
<v-btn value="nearby" to="/books">
|
||||||
<v-icon icon="fas fa-book-open"></v-icon>
|
<v-icon icon="fas fa-book-open"></v-icon>
|
||||||
|
|
||||||
<span>Books</span>
|
|
||||||
</v-btn>
|
|
||||||
</v-bottom-navigation>
|
|
||||||
|
|
||||||
|
<span>Books</span>
|
||||||
|
</v-btn>
|
||||||
|
</v-bottom-navigation>
|
||||||
|
|
||||||
|
|
||||||
</v-app>
|
</v-app>
|
||||||
|
|||||||
59
vue3/src/components/display/HorizontalRecipeScroller.vue
Normal file
59
vue3/src/components/display/HorizontalRecipeScroller.vue
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
<template>
|
||||||
|
<v-row justify="space-between">
|
||||||
|
<v-col>
|
||||||
|
<h2>{{ title }}</h2>
|
||||||
|
</v-col>
|
||||||
|
<v-col>
|
||||||
|
<v-btn density="default" variant="outlined" size="x-small" icon="fas fa-chevron-left" @click="scrollList('left', scroll_id)"></v-btn>
|
||||||
|
<v-btn density="default" variant="outlined" size="x-small" icon="fas fa-chevron-right" @click="scrollList('right', scroll_id)"></v-btn>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
|
||||||
|
<v-row>
|
||||||
|
<v-col>
|
||||||
|
|
||||||
|
<v-infinite-scroll direction="horizontal" mode="manual" :id="scroll_id">
|
||||||
|
|
||||||
|
<div v-for="r in recipes" class="mr-2">
|
||||||
|
<recipe-card :recipe="r" :show_description="false" :show_keywords="false" style="width: 45vw; height: 30vh"></recipe-card>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<template #load-more></template>
|
||||||
|
|
||||||
|
</v-infinite-scroll>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import {defineComponent, PropType} from 'vue'
|
||||||
|
import {Recipe, RecipeOverview} from "@/openapi";
|
||||||
|
import RecipeCard from "@/components/display/RecipeCard.vue";
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: "HorizontalRecipeScroller",
|
||||||
|
components: {RecipeCard},
|
||||||
|
props: {
|
||||||
|
title: {type: String, required: true},
|
||||||
|
recipes: {type: Array as PropType<Array<Recipe | RecipeOverview>>, required: true},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
scroll_id: Math.random(1000).toString()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
scrollList(direction: string, target: string) {
|
||||||
|
const newRecipeScroll = document.getElementById(target)
|
||||||
|
if (newRecipeScroll != null) {
|
||||||
|
newRecipeScroll.scrollLeft = newRecipeScroll.scrollLeft + (200 * ((direction == 'left') ? -1 : 1))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -3,19 +3,19 @@
|
|||||||
|
|
||||||
<v-img
|
<v-img
|
||||||
cover
|
cover
|
||||||
height="250"
|
height="50%"
|
||||||
:src="recipe.image"
|
:src="recipe.image"
|
||||||
></v-img>
|
></v-img>
|
||||||
|
|
||||||
<v-card-item>
|
<v-card-item>
|
||||||
<v-card-title>{{ recipe.name }}</v-card-title>
|
<v-card-title>{{ recipe.name }}</v-card-title>
|
||||||
|
|
||||||
<v-card-subtitle>
|
<v-card-subtitle v-if="show_keywords">
|
||||||
<KeywordsComponent :keywords="recipe.keywords"></KeywordsComponent>
|
<KeywordsComponent :keywords="recipe.keywords"></KeywordsComponent>
|
||||||
</v-card-subtitle>
|
</v-card-subtitle>
|
||||||
</v-card-item>
|
</v-card-item>
|
||||||
|
|
||||||
<v-card-text>
|
<v-card-text v-if="show_description">
|
||||||
<v-row align="center" class="mx-0" v-if="recipe.rating">
|
<v-row align="center" class="mx-0" v-if="recipe.rating">
|
||||||
<v-rating
|
<v-rating
|
||||||
:model-value="recipe.rating"
|
:model-value="recipe.rating"
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
size="small"
|
size="small"
|
||||||
></v-rating>
|
></v-rating>
|
||||||
|
|
||||||
<div class="text-grey ms-4">
|
<div class="text-grey ">
|
||||||
{{ recipe.rating }}
|
{{ recipe.rating }}
|
||||||
</div>
|
</div>
|
||||||
</v-row>
|
</v-row>
|
||||||
@@ -46,7 +46,9 @@ export default defineComponent({
|
|||||||
name: "RecipeCard",
|
name: "RecipeCard",
|
||||||
components: {KeywordsComponent},
|
components: {KeywordsComponent},
|
||||||
props: {
|
props: {
|
||||||
recipe: {} as Recipe
|
recipe: {} as Recipe,
|
||||||
|
show_keywords: {type: Boolean, required: false},
|
||||||
|
show_description: {type: Boolean, required: false},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,42 +1,54 @@
|
|||||||
<template>
|
<template>
|
||||||
|
<v-container>
|
||||||
|
|
||||||
|
|
||||||
|
<horizontal-recipe-scroller title="New Recipes" :recipes="new_recipes"></horizontal-recipe-scroller>
|
||||||
|
<horizontal-recipe-scroller title="Top Rated" :recipes="high_rated_recipes"></horizontal-recipe-scroller>
|
||||||
|
|
||||||
|
|
||||||
|
</v-container>
|
||||||
|
|
||||||
|
|
||||||
<!--TODO ideas for "start page": new recipes, meal plan, "last year/month/cooked long ago", high rated, random keyword -->
|
<!--TODO ideas for "start page": new recipes, meal plan, "last year/month/cooked long ago", high rated, random keyword -->
|
||||||
|
|
||||||
<!-- <v-row>-->
|
|
||||||
<!-- <v-col cols="12" sm="3" md="4" v-for="r in recipes" :key="r.id">-->
|
|
||||||
<!-- <RecipeCardComponent :recipe="r"></RecipeCardComponent>-->
|
|
||||||
<!-- </v-col>-->
|
|
||||||
<!-- </v-row>-->
|
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import {defineComponent} from 'vue'
|
import {defineComponent, ref} from 'vue'
|
||||||
import {ApiApi, Recipe} from "@/openapi";
|
import {ApiApi, Recipe, RecipeOverview} from "@/openapi";
|
||||||
import KeywordsComponent from "@/components/display/KeywordsBar.vue";
|
import KeywordsComponent from "@/components/display/KeywordsBar.vue";
|
||||||
import RecipeCardComponent from "@/components/display/RecipeCard.vue";
|
import RecipeCardComponent from "@/components/display/RecipeCard.vue";
|
||||||
import GlobalSearchDialog from "@/components/inputs/GlobalSearchDialog.vue";
|
import GlobalSearchDialog from "@/components/inputs/GlobalSearchDialog.vue";
|
||||||
|
import RecipeCard from "@/components/display/RecipeCard.vue";
|
||||||
|
import HorizontalRecipeScroller from "@/components/display/HorizontalRecipeScroller.vue";
|
||||||
|
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "RecipeSearchPage",
|
name: "RecipeSearchPage",
|
||||||
components: {GlobalSearchDialog, RecipeCardComponent, KeywordsComponent},
|
components: {HorizontalRecipeScroller, RecipeCard, GlobalSearchDialog, RecipeCardComponent, KeywordsComponent},
|
||||||
computed: {
|
computed: {},
|
||||||
|
|
||||||
},
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
recipes: [] as Recipe[],
|
recipes: [] as Recipe[],
|
||||||
|
items: Array.from({length: 50}, (k, v) => v + 1),
|
||||||
|
|
||||||
|
new_recipes: [] as RecipeOverview[],
|
||||||
|
high_rated_recipes: [] as RecipeOverview[],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
const api = new ApiApi()
|
||||||
|
api.apiRecipeList({_new: 'true'}).then(r => {
|
||||||
|
if (r.results != undefined) { // TODO why this check, worst case its empty
|
||||||
|
this.new_recipes = r.results
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
api.apiRecipeList({rating: 4}).then(r => {
|
||||||
|
if (r.results != undefined) { // TODO why this check, worst case its empty
|
||||||
|
this.high_rated_recipes = r.results
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|||||||
Reference in New Issue
Block a user