remove now works on transactions

This commit is contained in:
Annika
2022-07-13 15:32:27 -06:00
parent 2ec1291832
commit 775bf23c19
6 changed files with 117 additions and 45 deletions
+48 -28
View File
@@ -1,7 +1,7 @@
<template> <template>
<div class="component flex flex-wrap md:flex-nowrap justify-between bg-stone-800 mb-2"> <form class="component flex flex-wrap md:flex-nowrap justify-between bg-stone-700 mb-2" @submit.prevent="create">
<div class="pr-4"> <div class="pr-4">
<input type="date" v-model="transData.date" class="text-slate-50 bg-stone-800 w-32 hover:bg-green-300 hover:text-stone-900"> <input type="date" v-model="transData.date" class="text-slate-50 bg-stone-700 w-32 hover:bg-green-200 hover:text-stone-900">
</div> </div>
<div class="pr-4"> <div class="pr-4">
<!-- TODO this is bad! don't manipulate the prop --> <!-- TODO this is bad! don't manipulate the prop -->
@@ -9,29 +9,29 @@
<!-- use editable object --> <!-- use editable object -->
<span class="flex"> <span class="flex">
$ $
<input type="number" v-model="transData.amount" :placeholder="transData.amount" class="w-24 bg-stone-800 text-slate-50 hover:bg-green-300 hover:text-stone-900"> <input type="number" v-model="transData.amount" placeholder="Amount" class="w-24 bg-stone-700 text-slate-50 hover:bg-green-200 hover:text-stone-900">
</span> </span>
</div> </div>
<div class="pr-4"> <div class="pr-4">
<input type="text" v-model="transData.payee" :placeholder="transData.payee" class="text-slate-50 bg-stone-800 w-32 hover:bg-green-300 hover:text-stone-900"> <input type="text" v-model="transData.payee" placeholder="Payee" class="text-slate-50 bg-stone-700 w-32 hover:bg-green-200 hover:text-stone-900">
</div> </div>
<div class="pr-4"> <div class="pr-4">
<select v-model="transData.categoryId" class="text-slate-50 bg-stone-800 w-36 hover:bg-green-300 hover:text-stone-900"> <select v-model="transData.categoryId" class="text-slate-50 bg-stone-700 w-36 hover:bg-green-200 hover:text-stone-900">
<option :value="transData.categoryId" selected>{{categories.find((c) => c._id == transData.categoryId)?.name}}</option> <option value="" disabled selected>Category</option>
<!-- cat?.name - null coalescence - returns value iff object is valid --> <!-- cat?.name - null coalescence - returns value iff object is valid -->
<!-- TODO there's an error here but it works??? --> <!-- TODO there's an error here but it works??? -->
<option v-for="c in categories" :value="c._id">{{c.name}}</option> <option v-for="c in categories" :value="c._id">{{c.name}}</option>
</select> </select>
</div> </div>
<div class="pr-4"> <div class="w-full pr-4">
<input type="text" v-model="transData.comment" :placeholder="transData.comment" class="text-slate-50 bg-stone-800 w-48 hover:bg-green-300 hover:text-stone-900"> <input type="text" v-model="transData.comment" placeholder="Comment" class="text-slate-50 bg-stone-700 w-full hover:bg-green-200 hover:text-stone-900">
</div> </div>
<div> <div>
<button class="text-slate-50 bg-stone-800 w-16 hover:bg-green-300 hover:text-stone-900" @click="update"> <button class="text-slate-50 bg-stone-700 px-2 hover:bg-green-200 hover:text-stone-900" action="submit">
Save Add
</button> </button>
</div> </div>
</div> </form>
</template> </template>
@@ -44,31 +44,51 @@ import { computed, reactive, onMounted, ref, watchEffect } from "vue";
export default { export default {
// TODO there's probably something wrong with this... // TODO there's probably something wrong with this...
props: { props: {
transaction: {
type: Object,
required: true
},
categories: { categories: {
type: Object, type: Object,
required: true required: true
} }
}, },
setup(props){ setup(props){
// create editable object and use watchEffect // // create editable object and use watchEffect
const transData = ref({}) // const transData = ref({})
watchEffect(() => { // watchEffect(() => {
transData.value = props.transaction // transData.value = props.transaction
// whatever this doesn't work because WHYNOT // // whatever this doesn't work because WHYNOT
// transData.dollars = props.transaction.amount / 100 // // transData.dollars = props.transaction.amount / 100
}) // })
return { return {
transData, transData: {
async update() { date: new Date().toISOString().slice(0,10),
// console.log(props.transaction) amount: 0,
// send off request to update transaction payee: '',
categoryId: '',
comment: ''
},
// async update() {
// // console.log(props.transaction)
// // send off request to update transaction
// try {
// // use the editable object instead
// await transactionsService.update(transData.value)
// } catch (error) {
// console.log(error)
// }
// }
async create() {
console.log('create triggered')
try { try {
// use the editable object instead // TODO WHY is it creating twice? (FIXED)
await transactionsService.update(transData.value) // TODO certain requests are 400 errors - sanitize
await transactionsService.create(this.transData)
// TODO empty after creation (not working)
this.transData = {
date: new Date().toISOString().slice(0,10),
amount: 0,
payee: '',
categoryId: '',
comment: ''
}
} catch (error) { } catch (error) {
console.log(error) console.log(error)
} }
@@ -81,6 +81,11 @@ export default {
async remove() { async remove() {
// TODO need to write CRUD method for this // TODO need to write CRUD method for this
// probably good to write an Are-you-sure Modal too... // probably good to write an Are-you-sure Modal too...
try {
await transactionsService.remove(props.transaction._id)
} catch (error) {
console.log(error)
}
} }
} }
} }
+11 -7
View File
@@ -1,6 +1,7 @@
<template> <template>
<div class="component"> <div class="component">
<div class="flex mt-6 md:mx-40 flex-col"> <div class="flex mt-6 md:mx-40 flex-col">
<AddTransaction :categories="categories" />
<Transaction v-for="t in transactions" :key="t._id" :transaction="t" :categories="categories" /> <Transaction v-for="t in transactions" :key="t._id" :transaction="t" :categories="categories" />
</div> </div>
</div> </div>
@@ -13,22 +14,25 @@ import { AppState } from '../AppState'
import { categoriesService } from '../services/CategoriesService' import { categoriesService } from '../services/CategoriesService'
import { transactionsService } from '../services/TransactionsService' import { transactionsService } from '../services/TransactionsService'
import { logger } from '../utils/Logger' import { logger } from '../utils/Logger'
import AddTransaction from '../components/AddTransaction.vue'
export default { export default {
setup() { setup() {
onMounted(async () => { onMounted(async () => {
try { try {
await categoriesService.getAll() await categoriesService.getAll();
await transactionsService.getAll() await transactionsService.getAll();
} catch (error) {
logger.log(error)
} }
}) catch (error) {
logger.log(error);
}
});
return { return {
transactions: computed(() => AppState.transactions), transactions: computed(() => AppState.transactions),
categories: computed(() => AppState.categories) categories: computed(() => AppState.categories)
} };
} },
components: { AddTransaction }
} }
</script> </script>
@@ -27,6 +27,21 @@ class TransactionsService {
// console.log('transactionUpdate: ' + res.data) // console.log('transactionUpdate: ' + res.data)
// AppState.transactions.find((t) => t._id == transactionId) = res.data // AppState.transactions.find((t) => t._id == transactionId) = res.data
} }
async create(transaction) {
const res = await api.post('api/transactions/', transaction)
// console.log(res.data)
AppState.transactions.push(res.data)
}
// TODO fix bug when deleting multiple sometimes gives 400 error
// accountId DNE? maybe bad data?
// i think it's just the button clicking before updated response?
async remove(id) {
const res = await api.delete('api/transactions/' + id)
// console.log(res.data)
AppState.transactions = res.data
}
} }
export const transactionsService = new TransactionsService() export const transactionsService = new TransactionsService()
@@ -25,6 +25,7 @@ export class TransactionsController extends BaseController {
.post('', this.create) .post('', this.create)
.get('', this.getAll) .get('', this.getAll)
.put('/:id', this.update) .put('/:id', this.update)
.delete('/:id', this.remove)
} }
async create(req, res, next) { async create(req, res, next) {
@@ -50,7 +51,7 @@ export class TransactionsController extends BaseController {
async update(req, res, next) { async update(req, res, next) {
try { try {
// I'm tired of losing the people I love... // I'm tired of losing the people I love...
logger.log(req) // logger.log(req)
const updatedTransaction = await transactionsService.update(req.userInfo.id, req.params.id, req.body) const updatedTransaction = await transactionsService.update(req.userInfo.id, req.params.id, req.body)
// I'm tired of not being enough... // I'm tired of not being enough...
return res.send(updatedTransaction) return res.send(updatedTransaction)
@@ -59,4 +60,13 @@ export class TransactionsController extends BaseController {
next(error) next(error)
} }
} }
async remove(req, res, next) {
try {
const transList = await transactionsService.remove(req.userInfo.id, req.params.id)
return res.send(transList)
} catch (error) {
next(error)
}
}
} }
+20 -2
View File
@@ -25,11 +25,14 @@ async update(accountId, transactionId, update) {
throw new BadRequest('Bad transaction id') throw new BadRequest('Bad transaction id')
} }
let original = await dbContext.Transactions.findById(transactionId) let original = await dbContext.Transactions.findById(transactionId)
if (!update) {
throw new BadRequest('Transcaction DNE')
}
if (accountId != original.accountId) { if (accountId != original.accountId) {
throw new BadRequest('Das nacho transaction') throw new BadRequest('Das nacho transaction')
} }
logger.log('original: ' + original) // logger.log('original: ' + original)
logger.log('update: ' + update) // logger.log('update: ' + update)
original.categoryId = update.categoryId || original.categoryId original.categoryId = update.categoryId || original.categoryId
original.amount = update.amount || original.amount original.amount = update.amount || original.amount
original.date = update.date || original.date original.date = update.date || original.date
@@ -39,6 +42,21 @@ async update(accountId, transactionId, update) {
return update return update
} }
async remove(accountId, transactionId) {
if (!transactionId) {
throw new BadRequest('Bad transaction id')
}
const original = await dbContext.Transactions.findById(transactionId)
if (!original) {
throw new BadRequest('Transaction DNE')
}
if (original.accountId != accountId) {
throw new BadRequest('Das nacho transaction')
}
await dbContext.Transactions.findByIdAndRemove(transactionId)
return await this.getAll(accountId)
}
} }