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

116 lines
4.3 KiB
Vue

<script setup lang="ts">
import { AccountApiClient, AccountTypes, type Account, type AccountType } from '@/api/account'
import { getSelectedProfile } from '@/api/profile'
import AppPage from '@/components/common/AppPage.vue'
import AppForm from '@/components/common/form/AppForm.vue'
import FormActions from '@/components/common/form/FormActions.vue'
import FormControl from '@/components/common/form/FormControl.vue'
import FormGroup from '@/components/common/form/FormGroup.vue'
import { computed, onMounted, ref, type Ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
const route = useRoute()
const router = useRouter()
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 () => {
const accountIdStr = route.params.id
if (accountIdStr && typeof accountIdStr === 'string') {
const accountId = parseInt(accountIdStr)
try {
loading.value = true
const api = new AccountApiClient(route)
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() {
const payload = {
name: accountName.value,
description: description.value,
type: accountType.value.id,
currency: currency.value,
numberSuffix: accountNumberSuffix.value,
}
try {
const api = new AccountApiClient(route)
loading.value = true
const account = editing.value
? await api.updateAccount(existingAccount.value?.id ?? 0, payload)
: await api.createAccount(payload)
await router.replace(`/profiles/${getSelectedProfile(route)}/accounts/${account.id}`)
} catch (err) {
console.error(err)
} finally {
loading.value = false
}
}
function onCancel() {
if (editing.value) {
router.replace(`/profiles/${getSelectedProfile(route)}/accounts/${existingAccount.value?.id}`)
} else {
router.replace(`/profiles/${getSelectedProfile(route)}`)
}
}
</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="onCancel" :disabled="loading" :submit-text="editing ? 'Save' : 'Add'" />
</AppForm>
</AppPage>
</template>