Newer
Older
<script lang="ts" setup>
import { useRouter } from 'vue-router'
import { computed, onMounted, type Ref, ref, watch } from 'vue'
import type { Goal } from '@/types/goal'
import ProgressBar from '@/components/ProgressBar.vue'
import authInterceptor from '@/services/authInterceptor'
import ModalComponent from '@/components/ModalComponent.vue'
import InteractiveSpare from '@/components/InteractiveSpare.vue'
const minDate = new Date(new Date().setDate(new Date().getDate() + 1)).toISOString().slice(0, 10)
const selectedDate = ref<string>(minDate)
const modalMessage = ref<string>('')
const modalTitle = ref<string>('')
const errorModalOpen = ref<boolean>(false)
const confirmModalOpen = ref<boolean>(false)
const goalInstance = ref<Goal>({
title: '',
saved: 0,
target: 0,
description: '',
due: ''
})
watch(selectedDate, (newDate) => {
goalInstance.value.due = newDate
})
const isEdit = computed(() => router.currentRoute.value.name === 'edit-goal')
const pageTitle = computed(() => (isEdit.value ? 'Rediger sparemål🎨' : 'Nytt sparemål🎨'))
const submitButton = computed(() => (isEdit.value ? 'Oppdater' : 'Opprett'))
const completion = computed(() => (goalInstance.value.saved / goalInstance.value.target) * 100)
function validateInputs() {
const errors = []
goalInstance.value.due = selectedDate.value + 'T23:59:59.999Z'
goalInstance.value.saved = parseInt(goalInstance.value.saved.toString())
goalInstance.value.target = parseInt(goalInstance.value.target.toString())
if (!goalInstance.value.title) {
errors.push('Tittel må fylles ut')
}
if (!goalInstance.value.target) {
errors.push('Målbeløp må fylles ut')
}
if (!goalInstance.value.due) {
errors.push('Forfallsdato må fylles ut')
}
if (goalInstance.value.target < 1) {
errors.push('Målbeløp må være større enn 0')
}
if (goalInstance.value.saved < 0) {
errors.push('Sparebeløp kan ikke være negativt')
}
if (goalInstance.value.saved > goalInstance.value.target) {
errors.push('Sparebeløp kan ikke være større enn målbeløp')
}
return errors
}
const submitAction = async () => {
const errors = validateInputs()
if (errors.length > 0) {
modalTitle.value = 'Oops! Noe er feil med det du har fylt ut🚨'
const goalId = isEdit.value ? goalInstance.value.id : response.id // Adjusted to handle the returned data
if (uploadedFile.value && goalId) {
const formData = new FormData()
formData.append('file', uploadedFile.value)
formData.append('id', goalId.toString())
await authInterceptor.post('/goals/picture', formData, {
modalTitle.value = 'Systemfeil'
modalMessage.value = 'En feil oppstod under lagring av utfordringen.'
errorModalOpen.value = true
}
}
onMounted(async () => {
if (isEdit.value) {
const goalId = router.currentRoute.value.params.id
if (!goalId) return router.push({ name: 'goals' })
await authInterceptor(`/goals/${goalId}`)
.then((response) => {
goalInstance.value = response.data
selectedDate.value = response.data.due.slice(0, 10)
})
.catch((error) => {
console.error(error)
router.push({ name: 'goals' })
})
} else {
goalInstance.value.due = selectedDate.value
}
})
const createGoal = async (): Promise<any> => {
try {
const response = await authInterceptor.post('/goals', goalInstance.value)
return response.data // Ensure the response data is returned
} catch (error) {
console.error('Failed to create goal:', error)
throw error // Rethrow the error to handle it in the submitAction method
const updateGoal = async (): Promise<any> => {
try {
const response = await authInterceptor.put(
`/goals/${goalInstance.value.id}`,
goalInstance.value
)
return response.data // Ensure the response data is returned
} catch (error) {
console.error('Failed to update goal:', error)
throw error // Rethrow the error to handle it in the submitAction method
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
}
const deleteGoal = () => {
authInterceptor
.delete(`/goals/${goalInstance.value.id}`)
.then(() => {
router.push({ name: 'goals' })
})
.catch((error) => {
console.error(error)
})
}
function cancelCreation() {
if (
goalInstance.value.title !== '' ||
goalInstance.value.description !== '' ||
goalInstance.value.target !== 0 ||
selectedDate.value !== ''
) {
modalTitle.value = 'Du er i ferd med å avbryte redigeringen🚨'
modalMessage.value = 'Er du sikker på at du vil avbryte?'
confirmModalOpen.value = true
} else {
router.push({ name: 'goals' })
}
}
const confirmCancel = () => {
router.push({ name: 'goals' })
confirmModalOpen.value = false
}
const handleFileChange = (event: Event) => {
if (target.files && target.files.length > 0) {
uploadedFile.value = target.files[0] // Save the first selected file
} else {
const removeUploadedFile = () => {
<div class="flex flex-col justify-center items-center">
<h1 class="font-bold" v-text="pageTitle" />
<div class="flex flex-col gap-5 items-center justify-center">
<div class="flex flex-col">
<p class="mx-4">Tittel*</p>
<input v-model="goalInstance.title" placeholder="Skriv en tittel" type="text" />
</div>
<div class="flex flex-col">
<p class="mx-4">Beskrivelse (valgfri)</p>
<textarea
v-model="goalInstance.description"
class="w-80 h-20 no-rezise"
placeholder="Beskriv sparemålet"
/>
</div>
<div class="flex flex-col sm:flex-row gap-3">
<p class="mx-4">Kroner spart💸</p>
<input
v-model="goalInstance.saved"
class="w-40 text-right"
placeholder="Sparebeløp"
type="number"
/>
<p class="mx-4">Av målbeløp💯*</p>
<input
v-model="goalInstance.target"
class="w-40 text-right"
placeholder="Målbeløp"
type="number"
</div>
<ProgressBar :completion="completion" />
<div class="flex flex-row gap-4">
<div class="flex flex-col">
<p class="mx-4">Forfallsdato*</p>
<input
:min="minDate"
v-model="selectedDate"
placeholder="Forfallsdato"
type="date"
/>
<div class="flex flex-col items-center">
<p>Last opp ikon for utfordringen📸</p>
<label
for="fileUpload"
class="bg-white text-black text-lg cursor-pointer leading-none rounded-full border p-3 border-black"
Legg til 💾
</label>
<input
id="fileUpload"
type="file"
accept=".jpg, .png"
hidden
@change="handleFileChange"
/>
<div v-if="uploadedFile" class="flex justify-center items-center mt-2">
<p class="text-sm">{{ uploadedFile.name }}</p>
<button
@click="removeUploadedFile"
class="ml-2 text-xs font-bold border-2 p-1 rounded text-red-500"
>
Fjern fil
</button>
</div>
<div class="flex flex-row justify-between w-full">
<button
v-if="isEdit"
class="ml-2 primary danger"
@click="deleteGoal"
v-text="'Slett'"
/>
<button
v-else
class="ml-2 primary danger"
@click="cancelCreation"
v-text="'Avbryt'"
<button class="primary" @click="submitAction" v-text="submitButton" />
<ModalComponent
:title="modalTitle"
:message="modalMessage"
:isModalOpen="errorModalOpen"
@close="errorModalOpen = false"
>
<template v-slot:buttons>
<button class="primary" @click="errorModalOpen = false">Lukk</button>
</template>
</ModalComponent>
<ModalComponent
:title="modalTitle"
:message="modalMessage"
:isModalOpen="confirmModalOpen"
@close="confirmModalOpen = false"
>
<template v-slot:buttons>
<button class="primary" @click="confirmCancel">Bekreft</button>
<button class="primary danger" @click="confirmModalOpen = false">
Avbryt
</button>
</template>
</ModalComponent>
</div>
<div
class="lg:absolute right-5 lg:top-1/3 max-lg:bottom-0 max-lg:mt-44 transform -translate-y-1/2 lg:w-1/4 lg:max-w-xs"
:speech="[`Trenger du hjelp? Trykk på ❓ nede i høyre hjørne!`]"
</template>
<style scoped>
.no-rezise {
resize: none;
}
</style>