finnow/web-app/src/pages/CategoriesPage.vue

106 lines
3.0 KiB
Vue

<script setup lang="ts">
import { getSelectedProfile } from '@/api/profile'
import {
TransactionApiClient,
type TransactionCategory,
type TransactionCategoryTree,
} from '@/api/transaction'
import AppButton from '@/components/common/AppButton.vue'
import AppPage from '@/components/common/AppPage.vue'
import ButtonBar from '@/components/common/ButtonBar.vue'
import CategoryDisplayItem from '@/components/CategoryDisplayItem.vue'
import EditCategoryModal from '@/components/EditCategoryModal.vue'
import { showConfirm } from '@/util/alert'
import { hideLoader, showLoader } from '@/util/loader'
import { nextTick, onMounted, ref, useTemplateRef, type Ref } from 'vue'
import { useRoute } from 'vue-router'
const route = useRoute()
const editCategoryModal = useTemplateRef('editCategoryModal')
const categories: Ref<TransactionCategoryTree[]> = ref([])
const editedCategory: Ref<TransactionCategory | undefined> = ref(undefined)
onMounted(async () => {
await loadCategories()
})
async function loadCategories() {
const api = new TransactionApiClient(getSelectedProfile(route))
categories.value = await api.getCategories()
}
async function editCategory(categoryId: number) {
try {
const api = new TransactionApiClient(getSelectedProfile(route))
editedCategory.value = await api.getCategory(categoryId)
await nextTick()
const result = await editCategoryModal.value?.show()
if (result === 'saved') {
await loadCategories()
}
} catch (err) {
console.error(err)
}
}
async function deleteCategory(categoryId: number) {
const result = await showConfirm(
'Are you sure you want to delete this category? It will be removed from all transactions. All sub-categories will also be removed.',
)
if (result) {
try {
showLoader()
const api = new TransactionApiClient(getSelectedProfile(route))
await api.deleteCategory(categoryId)
await loadCategories()
} catch (err) {
console.error(err)
} finally {
hideLoader()
}
}
}
async function addCategory() {
editedCategory.value = undefined
await nextTick()
const result = await editCategoryModal.value?.show()
if (result === 'saved') {
await loadCategories()
}
}
</script>
<template>
<AppPage title="Categories">
<p>
Categories are used to group related transactions for your own organization, as well as
analytics. Categories are structured hierarchically, where each category could have zero or
more sub-categories.
</p>
<div>
<CategoryDisplayItem
v-for="category in categories"
:key="category.id"
:category="category"
:editable="true"
@edited="editCategory"
@deleted="deleteCategory"
/>
</div>
<ButtonBar>
<AppButton
icon="plus"
@click="addCategory()"
>Add Category</AppButton
>
</ButtonBar>
<EditCategoryModal
ref="editCategoryModal"
:category="editedCategory"
/>
</AppPage>
</template>