From 822839be35d79ed5e2caccae47514e9483db0621 Mon Sep 17 00:00:00 2001 From: VIktorGrev <viktog2210@gmail.com> Date: Tue, 30 Apr 2024 15:58:24 +0200 Subject: [PATCH] feat: Adding premium ands no_ads features layout --- src/components/BaseComponents/Menu.vue | 2 +- .../LeaderboardComponents/Leaderboard.vue | 2 +- src/components/Login/LoginForm.vue | 5 +-- src/router/index.ts | 8 +++- src/stores/UserStore.ts | 12 ++++- src/views/BasePageView.vue | 5 ++- src/views/ShopView.vue | 44 +++++++++++++++---- 7 files changed, 59 insertions(+), 19 deletions(-) diff --git a/src/components/BaseComponents/Menu.vue b/src/components/BaseComponents/Menu.vue index 684401a..9b013b6 100644 --- a/src/components/BaseComponents/Menu.vue +++ b/src/components/BaseComponents/Menu.vue @@ -39,7 +39,7 @@ <li><router-link class="dropdown-item text-white dropdown-username-link" :to="toUserProfile()"><img src="@/assets/icons/person.svg">User Profile</router-link></li> - <li><router-link class="dropdown-item text-white dropdown-username-link" + <li v-if="useUserInfoStore().isPremium"><router-link class="dropdown-item text-white dropdown-username-link" :to="toBudget()"><img>Budget</router-link></li> <li><router-link class="dropdown-item text-white dropdown-username-link" :to="toFriends()"><img src="@/assets/icons/friends.svg">Friends</router-link></li> diff --git a/src/components/LeaderboardComponents/Leaderboard.vue b/src/components/LeaderboardComponents/Leaderboard.vue index 845622a..4b10065 100644 --- a/src/components/LeaderboardComponents/Leaderboard.vue +++ b/src/components/LeaderboardComponents/Leaderboard.vue @@ -57,7 +57,7 @@ console.log(props.leaderboardExtra); const userInLeaderboard = computed(() => props.leaderboard.some(entry => entry.user && entry.user.email === userStore.email)); const navigateToUserProfile = (id: number) => { - router.push({ name: 'user-profile' }); + router.push(`/profile/${id}`); }; </script> diff --git a/src/components/Login/LoginForm.vue b/src/components/Login/LoginForm.vue index 0ef2798..31cf6d2 100644 --- a/src/components/Login/LoginForm.vue +++ b/src/components/Login/LoginForm.vue @@ -47,7 +47,6 @@ const handleSubmit = async () => { try { let response = await AuthenticationService.login({ requestBody: loginUserPayload }); - if (response.token == null || response.token == undefined) { errorMsg.value = 'A valid token could not be created'; return; @@ -62,11 +61,9 @@ const handleSubmit = async () => { lastname: response.lastName, email: emailRef.value, role: response.role, + subscriptionLevel: response.subscriptionLevel, profileImage: response.profileImage }); - - console.log() - await router.push({ name: 'home' }); } catch (error: any) { errorMsg.value = handleUnknownError(error); diff --git a/src/router/index.ts b/src/router/index.ts index 2ccfc41..e82992b 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -95,11 +95,13 @@ const routes = [ path: '/budget-overview', name: 'budget overview', component: () => import('@/views/Budget/BudgetOverview.vue'), + meta: { requiresPremium: true }, }, { path: '/budget', name: 'budget', component: () => import('@/views/Budget/BudgetView.vue'), + meta: { requiresPremium: true }, }, { path: '/profile/:id', @@ -203,14 +205,18 @@ const router = createRouter({ router.beforeEach((to, from, next) => { const requiresAuth = to.matched.some(record => record.meta.requiresAuth); const requiresAdmin = to.matched.some(record => record.meta.requiresAdmin); - const user= useUserInfoStore(); + const requiresPremium = to.matched.some(record => record.meta.requiresPremium); + const user = useUserInfoStore(); const userRole = user.role; + const userSubscription = user.subscriptionLevel; const isAuthenticated = user.isLoggedIn; if (requiresAuth && !isAuthenticated) { next({ name: 'login', query: { redirect: to.fullPath } }); } else if (requiresAdmin && userRole !== 'admin') { next({ name: 'unauthorized' }); + } else if (requiresPremium && userSubscription !== 'PREMIUM') { + next({ name: 'home' }); } else { next(); } diff --git a/src/stores/UserStore.ts b/src/stores/UserStore.ts index fb8e369..9c852db 100644 --- a/src/stores/UserStore.ts +++ b/src/stores/UserStore.ts @@ -36,9 +36,10 @@ export type UserStoreInfo = { password?: string; accessToken?: string; role?: string; + subscriptionLevel?: string; profileImage?: number; }; -//todo Fix if there is time + export const useUserInfoStore = defineStore('UserInfoStore', { state: () => ({ id: 0, @@ -48,6 +49,7 @@ export const useUserInfoStore = defineStore('UserInfoStore', { password: '', accessToken: '', role: '', + subscriptionLevel: '', profileImage: 0, }), persist: { @@ -68,6 +70,7 @@ export const useUserInfoStore = defineStore('UserInfoStore', { userinfo.accessToken && (this.$state.accessToken = userinfo.accessToken); userinfo.accessToken && (OpenAPI.TOKEN = this.$state.accessToken); userinfo.role && (this.$state.role = userinfo.role); + userinfo.subscriptionLevel && (this.$state.subscriptionLevel = userinfo.subscriptionLevel); userinfo.profileImage && (this.$state.profileImage = userinfo.profileImage); }, clearUserInfo() { @@ -77,6 +80,7 @@ export const useUserInfoStore = defineStore('UserInfoStore', { this.$state.lastname = ''; this.$state.accessToken = ''; this.$state.role = ''; + this.$state.subscriptionLevel = ''; this.$state.profileImage = 0; OpenAPI.TOKEN = undefined; }, @@ -97,5 +101,11 @@ export const useUserInfoStore = defineStore('UserInfoStore', { isLoggedIn(): boolean { return this.accessToken !== ''; }, + isPremium(): boolean { + return this.subscriptionLevel === 'PREMIUM'; + }, + isNoAds(): boolean { + return this.subscriptionLevel === 'NO_ADS'; + } }, }); \ No newline at end of file diff --git a/src/views/BasePageView.vue b/src/views/BasePageView.vue index a7c413d..83a5382 100644 --- a/src/views/BasePageView.vue +++ b/src/views/BasePageView.vue @@ -3,18 +3,19 @@ import { RouterView } from 'vue-router' import Footer from '@/components/BaseComponents/Footer.vue' import Menu from '@/components/BaseComponents/Menu.vue' import FooterAlternative from "@/components/BaseComponents/FooterAlternative.vue"; +import { useUserInfoStore } from '@/stores/UserStore'; </script> <template> <Menu></Menu> - <div style="display: flex; flex-direction: row;"> + <div v-if="!useUserInfoStore().isPremium && !useUserInfoStore().isNoAds" style="display: flex; flex-direction: row;"> <img v-for="item in 7" src="@/assets/coca.webp" style="width: 100%; height: 100px; margin: 5px; border-radius: 1rem;" alt="picture"> </div> <div> <RouterView /> </div> - <div style="display: flex; flex-direction: row;"> + <div v-if="!useUserInfoStore().isPremium && !useUserInfoStore().isNoAds" style="display: flex; flex-direction: row;"> <img v-for="item in 7" src="@/assets/coca.webp" style="width: 100%; height: 100px; margin: 5px; border-radius: 1rem;" alt="picture"> </div> <FooterAlternative></FooterAlternative> diff --git a/src/views/ShopView.vue b/src/views/ShopView.vue index 01db9ba..20739f1 100644 --- a/src/views/ShopView.vue +++ b/src/views/ShopView.vue @@ -12,16 +12,17 @@ <img src="@/assets/items/adfree.png" class="card-img-top" alt="..."> <div class="card-body"> <h5 class="card-title">Adfree</h5> - <button type="button" class="btn btn-primary" id="buttonStyle"> +35kr</button> + <button type="button" class="btn btn-primary" id="buttonStyle" @click="buyNoAds"> +35kr</button> </div> - </div> + </div> <div class="card text-center" style="width: 16rem; border: none"> <img src="@/assets/items/piggybank.webp" class="card-img-top" alt="..."> <div class="card-body"> <h5 class="card-title">Premium</h5> - <button type="button" class="btn btn-primary" id="buttonStyle">+50kr</button> + <button type="button" class="btn btn-primary" id="buttonStyle" + @click="buyPremium">+50kr</button> </div> - </div> + </div> </div> </div> <div class="col-md-12"> @@ -68,21 +69,21 @@ <h5 class="card-title">Free Coffee</h5> <ShopButton button-text="500"></ShopButton> </div> - </div> + </div> <div class="card text-center" style="width: 16rem; border: none"> <img src="@/assets/items/viaplay.jpg" class="card-img-top" alt="..."> <div class="card-body"> <h5 class="card-title">1 Month Viaplay</h5> <ShopButton button-text="10000"></ShopButton> </div> - </div> + </div> <div class="card text-center" style="width: 16rem; border: none"> <img src="@/assets/items/pirbad.png" class="card-img-top" alt="..."> <div class="card-body"> <h5 class="card-title">-10% rabatt</h5> <ShopButton button-text="1000"></ShopButton> </div> - </div> + </div> </div> </div> @@ -92,6 +93,31 @@ <script setup lang="ts"> import ShopButton from '@/components/Buttons/ShopButton.vue'; +import { ref } from 'vue'; +import { UserService } from '@/api'; +import { useUserInfoStore } from '@/stores/UserStore'; + +const buyPremium = async () => { + try { + const response = await UserService.updateSubscriptionLevel({ subscriptionLevel: 'PREMIUM' }); + useUserInfoStore().setUserInfo({ + subscriptionLevel: 'PREMIUM', + }) + } catch (error) { + console.log(error); + } +} + +const buyNoAds = async () => { + try { + const response = await UserService.updateSubscriptionLevel({ subscriptionLevel: 'NO_ADS' }); + useUserInfoStore().setUserInfo({ + subscriptionLevel: 'NO_ADS', + }) + } catch (error) { + console.log(error); + } +} </script> <style scoped> @@ -105,14 +131,14 @@ import ShopButton from '@/components/Buttons/ShopButton.vue'; } .box { - width:90%; + width: 90%; } .card:hover { box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); } -.card-body{ +.card-body { height: 100px; padding: 5px; } -- GitLab