196 lines
6.7 KiB
Vue
196 lines
6.7 KiB
Vue
<script setup lang="ts">
|
|
import {useRoute} from "vue-router";
|
|
import {computed, onMounted, ref} from "vue";
|
|
import {useToolbarStore} from "@/stores/toolbar-store";
|
|
import {useToast} from "primevue/usetoast";
|
|
import {Divider, InputNumber} from "primevue";
|
|
import {categoriesService} from "@/services/categories-service";
|
|
import {useSpaceStore} from "@/stores/spaceStore";
|
|
import {recurrentsService} from "@/services/recurrents-service";
|
|
import {Category} from "@/models/category";
|
|
|
|
const route = useRoute()
|
|
const toolbar = useToolbarStore();
|
|
const toast = useToast();
|
|
const spaceStore = useSpaceStore();
|
|
|
|
const isCategorySelectorOpened = ref(false);
|
|
|
|
const categories = ref<Category[]>([]);
|
|
const recurrentId = ref<string | undefined>(route.params.id)
|
|
const mode = computed(() => {
|
|
return recurrentId.value ? "edit" : "create"
|
|
})
|
|
const recurrentCategory = ref<Category>({})
|
|
const recurrentName = ref<string>()
|
|
const recurrentAmount = ref<number>(0)
|
|
const recurrentDate = ref<number>(Math.floor(Math.random() * 31))
|
|
|
|
|
|
const fetchData = async () => {
|
|
try {
|
|
console.log('here')
|
|
if (spaceStore.selectedSpaceId) {
|
|
categories.value = await categoriesService.fetchCategories(spaceStore.selectedSpaceId)
|
|
if (categories.value.length > 0) {
|
|
if (mode.value === "edit") {
|
|
console.log('here2')
|
|
let recurrent = await recurrentsService.fetchRecurrent(spaceStore.selectedSpaceId, Number(recurrentId.value))
|
|
recurrentCategory.value = recurrent.category
|
|
recurrentName.value = recurrent.name
|
|
recurrentAmount.value = recurrent.amount
|
|
recurrentDate.value = recurrent.date
|
|
} else {
|
|
recurrentCategory.value = categories.value[0]
|
|
}
|
|
}
|
|
}
|
|
} catch (err) {
|
|
console.log(err)
|
|
toast.add({
|
|
severity: "error",
|
|
summary: "Error while fetching category",
|
|
detail: err.detail.message,
|
|
life: 3000,
|
|
})
|
|
}
|
|
}
|
|
|
|
function handleInput(e: Event) {
|
|
const el = e.target as HTMLInputElement
|
|
const val = el.value.trim()
|
|
|
|
// если пусто — сбрасываем
|
|
if (!val) {
|
|
recurrentAmount.value = 0
|
|
return
|
|
}
|
|
|
|
// пробуем преобразовать в число
|
|
const num = Number(val)
|
|
recurrentAmount.value = isNaN(num) ? 0 : num
|
|
}
|
|
|
|
function handlePaste(e: ClipboardEvent) {
|
|
e.preventDefault() // предотвратить стандартную вставку
|
|
const text = e.clipboardData?.getData('text')?.trim() ?? ''
|
|
|
|
if (!text) {
|
|
recurrentAmount.value = 0
|
|
return
|
|
}
|
|
|
|
const num = Number(text)
|
|
recurrentAmount.value = isNaN(num) ? 0 : num
|
|
}
|
|
|
|
|
|
onMounted(async () => {
|
|
await fetchData()
|
|
if (mode.value === "edit") {
|
|
|
|
toolbar.registerHandler('deleteRecurrent', () => {
|
|
console.log("delete recurrent")
|
|
})
|
|
toolbar.registerHandler('updateRecurrent', () => {
|
|
console.log("update Recurrent")
|
|
})
|
|
} else {
|
|
toolbar.registerHandler('createRecurrent', () => {
|
|
console.log("create Recurrent")
|
|
})
|
|
}
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
|
|
<div v-if="categories.length===0" class="card !gap-4 !p-10">
|
|
<span class="">No categories available.</span>
|
|
<span class="text-center">Maybe you want to <router-link to="/categories" class="!text-blue-700">create a new category</router-link> first?</span>
|
|
</div>
|
|
<div v-else class="flex flex-col w-full justify-items-start gap-7">
|
|
<div v-if="isCategorySelectorOpened" class="!absolute !top-0 !left-0 !h-full !w-full !z-50 !px-4 !overflow-y-auto"
|
|
style="background: var(--primary-color)">
|
|
<div class="card">
|
|
<div v-for="key in categories.keys()" :key="categories[key].id"
|
|
@click="recurrentCategory = categories[key]; isCategorySelectorOpened = false"
|
|
class="flex flex-col w-full gap-0 pl-5 items-start justify-items-center font-bold ">
|
|
<div class="flex-row w-full items-center justify-between">
|
|
<div class="flex-row items-center gap-2">
|
|
<span class="text-3xl">{{ categories[key].icon }} </span>
|
|
<div class="flex-col justify-between">
|
|
<div class="flex-row"> {{ categories[key].name }}</div>
|
|
<div class="flex flex-row text-sm">{{ categories[key].description }}</div>
|
|
</div>
|
|
</div>
|
|
<i class="pi pi-angle-right !font-extralight"/>
|
|
</div>
|
|
<Divider v-if="key+1 !== categories.length" class="!m-0 !py-3"/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="flex flex-col w-full ">
|
|
<div class="flex-col w-full">
|
|
|
|
<InputNumber
|
|
v-model="recurrentAmount"
|
|
@input="handleInput"
|
|
@paste="handlePaste"
|
|
type="text"
|
|
inputmode="numeric"
|
|
placeholder="Amount"
|
|
suffix="₽"
|
|
class="text-7xl font-bold w-full text-center focus:outline-none !p-0 !m-0"
|
|
|
|
/>
|
|
<!-- <span class="absolute right-2 top-1/2 -translate-y-1/2 text-7xl font-bold">₽</span>-->
|
|
|
|
<label class="!justify-items-center !justify-center !font-extralight text-gray-600 text-center">Amount</label>
|
|
</div>
|
|
|
|
|
|
</div>
|
|
<div class="flex flex-col w-full justify-items-start">
|
|
<label class="!font-semibold text-gray-600 pl-2">Recurrent category</label>
|
|
<div class="card !justify-start !items-start !p-4 !pl-5 " @click="isCategorySelectorOpened = true">
|
|
<div class="flex-row w-full gap-2 items-center justify-between">
|
|
<div class="flex-row gap-2 items-center">
|
|
<span class="!text-3xl ">{{ recurrentCategory.icon }}</span>
|
|
<div class="flex-col ">
|
|
<span class=" !">{{ recurrentCategory.name }}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<i class="pi pi-angle-right !font-extralight"/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="flex flex-col w-full justify-items-start">
|
|
<label class="!font-semibold text-gray-600 pl-2">Recurrent name</label>
|
|
<div class="card !justify-start !items-start !p-4 !pl-5 ">
|
|
<input class="font-extralight w-full focus:outline-0" placeholder="Name" v-model="recurrentName"/>
|
|
</div>
|
|
</div>
|
|
<div class="flex flex-col w-full justify-items-start">
|
|
<label class="!font-semibold text-gray-600 !pl-2">Recurrent date</label>
|
|
<div class="card !justify-start !items-start !pl-2">
|
|
<div class="!grid !grid-cols-7 gap-2">
|
|
<div v-for="i in 31" class="!w-12 !h-12 !items-center !justify-items-center !justify-center rounded-full "
|
|
:class="recurrentDate == i ? 'bg-green-200' : 'bg-gray-100'"
|
|
@click="recurrentDate=i">
|
|
{{ i }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<label class="!font-extralight text-gray-600 !pl-2">recurrent every N day of month</label>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
<style scoped>
|
|
|
|
</style> |