accounting/frontend/components/accountsSidebar.vue

245 lines
6.4 KiB
Vue
Raw Normal View History

2024-01-16 15:13:04 +00:00
<template>
<div>
<router-link
to="/"
class="d-flex align-items-center fs-5 mb-3 mb-md-0 me-md-auto text-start text-white text-decoration-none"
>
<i class="fas fa-fw fa-hand-holding-dollar me-2" />
My Budget
</router-link>
2024-01-16 15:13:04 +00:00
<hr>
2024-01-16 15:13:04 +00:00
<ul class="list-unstyled lh-lg ps-0">
<acc-list
:accounts="budgetAccounts"
header="Budget"
/>
<acc-list
:accounts="trackingAccounts"
header="Tracking"
/>
2024-01-16 15:13:04 +00:00
</ul>
2024-01-16 15:13:04 +00:00
<button
class="btn btn-sm w-100"
data-bs-toggle="modal"
data-bs-target="#createAccountModal"
>
<i class="fas fa-fw fa-circle-plus mr-1" />
Add Account
</button>
<div
id="createAccountModal"
ref="createAccountModal"
class="modal fade"
tabindex="-1"
2024-01-17 22:02:41 +00:00
aria-labelledby="createAccountModalLabel"
2024-01-16 15:13:04 +00:00
aria-hidden="true"
>
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header">
<h1
2024-01-17 22:02:41 +00:00
id="createAccountModalLabel"
2024-01-16 15:13:04 +00:00
class="modal-title fs-5"
>
Add Account
</h1>
<button
type="button"
class="btn-close"
data-bs-dismiss="modal"
aria-label="Close"
/>
</div>
<div class="modal-body">
<div class="mb-3">
<label
for="createAccountModalName"
class="form-label"
>Account Name</label>
<input
id="createAccountModalName"
v-model.trim="modals.addAccount.name"
type="text"
class="form-control"
required
>
</div>
<div class="mb-3">
<label
for="createAccountModalType"
class="form-label"
>Account Type</label>
<select
v-model="modals.addAccount.type"
class="form-select"
>
<option value="budget">
Budget
</option>
<option value="tracking">
Tracking
</option>
<option value="category">
Category
</option>
</select>
</div>
<div class="mb-3">
<label
for="createAccountModalBalance"
class="form-label"
>Starting Balance</label>
<div class="input-group">
<input
id="createAccountModalBalance"
v-model.number="modals.addAccount.startingBalance"
type="number"
step="0.01"
class="form-control"
>
<span class="input-group-text"></span>
</div>
</div>
</div>
<div class="modal-footer">
<button
type="button"
class="btn btn-primary"
@click="addAccount"
>
<i class="fas fa-fw fa-circle-plus mr-1" />
Add
</button>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
2024-01-17 22:02:41 +00:00
/* eslint-disable sort-imports */
2024-01-16 15:13:04 +00:00
import { Modal } from 'bootstrap'
import accList from './accountsSidebarAccList.vue'
2024-01-17 22:02:41 +00:00
import { formatNumber } from '../helpers'
2024-01-16 16:30:17 +00:00
import { unallocatedMoneyAcc } from '../constants'
2024-01-16 15:13:04 +00:00
export default {
components: { accList },
2024-01-16 15:13:04 +00:00
computed: {
budgetAccounts() {
const accs = (this.accounts || []).filter(acc => acc.type === 'budget')
accs.sort((a, b) => a.name.localeCompare(b.name))
return accs
},
budgetSum() {
return this.budgetAccounts.reduce((sum, acc) => sum + acc.balance, 0)
},
trackingAccounts() {
const accs = (this.accounts || []).filter(acc => acc.type === 'tracking')
accs.sort((a, b) => a.name.localeCompare(b.name))
return accs
},
trackingSum() {
return this.trackingAccounts.reduce((sum, acc) => sum + acc.balance, 0)
},
},
data() {
return {
modals: {
addAccount: {
name: '',
startingBalance: 0,
type: 'budget',
},
},
}
},
methods: {
addAccount() {
return fetch('/api/accounts', {
body: JSON.stringify({
name: this.modals.addAccount.name,
type: this.modals.addAccount.type,
}),
headers: {
'Content-Type': 'application/json',
},
method: 'POST',
})
.then(resp => resp.json())
.then(account => {
if (account.type === 'budget') {
return fetch('/api/transactions', {
body: JSON.stringify({
account: account.id,
amount: this.modals.addAccount.startingBalance,
2024-01-16 16:30:17 +00:00
category: unallocatedMoneyAcc,
2024-01-16 15:13:04 +00:00
cleared: true,
description: 'Starting Balance',
time: new Date(),
}),
headers: {
'Content-Type': 'application/json',
},
method: 'POST',
})
} else if (account.type === 'tracking') {
return fetch('/api/transactions', {
body: JSON.stringify({
account: account.id,
amount: this.modals.addAccount.startingBalance,
cleared: true,
description: 'Starting Balance',
time: new Date(),
}),
headers: {
'Content-Type': 'application/json',
},
method: 'POST',
})
} else if (account.type === 'category') {
2024-01-16 16:30:17 +00:00
return fetch(`/api/accounts/${unallocatedMoneyAcc}/transfer/${account.id}?amount=${this.modals.addAccount.startingBalance}`, {
2024-01-16 15:13:04 +00:00
method: 'PUT',
})
}
throw new Error('invalid account type detected')
})
.then(() => this.$emit('update-accounts'))
.then(() => {
Modal.getInstance(this.$refs.createAccountModal).toggle()
this.modals.addAccount = {
name: '',
startingBalance: 0,
type: 'budget',
}
})
},
2024-01-17 22:02:41 +00:00
formatNumber,
2024-01-16 15:13:04 +00:00
},
name: 'AccountingAppSidebar',
props: {
accounts: {
required: true,
type: Array,
},
},
}
</script>