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