new version of budget view and fixes

This commit is contained in:
xds
2025-02-13 14:23:33 +03:00
parent adc254a7fc
commit 9cf3b8ef82
6 changed files with 68 additions and 75 deletions

View File

@@ -16,7 +16,7 @@
<TransactionForm v-if="visible" :visible="visible" <TransactionForm v-if="visible" :visible="visible"
:transaction-type="drawerStore.transactionType ? drawerStore.transactionType : 'INSTANT'" :transaction-type="drawerStore.transactionType ? drawerStore.transactionType : 'INSTANT'"
:category-type="drawerStore.categoryType ? drawerStore.categoryType : 'EXPENSE'" @close-drawer="closeDrawer"/> :category-type="drawerStore.categoryType ? drawerStore.categoryType : 'EXPENSE'" :categoryId="drawerStore.categoryId" @close-drawer="closeDrawer"/>
</div> </div>
</template> </template>
@@ -35,6 +35,7 @@ import TransactionForm from "@/components/transactions/TransactionForm.vue";
const drawerStore = useDrawerStore(); const drawerStore = useDrawerStore();
const visible = computed(() => drawerStore.visible); const visible = computed(() => drawerStore.visible);
const closeDrawer = () => { const closeDrawer = () => {
drawerStore.setVisible(false); drawerStore.setVisible(false);

View File

@@ -29,7 +29,7 @@
<template #end> <template #end>
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
{{ user.firstName }} {{ user.firstName }}
<Button @click="drawerStore.visible = true" label="Создать"/> <Button @click="drawerStore.setCategoryType('EXPENSE');drawerStore.setTransactionType('INSTANT');drawerStore.visible = true" label="Создать"/>
<!-- <InputText placeholder="Search" type="text" class="w-32 sm:w-auto" />--> <!-- <InputText placeholder="Search" type="text" class="w-32 sm:w-auto" />-->
<!-- <Avatar image="https://primefaces.org/cdn/primevue/images/avatar/amyelsner.png" shape="circle" />--> <!-- <Avatar image="https://primefaces.org/cdn/primevue/images/avatar/amyelsner.png" shape="circle" />-->
@@ -74,42 +74,6 @@ const items = ref([
label: 'Бюджеты', label: 'Бюджеты',
icon: 'pi pi-briefcase', icon: 'pi pi-briefcase',
url: '/budgets' url: '/budgets'
// items: [
// {
// label: 'Core',
// icon: 'pi pi-bolt',
// shortcut: '⌘+S'
// },
// {
// label: 'Blocks',
// icon: 'pi pi-server',
// shortcut: '⌘+B'
// },
// {
// label: 'UI Kit',
// icon: 'pi pi-pencil',
// shortcut: '⌘+U'
// },
// {
// separator: true
// },
// {
// label: 'Templates',
// icon: 'pi pi-palette',
// items: [
// {
// label: 'Apollo',
// icon: 'pi pi-palette',
// badge: 2
// },
// {
// label: 'Ultima',
// icon: 'pi pi-palette',
// badge: 3
// }
// ]
// }
// ]
}, },
{ {
label: 'Транзакции', label: 'Транзакции',

View File

@@ -1,5 +1,5 @@
<script setup lang="ts" xmlns="http://www.w3.org/1999/html"> <script setup lang="ts" xmlns="http://www.w3.org/1999/html">
import {computed, onMounted, ref, watch, reactive} from 'vue'; import {computed, onMounted, ref, watch, reactive, onUnmounted} from 'vue';
import Chart from 'primevue/chart'; import Chart from 'primevue/chart';
import BudgetTransactionView from "@/components/budgets/BudgetTransactionView.vue"; import BudgetTransactionView from "@/components/budgets/BudgetTransactionView.vue";
import { import {
@@ -26,6 +26,8 @@ import SelectButton from "primevue/selectbutton";
import Divider from "primevue/divider"; import Divider from "primevue/divider";
import TransactionForm from "@/components/transactions/TransactionForm.vue"; import TransactionForm from "@/components/transactions/TransactionForm.vue";
import Checkbox from "primevue/checkbox"; import Checkbox from "primevue/checkbox";
import {useDrawerStore} from "@/stores/drawerStore";
import { EventBus } from '@/utils/EventBus.ts';
// Зарегистрируем плагин // Зарегистрируем плагин
ChartJS.register(ChartDataLabels); ChartJS.register(ChartDataLabels);
@@ -121,19 +123,24 @@ const totalSaving = computed(() => {
const drawerOpened = ref(false) const drawerOpened = ref(false)
const transactionType = ref('') const transactionType = ref('')
const categoryType = ref('') const categoryType = ref('')
const openDrawer = (selectedTransactionType = null, selectedCategoryType = null) => {
if (selectedTransactionType && selectedCategoryType) { const drawerStore = useDrawerStore()
transactionType.value = selectedTransactionType; const openDrawer = (selectedTransactionType = null, selectedCategoryType = null, categoryId = null) => {
categoryType.value = selectedCategoryType;
} else if (selectedTransactionType) { if (selectedTransactionType) {
transactionType.value = selectedTransactionType; drawerStore.setTransactionType(selectedCategoryType)
categoryType.value = 'EXPENSE' } else drawerStore.setCategoryType("INSTANT")
} if (selectedCategoryType) {
drawerStore.setCategoryType(selectedCategoryType)
} else drawerStore.setCategoryType("EXPENSE")
if (categoryId) {
drawerStore.setCategoryId(categoryId)
} else drawerStore.setCategoryId(null)
drawerOpened.value = true; drawerOpened.value = true;
drawerStore.visible = true
} }
const closeDrawer = async () => { const closeDrawer = async () => {
drawerOpened.value = false; drawerOpened.value = false;
// await updateTransactions() // await updateTransactions()
@@ -378,7 +385,8 @@ const updateLimitOnBackend = async (categoryId, newLimit) => {
const budgetInfo = ref<Budget>(); const budgetInfo = ref<Budget>();
const fetchBudgetInfo = async () => { const fetchBudgetInfo = async (test) => {
loading.value = test ? test : false;
await getBudgetInfo(route.params.id).then((data) => { await getBudgetInfo(route.params.id).then((data) => {
budget.value = data budget.value = data
plannedExpenses.value = budget.value?.plannedExpenses plannedExpenses.value = budget.value?.plannedExpenses
@@ -389,6 +397,8 @@ const fetchBudgetInfo = async () => {
updateLoading.value = false updateLoading.value = false
} }
) )
updateLoading.value = false
loading.value = false
} }
@@ -616,7 +626,7 @@ const expandCats = (value: boolean) => {
}; };
onMounted(async () => { onMounted(async () => {
updateLoading.value = true;
try { try {
await Promise.all([ await Promise.all([
fetchBudgetInfo(), fetchBudgetInfo(),
@@ -627,12 +637,17 @@ onMounted(async () => {
// fetchBudgetCategories(), // fetchBudgetCategories(),
// fetchBudgetTransactions(), // fetchBudgetTransactions(),
]); ]);
EventBus.on('transactions-updated', fetchBudgetInfo,true);
} catch (error) { } catch (error) {
console.error('Error during fetching data:', error); console.error('Error during fetching data:', error);
} finally { } finally {
loading.value = false loading.value = false
} }
}); });
onUnmounted( async () => {
EventBus.off('transactions-updated', fetchBudgetInfo);
})
</script> </script>
<template> <template>
@@ -640,18 +655,8 @@ onMounted(async () => {
<LoadingView v-if="loading"/> <LoadingView v-if="loading"/>
<div v-else class="px-4 bg-gray-100 h-full "> <div v-else class="px-4 bg-gray-100 h-full ">
<div v-if="updateLoading" class="absolute top-0 left-0 w-full h-full flex items-center justify-center z-50">
<ProgressSpinner <div class=" flex flex-col gap-3">
v-if="updateLoading"
class="absolute top-0 left-0 w-full h-full flex items-center justify-center z-50"
style="width: 50px; height: 50px;"
strokeWidth="8"
fill="transparent"
animationDuration=".5s"
aria-label="Custom ProgressSpinner"
/>
</div>
<div :class="!updateLoading ? '' : 'h-fit bg-white opacity-50 z-0 '" class=" flex flex-col gap-3">
<div class="flex flex-row justify-between "> <div class="flex flex-row justify-between ">
<div class="flex flex-col gap-2"> <div class="flex flex-col gap-2">
<h2 class="text-4xl font-bold">Бюджет {{ budget.name }} </h2> <h2 class="text-4xl font-bold">Бюджет {{ budget.name }} </h2>
@@ -890,6 +895,7 @@ onMounted(async () => {
<span class="text-lg font-bold items-center">{{ <span class="text-lg font-bold items-center">{{
category.name.category.name category.name.category.name
}} {{ category.name.icon }}</span> }} {{ category.name.icon }}</span>
<div class="flex flex-row gap-4"> <div class="flex flex-row gap-4">
<span>{{ <span>{{
@@ -930,7 +936,7 @@ onMounted(async () => {
<div class="pb-4"> <div class="pb-4">
<div class="flex flex-row gap-4 items-center mb-4"> <div class="flex flex-row gap-4 items-center mb-4">
<h3 class="text-2xl font-bold text-rose-500 ">Расходы</h3> <h3 class="text-2xl font-bold text-rose-500 ">Расходы</h3>
<button @click="openDrawer('PLANNED', 'INCOME')"> <button @click="openDrawer('PLANNED', 'EXPENSE')">
<span class="font-light text-sm">+ Добавить</span> <span class="font-light text-sm">+ Добавить</span>
</button> </button>
</div> </div>
@@ -939,10 +945,15 @@ onMounted(async () => {
class="flex flex-col justify-between p-4 shadow-lg rounded-lg bg-white "> class="flex flex-col justify-between p-4 shadow-lg rounded-lg bg-white ">
<div class=""> <div class="">
<div class="flex flex-row justify-between w-full items-center"> <div class="flex flex-row justify-between w-full items-center">
<span class="text-2xl font-bold line-clamp-1">{{ <div class="flex flex-row col-span-2 gap-2 items-center">
<span class=" font-bold line-clamp-1" style="font-size: 1.25rem">{{
category.name.category.icon category.name.category.icon
}} {{ category.name.category.name }}</span> }} {{ category.name.category.name }}</span>
<div class="flex flex-row line-clamp-1 gap-1"> <button @click="openDrawer('INSTANT', 'EXPENSE', category.name.category.id)">
<i class="pi pi-plus-circle"/>
</button>
</div>
<div class="flex flex-row w-fit gap-1 justify-between">
<span>{{ formatAmount(category.name.currentSpent) }} </span> <span>{{ formatAmount(category.name.currentSpent) }} </span>
<span> / </span> <span> / </span>
@@ -1030,6 +1041,7 @@ onMounted(async () => {
</button> </button>
</div> </div>
<div class="grid grid-cols-1 gap-1 max-h-tlist overflow-y-auto "> <div class="grid grid-cols-1 gap-1 max-h-tlist overflow-y-auto ">
<BudgetTransactionView v-for="transaction in filteredTransactions" :key="transaction.id" <BudgetTransactionView v-for="transaction in filteredTransactions" :key="transaction.id"
:transaction="transaction" :transaction="transaction"
@@ -1046,10 +1058,10 @@ onMounted(async () => {
</div> </div>
</div> </div>
<TransactionForm v-if="drawerOpened" :visible="drawerOpened" :transaction-type="transactionType" <!-- <TransactionForm v-if="drawerOpened" :visible="drawerOpened" :transaction-type="transactionType"-->
:category-type="categoryType" @close-drawer="closeDrawer" @transaction-updated="updateTransactions" <!-- :category-type="categoryType" @close-drawer="closeDrawer" @transaction-updated="updateTransactions"-->
@delete-transaction="updateTransactions" <!-- @delete-transaction="updateTransactions"-->
@create-transaction="updateTransactions"/> <!-- @create-transaction="updateTransactions"/>-->
</div> </div>
<div id="footer" class="h-24 bg-gray-100"/> <div id="footer" class="h-24 bg-gray-100"/>

View File

@@ -2,14 +2,14 @@
<div class="card flex justify-center h-fit"> <div class="card flex justify-center h-fit">
<DrawerForm v-if="isDesktop" :visible="visible" :isEditing="isEditing" @close-drawer="closeDrawer" > <DrawerForm v-if="isDesktop" :visible="visible" :isEditing="isEditing" @close-drawer="closeDrawer" >
<template #default> <template #default>
<TransactionFormContent :transaction="props.transaction" :transaction-type="transactionType" :category-type="categoryType" @close-drawer="closeDrawer" @create-transaction="transactionUpdated('create')" <TransactionFormContent :transaction="props.transaction" :transaction-type="transactionType" :category-type="categoryType" :categoryId="categoryId" @close-drawer="closeDrawer" @create-transaction="transactionUpdated('create')"
@delete-transaction="transactionUpdated" @transaction-updated="transactionUpdated" /> @delete-transaction="transactionUpdated" @transaction-updated="transactionUpdated" />
</template> </template>
</DrawerForm> </DrawerForm>
<PopUp v-else :header="'Создать транзакцию'" @close-popup="closeDrawer"> <PopUp v-else :header="'Создать транзакцию'" @close-popup="closeDrawer">
<template #default> <template #default>
<TransactionFormContent :transaction="props.transaction" :transaction-type="transactionType" :category-type="categoryType" @close-drawer="closeDrawer" @create-transaction="transactionUpdated" <TransactionFormContent :transaction="props.transaction" :transaction-type="transactionType" :category-type="categoryType" :categoryId="categoryId" @close-drawer="closeDrawer" @create-transaction="transactionUpdated"
@delete-transaction="transactionUpdated" @transaction-updated="transactionUpdated" /> @delete-transaction="transactionUpdated" @transaction-updated="transactionUpdated" />
</template> </template>
</PopUp> </PopUp>
@@ -31,6 +31,7 @@ const props = defineProps({
}, },
transactionType: String, transactionType: String,
categoryType: String, categoryType: String,
categoryId: String,
}) })
const isDesktop = ref(window.innerWidth >= 1024); const isDesktop = ref(window.innerWidth >= 1024);

View File

@@ -6,7 +6,7 @@ import InputNumber from "primevue/inputnumber";
import Button from "primevue/button"; import Button from "primevue/button";
import {ref, onMounted, computed, nextTick} from 'vue'; import {ref, onMounted, computed, nextTick} from 'vue';
import {Transaction, TransactionType} from "@/models/Transaction"; import {Transaction, TransactionType} from "@/models/Transaction";
import {CategoryType} from "@/models/Category"; import {Category, CategoryType} from "@/models/Category";
import SelectButton from "primevue/selectbutton"; import SelectButton from "primevue/selectbutton";
import Select from "primevue/select"; import Select from "primevue/select";
import platform from 'platform'; import platform from 'platform';
@@ -38,6 +38,10 @@ const props = defineProps({
categoryType: { categoryType: {
type: String, type: String,
required: false required: false
},
categoryId: {
type: String,
required: false
} }
}); });
@@ -62,6 +66,7 @@ const editedTransaction = ref<Transaction | null>(null);
const selectedCategoryType = ref<CategoryType | null>(null); const selectedCategoryType = ref<CategoryType | null>(null);
const selectedTransactionType = ref<TransactionType | null>(null); const selectedTransactionType = ref<TransactionType | null>(null);
const selectedCategory = ref<Category | null>(null);
const entireCategories = ref<Category[]>([]); const entireCategories = ref<Category[]>([]);
const expenseCategories = ref<Category[]>([]); const expenseCategories = ref<Category[]>([]);
@@ -118,7 +123,10 @@ const prepareData = () => {
editedTransaction.value = new Transaction(); editedTransaction.value = new Transaction();
editedTransaction.value.type = transactionTypes.value.find(type => type.code === props.transactionType) || transactionTypes.value[0]; editedTransaction.value.type = transactionTypes.value.find(type => type.code === props.transactionType) || transactionTypes.value[0];
selectedCategoryType.value = categoryTypes.value.find(type => type.code === props.categoryType) || categoryTypes.value[0]; selectedCategoryType.value = categoryTypes.value.find(type => type.code === props.categoryType) || categoryTypes.value[0];
editedTransaction.value.category = props.categoryType === 'EXPENSE' ? expenseCategories.value[0] : incomeCategories.value[0]; console.log("hui " + props.categoryId)
entireCategories.value.find(category => category.id == props.categoryId ) ? entireCategories.value.find(category => category.id == props.categoryId ) : props.categoryType === 'EXPENSE' ? expenseCategories.value[0] : incomeCategories.value[0]
editedTransaction.value.category = entireCategories.value.find(category => category.id == props.categoryId ) ? entireCategories.value.find(category => category.id == props.categoryId ) : props.categoryType === 'EXPENSE' ? expenseCategories.value[0] : incomeCategories.value[0]
// editedTransaction.value.category = props.categoryType === 'EXPENSE' ? expenseCategories.value[0] : incomeCategories.value[0];
editedTransaction.value.date = new Date(); editedTransaction.value.date = new Date();
} else { } else {
editedTransaction.value = {...props.transaction}; editedTransaction.value = {...props.transaction};
@@ -218,7 +226,7 @@ const createTransaction = async (): Promise<void> => {
const transactionsUpdatedEmit = async () => { const transactionsUpdatedEmit = async () => {
await getTransactions('INSTANT', 'EXPENSE', null, user.value.id, false, 3).then(transactionsResponse => transactions.value = transactionsResponse.data); await getTransactions('INSTANT', 'EXPENSE', null, user.value.id, false, 3).then(transactionsResponse => transactions.value = transactionsResponse.data);
console.log("here created ")
EventBus.emit('transactions-updated', true) EventBus.emit('transactions-updated', true)
} }

View File

@@ -5,6 +5,7 @@ export const useDrawerStore = defineStore('drawer', () => {
const visible = ref(false); const visible = ref(false);
const transactionType = ref(null) const transactionType = ref(null)
const categoryType = ref(null) const categoryType = ref(null)
const categoryId = ref(null)
const setVisible = (isVisible: boolean) => { const setVisible = (isVisible: boolean) => {
visible.value = isVisible; visible.value = isVisible;
@@ -17,6 +18,12 @@ export const useDrawerStore = defineStore('drawer', () => {
const setCategoryType = (type: string) => { const setCategoryType = (type: string) => {
categoryType.value = type; categoryType.value = type;
} }
return {visible, transactionType, categoryType, setTransactionType, setCategoryType, setVisible}
const setCategoryId = (id: string|null) => {
categoryId.value = id
}
return {visible, transactionType, categoryType, categoryId, setTransactionType, setCategoryType, setVisible, setCategoryId};
}) })