Add fancier Account Card.
Build and Deploy Web App / build-and-deploy (push) Successful in 22s Details

This commit is contained in:
andrewlalis 2025-09-06 15:19:44 -04:00
parent 25b715156b
commit 1b32925add
2 changed files with 112 additions and 27 deletions

View File

@ -0,0 +1,110 @@
<script setup lang="ts">
import { AccountTypes, type Account } from '@/api/account';
import { formatMoney } from '@/api/data';
import { getSelectedProfile } from '@/api/profile';
import { computed } from 'vue';
import { useRoute, useRouter } from 'vue-router';
const router = useRouter()
const route = useRoute()
const props = defineProps<{ account: Account }>()
const accountType = computed(() => AccountTypes.of(props.account.type))
const isBalancePositive = computed(() => {
return props.account.currentBalance !== null && (
accountType.value.debitsPositive
? props.account.currentBalance > 0
: props.account.currentBalance < 0
)
})
const isBalanceNegative = computed(() => {
return props.account.currentBalance !== null && (
accountType.value.debitsPositive
? props.account.currentBalance < 0
: props.account.currentBalance > 0
)
})
function goToAccount() {
const profile = getSelectedProfile(route)
router.push(`/profiles/${profile}/accounts/${props.account.id}`)
}
</script>
<template>
<div class="account-card" @click="goToAccount()">
<!-- A top row for the name on the left, and balance on the right. -->
<div class="account-card-top-row">
<div>
<span class="account-card-name">{{ account.name }}</span>
<span class="account-card-number-suffix">#{{ account.numberSuffix }}</span>
</div>
<div class="account-card-balance" :class="{
'account-card-balance-positive': isBalancePositive,
'account-card-balance-negative': isBalanceNegative
}">
<span v-if="account.currentBalance !== null">
{{ formatMoney(account.currentBalance, account.currency) }}
</span>
<span v-if="account.currentBalance === null">-</span>
<span>&nbsp;{{ account.currency.code }}</span>
</div>
</div>
<!-- A bottom row for other attributes. -->
<div>
<span class="account-card-badge">
{{ accountType.name }}
</span>
</div>
</div>
</template>
<style lang="css">
.account-card {
background-color: var(--bg-primary);
padding: 0.5rem 0.5rem;
border-radius: 0.5rem;
margin: 0.5rem 0;
cursor: pointer;
}
.account-card:hover {
background-color: var(--bg-page);
}
.account-card-top-row {
display: flex;
justify-content: space-between;
}
.account-card-name {
font-size: 1rem;
font-weight: 600;
margin-right: 0.5rem;
}
.account-card-number-suffix {
font-size: 0.8rem;
font-family: monospace;
}
.account-card-balance {
font-size: 0.9rem;
font-family: monospace;
color: white;
}
.account-card-balance-positive {
color: green;
}
.account-card-balance-negative {
color: red;
}
.account-card-badge {
font-size: 0.75rem;
padding: 0.1rem 0.25rem;
background-color: var(--bg-secondary);
border-radius: 0.3rem;
}
</style>

View File

@ -2,6 +2,7 @@
import { AccountApiClient, type Account, type CurrencyBalance } from '@/api/account'
import { formatMoney } from '@/api/data'
import { getSelectedProfile } from '@/api/profile'
import AccountCard from '@/components/AccountCard.vue'
import AppButton from '@/components/AppButton.vue'
import HomeModule from '@/components/HomeModule.vue'
import { onMounted, ref, type Ref } from 'vue'
@ -26,33 +27,7 @@ onMounted(async () => {
<template>
<HomeModule title="Accounts">
<template v-slot:default>
<table class="app-table" v-if="accounts.length > 0">
<thead>
<tr>
<th>Name</th>
<th>Currency</th>
<th>Number</th>
<th>Type</th>
<th>Balance</th>
</tr>
</thead>
<tbody>
<tr v-for="account in accounts" :key="account.id">
<td>
<RouterLink :to="`/profiles/${getSelectedProfile(route)}/accounts/${account.id}`">{{ account.name }}
</RouterLink>
</td>
<td>{{ account.currency.code }}</td>
<td>...{{ account.numberSuffix }}</td>
<td>{{ account.type }}</td>
<td>
<span v-if="account.currentBalance !== null">{{ formatMoney(account.currentBalance, account.currency)
}}</span>
<span v-if="account.currentBalance === null">-</span>
</td>
</tr>
</tbody>
</table>
<AccountCard v-for="a in accounts" :account="a" :key="a.id" />
<p v-if="accounts.length === 0">
You haven't added any accounts. Add one to start tracking your finances.
</p>