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 @@
{{ item.type }}
+
+
+
+
- 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
}