Files
money.sori.studio/components/TransactionListRow.vue

59 lines
1.7 KiB
Vue

<template>
<NuxtLink
:to="`/transactions/${transaction.id}`"
class="grid grid-cols-[2.5rem_minmax(0,1fr)_auto] items-start gap-3 px-4 py-3 active:bg-paper md:px-5"
>
<div
class="mt-0.5 flex h-10 w-10 items-center justify-center rounded-md bg-paper text-sm font-bold"
:class="transaction.type === 'income' ? 'text-brand-700' : 'text-muted'"
aria-hidden="true"
>
{{ categoryInitial }}
</div>
<div class="min-w-0">
<p class="truncate text-[15px] font-bold leading-5 text-ink">
{{ transaction.title }}
</p>
<p class="mt-1 truncate text-xs font-medium leading-5 text-muted">
{{ metaLine }}
</p>
<p v-if="memoPreview" class="mt-1 truncate text-xs font-medium leading-5 text-muted">
{{ memoPreview }}
</p>
</div>
<p
class="whitespace-nowrap pt-0.5 text-right text-[15px] font-bold leading-5"
:class="transaction.type === 'income' ? 'text-brand-700' : 'text-ink'"
>
{{ formatWon(transaction.amount) }}
</p>
</NuxtLink>
</template>
<script setup lang="ts">
import type { Transaction } from '~/composables/useMoney'
const props = defineProps<{
transaction: Transaction
}>()
const categoryLabel = computed(() => {
const category = props.transaction.category
return category.name
})
const categoryInitial = computed(() => {
const category = props.transaction.category
const name = category.parent?.name || category.name || (props.transaction.type === 'income' ? '수' : '지')
return name.slice(0, 1)
})
const metaLine = computed(() => {
return [props.transaction.asset.name, categoryLabel.value].filter(Boolean).join(' · ')
})
const memoPreview = computed(() => props.transaction.memo?.trim().slice(0, 60) || '')
</script>