diff --git a/frontend/src/views/categories/CategoriesView.vue b/frontend/src/views/categories/CategoriesView.vue index 72eb924..2fbefe5 100644 --- a/frontend/src/views/categories/CategoriesView.vue +++ b/frontend/src/views/categories/CategoriesView.vue @@ -3,7 +3,7 @@

Categories

- Add Category + Add Category
@@ -11,22 +11,41 @@ + - Add Category + {{ editingCategory ? 'Edit Category' : 'Add Category' }} - + + Cancel - Create + {{ editingCategory ? 'Save' : 'Create' }} + + + + + + + Delete Category + + Are you sure you want to delete {{ deleteTarget?.name }}? This action cannot be undone. + + + + Cancel + Delete @@ -41,22 +60,64 @@ import type { CategoryTree, Category } from '@/types' const categoryTree = ref([]) const allCategories = ref([]) const showDialog = ref(false) -const form = ref({ name: '', type: 'Expense', parentId: null as string | null }) +const editingCategory = ref(null) +const showDeleteDialog = ref(false) +const deleteTarget = ref(null) +const form = ref({ name: '', type: 'Expense', parentId: null as string | null, isActive: true }) const parentOptions = computed(() => allCategories.value.filter(c => !c.parentId)) onMounted(async () => { - const [tree, all] = await Promise.all([categoriesApi.getTree(), categoriesApi.getAll()]) - categoryTree.value = tree.data - allCategories.value = all.data + await reloadCategories() }) -async function saveCategory() { - await categoriesApi.create(form.value) +async function reloadCategories() { const [tree, all] = await Promise.all([categoriesApi.getTree(), categoriesApi.getAll()]) categoryTree.value = tree.data allCategories.value = all.data +} + +function openCreateDialog() { + editingCategory.value = null + form.value = { name: '', type: 'Expense', parentId: null, isActive: true } + showDialog.value = true +} + +function openEditDialog(item: CategoryTree) { + const cat = allCategories.value.find(c => c.id === item.id) + if (!cat) return + editingCategory.value = cat + form.value = { name: cat.name, type: cat.type, parentId: cat.parentId, isActive: cat.isActive } + showDialog.value = true +} + +function openDeleteDialog(item: CategoryTree) { + deleteTarget.value = item + showDeleteDialog.value = true +} + +async function saveCategory() { + if (editingCategory.value) { + await categoriesApi.update(editingCategory.value.id, { + name: form.value.name, + parentId: form.value.parentId, + sortOrder: editingCategory.value.sortOrder, + isActive: form.value.isActive, + }) + } else { + await categoriesApi.create(form.value) + } + await reloadCategories() showDialog.value = false - form.value = { name: '', type: 'Expense', parentId: null } + editingCategory.value = null + form.value = { name: '', type: 'Expense', parentId: null, isActive: true } +} + +async function confirmDelete() { + if (!deleteTarget.value) return + await categoriesApi.delete(deleteTarget.value.id) + await reloadCategories() + showDeleteDialog.value = false + deleteTarget.value = null }