diff --git a/.gitignore b/.gitignore
index ee5c9d8..b91b5da 100644
--- a/.gitignore
+++ b/.gitignore
@@ -37,3 +37,4 @@ testem.log
# System Files
.DS_Store
Thumbs.db
+*.swp
diff --git a/package-lock.json b/package-lock.json
index 223bfd1..c909e46 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2508,6 +2508,11 @@
"integrity": "sha1-ogM8CcyOFY03dI+951B4Mr1s4Sc=",
"dev": true
},
+ "dexie": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/dexie/-/dexie-2.0.4.tgz",
+ "integrity": "sha512-aQ/s1U2wHxwBKRrt2Z/mwFNHMQWhESerFsMYzE+5P5OsIe5o1kgpFMWkzKTtkvkyyEni6mWr/T4HUJuY9xIHLA=="
+ },
"di": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz",
diff --git a/package.json b/package.json
index 6b315aa..9ef9e21 100644
--- a/package.json
+++ b/package.json
@@ -23,6 +23,7 @@
"@angular/platform-browser-dynamic": "^6.1.0",
"@angular/router": "^6.1.0",
"core-js": "^2.5.4",
+ "dexie": "^2.0.4",
"hammerjs": "^2.0.8",
"rxjs": "^6.0.0",
"zone.js": "~0.8.26"
diff --git a/src/app/add-edit-transaction/add-edit-transaction.component.css b/src/app/add-edit-transaction/add-edit-transaction.component.css
new file mode 100644
index 0000000..27c5310
--- /dev/null
+++ b/src/app/add-edit-transaction/add-edit-transaction.component.css
@@ -0,0 +1,12 @@
+.transaction-form {
+ padding: 1em;
+ color: #F1F1F1;
+}
+
+.transaction-form * {
+ display: block;
+}
+
+mat-radio-button {
+ padding-bottom: 15px;
+}
diff --git a/src/app/add-edit-transaction/add-edit-transaction.component.html b/src/app/add-edit-transaction/add-edit-transaction.component.html
new file mode 100644
index 0000000..bf59689
--- /dev/null
+++ b/src/app/add-edit-transaction/add-edit-transaction.component.html
@@ -0,0 +1,39 @@
+
+
+
+ arrow_back
+
+
+
+ {{ title }}
+
+
+ Save
+
+
+
+
Select a transaction from the list to view details about it or edit it.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Expense
+ Income
+
+
+
diff --git a/src/app/add-edit-transaction/add-edit-transaction.component.spec.ts b/src/app/add-edit-transaction/add-edit-transaction.component.spec.ts
new file mode 100644
index 0000000..1ff2942
--- /dev/null
+++ b/src/app/add-edit-transaction/add-edit-transaction.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { AddEditTransactionComponent } from './add-edit-transaction.component';
+
+describe('AddEditTransactionComponent', () => {
+ let component: AddEditTransactionComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [ AddEditTransactionComponent ]
+ })
+ .compileComponents();
+ }));
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(AddEditTransactionComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/src/app/add-edit-transaction/add-edit-transaction.component.ts b/src/app/add-edit-transaction/add-edit-transaction.component.ts
new file mode 100644
index 0000000..dd0002c
--- /dev/null
+++ b/src/app/add-edit-transaction/add-edit-transaction.component.ts
@@ -0,0 +1,45 @@
+import { Component, OnInit, Input } from '@angular/core';
+import { Transaction } from '../transaction'
+import { TransactionType } from '../transaction.type'
+import { TransactionService } from '../transaction.service'
+import { Location } from '@angular/common';
+
+@Component({
+ selector: 'app-add-edit-transaction',
+ templateUrl: './add-edit-transaction.component.html',
+ styleUrls: ['./add-edit-transaction.component.css']
+})
+export class AddEditTransactionComponent implements OnInit {
+
+ @Input() title: string;
+ @Input() currentTransaction: Transaction;
+ public transactionType = TransactionType;
+
+ constructor(
+ private transactionService: TransactionService,
+ private location: Location
+ ) { }
+
+ ngOnInit() {
+ }
+
+ goBack(): void {
+ this.location.back()
+ }
+
+ save(): void {
+ if (this.currentTransaction.id) {
+ // This is an existing transaction, update it
+ this.transactionService.updateTransaction(this.currentTransaction);
+ } else {
+ // This is a new transaction, save it
+ this.transactionService.saveTransaction(this.currentTransaction);
+ }
+ this.goBack()
+ }
+
+ delete(): void {
+ this.transactionService.deleteTransaction(this.currentTransaction);
+ this.goBack()
+ }
+}
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index f348732..a371fd0 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -18,13 +18,15 @@ import { TransactionsComponent } from './transactions/transactions.component';
import { AppRoutingModule } from './app-routing.module';
import { TransactionDetailsComponent } from './transaction-details/transaction-details.component';
import { NewTransactionComponent } from './new-transaction/new-transaction.component';
+import { AddEditTransactionComponent } from './add-edit-transaction/add-edit-transaction.component';
@NgModule({
declarations: [
AppComponent,
TransactionsComponent,
TransactionDetailsComponent,
- NewTransactionComponent
+ NewTransactionComponent,
+ AddEditTransactionComponent
],
imports: [
BrowserModule,
diff --git a/src/app/budget-database.ts b/src/app/budget-database.ts
new file mode 100644
index 0000000..57dadb7
--- /dev/null
+++ b/src/app/budget-database.ts
@@ -0,0 +1,37 @@
+import Dexie from 'dexie';
+import { TransactionType } from './transaction.type';
+import { Category } from './category'
+import { Transaction } from './transaction'
+
+export class BudgetDatabase extends Dexie {
+ transactions: Dexie.Table;
+ categories: Dexie.Table;
+
+ constructor () {
+ super('BudgetDatabase')
+ this.version(1).stores({
+ transactions: `++id, title, description, amount, date, category, type`,
+ categories: `++id, name, amount, repeat, color`
+ })
+ this.transactions.mapToClass(Transaction)
+ this.categories.mapToClass(Category)
+ }
+}
+
+export interface ITransaction {
+ id: number;
+ title: string;
+ description: string;
+ amount: number;
+ date: Date;
+ category: ICategory;
+ type: TransactionType;
+}
+
+export interface ICategory{
+ id: number;
+ name: string;
+ amount: number;
+ repeat: string;
+ color: string;
+}
diff --git a/src/app/category.ts b/src/app/category.ts
new file mode 100644
index 0000000..e694475
--- /dev/null
+++ b/src/app/category.ts
@@ -0,0 +1,9 @@
+import { ICategory } from './budget-database'
+
+export class Category implements ICategory {
+ id: number;
+ name: string;
+ amount: number;
+ repeat: string;
+ color: string;
+}
diff --git a/src/app/new-transaction/new-transaction.component.html b/src/app/new-transaction/new-transaction.component.html
index 47432a4..d3904c5 100644
--- a/src/app/new-transaction/new-transaction.component.html
+++ b/src/app/new-transaction/new-transaction.component.html
@@ -1,34 +1 @@
-
-
-
- Add Transaction
-
-
- Save
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Expense
- Income
-
-
-
+
diff --git a/src/app/new-transaction/new-transaction.component.ts b/src/app/new-transaction/new-transaction.component.ts
index 070a44a..76e241c 100644
--- a/src/app/new-transaction/new-transaction.component.ts
+++ b/src/app/new-transaction/new-transaction.component.ts
@@ -1,8 +1,5 @@
import { Component, OnInit } from '@angular/core';
-import { TransactionService } from '../transaction.service'
import { Transaction } from '../transaction'
-import { TransactionType } from '../transaction.type'
-import { Location } from '@angular/common';
@Component({
selector: 'app-new-transaction',
@@ -11,19 +8,12 @@ import { Location } from '@angular/common';
})
export class NewTransactionComponent implements OnInit {
- public transaction = new Transaction()
- public transactionType = TransactionType;
+ transaction: Transaction;
- constructor(
- private transactionService: TransactionService,
- private location: Location
- ) { }
+ constructor() { }
ngOnInit() {
+ this.transaction = new Transaction()
}
- save(): void {
- this.transactionService.saveTransaction(this.transaction);
- this.location.back()
- }
}
diff --git a/src/app/transaction-details/transaction-details.component.html b/src/app/transaction-details/transaction-details.component.html
index dfadeda..dcb7fdf 100644
--- a/src/app/transaction-details/transaction-details.component.html
+++ b/src/app/transaction-details/transaction-details.component.html
@@ -1,8 +1 @@
-
-
-
- transaction-details works!
-
-
- transaction-details works!
-
+
diff --git a/src/app/transaction-details/transaction-details.component.ts b/src/app/transaction-details/transaction-details.component.ts
index 2b1747f..3646d2f 100644
--- a/src/app/transaction-details/transaction-details.component.ts
+++ b/src/app/transaction-details/transaction-details.component.ts
@@ -1,4 +1,6 @@
-import { Component, OnInit } from '@angular/core';
+import { Component, OnInit, Input } from '@angular/core';
+import { TransactionService } from '../transaction.service'
+import { ActivatedRoute } from '@angular/router';
import { Transaction } from '../transaction'
@Component({
@@ -8,11 +10,20 @@ import { Transaction } from '../transaction'
})
export class TransactionDetailsComponent implements OnInit {
- public transaction: Transaction;
+ transaction: Transaction;
- constructor() { }
+ constructor(
+ private route: ActivatedRoute,
+ private transactionService: TransactionService
+ ) { }
ngOnInit() {
+ this.getTransaction()
}
+ getTransaction(): void {
+ const id = +this.route.snapshot.paramMap.get('id')
+ this.transactionService.getTransaction(id)
+ .subscribe(transaction => this.transaction = transaction)
+ }
}
diff --git a/src/app/transaction.service.ts b/src/app/transaction.service.ts
index 8cc7a9a..017c24d 100644
--- a/src/app/transaction.service.ts
+++ b/src/app/transaction.service.ts
@@ -1,41 +1,39 @@
import { Injectable } from '@angular/core';
-import { of, Observable } from 'rxjs';
+import { of, Observable, from } from 'rxjs';
import { Transaction } from './transaction';
import { TransactionType } from './transaction.type';
+import { BudgetDatabase } from './budget-database';
@Injectable({
providedIn: 'root'
})
export class TransactionService {
- transactions: Transaction[] = [
- {id: 0, amount: Math.random() * 100, date: new Date(), description: "Spent some money", title: "An Expense", type: TransactionType.EXPENSE, categoryId: 0},
- {id: 0, amount: Math.random() * 100, date: new Date(), description: "Earned some money", title: "Some Income", type: TransactionType.INCOME, categoryId: 0},
- {id: 0, amount: Math.random() * 100, date: new Date(), description: "Spent some money", title: "An Expense", type: TransactionType.EXPENSE, categoryId: 0},
- {id: 0, amount: Math.random() * 100, date: new Date(), description: "Earned some money", title: "Some Income", type: TransactionType.INCOME, categoryId: 0},
- {id: 0, amount: Math.random() * 100, date: new Date(), description: "Spent some money", title: "An Expense", type: TransactionType.EXPENSE, categoryId: 0},
- {id: 0, amount: Math.random() * 100, date: new Date(), description: "Earned some money", title: "Some Income", type: TransactionType.INCOME, categoryId: 0},
- {id: 0, amount: Math.random() * 100, date: new Date(), description: "Spent some money", title: "An Expense", type: TransactionType.EXPENSE, categoryId: 0},
- {id: 0, amount: Math.random() * 100, date: new Date(), description: "Earned some money", title: "Some Income", type: TransactionType.INCOME, categoryId: 0},
- {id: 0, amount: Math.random() * 100, date: new Date(), description: "Spent some money", title: "An Expense", type: TransactionType.EXPENSE, categoryId: 0},
- {id: 0, amount: Math.random() * 100, date: new Date(), description: "Earned some money", title: "Some Income", type: TransactionType.INCOME, categoryId: 0},
- ]
- constructor() { }
+ db: BudgetDatabase;
+
+ constructor() {
+ this.db = new BudgetDatabase();
+ }
getTransactions(): Observable {
- return of(this.transactions)
+ return from(this.db.transactions.toCollection().toArray())
+ }
+
+ getTransaction(id: number): Observable {
+ return from(this.db.transactions.where('id').equals(id).first())
}
saveTransaction(transaction: Transaction): Observable {
- // TODO: Replace this with a DB save method
- var newId = 0;
- for (let transaction of this.transactions) {
- if (transaction.id > newId) {
- newId = transaction.id + 1;
- }
- }
- transaction.id = newId;
- this.transactions.push(transaction)
+ this.db.transactions.put(transaction)
return of(transaction)
}
+
+ updateTransaction(transaction: Transaction): Observable {
+ this.db.transactions.update(transaction.id, transaction)
+ return of([])
+ }
+
+ deleteTransaction(transaction: Transaction): Observable {
+ return from(this.db.transactions.delete(transaction.id))
+ }
}
diff --git a/src/app/transaction.ts b/src/app/transaction.ts
index c808345..f2af498 100644
--- a/src/app/transaction.ts
+++ b/src/app/transaction.ts
@@ -1,11 +1,13 @@
+import { ITransaction } from './budget-database'
+import { ICategory } from './budget-database'
import { TransactionType } from './transaction.type';
-export class Transaction {
+export class Transaction implements ITransaction {
id: number;
title: string;
description: string;
amount: number;
date: Date = new Date();
- categoryId: number;
+ category: ICategory;
type: TransactionType = TransactionType.EXPENSE;
}
diff --git a/src/app/transactions/transactions.component.css b/src/app/transactions/transactions.component.css
index 9ad4f42..48a3f16 100644
--- a/src/app/transactions/transactions.component.css
+++ b/src/app/transactions/transactions.component.css
@@ -1,5 +1,5 @@
-p {
- margin: 0;
+mat-toolbar {
+ justify-content: center;
}
.amount.income {
@@ -15,8 +15,3 @@ p {
justify-content: space-between;
}
-a.mat-fab {
- position: fixed;
- right: 2em;
- bottom: 2em;
-}
diff --git a/src/app/transactions/transactions.component.html b/src/app/transactions/transactions.component.html
index ae481a7..1151aba 100644
--- a/src/app/transactions/transactions.component.html
+++ b/src/app/transactions/transactions.component.html
@@ -1,14 +1,14 @@
- Transactions
-
-
-
-
{{transaction.title}}
-
{{
- transaction.amount | currency }}
-
- {{ transaction.date | date }}
-
-
-
- add
+Transactions
+
+
+
+
{{transaction.title}}
+
{{
+ transaction.amount | currency }}
+
+ {{ transaction.date | date }}
+
+
+ add
+
diff --git a/src/styles.css b/src/styles.css
index 434af83..83a4907 100644
--- a/src/styles.css
+++ b/src/styles.css
@@ -1,34 +1,43 @@
/* You can add global styles to this file, and also import other style files */
html, body {
- background: #333333;
- font-family: Roboto, "Helvetica Neue", sans-serif;
- margin: 0;
- padding: 0;
+ background: #333333;
+ font-family: Roboto, "Helvetica Neue", sans-serif;
+ margin: 0;
+ padding: 0;
+}
+
+p {
+ margin: 0;
+}
+
+a.mat-fab {
+ position: fixed;
+ right: 2em;
+ bottom: 2em;
}
.text-small {
- font-size: 1em;
- color: #BDBDBD
+ font-size: 1em;
+ color: #BDBDBD
}
.mat-toolbar {
- box-shadow: 0px 3px 3px 1px #212121;
+ box-shadow: 0px 3px 3px 1px #212121;
+ display: flex;
+ justify-content: space-between;
}
-/* .page-title {
- background: #333333;
- color: #F1f1f1;
- position: fixed;
- left: 0;
- top: 0;
- right: 0;
- z-index: 99;
- padding: 1em;
+mat-toolbar mat-icon {
+ vertical-align: middle;
+ cursor: pointer;
}
-.page-title h1 {
- margin: 0;
+mat-toolbar .action-item {
+ font-weight: normal;
+ cursor: pointer;
+ font-size: 0.9em;
+}
+
+mat-toolbar .action-item a {
+ vertical-align: middle;
}
-.content {
- padding-top: 68px;
-} */
\ No newline at end of file