+ some fixes

This commit is contained in:
xds
2025-05-26 13:58:56 +03:00
parent 961d6ba2b9
commit df20496180
6 changed files with 129 additions and 51 deletions

View File

@@ -15,7 +15,7 @@
<!-- Название -->
<FloatLabel class="w-full" variant="on">
<label for="paymentName">Название платежа</label>
<InputText v-model="name" id="paymentName" class="!w-full"/>
<InputText v-model="payment.name" id="paymentName" class="!w-full"/>
</FloatLabel>
<!-- Категория -->
@@ -64,7 +64,7 @@
<!-- Описание -->
<FloatLabel class="!w-full">
<label for="description">Описание</label>
<Textarea v-model="description" id="description" rows="3" class="!w-full"/>
<Textarea v-model="payment.description" id="description" rows="3" class="!w-full"/>
</FloatLabel>
<!-- Дата повторения (выпадающий список) -->
@@ -73,7 +73,7 @@
@click="isDaySelectorOpened = !isDaySelectorOpened">
<div class="flex flex-row items-center pe-4 py-2 gap-4">
<div class="flex flex-row justify-between w-full px-4">
<p class="font-bold">Повторять каждый {{ repeatDay || 'N' }} день месяца</p>
<p class="font-bold">Повторять каждый {{ payment.atDay || 'N' }} день месяца</p>
</div>
<div>
<span :class="{'rotate-90': isDaySelectorOpened}"
@@ -98,7 +98,7 @@
<!-- Сумма -->
<InputGroup class="w-full">
<InputGroupAddon></InputGroupAddon>
<InputNumber v-model="amount" placeholder="Сумма"/>
<InputNumber v-model="payment.amount" placeholder="Сумма"/>
<InputGroupAddon>.00</InputGroupAddon>
</InputGroup>
@@ -117,7 +117,7 @@
</template>
<script setup lang="ts">
import {ref, watch, computed, defineEmits} from 'vue';
import {ref, watch, computed, defineEmits, nextTick} from 'vue';
import Button from 'primevue/button';
import InputText from 'primevue/inputtext';
import InputNumber from 'primevue/inputnumber';
@@ -128,14 +128,19 @@ import FloatLabel from 'primevue/floatlabel';
import InputGroup from 'primevue/inputgroup';
import InputGroupAddon from "primevue/inputgroupaddon";
import SelectButton from 'primevue/selectbutton';
import {saveRecurrentPayment} from "@/services/recurrentService";
import {saveRecurrentPayment, updateRecurrent} from "@/services/recurrentService";
import {Category} from "@/models/Category";
import {RecurrentPayment} from "@/models/Recurrent";
import {useToast} from "primevue/usetoast";
const toast = useToast()
const props = defineProps({
show: Boolean, // Показать/скрыть модальное окно
expenseCategories: Array, // Внешние данные для списка категорий
incomeCategories: Array, // Внешние данные для списка категорий
categoryTypes: Array,
payment: Object | null // Для редактирования существующего платежа
payment: RecurrentPayment | null // Для редактирования существующего платежа
})
const emits = defineEmits(["open-edit", "save-payment", "close-modal"]);
@@ -143,13 +148,12 @@ const emits = defineEmits(["open-edit", "save-payment", "close-modal"]);
const loading = ref(false)
// Поля для формы
const name = ref('');
const selectedCategoryType = ref(props.payment ? props.payment.type : props.categoryTypes[0]);
console.log(props.categoryTypes)
console.log(selectedCategoryType.value)
console.log(props.expenseCategories)
console.log(props.incomeCategories)
const selectedCategory = ref(selectedCategoryType.code == 'EXPENSE' ? props.expenseCategories[0] ? props.expenseCategories[0] : props.incomeCategories[0] : props.incomeCategories[0] ? props.incomeCategories[0] : props.expenseCategories[0]);
console.log(selectedCategory.value)
const payment = ref(props.payment ? props.payment : new RecurrentPayment())
const selectedCategoryType = ref(props.payment ? props.payment.category.type : props.categoryTypes[0]);
const selectedCategory = ref(props.payment ? props.payment.category : selectedCategoryType.code == 'EXPENSE'
? props.expenseCategories[0]
: props.incomeCategories[0]);
const categoryTypeChanged = (code) => {
@@ -170,12 +174,15 @@ const days = Array.from({length: 31}, (_, i) => i + 1);
// Выбор дня
const selectDay = (day: number) => {
console.log(day)
payment.value.atDay = day;
repeatDay.value = day;
isDaySelectorOpened.value = false;
};
// Выбор категории
const selectCategory = (category) => {
const selectCategory = (category: Category) => {
payment.value.category = category;
isCategorySelectorOpened.value = false;
selectedCategory.value = category;
};
@@ -211,13 +218,32 @@ const savePayment = async () => {
if (isEditing.value && props.payment) {
paymentData.id = props.payment.id; // Если редактируем, сохраняем ID
}
try {
await saveRecurrentPayment(paymentData)
loading.value = false
resetForm();
} catch (error) {
console.error('Error saving payment:', error);
// try {
if (props.payment) {
await updateRecurrent(payment.value)
.then(res => {
loading.value = false;
})
.catch((err) => {
console.log(err)
toast.add({severity: 'error', summary: 'Ошибка сохранения', detail: err.response.data.message, life: 3000})
})
}
else {
await saveRecurrentPayment(payment.value)
.then(() => {
loading.value = false;
})
.catch((err) => {
toast.add({severity: 'error', summary: 'Ошибка сохранения', detail: err.response.data.message, life: 3000})
console.log(err)
})
}
// loading.value = false
// resetForm();
// } catch (error) {
// console.error('Error saving payment:', error);
// }
emits('save-payment', paymentData);
resetForm();
closeModal();

View File

@@ -26,6 +26,7 @@ const loading = ref(false)
// Поля для формы
const name = ref('');
const selectedCategoryType = ref(props.payment ? props.payment.type : props.categoryTypes[0]);
console.log(selectedCategoryType.value);
const selectedCategory = ref(selectedCategoryType.code == 'EXPESE' ? props.expenseCategories[0] : props.incomeCategories[0]);
const categoryTypeChanged = (code) => {

View File

@@ -7,7 +7,8 @@
<!-- Заголовок -->
<div class="flex flex-col gap-4 xl:flex-row justify-between bg-gray-100">
<h1 class="text-4xl text-gray-800">Ежемесячные платежи</h1>
<Button label="Добавить платеж" icon="pi pi-plus" class="text-sm !bg-blue-300 hover:!bg-blue-400 !border-blue-300" @click="toggleModal(null)"/>
<Button label="Добавить платеж" icon="pi pi-plus"
class="text-sm !bg-blue-300 hover:!bg-blue-400 !border-blue-300" @click="toggleModal(null)"/>
</div>
<div v-if="!space">Выберите сперва пространство</div>
<!-- Список рекуррентных платежей -->
@@ -20,23 +21,24 @@
@delete-payment="deletePayment"
/>
<div>
<!-- <div-->
<!-- class=" bg-white shadow-lg rounded-lg p-6 ">-->
<!-- <div class="flex justify-between items-center">-->
<!-- <div class="flex items-center w-full justify-center gap-4" style="height: 160px;">-->
<!-- <div-->
<!-- class=" bg-white shadow-lg rounded-lg p-6 ">-->
<!-- <div class="flex justify-between items-center">-->
<!-- <div class="flex items-center w-full justify-center gap-4" style="height: 160px;">-->
<!-- <Button text class="flex-col" @click="toggleModal">-->
<!-- <i class="pi pi-plus-circle" style="font-size: 2.5rem"></i>-->
<!-- <p></p>-->
<!-- </Button>-->
<CreateRecurrentModal
v-if="showModal"
:show="showModal"
:expenseCategories="expenseCategories"
:incomeCategories="incomeCategories"
:categoryTypes="categoryTypes"
@save-payment="savePayment"
@close-modal="toggleModal"/>
<!-- <Button text class="flex-col" @click="toggleModal">-->
<!-- <i class="pi pi-plus-circle" style="font-size: 2.5rem"></i>-->
<!-- <p></p>-->
<!-- </Button>-->
<CreateRecurrentModal
v-if="showModal"
:show="showModal"
:expenseCategories="expenseCategories"
:incomeCategories="incomeCategories"
:categoryTypes="categoryTypes"
:payment="editingPayment"
@save-payment="savePayment"
@close-modal="toggleModal"/>
</div>
</div>
@@ -49,13 +51,18 @@ import {computed, onMounted, ref, watch} from 'vue';
import RecurrentListItem from "@/components/settings/recurrent/RecurrentListItem.vue";
import Button from "primevue/button";
import {RecurrentPayment} from "@/models/Recurrent";
import {getRecurrentPayments} from "@/services/recurrentService";
import {deleteRecurrent, getRecurrentPayments} from "@/services/recurrentService";
import CreateRecurrentModal from "@/components/settings/recurrent/CreateRecurrentModal.vue";
import {Category, CategoryType} from "@/models/Category";
import {getCategories, getCategoryTypes} from "@/services/categoryService";
import {deleteCategoryRequest, getCategories, getCategoryTypes} from "@/services/categoryService";
import LoadingView from "@/components/LoadingView.vue";
import {useSpaceStore} from "@/stores/spaceStore";
import {getBudgetInfos} from "@/services/budgetsService";
import {useConfirm} from "primevue/useconfirm";
import {useToast} from "primevue/usetoast";
const confirm = useConfirm();
const toast = useToast()
const spaceStore = useSpaceStore()
@@ -84,7 +91,9 @@ const loading = ref(true);
const showModal = ref(false);
const toggleModal = () => {
const editingPayment = ref<RecurrentPayment | null>(null);
const toggleModal = (payment: RecurrentPayment | null) => {
editingPayment.value = payment
showModal.value = !showModal.value;
}
@@ -137,11 +146,39 @@ const savePayment = async () => {
// Обработчики событий
const editPayment = (payment: any) => {
const editPayment = (payment: RecurrentPayment) => {
toggleModal(payment)
};
const deletePayment = (payment: any) => {
const deletePayment = (payment: RecurrentPayment) => {
console.log('delete payment:', payment);
confirm.require({
message: 'Вы уверены, что хотите выполнить это действие?\n Это нельзя будет отменить.\n',
header: `Удаление ежемесячной транзакции ${payment.name}`,
icon: 'pi pi-info-circle',
rejectLabel: 'Cancel',
rejectProps: {
label: 'Cancel',
severity: 'secondary',
outlined: true
},
acceptProps: {
label: 'Delete',
severity: 'danger'
},
accept: async () => {
await deleteRecurrent(payment.id).then(async (result) => {
await fetchRecurrentPayments()
toast.add({severity: 'info', summary: 'Confirmed', detail: 'Удалено!', life: 3000});
}).catch(((err) => {
toast.add({severity: 'error', summary: 'Rejected', detail: 'Ошибка удаления платежа', life: 3000});
})
)
},
reject: () => {
// toast.add({severity: 'error', summary: 'Rejected', detail: 'You have rejected', life: 3000});
}
});
};

View File

@@ -69,6 +69,7 @@ const editPayment = () => {
};
const deletePayment = () => {
console.log('deleting payment');
emit('delete-payment', props.payment);
};
</script>

View File

@@ -2,6 +2,7 @@ import {Category} from "@/models/Category";
export class RecurrentPayment {
public id: number;
public space: Space;
public atDay: number;
public category: Category;
public name: string;

View File

@@ -12,6 +12,7 @@ export const getRecurrentPayments = async () => {
export const saveRecurrentPayment = async (payment: RecurrentPayment) => {
const spaceStore = useSpaceStore()
payment.space = spaceStore.space
return await apiClient.post(`/spaces/${spaceStore.space?.id}/recurrents`, payment)
}
//
@@ -23,10 +24,21 @@ export const saveRecurrentPayment = async (payment: RecurrentPayment) => {
// return await apiClient.post('/categories', category);
// };
//
// export const updateCategory = async (id: number, category: any) => {
// return await apiClient.put(`/categories/${id}`, category);
// };
//
// export const deleteCategory = async (id: number) => {
// return await apiClient.delete(`/categories/${id}`);
// };
export const updateRecurrent = async (recurrent: RecurrentPayment) => {
const id = recurrent.id
const spaceStore = useSpaceStore()
recurrent.space = spaceStore.space
return await apiClient.put(`/spaces/${spaceStore.space?.id}/recurrents/${id}`, recurrent)
.then(res => res.data)
.catch(err => {
console.log(err)
throw err
})
};
export const deleteRecurrent = async (id: number) => {
const spaceStore = useSpaceStore()
return await apiClient.delete(`/spaces/${spaceStore.space?.id}/recurrents/${id}`)
.then(res => res.data)
.catch(err => console.log(err))
};