Skip to content
Snippets Groups Projects
Commit 8997ca28 authored by Trygve Jørgensen's avatar Trygve Jørgensen
Browse files

feat(goal): pure frontend functionality for creating and editing goals

parent b78cd16c
No related branches found
No related tags found
Loading
Pipeline #276466 failed
<script lang="ts" setup>
import type { Goal } from '@/types/goal'
import type { PropType } from 'vue'
import { reactive } from 'vue'
import ProgressBar from '@/components/ProgressBar.vue'
import router from '@/router'
defineProps({
const props = defineProps({
goalInstance: {
type: Object as PropType<Goal>,
default: () => ({
......@@ -19,10 +21,19 @@ defineProps({
})
}
})
const goalInstance = reactive(props.goalInstance)
const editGoal = () => {
router.push({ name: 'edit-goal', params: { id: goalInstance.id } })
}
</script>
<template>
<div class="border-2 border-black rounded-xl p-4 flex flex-col items-center gap-2">
<div
class="border-2 border-black rounded-xl p-4 flex flex-col items-center gap-2"
@click="editGoal"
>
<h2 class="m-0">{{ goalInstance.title }}</h2>
<p>{{ goalInstance.saved }}kr / {{ goalInstance.target }}kr</p>
<ProgressBar :completion="goalInstance.completion" />
......
......@@ -5,7 +5,7 @@ defineProps({
</script>
<template>
<div class="w-full bg-gray-200 rounded-full">
<div class="w-full bg-gray-200 rounded-full overflow-hidden">
<div :style="{ width: completion + '%' }" class="bg-green-500 h-2 rounded-full"></div>
</div>
</template>
......
import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
......@@ -7,7 +6,7 @@ const router = createRouter({
{
path: '/',
name: 'home',
component: HomeView
component: () => import('../views/HomeView.vue')
},
{
path: '/login',
......@@ -22,7 +21,17 @@ const router = createRouter({
{
path: '/sparemaal',
name: 'goals',
component: () => import('../views/GoalView.vue')
component: () => import('../views/UserGoalsView.vue')
},
{
path: '/sparemaal/ny',
name: 'new-goal',
component: () => import('../views/ManageGoalView.vue')
},
{
path: '/sparemaal/:id',
name: 'edit-goal',
component: () => import('../views/ManageGoalView.vue')
},
{
path: '/spareutfordringer',
......
export interface Goal {
id: number
id: number | null | undefined
title: string
saved: number
target: number
completion: number
description: string
priority: number
createdOn: string
dueDate: string | null
createdOn: string | null | undefined
due: string | null | undefined
completedOn: string | null | undefined
}
<script lang="ts" setup>
import { useRouter } from 'vue-router'
import { computed, onMounted, ref, watch } from 'vue'
import type { Goal } from '@/types/goal'
import ProgressBar from '@/components/ProgressBar.vue'
const router = useRouter()
const oneWeekFromNow = new Date()
oneWeekFromNow.setDate(oneWeekFromNow.getDate() + 7)
const minDate = oneWeekFromNow.toISOString().split('T')[0]
const thirtyDaysFromNow = new Date()
thirtyDaysFromNow.setDate(thirtyDaysFromNow.getDate() + 30)
const maxDate = thirtyDaysFromNow.toISOString().split('T')[0]
const goalInstance = ref<Goal>({
id: 0,
title: '',
saved: 50,
target: 100,
completion: 0,
description: '',
priority: 0,
createdOn: undefined,
due: minDate,
completedOn: null
})
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)
const submitAction = computed(() => {
if (
goalInstance.value.title === '' ||
goalInstance.value.target < 1 ||
goalInstance.value.due === ''
) {
return () => alert('Fyll ut alle feltene')
}
return isEdit.value ? updateGoal : createGoal
})
watch(
() => goalInstance.value.saved,
(newVal) => {
goalInstance.value.saved = Math.max(0, Math.min(goalInstance.value.target, newVal))
}
)
watch(
() => goalInstance.value.target,
(newVal) => {
goalInstance.value.target = Math.max(Math.max(goalInstance.value.saved, 1), newVal)
}
)
watch(
() => goalInstance.value.due,
(newVal) => {
if (newVal) {
goalInstance.value.due = newVal < minDate ? minDate : newVal
}
}
)
onMounted(() => {
const routeName = router.currentRoute.value.name
let id = null
if (routeName === 'edit-goal') {
id = Number(router.currentRoute.value.params.id)
if (!id) {
router.push('/')
}
goalInstance.value.id = id
// TODO Fetch goal data from API
}
})
const createGoal = () => {
// TODO Create goal
router.push('/')
}
const updateGoal = () => {
// TODO Update goal
router.push('/')
}
</script>
<template>
<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</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">
<div class="flex flex-col">
<p class="mx-4">Kroner spart...</p>
<input
v-model="goalInstance.saved"
class="w-40 text-right"
min="0"
placeholder="Sparebeløp"
type="number"
/>
</div>
<div class="flex flex-col">
<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>
</div>
<ProgressBar :completion="completion" />
<div class="flex flex-col">
<p class="mx-4">Forfallsdato*</p>
<input
v-model="goalInstance.due"
:max="maxDate"
:min="minDate"
placeholder="Forfallsdato"
type="date"
/>
</div>
<button @click="submitAction" v-text="submitButton" />
</div>
</div>
</template>
<style scoped>
.no-rezise {
resize: none;
}
</style>
<script lang="ts" setup>
import CardGoal from '@/components/CardGoal.vue'
import PageControl from '@/components/PageControl.vue'
import { useRouter } from 'vue-router'
const router = useRouter()
</script>
<template>
<h1 class="font-bold text-center">Dine sparemål</h1>
<div class="flex flex-row justify-center gap-2">
<CardGoal />
<CardGoal />
<CardGoal />
<div class="flex flex-col gap-5 items-center">
<div class="flex flex-col justify-center gap-10 sm:flex-row">
<CardGoal />
<CardGoal />
<CardGoal />
</div>
<PageControl />
<button @click="router.push('/sparemaal/ny')">Opprett et nytt sparemål</button>
</div>
</template>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment