mirror of
https://github.com/mealie-recipes/mealie.git
synced 2026-01-17 14:31:21 -05:00
feature/favorite-recipes (#443)
* add favorites options * bump dependencies * add badges to all cards * typo * remove console.log * fix site-loader viewport Co-authored-by: hay-kot <hay-kot@pm.me>
This commit is contained in:
@@ -87,8 +87,7 @@ export default {
|
||||
this.clear();
|
||||
this.$store.commit("setToken", response.data.access_token);
|
||||
this.$emit("logged-in");
|
||||
let user = await api.users.self();
|
||||
this.$store.commit("setUserData", user);
|
||||
this.$store.dispatch("requestUserData");
|
||||
}
|
||||
|
||||
this.loading = false;
|
||||
|
||||
@@ -106,14 +106,7 @@ export default {
|
||||
},
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
value(val) {
|
||||
console.log(val);
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
console.log(this.value);
|
||||
},
|
||||
|
||||
methods: {
|
||||
getImage(slug) {
|
||||
if (slug) {
|
||||
@@ -161,7 +154,6 @@ export default {
|
||||
this.setSide(this.customMeal.name, this.customMeal.slug, this.customMeal.description);
|
||||
break;
|
||||
}
|
||||
console.log("Hello World");
|
||||
this.customMeal = { name: "", slug: null, description: "" };
|
||||
},
|
||||
},
|
||||
|
||||
@@ -28,9 +28,7 @@ export default {
|
||||
props: {
|
||||
mealPlan: Object,
|
||||
},
|
||||
mounted() {
|
||||
console.log(this.mealPlan);
|
||||
},
|
||||
|
||||
methods: {
|
||||
formatDate(timestamp) {
|
||||
let dateObject = new Date(timestamp);
|
||||
|
||||
54
frontend/src/components/Recipe/FavoriteBadge.vue
Normal file
54
frontend/src/components/Recipe/FavoriteBadge.vue
Normal file
@@ -0,0 +1,54 @@
|
||||
<template>
|
||||
<v-btn
|
||||
small
|
||||
@click.prevent="toggleFavorite"
|
||||
v-if="isFavorite || showAlways"
|
||||
:color="isFavorite && buttonStyle ? 'secondary' : 'primary'"
|
||||
:icon="!buttonStyle"
|
||||
:fab="buttonStyle"
|
||||
>
|
||||
<v-icon :small="!buttonStyle" color="secondary">
|
||||
{{ isFavorite ? "mdi-heart" : "mdi-heart-outline" }}
|
||||
</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { api } from "@/api";
|
||||
export default {
|
||||
props: {
|
||||
slug: {
|
||||
default: "",
|
||||
},
|
||||
showAlways: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
buttonStyle: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
user() {
|
||||
return this.$store.getters.getUserData;
|
||||
},
|
||||
isFavorite() {
|
||||
return this.user.favoriteRecipes.indexOf(this.slug) !== -1;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
async toggleFavorite() {
|
||||
if (!this.isFavorite) {
|
||||
await api.users.addFavorite(this.user.id, this.slug);
|
||||
} else {
|
||||
await api.users.removeFavorite(this.user.id, this.slug);
|
||||
}
|
||||
this.$store.dispatch("requestUserData");
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
@@ -23,6 +23,7 @@
|
||||
<v-list-item-title class=" mb-1">{{ name }} </v-list-item-title>
|
||||
<v-list-item-subtitle> {{ description }} </v-list-item-subtitle>
|
||||
<div class="d-flex justify-center align-center">
|
||||
<FavoriteBadge v-if="loggedIn" :slug="slug" show-always />
|
||||
<v-rating
|
||||
color="secondary"
|
||||
class="ml-auto"
|
||||
@@ -42,10 +43,12 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import FavoriteBadge from "@/components/Recipe/FavoriteBadge";
|
||||
import ContextMenu from "@/components/Recipe/ContextMenu";
|
||||
import { api } from "@/api";
|
||||
export default {
|
||||
components: {
|
||||
FavoriteBadge,
|
||||
ContextMenu,
|
||||
},
|
||||
props: {
|
||||
@@ -71,6 +74,11 @@ export default {
|
||||
return api.recipes.recipeSmallImage(slug, this.image);
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
loggedIn() {
|
||||
return this.$store.getters.getIsLoggedIn;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
</v-card-title>
|
||||
|
||||
<v-card-actions>
|
||||
<FavoriteBadge v-if="loggedIn" :slug="slug" show-always />
|
||||
<Rating :value="rating" :name="name" :slug="slug" :small="true" />
|
||||
<v-spacer></v-spacer>
|
||||
<RecipeChips :truncate="true" :items="tags" :title="false" :limit="2" :small="true" :isCategory="false" />
|
||||
@@ -33,18 +34,14 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import FavoriteBadge from "@/components/Recipe/FavoriteBadge";
|
||||
import RecipeChips from "@/components/Recipe/RecipeViewer/RecipeChips";
|
||||
import ContextMenu from "@/components/Recipe/ContextMenu";
|
||||
import CardImage from "@/components/Recipe/CardImage";
|
||||
import Rating from "@/components/Recipe/Parts/Rating";
|
||||
import { api } from "@/api";
|
||||
export default {
|
||||
components: {
|
||||
RecipeChips,
|
||||
ContextMenu,
|
||||
Rating,
|
||||
CardImage,
|
||||
},
|
||||
components: { FavoriteBadge, RecipeChips, ContextMenu, Rating, CardImage },
|
||||
props: {
|
||||
name: String,
|
||||
slug: String,
|
||||
@@ -64,6 +61,11 @@ export default {
|
||||
fallBackImage: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
loggedIn() {
|
||||
return this.$store.getters.getIsLoggedIn;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
getImage(slug) {
|
||||
return api.recipes.recipeSmallImage(slug, this.image);
|
||||
|
||||
@@ -95,7 +95,7 @@
|
||||
</div>
|
||||
<div v-intersect="bumpList" class="d-flex">
|
||||
<v-expand-x-transition>
|
||||
<SiteLoader v-if="loading" :loading="loading" :size="150" />
|
||||
<SiteLoader v-if="loading" :loading="loading" />
|
||||
</v-expand-x-transition>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<slot v-bind="{ open, close }"> </slot>
|
||||
<v-dialog
|
||||
v-model="dialog"
|
||||
:width="isMobile ? undefined : '700'"
|
||||
:width="isMobile ? undefined : '65%'"
|
||||
:height="isMobile ? undefined : '0'"
|
||||
:fullscreen="isMobile"
|
||||
content-class="top-dialog"
|
||||
|
||||
@@ -1,14 +1,23 @@
|
||||
<template>
|
||||
<v-progress-circular class="mx-auto" :width="size / 20" :size="size" color="primary lighten-2" indeterminate>
|
||||
<div class="text-center">
|
||||
<v-icon :size="size / 2" color="primary lighten-2">
|
||||
{{ $globals.icons.primary }}
|
||||
</v-icon>
|
||||
<div>
|
||||
Loading Recipes
|
||||
<div class="mx-auto">
|
||||
<v-progress-circular :width="size.width" :size="size.size" color="primary lighten-2" indeterminate>
|
||||
<div class="text-center">
|
||||
<v-icon :size="size.icon" color="primary lighten-2">
|
||||
{{ $globals.icons.primary }}
|
||||
</v-icon>
|
||||
<div v-if="large" class="text-small">
|
||||
<slot>
|
||||
{{ small ? "" : "Loading Recipes" }}
|
||||
</slot>
|
||||
</div>
|
||||
</div>
|
||||
</v-progress-circular>
|
||||
<div v-if="!large" class="text-small">
|
||||
<slot>
|
||||
{{ small ? "" : "Loading Recipes" }}
|
||||
</slot>
|
||||
</div>
|
||||
</v-progress-circular>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -17,8 +26,39 @@ export default {
|
||||
loading: {
|
||||
default: true,
|
||||
},
|
||||
size: {
|
||||
default: 200,
|
||||
small: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
medium: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
large: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
size() {
|
||||
if (this.small) {
|
||||
return {
|
||||
width: 2,
|
||||
icon: 30,
|
||||
size: 50,
|
||||
};
|
||||
} else if (this.large) {
|
||||
return {
|
||||
width: 4,
|
||||
icon: 120,
|
||||
size: 200,
|
||||
};
|
||||
}
|
||||
return {
|
||||
width: 3,
|
||||
icon: 75,
|
||||
size: 125,
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -15,6 +15,17 @@
|
||||
<v-list-item-subtitle> {{ user.admin ? $t("user.admin") : $t("user.user") }}</v-list-item-subtitle>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
|
||||
<v-list-item dense v-if="isLoggedIn" :to="`/user/${user.id}/favorites`">
|
||||
<v-list-item-icon>
|
||||
<v-icon>
|
||||
mdi-heart
|
||||
</v-icon>
|
||||
</v-list-item-icon>
|
||||
<v-list-item-content>
|
||||
<v-list-item-title> Favorites </v-list-item-title>
|
||||
</v-list-item-content>
|
||||
</v-list-item>
|
||||
</template>
|
||||
<v-divider></v-divider>
|
||||
|
||||
@@ -30,7 +41,7 @@
|
||||
<!-- Version List Item -->
|
||||
<v-list nav dense class="fixedBottom" v-if="!isMain">
|
||||
<v-list-item href="https://github.com/sponsors/hay-kot" target="_target">
|
||||
<v-list-item-icon >
|
||||
<v-list-item-icon>
|
||||
<v-icon color="pink">
|
||||
mdi-heart
|
||||
</v-icon>
|
||||
|
||||
Reference in New Issue
Block a user