Group accounts by Assets and Liabilities with section totals
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -6,34 +6,43 @@
|
||||
<v-btn color="primary" prepend-icon="mdi-plus" @click="showDialog = true">Add Account</v-btn>
|
||||
</div>
|
||||
|
||||
<v-row>
|
||||
<v-col v-for="account in accountsStore.accounts" :key="account.id" cols="12" md="6" lg="4">
|
||||
<v-card :to="`/accounts/${account.id}/transactions`" hover class="d-flex flex-column" height="100%">
|
||||
<v-card-title>
|
||||
<v-icon class="mr-2">{{ accountTypeIcon(account.type) }}</v-icon>
|
||||
{{ account.name }}
|
||||
</v-card-title>
|
||||
<v-card-subtitle>{{ account.institution }} - {{ accountTypeLabel(account.type) }}</v-card-subtitle>
|
||||
<v-card-text>
|
||||
<div class="text-h4" :class="account.balance >= 0 ? 'text-success' : 'text-error'">
|
||||
{{ formatCurrency(account.balance) }}
|
||||
</div>
|
||||
<div v-if="account.creditLimit" class="text-caption mt-1">
|
||||
Credit Limit: {{ formatCurrency(account.creditLimit) }}
|
||||
({{ ((Math.abs(account.balance) / account.creditLimit) * 100).toFixed(0) }}% used)
|
||||
</div>
|
||||
<div v-if="account.interestRate" class="text-caption">APR: {{ account.interestRate }}%</div>
|
||||
</v-card-text>
|
||||
<template v-for="group in accountGroups" :key="group.label">
|
||||
<div v-if="group.accounts.length" class="mb-6">
|
||||
<div class="d-flex align-center mb-3">
|
||||
<h2 class="text-h6">{{ group.label }}</h2>
|
||||
<v-spacer />
|
||||
<v-card-actions>
|
||||
<v-btn size="small" variant="text" @click.prevent="editAccount(account)">Edit</v-btn>
|
||||
<v-btn v-if="account.hasLoanDetail" size="small" variant="text" color="info" :to="`/loans/${account.id}`" @click.stop>Loan Details</v-btn>
|
||||
<v-spacer />
|
||||
<v-btn size="small" variant="text" color="error" @click.prevent="confirmDelete(account)">Delete</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
<span class="text-body-2 text-medium-emphasis">{{ formatCurrency(group.total) }}</span>
|
||||
</div>
|
||||
<v-row>
|
||||
<v-col v-for="account in group.accounts" :key="account.id" cols="12" md="6" lg="4">
|
||||
<v-card :to="`/accounts/${account.id}/transactions`" hover class="d-flex flex-column" height="100%">
|
||||
<v-card-title>
|
||||
<v-icon class="mr-2">{{ accountTypeIcon(account.type) }}</v-icon>
|
||||
{{ account.name }}
|
||||
</v-card-title>
|
||||
<v-card-subtitle>{{ account.institution }} - {{ accountTypeLabel(account.type) }}</v-card-subtitle>
|
||||
<v-card-text>
|
||||
<div class="text-h4" :class="account.balance >= 0 ? 'text-success' : 'text-error'">
|
||||
{{ formatCurrency(account.balance) }}
|
||||
</div>
|
||||
<div v-if="account.creditLimit" class="text-caption mt-1">
|
||||
Credit Limit: {{ formatCurrency(account.creditLimit) }}
|
||||
({{ ((Math.abs(account.balance) / account.creditLimit) * 100).toFixed(0) }}% used)
|
||||
</div>
|
||||
<div v-if="account.interestRate" class="text-caption">APR: {{ account.interestRate }}%</div>
|
||||
</v-card-text>
|
||||
<v-spacer />
|
||||
<v-card-actions>
|
||||
<v-btn size="small" variant="text" @click.prevent="editAccount(account)">Edit</v-btn>
|
||||
<v-btn v-if="account.hasLoanDetail" size="small" variant="text" color="info" :to="`/loans/${account.id}`" @click.stop>Loan Details</v-btn>
|
||||
<v-spacer />
|
||||
<v-btn size="small" variant="text" color="error" @click.prevent="confirmDelete(account)">Delete</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<v-dialog v-model="showDialog" max-width="600">
|
||||
<v-card>
|
||||
@@ -93,8 +102,19 @@ const accountTypes = [
|
||||
|
||||
const form = ref({ name: '', type: 'Checking', institution: '', accountNumber: '', balance: 0, creditLimit: null as number | null, interestRate: null as number | null, notes: '' })
|
||||
|
||||
const liabilityTypes = ['CreditCard', 'AutoLoan', 'PersonalLoan', 'Mortgage', 'LineOfCredit']
|
||||
|
||||
const accountGroups = computed(() => {
|
||||
const assets = accountsStore.accounts.filter(a => !liabilityTypes.includes(a.type))
|
||||
const liabilities = accountsStore.accounts.filter(a => liabilityTypes.includes(a.type))
|
||||
return [
|
||||
{ label: 'Assets', accounts: assets, total: assets.reduce((sum, a) => sum + a.balance, 0) },
|
||||
{ label: 'Liabilities', accounts: liabilities, total: liabilities.reduce((sum, a) => sum + a.balance, 0) },
|
||||
]
|
||||
})
|
||||
|
||||
const showCreditLimit = computed(() => ['CreditCard', 'LineOfCredit'].includes(form.value.type))
|
||||
const showInterestRate = computed(() => ['CreditCard', 'AutoLoan', 'PersonalLoan', 'Mortgage', 'LineOfCredit'].includes(form.value.type))
|
||||
const showInterestRate = computed(() => liabilityTypes.includes(form.value.type))
|
||||
|
||||
onMounted(() => accountsStore.fetchAccounts())
|
||||
|
||||
|
||||
Reference in New Issue
Block a user