chet novoe
This commit is contained in:
@@ -3,71 +3,75 @@ import Button from "primevue/button";
|
|||||||
import InputNumber from "primevue/inputnumber";
|
import InputNumber from "primevue/inputnumber";
|
||||||
import ProgressBar from "primevue/progressbar";
|
import ProgressBar from "primevue/progressbar";
|
||||||
|
|
||||||
import {Category} from "@/models/Category";
|
import { Category } from "@/models/Category";
|
||||||
import {computed, ref} from "vue";
|
import { computed, ref, watch } from "vue";
|
||||||
import {formatAmount} from "@/utils/utils";
|
import { formatAmount } from "@/utils/utils";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
category: {
|
category: {
|
||||||
type: Object as Category,
|
type: Object as () => Category,
|
||||||
require: true
|
required: true
|
||||||
},
|
},
|
||||||
budgetId: {
|
budgetId: {
|
||||||
type: Number,
|
type: Number,
|
||||||
require: true
|
required: true
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
const emits = defineEmits(['category-updated'])
|
const emits = defineEmits(["category-updated"]);
|
||||||
|
|
||||||
const isEditing = ref(false);
|
const isEditing = ref(false);
|
||||||
|
const currentLimit = ref(props.category.currentLimit);
|
||||||
|
|
||||||
const startEditing = () => {
|
const startEditing = () => {
|
||||||
isEditing.value = true;
|
isEditing.value = true;
|
||||||
}
|
};
|
||||||
|
|
||||||
const stopEditing = () => {
|
const stopEditing = () => {
|
||||||
isEditing.value = false;
|
isEditing.value = false;
|
||||||
|
emits("category-updated", { ...props.category, currentLimit: currentLimit.value });
|
||||||
|
};
|
||||||
|
|
||||||
emits('category-updated', editedCategory.value);
|
// Реактивное вычисление отношения затрат к плану
|
||||||
|
const spentPlannedRatio = computed(() => {
|
||||||
|
return props.category.currentLimit
|
||||||
|
? (props.category.currentSpent / props.category.currentLimit) * 100
|
||||||
|
: 0;
|
||||||
|
});
|
||||||
|
|
||||||
}
|
// Синхронизация `currentLimit` с `props.category.currentLimit` при обновлении
|
||||||
// const selectedCategorySettingType = ref(props.category.categorySetting.type)
|
watch(
|
||||||
|
() => props.category.currentLimit,
|
||||||
const categoryAmount = ref(1000)
|
(newLimit) => {
|
||||||
|
currentLimit.value = newLimit;
|
||||||
const editedCategory = ref(props.category);
|
|
||||||
const spentPlannedRatio = computed( () => {
|
|
||||||
if (editedCategory.value.currentLimit == 0){
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
return editedCategory.value.currentSpent / editedCategory.value.currentLimit * 100
|
|
||||||
}
|
}
|
||||||
})
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
||||||
<div class="p-2 shadow-lg rounded-lg bg-white flex justify-between flex-col ">
|
<div class="p-2 shadow-lg rounded-lg bg-white flex justify-between flex-col ">
|
||||||
|
|
||||||
<div class="flex flex-row justify-between w-full">
|
<div class="flex flex-row justify-between w-full">
|
||||||
<div :class="isEditing ? 'w-1/5': ''" class="min-w-1 w-4/6 justify-between ">
|
<div :class="isEditing ? 'w-1/5': ''" class="min-w-1 w-4/6 justify-between ">
|
||||||
<h4 class="text-lg line-clamp-1">{{editedCategory.category.icon }} {{ editedCategory.category.name }}</h4>
|
<h4 class="text-lg line-clamp-1">{{props.category.category.icon }} {{ props.category.category.name }}</h4>
|
||||||
<!-- <p class="text-sm text-gray-500 line-clamp-1 min-w-1 ">{{ editedCategory.category.description }}</p>-->
|
<!-- <p class="text-sm text-gray-500 line-clamp-1 min-w-1 ">{{ editedCategory.category.description }}</p>-->
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-row gap-2 justify-end items-center w-3/6 ">
|
<div class="flex flex-row gap-2 justify-end items-center w-4/6 ">
|
||||||
|
|
||||||
<!-- Сумма, которая становится редактируемой при клике -->
|
<!-- Сумма, которая становится редактируемой при клике -->
|
||||||
<button v-if="!isEditing" @click="startEditing"
|
<button v-if="!isEditing" @click="startEditing"
|
||||||
class="text-lg font-bold cursor-pointer w-fit text-end line-clamp-1">
|
class="text-lg font-bold cursor-pointer w-fit text-end line-clamp-1">
|
||||||
<div class="flex flex-row gap-2 items-baseline" >
|
<div class="flex flex-row gap-2 items-baseline" >
|
||||||
<p class="font-light text-sm" :class="spentPlannedRatio == 0 ? 'hidden': ''">{{spentPlannedRatio.toFixed(0)}} %</p>
|
<p class="font-light text-sm" :class="spentPlannedRatio == 0 ? 'hidden': ''">{{spentPlannedRatio.toFixed(0)}} %</p>
|
||||||
<p class="line-clamp-1 w-fit">{{ formatAmount(editedCategory.currentSpent) }} /
|
<p class="line-clamp-1 w-fit">{{ formatAmount(props.category.currentSpent) }} /
|
||||||
{{ formatAmount(editedCategory.currentLimit) }} ₽</p>
|
{{ formatAmount(currentLimit) }} ₽</p>
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<InputNumber v-else ref="inputRefs" type="text" v-model="editedCategory.currentLimit"
|
<InputNumber v-else ref="inputRefs" type="text" v-model="editedCategory.currentLimit"
|
||||||
class="text-lg font-bold border-b-2 border-gray-300 outline-none focus:border-blue-500 w-32 text-right"
|
class="text-lg font-bold border-b-2 border-gray-300 outline-none focus:border-blue-500 w-32 text-right"
|
||||||
:min="editedCategory.categoryPlannedLimit" :max="900000" :invalid="editedCategory.currentLimit < editedCategory.categoryPlannedLimit" v-tooltip.top="'Сумма не должна быть ниже суммы запланированных!'"/>
|
:min="props.category.categoryPlannedLimit" :max="900000" :invalid="currentLimit < props.category.categoryPlannedLimit" v-tooltip.top="'Сумма не должна быть ниже суммы запланированных!'"/>
|
||||||
<Button v-if="isEditing" @click="stopEditing" icon="pi pi-check" severity="success" rounded outlined
|
<Button v-if="isEditing" @click="stopEditing" icon="pi pi-check" severity="success" rounded outlined
|
||||||
aria-label="Search"/>
|
aria-label="Search"/>
|
||||||
|
|
||||||
|
|||||||
@@ -44,12 +44,12 @@
|
|||||||
class="chart "/>
|
class="chart "/>
|
||||||
|
|
||||||
|
|
||||||
<div class="flex gap-5 items-center justify-items-center ">
|
<div class="flex gap-5 items-center justify-items-center w-full ">
|
||||||
<div class="w-full">
|
<div class="w-full">
|
||||||
<button class="grid grid-cols-2 gap-5 items-center w-full" @click="detailedShowed = !detailedShowed">
|
<button class="grid grid-cols-2 gap-5 items-center w-full" @click="detailedShowed = !detailedShowed">
|
||||||
<div class="flex flex-col items-center font-bold ">
|
<div class="flex flex-col items-center font-bold ">
|
||||||
<h4 class="text-lg font-bold">Поступления</h4>
|
<h4 class="text-lg font-bold">Поступления</h4>
|
||||||
<div class="font-bold bg-gray-100 p-1 rounded-lg box-shadow-inner w-full text-center">
|
<div class="font-light bg-gray-100 p-1 rounded-lg box-shadow-inner w-full text-center">
|
||||||
+{{ formatAmount(totalIncomes) }}
|
+{{ formatAmount(totalIncomes) }}
|
||||||
₽
|
₽
|
||||||
</div>
|
</div>
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col items-center ">
|
<div class="flex flex-col items-center ">
|
||||||
<h4 class="text-lg font-bold ">Расходы</h4>
|
<h4 class="text-lg font-bold ">Расходы</h4>
|
||||||
<div class="font-bold bg-gray-100 p-1 rounded-lg box-shadow-inner w-full text-center">
|
<div class="font-light bg-gray-100 p-1 rounded-lg box-shadow-inner w-full text-center">
|
||||||
-{{ formatAmount(totalExpenses) }}
|
-{{ formatAmount(totalExpenses) }}
|
||||||
₽
|
₽
|
||||||
</div>
|
</div>
|
||||||
@@ -94,7 +94,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="grid gap-5 items-center justify-items-center ">
|
<div class="grid gap-5 items-center justify-items-center w-full">
|
||||||
<div class="w-full">
|
<div class="w-full">
|
||||||
<button class="grid grid-cols-3 justify-between gap-5 items-center w-full"
|
<button class="grid grid-cols-3 justify-between gap-5 items-center w-full"
|
||||||
@click="detailedShowed = !detailedShowed">
|
@click="detailedShowed = !detailedShowed">
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ import axios from 'axios';
|
|||||||
|
|
||||||
// Создание экземпляра axios с базовым URL
|
// Создание экземпляра axios с базовым URL
|
||||||
const apiClient = axios.create({
|
const apiClient = axios.create({
|
||||||
// baseURL: 'https://luminic.space/api/v1',
|
baseURL: 'https://luminic.space/api/v1',
|
||||||
baseURL: 'http://localhost:8000/api/v1',
|
// baseURL: 'http://localhost:8000/api/v1',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user