mirror of
https://github.com/TandoorRecipes/recipes.git
synced 2025-12-24 02:39:20 -05:00
start page taking shape
This commit is contained in:
59
vue3/src/assets/recipe_no_image.svg
Normal file
59
vue3/src/assets/recipe_no_image.svg
Normal file
@@ -0,0 +1,59 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
aria-hidden="true"
|
||||
focusable="false"
|
||||
data-prefix="fas"
|
||||
data-icon="pizza-slice"
|
||||
class="svg-inline--fa fa-pizza-slice fa-w-16"
|
||||
role="img"
|
||||
viewBox="0 0 512 512"
|
||||
version="1.1"
|
||||
id="svg4"
|
||||
sodipodi:docname="recipe_no_image.svg"
|
||||
inkscape:version="0.92.4 (5da689c313, 2019-01-14)">
|
||||
<metadata
|
||||
id="metadata10">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs8" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2066"
|
||||
id="namedview6"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.921875"
|
||||
inkscape:cx="-25.662611"
|
||||
inkscape:cy="214.71807"
|
||||
inkscape:window-x="2869"
|
||||
inkscape:window-y="54"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg4" />
|
||||
<path
|
||||
d="m 235.62851,202.1526 c -3.38906,-0.31992 -6.54323,1.7722 -7.40937,5.07666 l -3.10593,11.84344 c 39.34747,1.15551 65.965,27.49017 67.63017,66.72064 l 11.9414,-3.32129 c 3.29677,-0.91767 5.34573,-4.14216 4.95356,-7.55606 -4.37894,-38.04972 -35.85985,-69.14953 -74.00983,-72.76339 z m -12.26226,23.57322 -20.94044,79.87325 a 3.3995443,3.4118034 0 0 0 4.19438,4.15688 L 286.10367,287.635 c -0.8955,-36.81001 -25.8122,-61.48823 -62.73742,-61.90076 z m 5.78824,63.9529 a 6.7110067,6.7352075 0 1 1 6.711,-6.73521 6.7110067,6.7352075 0 0 1 -6.711,6.73521 z M 239.221,257.68648 a 6.7110067,6.7352075 0 1 1 6.71101,-6.7352 6.7110067,6.7352075 0 0 1 -6.71101,6.7352 z m 21.81077,21.88943 a 6.7110067,6.7352075 0 1 1 6.71101,-6.73521 6.7110067,6.7352075 0 0 1 -6.71101,6.73521 z"
|
||||
id="path2"
|
||||
style="fill:#d9cfbe;fill-opacity:1;stroke-width:0.21009675"
|
||||
inkscape:connector-curvature="0" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.4 KiB |
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<v-row justify="space-between">
|
||||
<v-col>
|
||||
<h2>{{ title }}</h2>
|
||||
<h2><i v-if="icon != 'undefined'" :class="icon + ' fa-fw'"></i> {{ title }}</h2>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
@@ -18,6 +18,19 @@
|
||||
</v-window>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<v-row v-if="recipeWindows.length == 0 && skeletons > 0">
|
||||
<v-col>
|
||||
<v-window >
|
||||
<v-window-item>
|
||||
<v-row>
|
||||
<v-col v-for="n in skeletons">
|
||||
<v-skeleton-loader :elevation="3" type="card"></v-skeleton-loader>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-window-item>
|
||||
</v-window>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
</template>
|
||||
|
||||
@@ -32,7 +45,9 @@ const {mdAndUp} = useDisplay()
|
||||
|
||||
const props = defineProps(
|
||||
{
|
||||
title: {type: String, required: true},
|
||||
title: {type: String as PropType<undefined|String>, required: true},
|
||||
icon: {type: String, required: false},
|
||||
skeletons: {type: Number, default: 0},
|
||||
recipes: {
|
||||
type: Array as PropType<Recipe[] | RecipeOverview[]>,
|
||||
required: true
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
<template>
|
||||
<v-card :to="`/recipe/${recipe.id}`">
|
||||
|
||||
<v-img
|
||||
<v-img v-if="recipe.image != null"
|
||||
cover
|
||||
height="50%"
|
||||
:src="recipe.image"
|
||||
></v-img>
|
||||
<v-img v-else src="../../assets/recipe_no_image.svg" cover
|
||||
height="50%"></v-img>
|
||||
|
||||
<v-card-item>
|
||||
<v-card-title>{{ recipe.name }}</v-card-title>
|
||||
@@ -38,15 +40,15 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {defineComponent} from 'vue'
|
||||
import {defineComponent, PropType} from 'vue'
|
||||
import KeywordsComponent from "@/components/display/KeywordsBar.vue";
|
||||
import {Recipe} from "@/openapi";
|
||||
import {Recipe, RecipeOverview} from "@/openapi";
|
||||
|
||||
export default defineComponent({
|
||||
name: "RecipeCard",
|
||||
components: {KeywordsComponent},
|
||||
props: {
|
||||
recipe: {} as Recipe,
|
||||
recipe: {type: {} as PropType<Recipe|RecipeOverview>, required: true,},
|
||||
show_keywords: {type: Boolean, required: false},
|
||||
show_description: {type: Boolean, required: false},
|
||||
}
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
<v-container>
|
||||
|
||||
<!--TODO ideas for "start page": new recipes, meal plan, "last year/month/cooked long ago", high rated, random keyword -->
|
||||
<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>
|
||||
<horizontal-recipe-scroller title="New Recipes" :skeletons="4" :recipes="new_recipes" icon="fas fa-calendar-alt"></horizontal-recipe-scroller>
|
||||
<horizontal-recipe-scroller title="Top Rated" :skeletons="2" :recipes="high_rated_recipes" icon="fas fa-star"></horizontal-recipe-scroller>
|
||||
<horizontal-recipe-scroller :title="random_keyword.label" :skeletons="4" :recipes="random_keyword_recipes" icon="fas fa-tags"></horizontal-recipe-scroller>
|
||||
|
||||
</v-container>
|
||||
|
||||
@@ -11,7 +12,7 @@
|
||||
|
||||
<script lang="ts">
|
||||
import {defineComponent, ref} from 'vue'
|
||||
import {ApiApi, Recipe, RecipeOverview} from "@/openapi";
|
||||
import {ApiApi, Keyword, Recipe, RecipeOverview} from "@/openapi";
|
||||
import KeywordsComponent from "@/components/display/KeywordsBar.vue";
|
||||
import RecipeCardComponent from "@/components/display/RecipeCard.vue";
|
||||
import GlobalSearchDialog from "@/components/inputs/GlobalSearchDialog.vue";
|
||||
@@ -30,22 +31,34 @@ export default defineComponent({
|
||||
|
||||
new_recipes: [] as RecipeOverview[],
|
||||
high_rated_recipes: [] as RecipeOverview[],
|
||||
random_keyword: {} as Keyword,
|
||||
random_keyword_recipes: [] as RecipeOverview[],
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
const api = new ApiApi()
|
||||
api.apiRecipeList({_new: 'true'}).then(r => {
|
||||
if (r.results != undefined) { // TODO why this check, worst case its empty
|
||||
api.apiRecipeList({_new: 'true', pageSize: 16}).then(r => {
|
||||
if (r.results != undefined) { // TODO openapi generator makes arrays nullable for some reason
|
||||
this.new_recipes = r.results
|
||||
}
|
||||
})
|
||||
|
||||
api.apiRecipeList({rating: 4}).then(r => {
|
||||
if (r.results != undefined) { // TODO why this check, worst case its empty
|
||||
api.apiRecipeList({rating: 4, pageSize: 16}).then(r => {
|
||||
if (r.results != undefined) {
|
||||
this.high_rated_recipes = r.results
|
||||
}
|
||||
})
|
||||
|
||||
api.apiKeywordList({random: 'true', limit: '1'}).then(r => {
|
||||
if (r.results != undefined && r.results.length > 0) {
|
||||
this.random_keyword = r.results[0]
|
||||
api.apiRecipeList({keywords: r.results[0].id}).then(r => {
|
||||
if (r.results != undefined) {
|
||||
this.random_keyword_recipes = r.results
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
methods: {}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user