diff --git a/src/components/BaseComponents/Menu.vue b/src/components/BaseComponents/Menu.vue index 942220d60655c4c491eb021a321dd6e81daad604..74ed16328a0cbc6d181fa70bb96ebce1a809b624 100644 --- a/src/components/BaseComponents/Menu.vue +++ b/src/components/BaseComponents/Menu.vue @@ -70,7 +70,7 @@ <li><router-link data-cy="profile" class="dropdown-item text-white dropdown-username-link" :to="toUserProfile()"><img src="@/assets/icons/person.svg">User Profile</router-link></li> - <li><router-link data-cy="budget" + <li v-if="useUserInfoStore().isPremium"><router-link data-cy="budget" class="dropdown-item text-white dropdown-username-link" :to="toBudget()"><img>Budget</router-link></li> <li><router-link data-cy="friends" class="dropdown-item text-white dropdown-username-link" :to="toFriends()"><img diff --git a/src/components/LeaderboardComponents/Leaderboard.vue b/src/components/LeaderboardComponents/Leaderboard.vue index 845622ac297fc49fac64f058cef23a6189fff184..4b1006543b6a7526b3d91805e416c499b8fc765c 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 0ef2798aab894ad01405e13392ac9ccc1b3a3ec4..31cf6d2cc8e87e56bc4beb815002b36ceb00b8d4 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 2ccfc4126193fc6e595bd88598894ca01f696319..e82992ba2009ebf7dcaa334c872c94596cfa9618 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 fb8e369b7d49f34a5932c4c8f7f622d9319a0acd..9c852dbcca932782cdcab4ace9c6816b7f762cf7 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 b3c26b6bf62ed02c0d70b7a1e0708d1d3a77d1a5..312242fa196f91ac4a2def0a9c793f2b82b65c2c 100644 --- a/src/views/BasePageView.vue +++ b/src/views/BasePageView.vue @@ -3,18 +3,18 @@ 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 data-cy="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 01db9badfb1f2b6910e809dd2465e9558c1eff23..20739f15d353a92c7e6e0cbf49b566d944617afb 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; }