From 9a3bab368b16c24e5a9cdf10614cb9e0a4f71f5a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Trygve=20J=C3=B8rgensen?= <trygjor@stud.ntnu.no>
Date: Fri, 26 Apr 2024 10:23:05 +0200
Subject: [PATCH] feat(goals): user can now sort active goals

---
 src/components/CardGoal.vue | 10 ++++++-
 src/views/UserGoalsView.vue | 52 ++++++++++++++++++++++---------------
 2 files changed, 40 insertions(+), 22 deletions(-)

diff --git a/src/components/CardGoal.vue b/src/components/CardGoal.vue
index bceaaeb..f04058b 100644
--- a/src/components/CardGoal.vue
+++ b/src/components/CardGoal.vue
@@ -8,6 +8,10 @@ const props = defineProps({
     goalInstance: {
         type: Object as PropType<Goal>,
         required: true
+    },
+    isClickable: {
+        type: Boolean,
+        default: true
     }
 })
 
@@ -15,7 +19,11 @@ const goalInstance = props.goalInstance
 const displayDate = computed(() => goalInstance.due?.slice(0, 16).split('T').join(' '))
 const isCompleted = computed(() => goalInstance.completedOn != null)
 
-const handleCardClick = () => router.push({ name: 'view-goal', params: { id: goalInstance.id } })
+const handleCardClick = () => {
+    if (props.isClickable) {
+        router.push({ name: 'view-goal', params: { id: goalInstance.id } })
+    }
+}
 </script>
 
 <template>
diff --git a/src/views/UserGoalsView.vue b/src/views/UserGoalsView.vue
index 21cb663..558f773 100644
--- a/src/views/UserGoalsView.vue
+++ b/src/views/UserGoalsView.vue
@@ -2,7 +2,7 @@
 import CardGoal from '@/components/CardGoal.vue'
 
 import { useRouter } from 'vue-router'
-import { onMounted, ref, watch } from 'vue'
+import { onMounted, ref } from 'vue'
 import authInterceptor from '@/services/authInterceptor'
 import type { Goal } from '@/types/goal'
 import draggable from 'vuedraggable'
@@ -16,24 +16,19 @@ const totalPages = ref(1)
 const activeGoals = ref<Goal[]>([])
 const completedGoals = ref<Goal[]>([])
 
+const isDraggable = ref(false)
+
 onMounted(async () => {
     await authInterceptor('/users/me/goals/active')
         .then((response) => {
             activeGoals.value = response.data
+            activeGoals.value.sort((a, b) => (a.priority || 0) - (b.priority || 0))
         })
         .catch((error) => {
             console.error(error)
         })
 
-    await authInterceptor(`/users/me/goals/completed?page=${currentPage.value}&size=5`)
-        .then((response) => {
-            currentPage.value = response.data.number
-            totalPages.value = response.data.totalPages
-            completedGoals.value = response.data.content
-        })
-        .catch((error) => {
-            console.error(error)
-        })
+    await updatePage(0)
 })
 
 const updatePage = async (page: number) => {
@@ -48,34 +43,49 @@ const updatePage = async (page: number) => {
         })
 }
 
-watch(activeGoals, (newGoals) => {
-    console.log(newGoals)
-})
+const changeOrder = async () => {
+    if (isDraggable.value) {
+        const priorities = activeGoals.value.map((goal) => goal.id)
+        await authInterceptor.put('/users/me/goals', priorities).catch((error) => {
+            console.error(error)
+        })
+        isDraggable.value = false
+        await updatePage(currentPage.value)
+    } else {
+        isDraggable.value = true
+    }
+}
 </script>
 
 <template>
     <div class="flex flex-col gap-5 items-center">
         <h1 class="font-bold m-0">Dine sparemål</h1>
         <button @click="router.push({ name: 'new-goal' })">Opprett et nytt sparemål</button>
-        <h2 class="font-bold m-0">Aktive sparemål</h2>
+        <h2 class="font-thin m-0">Aktive sparemål</h2>
         <p v-if="activeGoals.length === 0">Du har ingen aktive sparemål</p>
         <draggable
             v-else
             v-model="activeGoals"
             class="flex flex-row flex-wrap justify-center gap-10"
             item-key="id"
+            :disabled="!isDraggable"
         >
             <template #item="{ element, index }">
-                <CardGoal :key="index" :goal-instance="element" />
+                <CardGoal
+                    :key="index"
+                    :class="[
+                        { 'cursor-move shadow-xl -translate-y-2 duration-300': isDraggable },
+                        { 'border-4 border-green-500': index === 0 }
+                    ]"
+                    :goal-instance="element"
+                    :is-clickable="!isDraggable"
+                />
             </template>
         </draggable>
-        <button
-            :disabled="activeGoals.length === 0"
-            @click="router.push({ name: 'edit-goal', params: { id: 1 } })"
-        >
-            Rediger rekkefølge
+        <button :disabled="activeGoals.length === 0" @click="changeOrder()">
+            {{ isDraggable ? 'Lagre rekkefølge' : 'Endre rekkefølge' }}
         </button>
-        <h2 class="font-bold m-0">Fullførte sparemål</h2>
+        <h2 class="font-thin m-0">Fullførte sparemål</h2>
         <p v-if="completedGoals.length === 0">Du har ingen fullførte sparemål</p>
         <div v-else class="flex flex-row flex-wrap justify-center gap-10">
             <CardGoal v-for="goal in completedGoals" :key="goal.id" :goal-instance="goal" />
-- 
GitLab