123 lines
3.1 KiB
Vue
123 lines
3.1 KiB
Vue
<script setup>
|
|
import { ref, onMounted, inject } from 'vue'
|
|
import { useRoute, useRouter } from 'vue-router'
|
|
import { getTask, updateTask, deleteTask } from '../services/api'
|
|
import { useCategoriesStore } from '../stores/categories'
|
|
import Icon from '../components/Icon.vue'
|
|
|
|
const route = useRoute()
|
|
const router = useRouter()
|
|
const setDynamicLabel = inject('setDynamicLabel')
|
|
|
|
const categoriesStore = useCategoriesStore()
|
|
const loading = ref(true)
|
|
const saving = ref(false)
|
|
const occurrence = ref(null)
|
|
const form = ref({ name: '', status: 'active', date: '', categoryId: null })
|
|
|
|
async function load() {
|
|
loading.value = true
|
|
const data = await getTask(route.params.id)
|
|
occurrence.value = data
|
|
form.value = { name: data.name, status: data.status, date: data.date, categoryId: data.category?.id ?? null }
|
|
setDynamicLabel(data.name)
|
|
loading.value = false
|
|
}
|
|
|
|
async function save() {
|
|
saving.value = true
|
|
await updateTask(route.params.id, {
|
|
name: form.value.name,
|
|
categoryId: form.value.categoryId,
|
|
status: form.value.status,
|
|
date: form.value.date || null,
|
|
})
|
|
saving.value = false
|
|
router.back()
|
|
}
|
|
|
|
async function remove() {
|
|
if (!confirm('Aufgabe wirklich löschen?')) return
|
|
await deleteTask(route.params.id)
|
|
router.back()
|
|
}
|
|
|
|
onMounted(() => {
|
|
categoriesStore.fetchCategories()
|
|
load()
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<div>
|
|
<div class="header-row">
|
|
<button type="button" class="btn-danger" @click="remove">
|
|
<Icon name="trash" />
|
|
</button>
|
|
<div class="btn-row">
|
|
<button class="btn-primary" :disabled="saving" @click="save">
|
|
<Icon name="save" />
|
|
</button>
|
|
<button @click="router.back()"><Icon name="arrowLeft" /></button>
|
|
</div>
|
|
</div>
|
|
|
|
<p v-if="loading" class="loading">Laden...</p>
|
|
|
|
<div v-else>
|
|
<div class="form-row">
|
|
<div class="form-group flex-1">
|
|
<label for="name">Name</label>
|
|
<input id="name" v-model="form.name" type="text" required />
|
|
</div>
|
|
<div class="form-group flex-1">
|
|
<label for="category">Kategorie</label>
|
|
<select id="category" v-model="form.categoryId">
|
|
<option :value="null">Keine Kategorie</option>
|
|
<option v-for="cat in categoriesStore.items" :key="cat.id" :value="cat.id">
|
|
{{ cat.name }}
|
|
</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
<div class="form-group flex-1">
|
|
<label for="status">Status</label>
|
|
<select id="status" v-model="form.status">
|
|
<option value="active">Aktiv</option>
|
|
<option value="done">Erledigt</option>
|
|
</select>
|
|
</div>
|
|
<div class="form-group flex-1">
|
|
<label for="date">Datum</label>
|
|
<input id="date" v-model="form.date" type="date" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.header-row {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 1rem;
|
|
}
|
|
|
|
.form-row {
|
|
display: flex;
|
|
gap: 1rem;
|
|
}
|
|
|
|
.flex-1 {
|
|
flex: 1;
|
|
}
|
|
|
|
.loading {
|
|
text-align: center;
|
|
color: var(--text);
|
|
}
|
|
</style>
|