Files
money.sori.studio/pages/index.vue
2026-08-13 15:58:42 +09:00

78 lines
2.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<section>
<header class="sticky top-0 z-10 border-b border-line bg-white px-4 pb-3 pt-4">
<div class="flex items-center justify-between">
<button class="btn-secondary min-h-10 px-3" @click="moveMonth(-1)">‹</button>
<input v-model="selectedMonth" class="w-36 rounded-md border border-line px-3 py-2 text-center font-semibold" type="month">
<button class="btn-secondary min-h-10 px-3" @click="moveMonth(1)">›</button>
</div>
<div class="mt-4 grid grid-cols-3 gap-2 text-sm">
<div>
<p class="text-muted">수입</p>
<p class="font-bold text-brand-700">{{ formatWon(data?.summary.income || 0) }}</p>
</div>
<div>
<p class="text-muted">지출</p>
<p class="font-bold text-red-600">{{ formatWon(data?.summary.expense || 0) }}</p>
</div>
<div>
<p class="text-muted">차액</p>
<p class="font-bold">{{ formatWon(data?.summary.diff || 0) }}</p>
</div>
</div>
</header>
<div class="divide-y divide-line">
<NuxtLink
v-for="tx in data?.transactions"
:key="tx.id"
:to="`/transactions/${tx.id}`"
class="grid grid-cols-[1fr_auto] gap-3 px-4 py-3"
>
<div class="min-w-0">
<p class="truncate font-semibold text-ink">{{ tx.title }}</p>
<p class="mt-1 text-xs text-muted">
{{ timeLabel(tx.occurredAt) }} · {{ tx.asset.name }}
</p>
<p class="mt-1 truncate text-xs text-muted">
{{ categoryLabel(tx.category) }}
</p>
</div>
<div class="text-right">
<p class="font-bold" :class="tx.type === 'income' ? 'text-brand-700' : 'text-red-600'">
{{ tx.type === 'income' ? '+' : '-' }}{{ formatWon(tx.amount) }}
</p>
</div>
</NuxtLink>
</div>
<div v-if="!data?.transactions.length" class="px-4 py-16 text-center text-muted">
아직 거래가 없습니다.
</div>
</section>
</template>
<script setup lang="ts">
import { addMonths, format, parse } from 'date-fns'
import type { Category } from '~/composables/useMoney'
const selectedMonth = ref(monthKey())
const { data } = await useFetch('/api/transactions', {
query: { month: selectedMonth }
})
function moveMonth(amount: number) {
const date = parse(selectedMonth.value, 'yyyy-MM', new Date())
selectedMonth.value = format(addMonths(date, amount), 'yyyy-MM')
}
function timeLabel(value: string) {
return new Intl.DateTimeFormat('ko-KR', { hour: '2-digit', minute: '2-digit' }).format(new Date(value))
}
function categoryLabel(category: Category & { parent?: Category | null }) {
return category.parent ? `${category.parent.name} > ${category.name}` : category.name
}
</script>