Skip to content
Snippets Groups Projects
Commit d0e618d6 authored by VIktorGrev's avatar VIktorGrev
Browse files

feat: Integrating profile stats into profile and external profile

parent 8d75c023
No related branches found
No related tags found
1 merge request!90Profile stats
Pipeline #283759 passed with warnings
<script setup lang="ts"> <script setup lang="ts">
import {ref, onMounted} from "vue";
import { useRoute, useRouter } from "vue-router"; import { useRoute, useRouter } from "vue-router";
import { useUserInfoStore } from "@/stores/UserStore";
import {onMounted, type Ref, ref, type UnwrapRef} from "vue"; import {UserService, BadgeService, GoalService, type GoalDTO, type BadgeDTO, FriendService} from "@/api";
import {UserService, type ProfileDTO, GoalService, type GoalDTO} from "@/api"; import { ItemService } from "@/api";
import handleUnknownError from '@/components/Exceptions/unkownErrorHandler'
let numberOfHistory = 6; let numberOfHistory = 6;
let cardTitles = ["Spain tour", "Food waste", "Coffee", "Concert", "New book", "Pretty clothes"] let cardTitles = ["Spain tour", "Food waste", "Coffee", "Concert", "New book", "Pretty clothes"]
let hasHistory = ref(true)
let firstname = ref(); let firstname = ref();
let lastname = ref(); let lastname = ref();
let goals = ref<GoalDTO[]>([]);
let username = ref()
let friend = ref(false)
let profile: ProfileDTO;
const imageUrl = ref(`../src/assets/userprofile.png`); const imageUrl = ref(`../src/assets/userprofile.png`);
let hasHistory = ref(true)
let hasBadges = ref(false)
let hasInventory = ref(false)
let id = ref() const router = useRouter();
const route = useRoute();
//Get the id from the url. viktor har eksempel const inventory = ref([] as any);
const badges = ref<BadgeDTO[]>([]);
let user = useRoute() const backgroundName = ref("");
id.value = user.params const points = ref(0 as any);
console.log(id.value.id) const streak = ref(0 as any);
let route = useRouter()
function toRoadmap(){
route.push('/roadmap')
}
//todo Make a store of a friend-instance
onMounted(async () => {
try {
let response = await UserService.getProfile({
userId: id.value.id
})
profile = response;
console.log(profile)
username.value = profile.firstName
if (profile.profileImage){
imageUrl.value = `http://localhost:8080/api/images/${profile.profileImage}`
}
console.log(username)
} catch (error) {
console.error("Something went wrong getting the profile: ", error)
}
})
function addFriend() { let goalName = ref('');
friend.value = true let goalDescription = ref('');
console.log("Added friend") let targetAmount = ref('');
let targetDate = ref('');
let createdAt = ref('');
let goals = ref<GoalDTO[]>([])
}
async function getGoals() { async function getGoals() {
try { try {
goals.value = await GoalService.getGoals(); goals.value = await GoalService.getGoals();
console.log("number of goals: ", goals.value.length) console.log("number of goals: ", goals.value.length)
console.log('The id of a goal: ', goals.value[0])
if (goals.value.length > 0) { if (goals.value.length > 0) {
hasHistory.value = true hasHistory.value = true
} else { } else {
...@@ -72,138 +44,175 @@ async function getGoals() { ...@@ -72,138 +44,175 @@ async function getGoals() {
console.log('No history') console.log('No history')
} }
}catch (error){ }catch (error){
console.error("Something went wrong getting the goals: " , error) handleUnknownError(error)
console.error("Something went wrong", error)
} }
} }
async function setupForm() {
try {
let id = route.params.id as any;
let response = await UserService.getProfile({
userId: id
})
firstname.value = response.firstName;
lastname.value = response.lastName;
if (response.point?.currentPoints) {
points.value = response.point?.currentPoints;
}
if (response.streak?.currentStreak) {
streak.value = response.streak?.currentStreak;
}
if (response.profileImage) {
imageUrl.value = "http://localhost:8080/api/images/" + response.profileImage;
}
getInventory();
getBadges();
} catch (err) {
handleUnknownError(err)
console.error(err)
}
}
// Function to navigate to update user settings const getInventory = async () => {
try {
const response = await ItemService.getInventory();
//todo Send POST to backend when endpoints is made and add friend inventory.value = response;
if (inventory.value.length > 0) {
hasInventory.value = true
function removeFriend(){ } else {
friend.value = false hasInventory.value = false
console.log("Removed friend") console.log('No history')
}
} catch (error) {
handleUnknownError(error)
console.log(error);
}
}
//todo Send POST to backend when endpoints is made and remove friend const getBadges = async () => {
try {
const responseBadge = await BadgeService.getBadgesUnlockedByUser();
badges.value = responseBadge;
if (badges.value.length > 0) {
hasBadges.value = true
} else {
hasBadges.value = false
console.log('No history')
}
} catch (error) {
handleUnknownError(error)
console.log(error);
}
}
const selectItem = (item: any) => {
backgroundName.value = item.itemName;
useUserInfoStore().setUserInfo({
roadBackground: item.imageId,
})
} }
onMounted(() => { onMounted(() => {
setupForm()
getGoals() getGoals()
}) })
</script> const toRoadmap = () => {
router.push('/');
};
const addFriend = () => {
let id = route.params.id as any;
const response = FriendService.addFriendRequest({ userId: id });
};
const removeFriend = () => {
let id = route.params.id as any;
const response = FriendService.deleteFriendOrFriendRequest({ friendId: id });
};
</script>
<template> <template>
<div class="container py-5 h-100"> <div class="container py-5 h-100">
<div class="row d-flex justify-content-center align-items-center h-100"> <div class="row d-flex justify-content-center align-items-center h-100">
<div class="col 12"> <div class="col 12">
<div class="card"> <div class="card">
<div class="rounded-top text-white d-flex flex-row bg-primary" style="height:200px;"> <div class="rounded-top text-white d-flex flex-row bg-primary" style="height:200px;" id="banner">
<div class="ms-4 mt-5 d-flex flex-column" style="width: 150px;"> <div class=" d-flex flex-column align-items-center justify-content-center">
<img :src="imageUrl" alt="Generisk plassholderbilde" <img :src="imageUrl" alt="Generisk plassholderbilde" class="img-fluid img-thumbnail"
class="img-fluid img-thumbnail mt-4 mb-2" style="width: 150px; z-index: 1"> style="width: 150px; height:150px; margin-left: 25px; margin-right: 15px;">
<button v-if="!friend" type="button" data-mdb-button-init data-mdb-ripple-init class="btn btn-outline-primary"
data-mdb-ripple-color="dark" style="z-index: 1;" @click="addFriend">
Legg til venn
</button>
<button v-if="friend" type="button" data-mdb-button-init data-mdb-ripple-init class="btn btn-outline-danger"
data-mdb-ripple-color="dark" style="z-index: 1;" @click="removeFriend">
Fjern venn
</button>
</div>
<div class="ms-3" style="margin-top: 130px;">
<h1>{{username}}</h1>
</div> </div>
<h1 data-cy="firstname" style="display: flex; align-items: end; margin-bottom: 20px;">{{ firstname }} {{ lastname }}</h1>
</div> </div>
<div class="p-4 text-black" style="background-color: #f8f9fa;"> <div class="p-3 text-black" style="background-color: #f8f9fa;">
<div class="d-flex justify-content-end text-center py-1"> <div class="d-flex justify-content-end text-center py-1">
<div style="width: 100%; display: flex; justify-content: start">
<button data-cy="toUpdate" type="button" data-mdb-button-init data-mdb-ripple-init class="btn btn-outline-primary"
data-mdb-ripple-color="dark" style="z-index: 1; height: 40px; margin-left: 17px" id="toUpdate" @click="addFriend">
Rediger profil
</button>
</div>
<div> <div>
<p class="mb-1 h2">253 <img src="@/assets/items/pigcoin.png" style="width: 4rem"></p> <p class="mb-1 h2" data-cy="points">{{ points }} <img src="@/assets/items/pigcoin.png" style="width: 4rem"></p>
<p class="small text-muted mb-0">Poeng</p> <p class="small text-muted mb-0">Poeng</p>
</div> </div>
<div class="px-3"> <div class="px-3">
<p class="mb-1 h2">1026 <img src="@/assets/icons/fire.png" style="width: 4rem"></p> <p class="mb-1 h2" data-cy="streak">{{ streak }} <img src="@/assets/icons/fire.png" style="width: 4rem"></p>
<p class="small text-muted mb-0">Streak</p> <p class="small text-muted mb-0">Streak</p>
</div> </div>
</div> </div>
</div> </div>
<hr>
<div class="card-body p-1 text-black"> <div class="card-body p-1 text-black">
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<div class="container-fluid"> <div class="container-fluid">
<h1 class="mt-5 text-start badges-text">Merker</h1> <h1 class="mt-1 text-start badges-text">Lageret ditt</h1>
<div class="scrolling-wrapper-badges row flex-row flex-nowrap mt-4 pb-4 pt-2"> <div v-if="hasInventory" class="scrolling-wrapper-badges row flex-row flex-nowrap mt-2 pb-2 pt-2">
<div v-for="product in inventory" :key="product.id" class="card text-center"
<div class="col-5"> style="width: 12rem; border: none; cursor: pointer; margin: 1rem; border: 2px solid black" @click="selectItem(product)">
<div class="card badges-block card-1"></div> <img :src="`http://localhost:8080/api/images/${product.imageId}`" class="card-img-top"
</div> alt="..." />
<div class="col-5"> <div class="card-body">
<div class="card badges-block card-2"></div> <h5 class="card-title">{{ product.itemName }}</h5>
</div>
<div class="col-5">
<div class="card badges-block card-3"></div>
</div>
<div class="col-5">
<div class="card badges-block card-4"></div>
</div>
<div class="col-5">
<div class="card badges-block card-5"></div>
</div>
<div class="col-5">
<div class="card badges-block card-6"></div>
</div>
<div class="col-5">
<div class="card badges-block card-7"></div>
</div>
<div class="col-5">
<div class="card badges-block card-8"></div>
</div> </div>
<div class="col-5">
<div class="card badges-block card-9"></div>
</div> </div>
<div class="col-5">
<div class="card badges-block card-10"></div>
</div> </div>
<div v-else>Du har ingen ting på lageret ditt, gå til butikken for å kjøpe!</div>
<div v-if="backgroundName" class="text-success">You selected the background: <strong>{{ backgroundName }}!</strong></div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<hr>
<div class="card-body p-1 text-black">
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<!-- Her er historikken over lagrede mål --> <div class="container-fluid">
<div class="container-fluid mb-5"> <h1 class="mt-1 text-start badges-text">Merker</h1>
<h1 class="mt-5 text-start history-text">Historie</h1> <div v-if="hasBadges" class="scrolling-wrapper-badges row flex-row flex-nowrap mt-2 pb-2 pt-2">
<div v-if="hasHistory" class="row scrolling-wrapper-history">
<div v-for="(item, index) in goals" :key="index" <div v-for="badge in badges" :key="badge.id" class="card text-center"
class="col-md-4 col-sm-4 col-lg-4 col-xs-4 col-xl-4 control-label"> style="width: 12rem; border: none; cursor: pointer; margin: 1rem;
<div class="card history-block"> border: 2px solid black" data-bs-toggle="tooltip" data-bs-placement="top"
<div class="card mb-3" style="max-width: 540px;"> data-bs-custom-class="custom-tooltip" :data-bs-title="badge.criteria">
<div class="row g-0"> <img :src="`http://localhost:8080/api/images/${badge.imageId}`" class="card-img-top"
<div class="col-md-4"> alt="..." />
<img src="/src/assets/icons/piggybank.svg"
class="img-fluid rounded-start h-40 mx-auto d-none d-md-block" alt="...">
</div>
<div class="col-md-8">
<div class="card-body"> <div class="card-body">
<h5 class="card-title">{{ goals[index]['name'] }}</h5> <h5 class="card-title">{{ badge.badgeName }}</h5>
<p class="card-text">{{goals[index]['description']}}</p>
<p class="card-text"><small class="text-muted">{{goals[index]['targetAmount']}}</small></p>
<a href="#" class="btn stretched-link" @click="toRoadmap"></a>
</div>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
<div v-else>
Ingen merker
</div> </div>
<div v-if="!hasHistory">No History!</div>
</div> </div>
</div> </div>
</div> </div>
...@@ -225,8 +234,6 @@ onMounted(() =>{ ...@@ -225,8 +234,6 @@ onMounted(() =>{
overflow: auto; overflow: auto;
} }
.badges-text { .badges-text {
font-weight: 500; font-weight: 500;
font-size: 2.0em; font-size: 2.0em;
...@@ -271,6 +278,10 @@ onMounted(() =>{ ...@@ -271,6 +278,10 @@ onMounted(() =>{
} }
} }
#banner {
background-image: url('/src/assets/banners/stacked.svg');
}
.card-1 { .card-1 {
background-color: #4158D0; background-color: #4158D0;
background-image: linear-gradient(43deg, #4158D0 0%, #C850C0 46%, #FFCC70 100%); background-image: linear-gradient(43deg, #4158D0 0%, #C850C0 46%, #FFCC70 100%);
......
...@@ -4,6 +4,7 @@ import { useRouter } from "vue-router"; ...@@ -4,6 +4,7 @@ import { useRouter } from "vue-router";
import { useUserInfoStore } from "@/stores/UserStore"; import { useUserInfoStore } from "@/stores/UserStore";
import {UserService, BadgeService, GoalService, type GoalDTO, type BadgeDTO} from "@/api"; import {UserService, BadgeService, GoalService, type GoalDTO, type BadgeDTO} from "@/api";
import { ItemService } from "@/api"; import { ItemService } from "@/api";
import handleUnknownError from '@/components/Exceptions/unkownErrorHandler'
let numberOfHistory = 6; let numberOfHistory = 6;
let cardTitles = ["Spain tour", "Food waste", "Coffee", "Concert", "New book", "Pretty clothes"] let cardTitles = ["Spain tour", "Food waste", "Coffee", "Concert", "New book", "Pretty clothes"]
...@@ -12,11 +13,15 @@ let lastname = ref(); ...@@ -12,11 +13,15 @@ let lastname = ref();
const imageUrl = ref(`../src/assets/userprofile.png`); const imageUrl = ref(`../src/assets/userprofile.png`);
let hasHistory = ref(true) let hasHistory = ref(true)
let hasBadges = ref(false)
let hasInventory = ref(false)
const router = useRouter(); const router = useRouter();
const inventory = ref([] as any); const inventory = ref([] as any);
const badges = ref<BadgeDTO[]>([]); const badges = ref<BadgeDTO[]>([]);
const backgroundName = ref(""); const backgroundName = ref("");
const points = ref(0 as any);
const streak = ref(0 as any);
let goalName = ref(''); let goalName = ref('');
...@@ -38,6 +43,7 @@ async function getGoals() { ...@@ -38,6 +43,7 @@ async function getGoals() {
console.log('No history') console.log('No history')
} }
}catch (error){ }catch (error){
handleUnknownError(error)
console.error("Something went wrong", error) console.error("Something went wrong", error)
} }
} }
...@@ -49,12 +55,19 @@ async function setupForm() { ...@@ -49,12 +55,19 @@ async function setupForm() {
firstname.value = response.firstName; firstname.value = response.firstName;
lastname.value = response.lastName; lastname.value = response.lastName;
if (response.point?.currentPoints) {
points.value = response.point?.currentPoints;
}
if (response.streak?.currentStreak) {
streak.value = response.streak?.currentStreak;
}
if (response.profileImage) { if (response.profileImage) {
imageUrl.value = "http://localhost:8080/api/images/" + response.profileImage; imageUrl.value = "http://localhost:8080/api/images/" + response.profileImage;
} }
getInventory(); getInventory();
getBadges(); getBadges();
} catch (err) { } catch (err) {
handleUnknownError(err)
console.error(err) console.error(err)
} }
} }
...@@ -63,7 +76,14 @@ const getInventory = async () => { ...@@ -63,7 +76,14 @@ const getInventory = async () => {
try { try {
const response = await ItemService.getInventory(); const response = await ItemService.getInventory();
inventory.value = response; inventory.value = response;
if (inventory.value.length > 0) {
hasInventory.value = true
} else {
hasInventory.value = false
console.log('No history')
}
} catch (error) { } catch (error) {
handleUnknownError(error)
console.log(error); console.log(error);
} }
} }
...@@ -72,7 +92,14 @@ const getBadges = async () => { ...@@ -72,7 +92,14 @@ const getBadges = async () => {
try { try {
const responseBadge = await BadgeService.getBadgesUnlockedByUser(); const responseBadge = await BadgeService.getBadgesUnlockedByUser();
badges.value = responseBadge; badges.value = responseBadge;
if (badges.value.length > 0) {
hasBadges.value = true
} else {
hasBadges.value = false
console.log('No history')
}
} catch (error) { } catch (error) {
handleUnknownError(error)
console.log(error); console.log(error);
} }
} }
...@@ -126,11 +153,11 @@ const toUpdateUserSettings = () => { ...@@ -126,11 +153,11 @@ const toUpdateUserSettings = () => {
</div> </div>
<div> <div>
<p class="mb-1 h2" data-cy="points">253 <img src="@/assets/items/pigcoin.png" style="width: 4rem"></p> <p class="mb-1 h2" data-cy="points">{{ points }} <img src="@/assets/items/pigcoin.png" style="width: 4rem"></p>
<p class="small text-muted mb-0">Poeng</p> <p class="small text-muted mb-0">Poeng</p>
</div> </div>
<div class="px-3"> <div class="px-3">
<p class="mb-1 h2" data-cy="streak">1026 <img src="@/assets/icons/fire.png" style="width: 4rem"></p> <p class="mb-1 h2" data-cy="streak">{{ streak }} <img src="@/assets/icons/fire.png" style="width: 4rem"></p>
<p class="small text-muted mb-0">Streak</p> <p class="small text-muted mb-0">Streak</p>
</div> </div>
</div> </div>
...@@ -141,7 +168,7 @@ const toUpdateUserSettings = () => { ...@@ -141,7 +168,7 @@ const toUpdateUserSettings = () => {
<div class="col"> <div class="col">
<div class="container-fluid"> <div class="container-fluid">
<h1 class="mt-1 text-start badges-text">Lageret ditt</h1> <h1 class="mt-1 text-start badges-text">Lageret ditt</h1>
<div class="scrolling-wrapper-badges row flex-row flex-nowrap mt-2 pb-2 pt-2"> <div v-if="hasInventory" class="scrolling-wrapper-badges row flex-row flex-nowrap mt-2 pb-2 pt-2">
<div v-for="product in inventory" :key="product.id" class="card text-center" <div v-for="product in inventory" :key="product.id" class="card text-center"
style="width: 12rem; border: none; cursor: pointer; margin: 1rem; border: 2px solid black" @click="selectItem(product)"> style="width: 12rem; border: none; cursor: pointer; margin: 1rem; border: 2px solid black" @click="selectItem(product)">
<img :src="`http://localhost:8080/api/images/${product.imageId}`" class="card-img-top" <img :src="`http://localhost:8080/api/images/${product.imageId}`" class="card-img-top"
...@@ -151,6 +178,7 @@ const toUpdateUserSettings = () => { ...@@ -151,6 +178,7 @@ const toUpdateUserSettings = () => {
</div> </div>
</div> </div>
</div> </div>
<div v-else>Du har ingen ting på lageret ditt, gå til butikken for å kjøpe!</div>
<div v-if="backgroundName" class="text-success">You selected the background: <strong>{{ backgroundName }}!</strong></div> <div v-if="backgroundName" class="text-success">You selected the background: <strong>{{ backgroundName }}!</strong></div>
</div> </div>
</div> </div>
...@@ -162,7 +190,7 @@ const toUpdateUserSettings = () => { ...@@ -162,7 +190,7 @@ const toUpdateUserSettings = () => {
<div class="col"> <div class="col">
<div class="container-fluid"> <div class="container-fluid">
<h1 class="mt-1 text-start badges-text">Merker</h1> <h1 class="mt-1 text-start badges-text">Merker</h1>
<div class="scrolling-wrapper-badges row flex-row flex-nowrap mt-2 pb-2 pt-2"> <div v-if="hasBadges" class="scrolling-wrapper-badges row flex-row flex-nowrap mt-2 pb-2 pt-2">
<div v-for="badge in badges" :key="badge.id" class="card text-center" <div v-for="badge in badges" :key="badge.id" class="card text-center"
style="width: 12rem; border: none; cursor: pointer; margin: 1rem; style="width: 12rem; border: none; cursor: pointer; margin: 1rem;
...@@ -176,6 +204,9 @@ const toUpdateUserSettings = () => { ...@@ -176,6 +204,9 @@ const toUpdateUserSettings = () => {
</div> </div>
</div> </div>
<div v-else>
Ingen merker
</div>
</div> </div>
</div> </div>
</div> </div>
...@@ -209,7 +240,7 @@ const toUpdateUserSettings = () => { ...@@ -209,7 +240,7 @@ const toUpdateUserSettings = () => {
</div> </div>
</div> </div>
<div v-if="!hasHistory"> <div v-if="!hasHistory">
No History! Ingen sparemål
</div> </div>
</div> </div>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment