70 lines
2.5 KiB
Vue
70 lines
2.5 KiB
Vue
<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>
|