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