+ dashboard
This commit is contained in:
69
src/components/dashboard/RecentTransactions.vue
Normal file
69
src/components/dashboard/RecentTransactions.vue
Normal file
@@ -0,0 +1,69 @@
|
||||
<script setup lang="ts">
|
||||
import { Transaction } from '@/models/transaction';
|
||||
import { computed } from 'vue';
|
||||
import dayjs from 'dayjs';
|
||||
import { formatAmount } from '@/utils/utils';
|
||||
|
||||
const props = defineProps<{
|
||||
transactions: Transaction[];
|
||||
}>();
|
||||
|
||||
const recentTransactions = computed(() => {
|
||||
return props.transactions.slice(0, 5);
|
||||
});
|
||||
|
||||
const formatDate = (date: string | Date) => {
|
||||
return dayjs(date).format('MMM D');
|
||||
};
|
||||
|
||||
const formatCurrency = (amount: number) => {
|
||||
return new Intl.NumberFormat('en-US', {
|
||||
style: 'currency',
|
||||
currency: 'USD',
|
||||
}).format(amount);
|
||||
};
|
||||
|
||||
const getAmountColor = (type: string) => {
|
||||
return type === 'INCOME' ? '!text-green-600 !dark:text-green-400' : '!text-red-600 !dark:text-red-400';
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col gap-4">
|
||||
<div class="flex items-center justify-between px-1">
|
||||
<h3 class="text-lg font-semibold text-surface-900 dark:text-surface-0">Recent Transactions</h3>
|
||||
<router-link to="/transactions" class="text-sm text-primary-600 dark:text-primary-400 hover:underline">
|
||||
View All
|
||||
</router-link>
|
||||
</div>
|
||||
|
||||
<div v-if="recentTransactions.length === 0" class="text-center py-8 text-surface-500 dark:text-surface-400">
|
||||
No recent transactions
|
||||
</div>
|
||||
|
||||
<div v-else class="flex flex-col gap-3">
|
||||
<div v-for="tx in recentTransactions" :key="tx.id"
|
||||
class="flex items-center justify-between p-3 bg-white dark:bg-surface-900 rounded-xl border border-surface-100 dark:border-surface-800 shadow-sm">
|
||||
<div class="flex items-center gap-3 w-full">
|
||||
<div
|
||||
class="w-10 h-10 rounded-full bg-surface-100 dark:bg-surface-800 flex items-center justify-center text-xl p-4">
|
||||
{{ tx.category.icon }}
|
||||
</div>
|
||||
<div class="flex flex-col w-full">
|
||||
<span class="font-medium text-surface-900 dark:text-surface-0 w-fit">{{ tx.comment }}</span>
|
||||
<span class="text-xs text-surface-500 dark:text-surface-400">{{ tx.category.name }} | {{ formatDate(tx.date)
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col items-end w-full">
|
||||
<span :class="['!font-semibold', getAmountColor(tx.type)]">
|
||||
{{ tx.type === 'EXPENSE' ? '-' : '+' }}{{ formatAmount(tx.amount) }} ₽
|
||||
</span>
|
||||
<!-- <span v-if="tx.comment" class="text-xs text-surface-500 dark:text-surface-400 truncate !w-fit">
|
||||
{{ tx.comment }}
|
||||
</span> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user