feat: implement user favorites page (#1376)

* fix geFavorites return

* add support for toggling to dense cards on desktop

* add favorites page link

* implement basic favorites page
This commit is contained in:
Hayden 2022-06-13 09:33:46 -08:00 committed by GitHub
parent f6c18ec73d
commit 3030e3e7f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 66 additions and 19 deletions

View File

@ -1,5 +1,15 @@
import { BaseCRUDAPI } from "../_base";
import { ChangePassword, DeleteTokenResponse, LongLiveTokenIn, LongLiveTokenOut, ResetPassword, UserBase, UserIn, UserOut } from "~/types/api-types/user";
import {
ChangePassword,
DeleteTokenResponse,
LongLiveTokenIn,
LongLiveTokenOut,
ResetPassword,
UserBase,
UserFavorites,
UserIn,
UserOut,
} from "~/types/api-types/user";
const prefix = "/api";
@ -32,7 +42,7 @@ export class UserApi extends BaseCRUDAPI<UserIn, UserOut, UserBase> {
}
async getFavorites(id: string) {
await this.requests.get(routes.usersIdFavorites(id));
return await this.requests.get<UserFavorites>(routes.usersIdFavorites(id));
}
async changePassword(id: string, changePassword: ChangePassword) {

View File

@ -14,6 +14,17 @@
</v-icon>
{{ $vuetify.breakpoint.xsOnly ? null : $t("general.random") }}
</v-btn>
<ContextMenu
v-if="!$vuetify.breakpoint.xsOnly"
:items="[
{
title: 'Toggle View',
icon: $globals.icons.eye,
event: 'toggle-dense-view',
},
]"
@toggle-dense-view="mobileCards = !mobileCards"
/>
<v-menu v-if="$listeners.sort" offset-y left>
<template #activator="{ on, attrs }">
<v-btn text :icon="$vuetify.breakpoint.xsOnly" v-bind="attrs" :loading="sortLoading" v-on="on">
@ -103,11 +114,11 @@
</template>
<script lang="ts">
import { computed, defineComponent, reactive, toRefs, useContext, useRouter } from "@nuxtjs/composition-api";
import { computed, defineComponent, reactive, toRefs, useContext, useRouter, ref } from "@nuxtjs/composition-api";
import RecipeCard from "./RecipeCard.vue";
import RecipeCardMobile from "./RecipeCardMobile.vue";
import { useSorter } from "~/composables/recipes";
import {Recipe} from "~/types/api-types/recipe";
import { Recipe } from "~/types/api-types/recipe";
const SORT_EVENT = "sort";
@ -129,10 +140,6 @@ export default defineComponent({
type: String,
default: null,
},
mobileCards: {
type: Boolean,
default: false,
},
singleColumn: {
type: Boolean,
default: false,
@ -143,6 +150,7 @@ export default defineComponent({
},
},
setup(props, context) {
const mobileCards = ref(false);
const utils = useSorter();
const EVENTS = {
@ -155,7 +163,7 @@ export default defineComponent({
const { $globals, $vuetify } = useContext();
const viewScale = computed(() => {
return props.mobileCards || $vuetify.breakpoint.smAndDown;
return mobileCards.value || $vuetify.breakpoint.smAndDown;
});
const displayTitleIcon = computed(() => {
@ -164,7 +172,7 @@ export default defineComponent({
const state = reactive({
sortLoading: false,
})
});
const router = useRouter();
function navigateRandom() {
@ -204,6 +212,7 @@ export default defineComponent({
}
return {
mobileCards,
...toRefs(state),
EVENTS,
viewScale,

View File

@ -7,7 +7,9 @@
<v-list-item-content>
<v-list-item-title> {{ $auth.user.fullName }}</v-list-item-title>
<v-list-item-subtitle> {{ $auth.user.admin ? $t("user.admin") : $t("user.user") }}</v-list-item-subtitle>
<v-list-item-subtitle>
<NuxtLink class="favorites-link" :to="`/user/${$auth.user.id}/favorites`"> Favorite Recipes </NuxtLink>
</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
<v-divider></v-divider>
@ -200,4 +202,12 @@ export default defineComponent({
display: none;
}
}
.favorites-link {
text-decoration: none;
}
.favorites-link:hover {
text-decoration: underline;
}
</style>

View File

@ -1,13 +1,32 @@
<template>
<div></div>
<v-container>
<RecipeCardSection v-if="user" :icon="$globals.icons.heart" title="User Favorites" :recipes="user.favoriteRecipes">
</RecipeCardSection>
</v-container>
</template>
<script lang="ts">
import { defineComponent } from "@nuxtjs/composition-api";
<script lang="ts">
import { defineComponent, useAsync, useRoute } from "@nuxtjs/composition-api";
import RecipeCardSection from "~/components/Domain/Recipe/RecipeCardSection.vue";
import { useUserApi } from "~/composables/api";
import { useAsyncKey } from "~/composables/use-utils";
export default defineComponent({
components: { RecipeCardSection },
setup() {
return {};
const api = useUserApi();
const route = useRoute();
const userId = route.value.params.id;
const user = useAsync(async () => {
const { data } = await api.users.getFavorites(userId);
return data;
}, useAsyncKey());
return {
user,
};
},
head() {
return {
@ -16,6 +35,5 @@ export default defineComponent({
},
});
</script>
<style scoped>
</style>
<style scoped></style>