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>
|
<v-btn color="primary" prepend-icon="mdi-plus" @click="showDialog = true">Add Account</v-btn>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<v-row>
|
<template v-for="group in accountGroups" :key="group.label">
|
||||||
<v-col v-for="account in accountsStore.accounts" :key="account.id" cols="12" md="6" lg="4">
|
<div v-if="group.accounts.length" class="mb-6">
|
||||||
<v-card :to="`/accounts/${account.id}/transactions`" hover class="d-flex flex-column" height="100%">
|
<div class="d-flex align-center mb-3">
|
||||||
<v-card-title>
|
<h2 class="text-h6">{{ group.label }}</h2>
|
||||||
<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-spacer />
|
||||||
<v-card-actions>
|
<span class="text-body-2 text-medium-emphasis">{{ formatCurrency(group.total) }}</span>
|
||||||
<v-btn size="small" variant="text" @click.prevent="editAccount(account)">Edit</v-btn>
|
</div>
|
||||||
<v-btn v-if="account.hasLoanDetail" size="small" variant="text" color="info" :to="`/loans/${account.id}`" @click.stop>Loan Details</v-btn>
|
<v-row>
|
||||||
<v-spacer />
|
<v-col v-for="account in group.accounts" :key="account.id" cols="12" md="6" lg="4">
|
||||||
<v-btn size="small" variant="text" color="error" @click.prevent="confirmDelete(account)">Delete</v-btn>
|
<v-card :to="`/accounts/${account.id}/transactions`" hover class="d-flex flex-column" height="100%">
|
||||||
</v-card-actions>
|
<v-card-title>
|
||||||
</v-card>
|
<v-icon class="mr-2">{{ accountTypeIcon(account.type) }}</v-icon>
|
||||||
</v-col>
|
{{ account.name }}
|
||||||
</v-row>
|
</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-dialog v-model="showDialog" max-width="600">
|
||||||
<v-card>
|
<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 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 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())
|
onMounted(() => accountsStore.fetchAccounts())
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user