Private
Public Access
1
0

Group accounts by Assets and Liabilities with section totals

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Catherine Renelle
2026-02-15 22:52:53 -05:00
parent 5537945276
commit e9ad7c0248
+48 -28
View File
@@ -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())