handling create update delete categories
This commit is contained in:
@@ -9,6 +9,8 @@ import {useSpaceStore} from "@/stores/spaceStore";
|
||||
import {CategoryType, CategoryTypeName} from "@/models/enums";
|
||||
import emojiRegex from 'emoji-regex'
|
||||
import {useCategoriesStore} from "@/stores/categories-store";
|
||||
import {CreateCategoryDTO, UpdateCategoryDTO} from "@/models/category";
|
||||
import ConfirmDialog from '@/components/ConfirmDialog.vue'
|
||||
|
||||
|
||||
const route = useRoute()
|
||||
@@ -17,14 +19,21 @@ const toolbar = useToolbarStore();
|
||||
const toast = useToast();
|
||||
const spaceStore = useSpaceStore();
|
||||
const categoriesStore = useCategoriesStore();
|
||||
const categoryId = ref<string | undefined>(route.params.id)
|
||||
const tgApp = window.Telegram.WebApp
|
||||
|
||||
|
||||
const categoryId = ref<string | undefined>(route.params.id as string)
|
||||
const mode = computed(() => {
|
||||
return categoryId.value ? "edit" : "create"
|
||||
})
|
||||
const categoryType = ref<CategoryType>(CategoryType.EXPENSE)
|
||||
const categoryName = ref<string>()
|
||||
const isCategoryTypeError = ref<boolean>(false)
|
||||
const categoryName = ref<string>('')
|
||||
const isCategoryNameError = ref<boolean>(false)
|
||||
const categoryIcon = ref<string>("🛍️")
|
||||
const categoryDescription = ref<string>()
|
||||
const isCategoryIconError = ref<boolean>(false)
|
||||
const categoryDescription = ref<string>('')
|
||||
const isCategoryDescriptionError = ref<boolean>(false)
|
||||
|
||||
|
||||
// Генерим опции: [{ label: "Расходы", value: "EXPENSE" }, ...]
|
||||
@@ -82,22 +91,123 @@ function handleCompositionEnd(e: CompositionEvent) {
|
||||
handleInput(e as unknown as Event)
|
||||
}
|
||||
|
||||
const validateForm = (): boolean => {
|
||||
if (!categoryType.value) {
|
||||
isCategoryTypeError.value = true
|
||||
return false;
|
||||
}
|
||||
if (categoryName.value.length == 0) {
|
||||
isCategoryNameError.value = true
|
||||
return false;
|
||||
}
|
||||
if (categoryIcon.value.length == 0) {
|
||||
isCategoryIconError.value = true
|
||||
return false;
|
||||
}
|
||||
console.log(categoryDescription.value.length)
|
||||
if (categoryDescription.value.length == 0) {
|
||||
isCategoryDescriptionError.value = true
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const buildUpdate = (): UpdateCategoryDTO => {
|
||||
if (validateForm()) {
|
||||
return {
|
||||
type: categoryType.value,
|
||||
name: categoryName.value,
|
||||
description: categoryDescription.value,
|
||||
icon: categoryIcon.value,
|
||||
} as UpdateCategoryDTO
|
||||
} else {
|
||||
throw Error("Error while validating form")
|
||||
}
|
||||
}
|
||||
|
||||
const buildCreate = (): CreateCategoryDTO => {
|
||||
if (validateForm()) {
|
||||
return {
|
||||
type: categoryType.value,
|
||||
name: categoryName.value,
|
||||
description: categoryDescription.value,
|
||||
icon: categoryIcon.value,
|
||||
} as CreateCategoryDTO
|
||||
} else {
|
||||
throw Error("Error while validating form")
|
||||
}
|
||||
}
|
||||
|
||||
const moveUser = async () => {
|
||||
if (window.history.length > 1) {
|
||||
console.log('moved back')
|
||||
router.back()
|
||||
} else {
|
||||
console.log('moved forward')
|
||||
await router.push('/categories')
|
||||
}
|
||||
}
|
||||
|
||||
const isDeleteAlertVisible = ref(false)
|
||||
const deleteAlertMessage = ref<string>('Do you really want to delete the category?')
|
||||
const deleteCategory = async () => {
|
||||
if (spaceStore.selectedSpaceId) {
|
||||
await categoriesService.deleteCategory(spaceStore.selectedSpaceId, Number(categoryId.value))
|
||||
await categoriesStore.fetchCategories(spaceStore.selectedSpaceId)
|
||||
await moveUser()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onMounted(async () => {
|
||||
if (mode.value === "edit") {
|
||||
await fetchCategory()
|
||||
toolbar.registerHandler('deleteCategory', () => {
|
||||
if (tgApp.initData) {
|
||||
tgApp.showConfirm(deleteAlertMessage, async (confirmed: boolean) => {
|
||||
if (confirmed) {
|
||||
await deleteCategory()
|
||||
}
|
||||
})
|
||||
} else {
|
||||
isDeleteAlertVisible.value = true
|
||||
}
|
||||
})
|
||||
toolbar.registerHandler('updateCategory', async () => {
|
||||
if (spaceStore.selectedSpaceId) {
|
||||
// await categoriesStore.fetchCategories(spaceStore.selectedSpaceId)
|
||||
router.back()
|
||||
try {
|
||||
let updateDTO = buildUpdate()
|
||||
await categoriesService.updateCategory(spaceStore.selectedSpaceId, updateDTO)
|
||||
console.log(updateDTO)
|
||||
await moveUser()
|
||||
} catch (e) {
|
||||
toast.add({
|
||||
severity: "error",
|
||||
summary: "Error while updating category",
|
||||
detail: e,
|
||||
life: 3000,
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
toolbar.registerHandler('createCategory', async () => {
|
||||
if (spaceStore.selectedSpaceId) {
|
||||
// await categoriesStore.fetchCategories(spaceStore.selectedSpaceId)
|
||||
router.back()
|
||||
try {
|
||||
let createDTO = buildCreate()
|
||||
await categoriesService.createCategory(spaceStore.selectedSpaceId, createDTO)
|
||||
console.log(createDTO)
|
||||
await moveUser()
|
||||
} catch (e) {
|
||||
toast.add({
|
||||
severity: "error",
|
||||
summary: "Error while creating category",
|
||||
detail: e,
|
||||
life: 3000
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
@@ -108,7 +218,11 @@ onMounted(async () => {
|
||||
<template>
|
||||
|
||||
<div class="flex flex-col w-full justify-items-start gap-7">
|
||||
|
||||
<ConfirmDialog
|
||||
v-if="isDeleteAlertVisible"
|
||||
:message="deleteAlertMessage"
|
||||
:callback="(confirmed: boolean) => { if (confirmed) deleteCategory(); isDeleteAlertVisible = false; }"
|
||||
/>
|
||||
<div class="flex flex-col w-full ">
|
||||
<div class=" flex-col " v-tooltip.focus.bottom="'Only emoji supported'">
|
||||
<input
|
||||
@@ -131,6 +245,8 @@ onMounted(async () => {
|
||||
/>
|
||||
<label class=" !justify-center !font-extralight text-gray-600 text-center">Category
|
||||
icon</label>
|
||||
<span v-if="isCategoryIconError"
|
||||
class="text-sm !text-red-500 font-extralight">Icon cannot be empty or non-emoji</span>
|
||||
</div>
|
||||
|
||||
<div class="w-full !items-center !justify-center">
|
||||
@@ -141,14 +257,18 @@ onMounted(async () => {
|
||||
optionValue="value"
|
||||
class="!w-full !items-center !justify-center "
|
||||
/>
|
||||
<span v-if="isCategoryTypeError"
|
||||
class="text-sm !text-red-500 font-extralight">Category type cannot be empty</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="flex flex-col w-full justify-items-start">
|
||||
<label class="!font-semibold text-gray-600 pl-2">Category name</label>
|
||||
<div class="card !rounded-3xl !justify-start !items-start !p-4 !pl-5 ">
|
||||
<input class="font-extralight w-full focus:outline-0" placeholder="Name" v-model="categoryName"/>
|
||||
<input class="font-extralight w-full focus:outline-0" placeholder="Name" v-model="categoryName"
|
||||
@input="categoryName.length !== 0 ? isCategoryNameError = false : true"/>
|
||||
</div>
|
||||
<span v-if="isCategoryNameError" class="text-sm !text-red-500 font-extralight">Name cannot be empty</span>
|
||||
</div>
|
||||
<div class="flex flex-col w-full justify-items-start">
|
||||
<label class="!font-semibold text-gray-600 !pl-2">Category description</label>
|
||||
@@ -156,8 +276,11 @@ onMounted(async () => {
|
||||
<textarea
|
||||
class="!font-extralight !text-start !pl-2 w-full focus:outline-0 !focus:border-0 !@focus:shadow-none !bg-white !border-0 min-h-36"
|
||||
style="box-shadow: none !important;"
|
||||
placeholder="Description" v-model="categoryDescription"/>
|
||||
placeholder="Description" v-model="categoryDescription"
|
||||
@input="categoryDescription.length !== 0 ? isCategoryDescriptionError = false : true"/>
|
||||
</div>
|
||||
<span v-if="isCategoryDescriptionError"
|
||||
class="text-sm !text-red-500 font-extralight">Description cannot be empty</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -36,7 +36,6 @@ const recurrentDate = ref<number>(Math.floor(Math.random() * 31))
|
||||
const isDateError = ref(false)
|
||||
|
||||
|
||||
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
if (spaceStore.selectedSpaceId) {
|
||||
@@ -172,7 +171,11 @@ const deleteAlertMessage = ref('Do you want to delete recurrent?')
|
||||
const deleteRecurrent = async () => {
|
||||
await recurrentsService.deleteRecurrent(spaceStore.selectedSpaceId, recurrentId.value)
|
||||
await recurrentsStore.fetchRecurrents(spaceStore.selectedSpaceId)
|
||||
router.back()
|
||||
if (window.history.length > 1) {
|
||||
router.back()
|
||||
} else {
|
||||
await router.push('/categories')
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
@@ -190,7 +193,7 @@ onMounted(async () => {
|
||||
console.log('deleteRecurrent2')
|
||||
if (tgApp.initData) {
|
||||
console.log('deleteRecurrent3')
|
||||
tgApp.showConfirm(deleteAlertMessage.value, async (confirmed) => {
|
||||
tgApp.showConfirm(deleteAlertMessage.value, async (confirmed: boolean) => {
|
||||
if (confirmed) {
|
||||
console.log("recurrent id is deleted")
|
||||
await deleteRecurrent()
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import {Category} from "@/models/category";
|
||||
import {Category, CreateCategoryDTO, UpdateCategoryDTO} from "@/models/category";
|
||||
import {CategoryType} from "@/models/enums";
|
||||
import {User} from "@/models/user";
|
||||
|
||||
async function fetchCategories(spaceId: number) {
|
||||
let categories : Category[] = []
|
||||
let categories: Category[] = []
|
||||
for (let i = 0; i < 10; i++) {
|
||||
categories.push({
|
||||
id: i,
|
||||
@@ -23,21 +23,33 @@ async function fetchCategories(spaceId: number) {
|
||||
}
|
||||
|
||||
async function fetchCategory(spaceId: number, categoryId: number): Promise<Category> {
|
||||
return {
|
||||
return {
|
||||
id: 1,
|
||||
type: Math.floor(Math.random() * 2) === 0 ? CategoryType.INCOME : CategoryType.EXPENSE,
|
||||
type: Math.floor(Math.random() * 2) === 0 ? CategoryType.INCOME : CategoryType.EXPENSE,
|
||||
name: `Category ${1}`,
|
||||
description: `Description of Category ${1}`,
|
||||
icon: "😇",
|
||||
createdBy: {
|
||||
id: 1,
|
||||
id: 1,
|
||||
username: `username_${1}`,
|
||||
firstName: `firstName ${1}`,
|
||||
} as User,
|
||||
} as User,
|
||||
createdAt: new Date(),
|
||||
} as Category
|
||||
}
|
||||
|
||||
export const categoriesService = {
|
||||
fetchCategories, fetchCategory
|
||||
async function createCategory(spaceId: number, category: CreateCategoryDTO): Promise<number> {
|
||||
return 1
|
||||
}
|
||||
|
||||
async function updateCategory(spaceId: number, category: UpdateCategoryDTO): Promise<void> {
|
||||
|
||||
}
|
||||
|
||||
async function deleteCategory(spaceId: number, categoryId: number): Promise<void> {
|
||||
|
||||
}
|
||||
|
||||
export const categoriesService = {
|
||||
fetchCategories, fetchCategory, createCategory, updateCategory, deleteCategory,
|
||||
}
|
||||
Reference in New Issue
Block a user