116 lines
4.3 KiB
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>
|