- {{ tx.category.icon }}
+
+
Looks like you haven't record any transaction yet.Try to create some.
+
+
+
+
{{
+ transactions[key].category.icon
+ }}
+
+
{{ transactions[key].comment }}
+
+ {{ transactions[key].category.name }}
+
+
-
-
{{ tx.comment }}
-
{{ tx.category.name }} | {{ formatDate(tx.date)
- }}
+
+
+ {{ formatAmount(transactions[key].amount) }} ₽
+
+
+
-
-
- {{ tx.type === 'EXPENSE' ? '-' : '+' }}{{ formatAmount(tx.amount) }} ₽
-
-
-
+
+
diff --git a/src/components/dashboard/StatsCard.vue b/src/components/dashboard/StatsCard.vue
index 86a5fa8..cf1121d 100644
--- a/src/components/dashboard/StatsCard.vue
+++ b/src/components/dashboard/StatsCard.vue
@@ -19,13 +19,14 @@ const formatCurrency = (value: number, currency = 'RUB') => {
-
-
+
{{ formatCurrency(amount, currency) }}
diff --git a/src/components/dashboard/UpcomingTransactions.vue b/src/components/dashboard/UpcomingTransactions.vue
index ded4bf9..7ea6dbe 100644
--- a/src/components/dashboard/UpcomingTransactions.vue
+++ b/src/components/dashboard/UpcomingTransactions.vue
@@ -3,67 +3,81 @@ import { Transaction } from '@/models/transaction';
import { computed } from 'vue';
import dayjs from 'dayjs';
import { formatAmount } from '@/utils/utils';
+import { Checkbox } from 'primevue';
+import { Divider } from 'primevue';
const props = defineProps<{
- transactions: Transaction[];
+ transactions: Transaction[];
}>();
+const emits = defineEmits(["set-tx-done"])
const upcomingTransactions = computed(() => {
- return props.transactions
- .sort((a, b) => new Date(a.date).getTime() - new Date(b.date).getTime())
- .slice(0, 5);
+ return props.transactions
+ .sort((a, b) => new Date(a.date).getTime() - new Date(b.date).getTime())
+ .slice(0, 5);
});
const formatDate = (date: string | Date) => {
- return dayjs(date).format('MMM D');
+ return dayjs(date).format('MMM D');
};
const getDaysUntilText = (date: string | Date) => {
- const days = dayjs(date).diff(dayjs(), 'day');
- if (days === 0) return 'Today';
- if (days === 1) return 'Tomorrow';
- if (days < 0) return 'Overdue';
- return `in ${days} days`;
+ const days = dayjs(date).diff(dayjs(), 'day');
+ if (days === 0) return 'Today';
+ if (days === 1) return 'Tomorrow';
+ if (days < 0) return 'Overdue';
+ return `in ${days} days`;
};
const getAmountColor = (type: string) => {
- return type === 'INCOME' ? '!text-green-600 !dark:text-green-400' : '!text-red-600 !dark:text-red-400';
+ return type === 'INCOME' ? '!text-green-600 !dark:text-green-400' : '!text-red-600 !dark:text-red-400';
};
+
+const setTxDone = (tx: Transaction) => {
+ emits("set-tx-done", tx)
+}
+
+
-
-
- No upcoming planned transactions
-
-
-
-
-
-
- {{ tx.category.icon }}
-
-
-
{{ tx.comment }}
-
-
{{ getDaysUntilText(tx.date) }}
-
({{ formatDate(tx.date) }})
+
+
+ Upcoming transactions
+ View
+ all
+
+
+
Looks like you haven't plan any transactions yet. Try to create some.
+
+
+
+ {{ transactions[key].category.icon }}
+
+
+
+
{{ transactions[key].comment }}
+
{{ transactions[key].category.icon }}
+ {{ transactions[key].category.name }}
+
+
+
+
+
+ {{ formatAmount(transactions[key].amount) }} ₽
+
+
+
+
+
+
+
-
-
-
- {{ tx.type === 'EXPENSE' ? '-' : '+' }}{{ formatAmount(tx.amount) }} ₽
-
-
-
-
-
diff --git a/src/models/dashboard.ts b/src/models/dashboard.ts
new file mode 100644
index 0000000..41ff666
--- /dev/null
+++ b/src/models/dashboard.ts
@@ -0,0 +1,19 @@
+import { Category } from "./category"
+import { Transaction } from "./transaction"
+
+export interface DashboardData {
+ totalExpense: number,
+ totalIncome: number,
+ balance: number,
+ categories: DashboardCategory[],
+ upcomingTransactions: Transaction[],
+ recentTransactions: Transaction[],
+}
+
+export interface DashboardCategory {
+ category: Category,
+ currentPeriodAmount: number,
+ previousPeriodAmount: number,
+ changeDiff: number,
+ changeDiffPercentage: number,
+}
diff --git a/src/services/dashboard-service.ts b/src/services/dashboard-service.ts
new file mode 100644
index 0000000..532eeb0
--- /dev/null
+++ b/src/services/dashboard-service.ts
@@ -0,0 +1,19 @@
+import api from "@/network/axiosSetup"
+import { toDateOnly } from "@/utils/utils"
+
+async function fetchDashboardData(spaceId: number, startDate: Date, endDate: Date) {
+ try {
+ const result = await api.get(`/spaces/${spaceId}/dashboard?startDate=${toDateOnly(startDate)}&endDate=${toDateOnly(endDate)}`)
+ return result.data
+ } catch (error) {
+ console.error(error)
+ throw error
+ }
+}
+
+
+
+
+export const DashboardService = {
+ fetchDashboardData
+}
\ No newline at end of file
diff --git a/src/services/transactions-service.ts b/src/services/transactions-service.ts
index ebb59ed..0e717cd 100644
--- a/src/services/transactions-service.ts
+++ b/src/services/transactions-service.ts
@@ -1,7 +1,7 @@
-import {CreateTransactionDTO, Transaction, UpdateTransactionDTO} from "@/models/transaction";
-import {TransactionKind, TransactionType} from "@/models/enums";
-import {categoriesService} from "@/services/categories-service";
-import {User} from "@/models/user";
+import { CreateTransactionDTO, Transaction, UpdateTransactionDTO } from "@/models/transaction";
+import { TransactionKind, TransactionType } from "@/models/enums";
+import { categoriesService } from "@/services/categories-service";
+import { User } from "@/models/user";
import api from "@/network/axiosSetup";
// const spaceStore = useSpaceStore();
@@ -12,21 +12,27 @@ function toDateOnly(d: Date): string {
return `${y}-${m}-${day}`;
}
-export interface TransactionFilters{
- type : TransactionType | null
+export interface TransactionFilters {
+ type: TransactionType | null
kind: TransactionKind | null
dateFrom: string | Date | null
dateTo: string | Date | null
isDone: boolean | null
offset: number | null
limit: number | null
+ sorts: Map
[]
+}
+
+enum SortDirection {
+ ASC = "ASC",
+ DESC = 'DESC'
}
async function getTransactions(spaceId: number, filters: TransactionFilters): Promise {
try {
- let response = await api.post(`/spaces/${spaceId}/transactions/_search`, filters );
+ let response = await api.post(`/spaces/${spaceId}/transactions/_search`, filters);
return response.data;
- }catch (error) {
+ } catch (error) {
console.error(error);
throw error;
}
@@ -34,7 +40,7 @@ async function getTransactions(spaceId: number, filters: TransactionFilters): Pr
async function getTransaction(spaceId: number, id: number): Promise {
try {
- let response = await api.get(`/spaces/${spaceId}/transactions/${id}`);
+ let response = await api.get(`/spaces/${spaceId}/transactions/${id}`);
return response.data;
} catch (error) {
console.error(error);
diff --git a/src/utils/utils.ts b/src/utils/utils.ts
index 61ecf4d..eb13151 100644
--- a/src/utils/utils.ts
+++ b/src/utils/utils.ts
@@ -89,3 +89,9 @@ export const getRandomColor = () => {
}
+export const toDateOnly = (d : Date): string => {
+ const y = d.getFullYear();
+ const m = String(d.getMonth() + 1).padStart(2, '0');
+ const day = String(d.getDate()).padStart(2, '0');
+ return `${y}-${m}-${day}`;
+}
\ No newline at end of file