start page taking shape

This commit is contained in:
vabene1111
2024-03-17 09:58:26 +01:00
committed by smilerz
parent 728bb76a43
commit facbe08e20
4 changed files with 102 additions and 13 deletions

View 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

View File

@@ -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

View File

@@ -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},
}

View File

@@ -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: {}
})