finnow/web-app/src/pages/forms/EditAccountPage.vue

113 lines
4.2 KiB
Vue

<script setup lang="ts">
import { AccountApiClient, AccountTypes, type Account, type AccountType } from '@/api/account';
import AppPage from '@/components/AppPage.vue';
import AppForm from '@/components/form/AppForm.vue';
import FormActions from '@/components/form/FormActions.vue';
import FormControl from '@/components/form/FormControl.vue';
import FormGroup from '@/components/form/FormGroup.vue';
import { useProfileStore } from '@/stores/profile-store';
import { computed, onMounted, ref, type Ref } from 'vue';
import { useRoute, useRouter } from 'vue-router';
const route = useRoute()
const router = useRouter()
const profileStore = useProfileStore()
const existingAccount: Ref<Account | null> = ref(null)
const editing = computed(() => {
return existingAccount.value !== null || route.meta.title === 'Edit Account'
})
const loading = ref(false)
const accountName = ref('')
const accountType: Ref<AccountType> = ref(AccountTypes.CHECKING)
const accountNumberSuffix = ref('')
const currency = ref('USD')
const description = ref('')
onMounted(async () => {
if (!profileStore.state) return
const accountIdStr = route.params.id
if (accountIdStr && typeof (accountIdStr) === 'string') {
const accountId = parseInt(accountIdStr)
try {
loading.value = true
const api = new AccountApiClient(profileStore.state)
existingAccount.value = await api.getAccount(accountId)
accountName.value = existingAccount.value.name
accountType.value = AccountTypes.of(existingAccount.value.type)
accountNumberSuffix.value = existingAccount.value.numberSuffix
currency.value = existingAccount.value.currency.code
description.value = existingAccount.value.description
} catch (err) {
console.error(err)
} finally {
loading.value = false
}
}
})
async function doSubmit() {
if (!profileStore.state) return
const payload = {
name: accountName.value,
description: description.value,
type: accountType.value.id,
currency: currency.value,
numberSuffix: accountNumberSuffix.value
}
try {
const api = new AccountApiClient(profileStore.state)
loading.value = true
const account = editing.value
? await api.updateAccount(existingAccount.value?.id ?? 0, payload)
: await api.createAccount(payload)
await router.replace(`/profiles/${profileStore.state.name}/accounts/${account.id}`)
} catch (err) {
console.error(err)
} finally {
loading.value = false
}
}
</script>
<template>
<AppPage :title="editing ? 'Edit Account' : 'Add Account'">
<AppForm @submit="doSubmit()">
<FormGroup>
<FormControl label="Account Name" style="max-width: 200px;">
<input v-model="accountName" :disabled="loading" />
</FormControl>
<FormControl label="Account Type">
<select id="account-type-select" v-model="accountType" :disabled="loading" required>
<option :value="AccountTypes.CHECKING">{{ AccountTypes.CHECKING.name }}</option>
<option :value="AccountTypes.SAVINGS">{{ AccountTypes.SAVINGS.name }}</option>
<option :value="AccountTypes.CREDIT_CARD">{{ AccountTypes.CREDIT_CARD.name }}</option>
<option :value="AccountTypes.BROKERAGE">{{ AccountTypes.BROKERAGE.name }}</option>
</select>
</FormControl>
<FormControl label="Currency">
<select id="currency-select" v-model="currency" :disabled="loading" required>
<option value="USD">USD</option>
<option value="EUR">EUR</option>
<option value="GBP">GBP</option>
</select>
</FormControl>
<FormControl label="Account Number Suffix" style="max-width: 200px;">
<input id="account-number-suffix-input" v-model="accountNumberSuffix" minlength="4" maxlength="4"
:disabled="loading" required />
</FormControl>
</FormGroup>
<FormGroup>
<FormControl label="Description">
<textarea id="description-textarea" v-model="description" :disabled="loading"></textarea>
</FormControl>
</FormGroup>
<FormActions @cancel="router.replace(`/profiles/${profileStore.state?.name}`)" :disabled="loading"
:submit-text="editing ? 'Save' : 'Add'" />
</AppForm>
</AppPage>
</template>