no longer manipulating prop. still can't get formatting to twork

This commit is contained in:
Annika
2022-07-12 16:12:03 -06:00
parent ef06dd057a
commit df80f78072
12 changed files with 265 additions and 22 deletions
+2 -1
View File
@@ -4,5 +4,6 @@ import { reactive } from 'vue'
export const AppState = reactive({
user: {},
account: {},
transactions: []
transactions: [],
categories: []
})
@@ -0,0 +1,113 @@
<template>
<div class="component flex flex-wrap md:flex-nowrap justify-between bg-stone-800 mb-2">
<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">
</div>
<div class="pr-4">
<!-- TODO this is bad! don't manipulate the prop -->
<!-- Look at cars in gregslist? -->
<!-- use editable object -->
<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">
</span>
</div>
<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">
</div>
<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">
<option :value="transData.categoryId" selected>{{categories.find((c) => c._id == transData.categoryId)?.name}}</option>
<!-- cat?.name - null coalescence - returns value iff object is valid -->
<!-- TODO there's an error here but it works??? -->
<option v-for="c in categories" :value="c._id">{{c.name}}</option>
</select>
</div>
<div class="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">
</div>
<div>
<button class="text-slate-50 bg-stone-800 w-16 hover:bg-green-300 hover:text-stone-900" @click="update">
Save
</button>
</div>
</div>
</template>
<script>
// import { logger } from '../utils/Logger'
import { transactionsService } from '../services/TransactionsService'
import { getDollars } from '../utils/Dollars'
import { computed, reactive, onMounted, ref, watchEffect } from "vue";
export default {
// TODO there's probably something wrong with this...
props: {
transaction: {
type: Object,
required: true
},
categories: {
type: Object,
required: true
}
},
setup(props){
// create editable object and use watchEffect
const transData = ref({})
watchEffect(() => {
transData.value = props.transaction
// whatever this doesn't work because WHYNOT
// transData.dollars = props.transaction.amount / 100
})
return {
transData,
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)
}
}
}
}
}
</script>
<!--
setup(props) {
const carData = ref({});
// NOTE the watcheffect runs when a piece of data inside it changes
// in this case props.edit car was accessed so if props.editCar changes it runs again
watchEffect(() => {
logger.log(props.editCar);
carData.value = props.editCar;
});
return {
carData, -->
<!-- // TODO undo this -->
<style lang="postcss" scoped>
input {
color-scheme: dark;
}
input::placeholder {
@apply text-slate-50;
opacity: 1;
}
input:hover::placeholder {
@apply text-stone-900;
opacity: 1;
}
input:hover {
color-scheme: light;
}
</style>
+28
View File
@@ -0,0 +1,28 @@
<template>
<div class="component">
<p>{{category}}</p>
</div>
</template>
<script>
import { computed, reactive, onMounted, ref, watchEffect } from "vue";
export default {
props: {
category: {
type: Object,
required: true
}
},
setup(props){
}
}
</script>
<style lang="scss" scoped>
</style>
+44 -10
View File
@@ -1,28 +1,35 @@
<template>
<div class="component flex flex-wrap md:flex-nowrap justify-between bg-stone-800 mb-2">
<div class="pr-4">
<input type="date" v-model="transaction.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-800 w-32 hover:bg-green-300 hover:text-stone-900">
</div>
<div class="pr-4">
<input type="number" v-model="transaction.amount" :placeholder="transaction.amount" class="w-24 bg-stone-800 text-slate-50 hover:bg-green-300 hover:text-stone-900">
<!-- TODO this is bad! don't manipulate the prop -->
<!-- Look at cars in gregslist? -->
<!-- use editable object -->
<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">
</span>
</div>
<div class="pr-4">
<input type="text" v-model="transaction.payee" :placeholder="transaction.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="transData.payee" class="text-slate-50 bg-stone-800 w-32 hover:bg-green-300 hover:text-stone-900">
</div>
<div class="pr-4">
<select v-model="transaction.category" class="text-slate-50 bg-stone-800 w-36 hover:bg-green-300 hover:text-stone-900">
<option value="" selected>{{transaction.category}}</option>
<option v-for="c in 10" value="meow">meow</option>
<select v-model="transData.categoryId" class="text-slate-50 bg-stone-800 w-36 hover:bg-green-300 hover:text-stone-900">
<option :value="transData.categoryId" selected>{{categories.find((c) => c._id == transData.categoryId)?.name}}</option>
<!-- cat?.name - null coalescence - returns value iff object is valid -->
<!-- TODO there's an error here but it works??? -->
<option v-for="c in categories" :value="c._id">{{c.name}}</option>
</select>
</div>
<div class="pr-4">
<input type="text" v-model="transaction.comment" :placeholder="transaction.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="transData.comment" class="text-slate-50 bg-stone-800 w-48 hover:bg-green-300 hover:text-stone-900">
</div>
<div>
<button class="text-slate-50 bg-stone-800 w-16 hover:bg-green-300 hover:text-stone-900" @click="update">
Save
</button>
{{transaction}}
</div>
</div>
</template>
@@ -31,6 +38,8 @@
<script>
// import { logger } from '../utils/Logger'
import { transactionsService } from '../services/TransactionsService'
import { getDollars } from '../utils/Dollars'
import { computed, reactive, onMounted, ref, watchEffect } from "vue";
export default {
// TODO there's probably something wrong with this...
@@ -38,15 +47,28 @@ export default {
transaction: {
type: Object,
required: true
},
categories: {
type: Object,
required: true
}
},
setup(props){
// create editable object and use watchEffect
const transData = ref({})
watchEffect(() => {
transData.value = props.transaction
// whatever this doesn't work because WHYNOT
// transData.dollars = props.transaction.amount / 100
})
return {
transData,
async update() {
console.log(props.transaction)
// console.log(props.transaction)
// send off request to update transaction
try {
await transactionsService.update(props.transaction)
// use the editable object instead
await transactionsService.update(transData.value)
} catch (error) {
console.log(error)
}
@@ -56,6 +78,18 @@ export default {
}
</script>
<!--
setup(props) {
const carData = ref({});
// NOTE the watcheffect runs when a piece of data inside it changes
// in this case props.edit car was accessed so if props.editCar changes it runs again
watchEffect(() => {
logger.log(props.editCar);
carData.value = props.editCar;
});
return {
carData, -->
<!-- // TODO undo this -->
<style lang="postcss" scoped>
+42 -2
View File
@@ -3,16 +3,35 @@
<p class="hover:text-green-300 cursor-pointer">Add Category</p>
<div class="flex md:mx-40 flex-col md:flex-row">
<div class="md:w-4/12 md:order-last">analysis container</div>
<div class="md:w-8/12">category container</div>
<div class="md:w-8/12">category container
<p v-for="c in categories" :key="c._id">{{c.name}}</p>
</div>
</div>
</div>
</template>
<script>
import { computed, onMounted } from 'vue'
import { AppState } from '../AppState'
import { categoriesService } from '../services/CategoriesService'
import { logger } from '../utils/Logger'
export default {
setup(){
return {}
onMounted(async () => {
try {
// console.log(AppState.categories)
await categoriesService.getAll()
// console.log(AppState.categories)
} catch (error) {
logger.log(error)
}
})
return {
categories: computed(() => AppState.categories)
}
}
}
</script>
@@ -21,3 +40,24 @@ export default {
<style lang="scss" scoped>
</style>
<!--
import { computed, onMounted } from 'vue'
import { AppState } from '../AppState'
import { transactionsService } from '../services/TransactionsService'
import { logger } from '../utils/Logger'
export default {
setup(){
onMounted(async () => {
try {
await transactionsService.getAll()
} catch (error) {
logger.log(error)
}
})
return {
transactions: computed(() => AppState.transactions)
}
}
} -->
+5 -2
View File
@@ -2,7 +2,7 @@
<div class="component">
<div class="flex mt-6 md:mx-40 flex-col">
<h1>Transactions Container</h1>
<Transaction v-for="t in transactions" :key="t._id" :transaction="t" />
<Transaction v-for="t in transactions" :key="t._id" :transaction="t" :categories="categories" />
</div>
</div>
</template>
@@ -11,6 +11,7 @@
<script>
import { computed, onMounted } from 'vue'
import { AppState } from '../AppState'
import { categoriesService } from '../services/CategoriesService'
import { transactionsService } from '../services/TransactionsService'
import { logger } from '../utils/Logger'
@@ -18,13 +19,15 @@ export default {
setup(){
onMounted(async () => {
try {
await categoriesService.getAll()
await transactionsService.getAll()
} catch (error) {
logger.log(error)
}
})
return {
transactions: computed(() => AppState.transactions)
transactions: computed(() => AppState.transactions),
categories: computed(() => AppState.categories)
}
}
}
+2 -1
View File
@@ -9,7 +9,8 @@ const routes = [
{
path: '/',
name: 'Overview',
component: loadPage('OverviewPage')
component: loadPage('OverviewPage'),
beforeEnter: authGuard
},
{
path: '/transactions',
@@ -0,0 +1,14 @@
import { AppState } from "../AppState"
import { logger } from "../utils/Logger"
import { api } from "./AxiosService"
class CategoriesService {
async getAll() {
const res = await api.get('api/categories')
// console.log(res.data)
AppState.categories = res.data
}
}
export const categoriesService = new CategoriesService()
@@ -1,6 +1,7 @@
import { AppState } from "../AppState"
import { logger } from "../utils/Logger"
import { api } from "./AxiosService"
import { getCents } from '../utils/Dollars'
// TODO build the service to get some real data
@@ -20,9 +21,10 @@ class TransactionsService {
// TODO test this
async update(transaction) {
console.log(transaction._id)
// transaction.amount = getCents(transaction.dollars)
// console.log(transaction._id)
const res = await api.put('api/transactions/' + transaction._id, transaction)
console.log('transactionUpdate: ' + res.data)
// console.log('transactionUpdate: ' + res.data)
// AppState.transactions.find((t) => t._id == transactionId) = res.data
}
}
+8
View File
@@ -0,0 +1,8 @@
export function getDollars(cents) {
// return `$${Math.floor(cents / 100)}.${cents % 100}`
return cents / 100
}
export function getCents(dollars) {
return Math.round(dollars * 100)
}
+1 -1
View File
@@ -5,7 +5,7 @@ const Schema = mongoose.Schema
export const CategorySchema = new Schema(
{
/** @property {ObjectId} [accountId] -ID of the account this transaction belongs to */
/** @property {ObjectId} [accountId] -ID of the account this category belongs to */
accountId: {type: Schema.Types.ObjectId, required: true},
/** @property {String} [name] -name of the category */
@@ -11,6 +11,7 @@ async create(newTransaction) {
return dbTransaction
}
// TODO need to populate categories
async getAll(accountId) {
if (!accountId) {
throw new BadRequest("User not logged in")
@@ -19,8 +20,6 @@ async getAll(accountId) {
return allTransactions
}
// TODO test this
// TODO fix this
async update(accountId, transactionId, update) {
if (!transactionId) {
throw new BadRequest('Bad transaction id')