Skip to content
Snippets Groups Projects
Commit 815b3603 authored by Henrik Teksle Sandok's avatar Henrik Teksle Sandok
Browse files

Merge branch 'Premium' into 'main'

Premium

See merge request !60
parents 2999ede5 ea1e9c33
No related branches found
No related tags found
1 merge request!60Premium
Pipeline #281918 passed with warnings
...@@ -70,7 +70,7 @@ ...@@ -70,7 +70,7 @@
<li><router-link data-cy="profile" <li><router-link data-cy="profile"
class="dropdown-item text-white dropdown-username-link" :to="toUserProfile()"><img class="dropdown-item text-white dropdown-username-link" :to="toUserProfile()"><img
src="@/assets/icons/person.svg">User Profile</router-link></li> 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> class="dropdown-item text-white dropdown-username-link" :to="toBudget()"><img>Budget</router-link></li>
<li><router-link data-cy="friends" <li><router-link data-cy="friends"
class="dropdown-item text-white dropdown-username-link" :to="toFriends()"><img class="dropdown-item text-white dropdown-username-link" :to="toFriends()"><img
......
...@@ -57,7 +57,7 @@ console.log(props.leaderboardExtra); ...@@ -57,7 +57,7 @@ console.log(props.leaderboardExtra);
const userInLeaderboard = computed(() => props.leaderboard.some(entry => entry.user && entry.user.email === userStore.email)); const userInLeaderboard = computed(() => props.leaderboard.some(entry => entry.user && entry.user.email === userStore.email));
const navigateToUserProfile = (id: number) => { const navigateToUserProfile = (id: number) => {
router.push({ name: 'user-profile' }); router.push(`/profile/${id}`);
}; };
</script> </script>
......
...@@ -47,7 +47,6 @@ const handleSubmit = async () => { ...@@ -47,7 +47,6 @@ const handleSubmit = async () => {
try { try {
let response = await AuthenticationService.login({ requestBody: loginUserPayload }); let response = await AuthenticationService.login({ requestBody: loginUserPayload });
if (response.token == null || response.token == undefined) { if (response.token == null || response.token == undefined) {
errorMsg.value = 'A valid token could not be created'; errorMsg.value = 'A valid token could not be created';
return; return;
...@@ -62,11 +61,9 @@ const handleSubmit = async () => { ...@@ -62,11 +61,9 @@ const handleSubmit = async () => {
lastname: response.lastName, lastname: response.lastName,
email: emailRef.value, email: emailRef.value,
role: response.role, role: response.role,
subscriptionLevel: response.subscriptionLevel,
profileImage: response.profileImage profileImage: response.profileImage
}); });
console.log()
await router.push({ name: 'home' }); await router.push({ name: 'home' });
} catch (error: any) { } catch (error: any) {
errorMsg.value = handleUnknownError(error); errorMsg.value = handleUnknownError(error);
......
...@@ -95,11 +95,13 @@ const routes = [ ...@@ -95,11 +95,13 @@ const routes = [
path: '/budget-overview', path: '/budget-overview',
name: 'budget overview', name: 'budget overview',
component: () => import('@/views/Budget/BudgetOverview.vue'), component: () => import('@/views/Budget/BudgetOverview.vue'),
meta: { requiresPremium: true },
}, },
{ {
path: '/budget', path: '/budget',
name: 'budget', name: 'budget',
component: () => import('@/views/Budget/BudgetView.vue'), component: () => import('@/views/Budget/BudgetView.vue'),
meta: { requiresPremium: true },
}, },
{ {
path: '/profile/:id', path: '/profile/:id',
...@@ -203,14 +205,18 @@ const router = createRouter({ ...@@ -203,14 +205,18 @@ const router = createRouter({
router.beforeEach((to, from, next) => { router.beforeEach((to, from, next) => {
const requiresAuth = to.matched.some(record => record.meta.requiresAuth); const requiresAuth = to.matched.some(record => record.meta.requiresAuth);
const requiresAdmin = to.matched.some(record => record.meta.requiresAdmin); const requiresAdmin = to.matched.some(record => record.meta.requiresAdmin);
const requiresPremium = to.matched.some(record => record.meta.requiresPremium);
const user = useUserInfoStore(); const user = useUserInfoStore();
const userRole = user.role; const userRole = user.role;
const userSubscription = user.subscriptionLevel;
const isAuthenticated = user.isLoggedIn; const isAuthenticated = user.isLoggedIn;
if (requiresAuth && !isAuthenticated) { if (requiresAuth && !isAuthenticated) {
next({ name: 'login', query: { redirect: to.fullPath } }); next({ name: 'login', query: { redirect: to.fullPath } });
} else if (requiresAdmin && userRole !== 'admin') { } else if (requiresAdmin && userRole !== 'admin') {
next({ name: 'unauthorized' }); next({ name: 'unauthorized' });
} else if (requiresPremium && userSubscription !== 'PREMIUM') {
next({ name: 'home' });
} else { } else {
next(); next();
} }
......
...@@ -36,9 +36,10 @@ export type UserStoreInfo = { ...@@ -36,9 +36,10 @@ export type UserStoreInfo = {
password?: string; password?: string;
accessToken?: string; accessToken?: string;
role?: string; role?: string;
subscriptionLevel?: string;
profileImage?: number; profileImage?: number;
}; };
//todo Fix if there is time
export const useUserInfoStore = defineStore('UserInfoStore', { export const useUserInfoStore = defineStore('UserInfoStore', {
state: () => ({ state: () => ({
id: 0, id: 0,
...@@ -48,6 +49,7 @@ export const useUserInfoStore = defineStore('UserInfoStore', { ...@@ -48,6 +49,7 @@ export const useUserInfoStore = defineStore('UserInfoStore', {
password: '', password: '',
accessToken: '', accessToken: '',
role: '', role: '',
subscriptionLevel: '',
profileImage: 0, profileImage: 0,
}), }),
persist: { persist: {
...@@ -68,6 +70,7 @@ export const useUserInfoStore = defineStore('UserInfoStore', { ...@@ -68,6 +70,7 @@ export const useUserInfoStore = defineStore('UserInfoStore', {
userinfo.accessToken && (this.$state.accessToken = userinfo.accessToken); userinfo.accessToken && (this.$state.accessToken = userinfo.accessToken);
userinfo.accessToken && (OpenAPI.TOKEN = this.$state.accessToken); userinfo.accessToken && (OpenAPI.TOKEN = this.$state.accessToken);
userinfo.role && (this.$state.role = userinfo.role); userinfo.role && (this.$state.role = userinfo.role);
userinfo.subscriptionLevel && (this.$state.subscriptionLevel = userinfo.subscriptionLevel);
userinfo.profileImage && (this.$state.profileImage = userinfo.profileImage); userinfo.profileImage && (this.$state.profileImage = userinfo.profileImage);
}, },
clearUserInfo() { clearUserInfo() {
...@@ -77,6 +80,7 @@ export const useUserInfoStore = defineStore('UserInfoStore', { ...@@ -77,6 +80,7 @@ export const useUserInfoStore = defineStore('UserInfoStore', {
this.$state.lastname = ''; this.$state.lastname = '';
this.$state.accessToken = ''; this.$state.accessToken = '';
this.$state.role = ''; this.$state.role = '';
this.$state.subscriptionLevel = '';
this.$state.profileImage = 0; this.$state.profileImage = 0;
OpenAPI.TOKEN = undefined; OpenAPI.TOKEN = undefined;
}, },
...@@ -97,5 +101,11 @@ export const useUserInfoStore = defineStore('UserInfoStore', { ...@@ -97,5 +101,11 @@ export const useUserInfoStore = defineStore('UserInfoStore', {
isLoggedIn(): boolean { isLoggedIn(): boolean {
return this.accessToken !== ''; return this.accessToken !== '';
}, },
isPremium(): boolean {
return this.subscriptionLevel === 'PREMIUM';
},
isNoAds(): boolean {
return this.subscriptionLevel === 'NO_ADS';
}
}, },
}); });
\ No newline at end of file
...@@ -3,18 +3,18 @@ import { RouterView } from 'vue-router' ...@@ -3,18 +3,18 @@ import { RouterView } from 'vue-router'
import Footer from '@/components/BaseComponents/Footer.vue' import Footer from '@/components/BaseComponents/Footer.vue'
import Menu from '@/components/BaseComponents/Menu.vue' import Menu from '@/components/BaseComponents/Menu.vue'
import FooterAlternative from "@/components/BaseComponents/FooterAlternative.vue"; import FooterAlternative from "@/components/BaseComponents/FooterAlternative.vue";
import { useUserInfoStore } from '@/stores/UserStore';
</script> </script>
<template> <template>
<Menu data-cy="menu"></Menu> <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"> <img v-for="item in 7" src="@/assets/coca.webp" style="width: 100%; height: 100px; margin: 5px; border-radius: 1rem;" alt="picture">
</div> </div>
<div> <div>
<RouterView /> <RouterView />
</div> </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"> <img v-for="item in 7" src="@/assets/coca.webp" style="width: 100%; height: 100px; margin: 5px; border-radius: 1rem;" alt="picture">
</div> </div>
<FooterAlternative></FooterAlternative> <FooterAlternative></FooterAlternative>
......
...@@ -12,14 +12,15 @@ ...@@ -12,14 +12,15 @@
<img src="@/assets/items/adfree.png" class="card-img-top" alt="..."> <img src="@/assets/items/adfree.png" class="card-img-top" alt="...">
<div class="card-body"> <div class="card-body">
<h5 class="card-title">Adfree</h5> <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>
<div class="card text-center" style="width: 16rem; border: none"> <div class="card text-center" style="width: 16rem; border: none">
<img src="@/assets/items/piggybank.webp" class="card-img-top" alt="..."> <img src="@/assets/items/piggybank.webp" class="card-img-top" alt="...">
<div class="card-body"> <div class="card-body">
<h5 class="card-title">Premium</h5> <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>
...@@ -92,6 +93,31 @@ ...@@ -92,6 +93,31 @@
<script setup lang="ts"> <script setup lang="ts">
import ShopButton from '@/components/Buttons/ShopButton.vue'; 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> </script>
<style scoped> <style scoped>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment