fix tx isdone checkbox text size
This commit is contained in:
76
src/components/targets/TargetList.vue
Normal file
76
src/components/targets/TargetList.vue
Normal file
@@ -0,0 +1,76 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
import {onMounted, ref} from "vue";
|
||||
import {Target} from "@/models/targets";
|
||||
import {useRouter} from "vue-router";
|
||||
import {useToolbarStore} from "@/stores/toolbar-store";
|
||||
import {useSpaceStore} from "@/stores/spaceStore";
|
||||
import {targetService} from "@/services/targets-service";
|
||||
import {useToast} from "primevue/usetoast";
|
||||
import {ProgressBar} from "primevue";
|
||||
import {TargetTypeIcon, TargetTypeName} from "@/models/enums";
|
||||
import {formatAmount} from "@/utils/utils";
|
||||
|
||||
const toast = useToast();
|
||||
|
||||
const router = useRouter()
|
||||
const toolbar = useToolbarStore()
|
||||
const spaceStore = useSpaceStore()
|
||||
|
||||
const targets = ref<Target[]>([])
|
||||
|
||||
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
if (spaceStore.selectedSpaceId) {
|
||||
targets.value = await targetService.fetchTargets(spaceStore.selectedSpaceId)
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
toast.add({
|
||||
severity: 'error',
|
||||
summary: 'Failed to fetch target list.',
|
||||
detail: e.message
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await fetchData()
|
||||
toolbar.registerHandler('openTargetCreation', () => {
|
||||
router.push('/targets/create')
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="targets-list">
|
||||
<div v-for="target in targets" class="card w-full">
|
||||
<div class="flex flex-col items-start justify-items-start justify-start w-full px-4 pb-4">
|
||||
<div class="flex flex-row items-center gap-2">
|
||||
<span class="text-4xl ">{{ TargetTypeIcon[target.type] }}</span>
|
||||
<div class="flex flex-col">
|
||||
<h2 class="text-2xl !font-semibold">{{ target.name }}</h2>
|
||||
<span class="text-sm text-gray-200"> {{ target.description }} | {{ TargetTypeName[target.type] }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col w-full">
|
||||
<div class="flex flex-row justify-between !w-full">
|
||||
<span> {{formatAmount(target.currentAmount)}} ₽</span>
|
||||
<span>{{formatAmount(target.amount)}} ₽</span>
|
||||
</div>
|
||||
<ProgressBar :value="((target.currentAmount / target.amount)*100).toFixed(0)" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.targets-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1.5rem;
|
||||
padding-bottom: 2.5rem;
|
||||
}
|
||||
</style>
|
||||
@@ -206,7 +206,9 @@ const deleteTransaction = async () => {
|
||||
if (spaceStore.selectedSpaceId && transactionId.value) {
|
||||
await transactionService.deleteTransaction(spaceStore.selectedSpaceId, Number(transactionId.value))
|
||||
await transactionStore.fetchTransactions(spaceStore.selectedSpaceId)
|
||||
await moveUser()
|
||||
if (openMode && openMode === "from_bot") {
|
||||
tgApp.close()
|
||||
} else await moveUser()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ export enum TransactionType {
|
||||
INCOME = "INCOME",
|
||||
EXPENSE = "EXPENSE",
|
||||
}
|
||||
|
||||
export const TransactionTypeName: Record<TransactionType, string> = {
|
||||
[TransactionType.EXPENSE]: 'Расходы',
|
||||
[TransactionType.INCOME]: 'Поступления',
|
||||
@@ -30,9 +31,33 @@ export enum TransactionKind {
|
||||
PLANNING = "PLANNING",
|
||||
INSTANT = "INSTANT",
|
||||
}
|
||||
|
||||
export const TransactionKindName: Record<TransactionKind, string> = {
|
||||
[TransactionKind.INSTANT]: 'Текущие',
|
||||
[TransactionKind.PLANNING]: 'Плановые',
|
||||
}
|
||||
|
||||
|
||||
export enum TargetType {
|
||||
AUTO = "AUTO",
|
||||
LEISURE = "LEISURE",
|
||||
VACATION = "VACATION",
|
||||
GOODS = "GOODS",
|
||||
OTHER = "OTHER",
|
||||
}
|
||||
|
||||
export const TargetTypeName: Record<TargetType, string> = {
|
||||
[TargetType.AUTO]: 'Авто',
|
||||
[TargetType.LEISURE]: 'Досуг',
|
||||
[TargetType.VACATION]: 'Отпуск',
|
||||
[TargetType.GOODS]: 'Покупка',
|
||||
[TargetType.OTHER]: 'Другое'
|
||||
}
|
||||
export const TargetTypeIcon: Record<TargetType, string> = {
|
||||
[TargetType.AUTO]: '🏎️',
|
||||
[TargetType.LEISURE]: '💃',
|
||||
[TargetType.VACATION]: '🏖',
|
||||
[TargetType.GOODS]: '🛍️',
|
||||
[TargetType.OTHER]: '💸'
|
||||
}
|
||||
|
||||
|
||||
63
src/models/targets.ts
Normal file
63
src/models/targets.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import {Transaction} from "@/models/transaction";
|
||||
import {User} from "@/models/user";
|
||||
import {TargetType} from "@/models/enums";
|
||||
|
||||
export interface Target {
|
||||
id: number,
|
||||
type: TargetType,
|
||||
name: string,
|
||||
description: string | null,
|
||||
amount: number,
|
||||
currentAmount: number,
|
||||
date: Date | string,
|
||||
components: TargetComponent[],
|
||||
transactions: Transaction[],
|
||||
createdBy: User,
|
||||
createdAt: Date,
|
||||
updatedBy: User | null,
|
||||
updatedAt: Date | null,
|
||||
}
|
||||
|
||||
|
||||
export interface CreateTargetDTO {
|
||||
type: TargetType,
|
||||
name: string,
|
||||
description: string | null,
|
||||
amount: number,
|
||||
date: Date | string,
|
||||
}
|
||||
|
||||
export interface UpdateTargetDTO {
|
||||
type: TargetType,
|
||||
name: string,
|
||||
description: string | null,
|
||||
amount: number,
|
||||
date: Date | string,
|
||||
}
|
||||
|
||||
|
||||
export interface TargetComponent {
|
||||
id: number,
|
||||
name: string,
|
||||
amount: number,
|
||||
isDone: boolean,
|
||||
date: Date | string,
|
||||
}
|
||||
|
||||
|
||||
export interface CreateTargetComponent {
|
||||
name: string,
|
||||
amount: number,
|
||||
date: Date | string,
|
||||
}
|
||||
|
||||
export interface UpdateTargetComponent {
|
||||
name: string,
|
||||
amount: number,
|
||||
isDone: boolean,
|
||||
date: Date | string,
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import RecurrentyCreateUpdate from "@/components/settings/RecurrentyCreateUpdate
|
||||
import TransactionList from "@/components/transactions/TransactionList.vue";
|
||||
import LoginPage from "@/components/auth/LoginPage.vue";
|
||||
import TransactionCreateUpdate from "@/components/transactions/TransactionCreateUpdate.vue";
|
||||
import TargetList from "@/components/targets/TargetList.vue";
|
||||
|
||||
// 📝 Расширяем тип меты роутов (типобезопасный toolbar, requiresAuth, guestOnly)
|
||||
declare module 'vue-router' {
|
||||
@@ -32,6 +33,9 @@ export const enum RouteName {
|
||||
TransactionList = 'transaction-list',
|
||||
TransactionCreate = 'transaction-create',
|
||||
TransactionUpdate = 'transaction-update',
|
||||
TargetList = 'target-list',
|
||||
TargetCreate = 'target-create',
|
||||
TargetUpdate = 'target-update',
|
||||
SettingsList = 'settings-list',
|
||||
CategoriesList = 'categories-list',
|
||||
CategoryCreate = 'category-create',
|
||||
@@ -45,7 +49,12 @@ export const enum RouteName {
|
||||
|
||||
const routes: RouteRecordRaw[] = [
|
||||
{path: '/login', name: RouteName.Login, component: LoginPage, meta: {requiresAuth: false, navStack: 'auth'}},
|
||||
{path: '/', name: RouteName.Dashboard, component: DashboardView, meta: {requiresAuth: true, navStack: 'dashboard', title: "Home"}},
|
||||
{
|
||||
path: '/',
|
||||
name: RouteName.Dashboard,
|
||||
component: DashboardView,
|
||||
meta: {requiresAuth: true, navStack: 'dashboard', title: "Home"}
|
||||
},
|
||||
{
|
||||
path: '/transactions',
|
||||
name: RouteName.TransactionList,
|
||||
@@ -83,11 +92,50 @@ const routes: RouteRecordRaw[] = [
|
||||
title: "Edit transaction"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
path: '/targets',
|
||||
name: RouteName.TargetList,
|
||||
component: TargetList,
|
||||
meta: {
|
||||
requiresAuth: true,
|
||||
toolbar: ({spaceStore}: { spaceStore: ReturnType<typeof useSpaceStore> }) => [
|
||||
|
||||
{id: 'openTargetCreation', text: '', icon: 'pi pi-plus', onClickId: 'openTargetCreation'},
|
||||
],
|
||||
navStack: 'targets',
|
||||
title: "Targets"
|
||||
|
||||
}
|
||||
},
|
||||
// {
|
||||
// path: '/transactions/create', name: RouteName.TransactionCreate, component: TransactionCreateUpdate, meta: {
|
||||
// requiresAuth: true,
|
||||
// toolbar: ({spaceStore}: { spaceStore: ReturnType<typeof useSpaceStore> }) => [
|
||||
// {id: 'createTransaction', text: '', icon: 'pi pi-save', onClickId: 'createTransaction'},
|
||||
// ],
|
||||
// navStack: 'transactions',
|
||||
// title: "Create transaction"
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// path: '/transactions/:id/edit', name: RouteName.TransactionUpdate, component: TransactionCreateUpdate, meta: {
|
||||
// requiresAuth: true,
|
||||
// toolbar: ({spaceStore}: { spaceStore: ReturnType<typeof useSpaceStore> }) => [
|
||||
//
|
||||
// {id: 'deleteTransaction', text: '', icon: 'pi pi-trash', onClickId: 'deleteTransaction'},
|
||||
// {id: 'updateTransaction', text: '', icon: 'pi pi-save', onClickId: 'updateTransaction'},
|
||||
// ],
|
||||
// navStack: 'settings',
|
||||
// title: "Edit transaction"
|
||||
// }
|
||||
// },
|
||||
|
||||
{
|
||||
path: '/settings',
|
||||
name: RouteName.SettingsList,
|
||||
component: SettingsList,
|
||||
meta: {requiresAuth: true, navStack: 'settings', title: "Settings"}
|
||||
meta: {requiresAuth: true, navStack: 'settings', title: "Settings"}
|
||||
},
|
||||
{
|
||||
path: '/categories', name: RouteName.CategoriesList, component: CategoriesList, meta: {
|
||||
|
||||
33
src/services/targets-service.ts
Normal file
33
src/services/targets-service.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import {Target} from "@/models/targets";
|
||||
import {TargetType} from "@/models/enums";
|
||||
import {User} from "@/models/user";
|
||||
|
||||
async function fetchTargets(spaceId: number): Promise<Target[]> {
|
||||
const targets = [];
|
||||
for (var i = 0; i < 10; i++) {
|
||||
const rand = Math.floor(Math.random() * 5);
|
||||
const now = new Date();
|
||||
const amount = Math.floor(Math.random() * 100000);
|
||||
now.setDate(Math.floor(Math.random() * 30))
|
||||
targets.push({
|
||||
id: i,
|
||||
type: rand == 1 ? TargetType.AUTO : rand == 2 ? TargetType.LEISURE : rand == 3 ? TargetType.VACATION : rand == 4 ? TargetType.GOODS : TargetType.OTHER,
|
||||
name: `Target ${i}`,
|
||||
description: `Target ${i} description`,
|
||||
amount: amount,
|
||||
currentAmount: Math.floor(Math.random() * amount),
|
||||
date: now,
|
||||
components: [],
|
||||
transactions: [],
|
||||
createdBy: {} as User,
|
||||
createdAt: new Date(),
|
||||
updatedBy: {} as User,
|
||||
updatedAt: new Date(),
|
||||
} as Target)
|
||||
}
|
||||
return targets;
|
||||
}
|
||||
|
||||
export const targetService = {
|
||||
fetchTargets
|
||||
};
|
||||
Reference in New Issue
Block a user