From b5a48a43fb85f87efa127fedc0fb353c26b627c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Trygve=20J=C3=B8rgensen?= <trygjor@stud.ntnu.no> Date: Thu, 25 Apr 2024 19:27:33 +0200 Subject: [PATCH] feat(goal): added a view goal page --- src/router/index.ts | 9 ++- src/types/goal.ts | 10 +-- src/views/ViewGoalView.vue | 137 +++++++++++++++++++++++++++++++++++++ 3 files changed, 149 insertions(+), 7 deletions(-) create mode 100644 src/views/ViewGoalView.vue diff --git a/src/router/index.ts b/src/router/index.ts index def052f..4ae0e9a 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -39,15 +39,20 @@ const router = createRouter({ component: () => import('@/views/UserGoalsView.vue') }, { - path: '/sparemaal/ny', + path: '/sparemaal/rediger/ny', name: 'new-goal', component: () => import('@/views/ManageGoalView.vue') }, { - path: '/sparemaal/:id', + path: '/sparemaal/rediger/:id', name: 'edit-goal', component: () => import('@/views/ManageGoalView.vue') }, + { + path: '/sparemaal/oversikt/:id', + name: 'view-goal', + component: () => import('@/views/ViewGoalView.vue') + }, { path: '/spareutfordringer', name: 'challenges', diff --git a/src/types/goal.ts b/src/types/goal.ts index 3ad1769..6c0962f 100644 --- a/src/types/goal.ts +++ b/src/types/goal.ts @@ -1,12 +1,12 @@ export interface Goal { - id: number | null | undefined + id?: number title: string saved: number target: number - completion: number + completion?: number description: string - priority: number - createdOn: string | null | undefined + priority?: number + createdOn?: string due: string - completedOn: string | null | undefined + completedOn?: string } diff --git a/src/views/ViewGoalView.vue b/src/views/ViewGoalView.vue new file mode 100644 index 0000000..4c4a96b --- /dev/null +++ b/src/views/ViewGoalView.vue @@ -0,0 +1,137 @@ +<script lang="ts" setup> +import { useRouter } from 'vue-router' +import { computed, onMounted, ref } from 'vue' +import ProgressBar from '@/components/ProgressBar.vue' +import authInterceptor from '@/services/authInterceptor' +import type { Goal } from '@/types/goal' +import InteractiveSpare from '@/components/InteractiveSpare.vue' + +const router = useRouter() + +const goalInstance = ref<Goal>({ + title: 'Test tittel', + saved: 0, + target: 100, + description: 'Dette er en lang textbeskrivelse', + due: '' +}) + +const completion = computed(() => (goalInstance.value.saved / goalInstance.value.target) * 100) +const isCompleted = computed(() => goalInstance.value.completedOn != null) + +const motivation = ref<string[]>([]) + +const calculateSpeech = () => { + if (completion.value === 0) { + return motivation.value.push( + `Du har ikke spart noe enda. Du har ${goalInstance.value.target}kr igjen til målet.` + ) + } else if (completion.value < 25) { + return motivation.value.push( + `Du har spart ${goalInstance.value.saved}kr av ${goalInstance.value.target}kr.` + ) + } else if (completion.value < 75) { + return motivation.value.push( + `Du er på god vei! Du har spart ${goalInstance.value.saved}kr av ${goalInstance.value.target}kr.` + ) + } else if (completion.value < 100) { + return motivation.value.push( + `Nesten der! Du har spart ${goalInstance.value.saved}kr av ${goalInstance.value.target}kr.` + ) + } else if (completion.value >= 100) { + return motivation.value.push( + `Fantastisk! Du har nådd målet ditt! Du har spart ${goalInstance.value.saved}kr av ${goalInstance.value.target}kr.` + ) + } +} + +onMounted(() => { + const goalId = router.currentRoute.value.params.id + if (!goalId) return router.push({ name: 'goals' }) + + authInterceptor(`/users/me/goals/${goalId}`) + .then((response) => { + goalInstance.value = response.data + calculateSpeech() + }) + .catch(() => router.push({ name: 'goals' })) +}) + +const completeGoal = () => { + authInterceptor + .put(`/users/me/goals/${goalInstance.value.id}/complete`) + .then(() => { + router.push({ name: 'goals' }) + }) + .catch((error) => { + console.error(error) + }) +} +</script> + +<template> + <div class="flex flex-row flex-wrap items-center justify-center gap-10"> + <div class="flex flex-col gap-5 max-w-96"> + <button + class="w-min" + @click="router.push({ name: 'goals', params: { id: goalInstance.id } })" + > + Oversikt + </button> + + <div + class="flex flex-col justify-center border-4 border-black rounded-3xl align-middle p-5 card-shadow overflow-hidden w-full" + > + <h2 class="my-0">Sparemål:</h2> + <h2 class="font-light"> + {{ goalInstance.title }} + </h2> + <p class="text-wrap break-words">{{ goalInstance.description }}</p> + <br /> + <p class="text-center"> + Du har spart {{ goalInstance.saved }}kr av {{ goalInstance.target }}kr + </p> + <ProgressBar :completion="completion" /> + </div> + + <div class="flex flex-row justify-between gap-2 w-full"> + <button + v-if="!isCompleted" + @click=" + router.push({ + name: 'edit-goal', + params: { id: goalInstance.id } + }) + " + > + Rediger + </button> + + <button + v-if="!isCompleted" + @click="completeGoal" + v-text="'Marker målet som ferdig'" + /> + + <button + class="bg-button-danger hover:bg-button-danger" + @click=" + authInterceptor + .delete(`/users/me/goals/${goalInstance.id}`) + .then(() => router.push({ name: 'goals' })) + .catch((error) => console.error(error)) + " + > + Slett + </button> + </div> + </div> + <InteractiveSpare :png-size="10" :speech="motivation" direction="left" /> + </div> +</template> + +<style scoped> +.card-shadow { + box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2); +} +</style> -- GitLab