diff --git a/backend/app.js b/backend/app.js
index c3a89a4..8b952c7 100644
--- a/backend/app.js
+++ b/backend/app.js
@@ -287,7 +287,35 @@ app.post('/api/order', (req, res, next) => {
const order = new ordermodel(req.body.order);
order.save();
res.status(200).json({
- message: 'Order added'
+ message: 'Order added',
+ order: order
+ });
+});
+
+app.post('/api/lineitem', (req, res, next) => {
+ console.log('Post /api/lineitem');
+ ordermodel.findByIdAndUpdate(req.body.order_id, { $push: {lines: req.body.line}}, function(err,docs) {
+ if (err) {
+ console.log(err);
+ } else {
+ res.status(200).json({
+ message: 'Item added to order'
+ });
+ }
+ });
+});
+
+app.delete('/api/order/:id', (req, res, next) => {
+ console.log('delete order endpoint', req.params.id);
+ ordermodel.findByIdAndDelete(req.params.id, function (err, docs) {
+ if (err) {
+ console.log(err);
+ } else {
+ console.log(docs);
+ res.status(200).json({
+ message: 'Order deleted'
+ });
+ }
});
});
diff --git a/backend/models/order.js b/backend/models/order.js
index 64af430..19c644e 100644
--- a/backend/models/order.js
+++ b/backend/models/order.js
@@ -7,7 +7,7 @@ const orderSchema = mongoose.Schema({
closed: { type: Boolean, required: true, default:false },
lines: [{
qty: {type: Number, required: true, default: 1},
- item: { type: String, required: true},
+ name: { type: String, required: true},
cost: { type: Number, required: true, default: 0}
}]
});
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 34e1e06..5e91973 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -20,6 +20,7 @@ import { ItemCreateComponent } from './items/item-create/item-create.component';
import { ItemDeleteComponent } from './items/item-delete/item-delete.component';
import { ItemAddComponent} from './items/item-add/item-add.component';
import { OrderComponent } from './order/order.component';
+import { CancelComponent } from './cancel/cancel.component';
//import { NameDialogComponent } from './namedialog/namedialog.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
@@ -33,7 +34,8 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
OrderComponent,
ItemCreateComponent,
ItemDeleteComponent,
- ItemAddComponent
+ ItemAddComponent,
+ CancelComponent
//NameDialogComponent,
],
imports: [
@@ -56,6 +58,6 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
],
providers: [],
bootstrap: [AppComponent],
- entryComponents: [ItemCreateComponent, ItemDeleteComponent, ItemAddComponent]
+ entryComponents: [ItemCreateComponent, ItemDeleteComponent, ItemAddComponent, CancelComponent]
})
export class AppModule { }
diff --git a/src/app/cancel/cancel.component.css b/src/app/cancel/cancel.component.css
new file mode 100644
index 0000000..8955a94
--- /dev/null
+++ b/src/app/cancel/cancel.component.css
@@ -0,0 +1,3 @@
+.text {
+ font-family: "Roboto-Mono", monospace;
+}
diff --git a/src/app/cancel/cancel.component.html b/src/app/cancel/cancel.component.html
new file mode 100644
index 0000000..264bf4e
--- /dev/null
+++ b/src/app/cancel/cancel.component.html
@@ -0,0 +1,24 @@
+
Cancel Order
+
+
+ Are you sure you want to cancel the order?
+
+
+
+
+
+
+
+
+ |
+
+
+
+ |
+
+
+
diff --git a/src/app/cancel/cancel.component.ts b/src/app/cancel/cancel.component.ts
new file mode 100644
index 0000000..2c71b59
--- /dev/null
+++ b/src/app/cancel/cancel.component.ts
@@ -0,0 +1,23 @@
+import { Inject, Component, OnInit, ViewEncapsulation} from '@angular/core';
+import { MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog';
+
+@Component({
+ selector: 'app-cancel',
+ templateUrl: './cancel.component.html',
+ styleUrls: ['./cancel.component.css']
+})
+
+export class CancelComponent {
+
+ constructor(
+ private dialogRef: MatDialogRef
+ ) {}
+
+ confirm() {
+ this.dialogRef.close(true);
+ }
+
+ close() {
+ this.dialogRef.close(false);
+ }
+}
diff --git a/src/app/checkout/checkout.component.css b/src/app/checkout/checkout.component.css
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/checkout/checkout.component.html b/src/app/checkout/checkout.component.html
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/checkout/checkout.component.ts b/src/app/checkout/checkout.component.ts
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/items/item-add/item-add.component.css b/src/app/items/item-add/item-add.component.css
index c921a22..0e0c7d0 100644
--- a/src/app/items/item-add/item-add.component.css
+++ b/src/app/items/item-add/item-add.component.css
@@ -1,3 +1,7 @@
.text {
font-family: "Roboto Mono", monospace;
}
+
+input[type=number]{
+ text-align: right;
+}
diff --git a/src/app/items/item-add/item-add.component.html b/src/app/items/item-add/item-add.component.html
index 82a25be..dc706e4 100644
--- a/src/app/items/item-add/item-add.component.html
+++ b/src/app/items/item-add/item-add.component.html
@@ -3,7 +3,7 @@
{{lineItem.name}}
-
+
diff --git a/src/app/items/item-create/item-create.component.css b/src/app/items/item-create/item-create.component.css
index 3267c9b..bfe9e5d 100644
--- a/src/app/items/item-create/item-create.component.css
+++ b/src/app/items/item-create/item-create.component.css
@@ -1,3 +1,7 @@
.text {
font-family: 'Roboto-Mono', monospace;
}
+
+input[type=number]{
+ text-align: right;
+}
diff --git a/src/app/items/item-list/item-list.component.css b/src/app/items/item-list/item-list.component.css
index ffdd64b..ad0540a 100644
--- a/src/app/items/item-list/item-list.component.css
+++ b/src/app/items/item-list/item-list.component.css
@@ -2,6 +2,12 @@
font-family: 'Roboto-Mono', monospace;
}
+.text {
+ font-family: 'Roboto-Mono', monospace;
+}
+.small {
+ font-size: 75%;
+}
.icons {
font-family: 'Material Icons';
}
@@ -11,7 +17,7 @@
}
img.icon{
- margin-bottom: -1px;
+ margin-bottom: -3px;
}
div.card{
diff --git a/src/app/items/item-list/item-list.component.html b/src/app/items/item-list/item-list.component.html
index e57ede7..850f895 100644
--- a/src/app/items/item-list/item-list.component.html
+++ b/src/app/items/item-list/item-list.component.html
@@ -1,20 +1,18 @@
0">
-
-
+
{{item.name}} |
{{item.cost | currency: 'USD'}}
- {{(item.cost/price) | number: '1.0-6'}}
+ {{(item.cost/price) | number: '1.0-6'}}
|
-
-
- {{item.description}}
-
+
diff --git a/src/app/order/order.component.css b/src/app/order/order.component.css
index 57c4236..a0b4f5c 100644
--- a/src/app/order/order.component.css
+++ b/src/app/order/order.component.css
@@ -1,3 +1,7 @@
.text {
- font-family: 'Roboto Mono', monospace;
+ font-family: "Roboto-Mono", monospace;
+}
+
+img.icon{
+ margin-bottom: -3px;
}
diff --git a/src/app/order/order.component.html b/src/app/order/order.component.html
index 44ebe1e..7ad9f07 100644
--- a/src/app/order/order.component.html
+++ b/src/app/order/order.component.html
@@ -1,13 +1,41 @@
No open order!
0">
-
-
- Qty. |
- Items |
-
-
- {{item.qty}} |
- {{item.name}} |
-
-
+
+
+ {{order._id}}
+
+
+ Order Total: |
+
+ {{total | currency: 'USD'}}
+ {{(total/price) | number: '1.0-6'}}
+ |
+
+
+
+
+
+ Qty. |
+ Items |
+
+
+ {{item.qty}} |
+ {{item.name}} |
+
+
+
+
+
+
+
+
+ |
+
+
+
+ |
+
+
+
+
diff --git a/src/app/order/order.component.ts b/src/app/order/order.component.ts
index 4fedf5f..2328c3a 100644
--- a/src/app/order/order.component.ts
+++ b/src/app/order/order.component.ts
@@ -1,9 +1,11 @@
import { Component, OnInit } from '@angular/core';
+import { MatDialog, MatDialogConfig} from '@angular/material/dialog';
import { Observable } from 'rxjs';
import { Order } from './order.model';
import { FullnodeService } from '../fullnode.service';
import { UserService } from '../user.service';
import { OrderService } from './order.service';
+import { CancelComponent } from '../cancel/cancel.component';
@Component({
selector: 'app-order',
@@ -14,20 +16,50 @@ import { OrderService } from './order.service';
export class OrderComponent implements OnInit{
public order: Order = {address: '', session: '', timestamp: '', closed: false, lines: [{qty: 1, name: '', cost: 0}]};
public price: number = 1;
+ public total: number = 0;
public orderUpdate: Observable;
public priceUpdate: Observable;
+ public totalUpdate: Observable;
constructor(
public fullnodeService: FullnodeService,
- public orderService: OrderService
+ public orderService: OrderService,
+ private dialog: MatDialog
) {
this.priceUpdate = fullnodeService.priceUpdate;
+ this.priceUpdate.subscribe((price) => {
+ this.price = price;
+ });
this.orderUpdate = orderService.orderUpdate;
this.orderUpdate.subscribe((order) => {
this.order = order;
});
+ this.totalUpdate = orderService.totalUpdate;
+ this.totalUpdate.subscribe((total) => {
+ this.total = total;
+ });
}
ngOnInit() {
}
+
+ cancelOrder() {
+ const dialogConfig = new MatDialogConfig();
+
+ dialogConfig.disableClose = true;
+ dialogConfig.autoFocus = true;
+
+ const dialogRef = this.dialog.open(CancelComponent, dialogConfig);
+ dialogRef.afterClosed().subscribe((val) => {
+ if (val) {
+ console.log('Canceling');
+ this.orderService.cancelOrder(this.order._id!).subscribe((response) => {
+ this.orderService.getOrder();
+ });;
+ } else {
+ console.log('Returning to page');
+ }
+ this.orderService.getOrder();
+ });
+ }
}
diff --git a/src/app/order/order.service.ts b/src/app/order/order.service.ts
index 799e679..dbf868e 100644
--- a/src/app/order/order.service.ts
+++ b/src/app/order/order.service.ts
@@ -9,7 +9,8 @@ import { LineItem} from '../items/lineitem.model';
@Injectable({providedIn: 'root'})
export class OrderService {
- private dataStore: { user: User, order: Order } = {
+ private dataStore: { total:number, user: User, order: Order } = {
+ total: 0,
user:{
address: '',
session: '',
@@ -31,6 +32,8 @@ export class OrderService {
};
private _orderUpdated: BehaviorSubject = new BehaviorSubject(this.dataStore.order);
public readonly orderUpdate: Observable = this._orderUpdated.asObservable();
+ private _totalUpdated: BehaviorSubject = new BehaviorSubject(this.dataStore.total);
+ public readonly totalUpdate: Observable = this._totalUpdated.asObservable();
public userUpdate: Observable;
constructor(
@@ -41,11 +44,12 @@ export class OrderService {
this.userUpdate.subscribe((user) => {
this.dataStore.user = user;
//console.log('OS: const', user);
- this.getOrder(this.dataStore.user.session);
+ this.getOrder();
});
}
- getOrder(session: string) {
+ getOrder() {
+ var session = this.dataStore.user.session;
const params = new HttpParams().append('session', session);
let obs = this.http.get<{message: string, order: any}>('http://localhost:3000/api/order', { headers:{}, params:params, observe: 'response'});
@@ -53,6 +57,11 @@ export class OrderService {
if (OrderDataResponse.status == 200) {
this.dataStore.order = OrderDataResponse.body!.order;
this._orderUpdated.next(Object.assign({}, this.dataStore).order);
+ this.dataStore.total = 0;
+ for(var line of this.dataStore.order.lines) {
+ this.dataStore.total += line.qty * line.cost;
+ }
+ this._totalUpdated.next(Object.assign({}, this.dataStore).total);
} else {
console.log('No order found');
}
@@ -62,30 +71,57 @@ export class OrderService {
}
addToOrder(lineItem: LineItem) {
- if (this.dataStore.order.address.length == 0) {
- console.log('No open order, creating...', lineItem);
- this.createOrder();
+ if(this.dataStore.order._id != null) {
+ let obs = this.http.post<{message: string}>('http://localhost:3000/api/lineitem', { order_id: this.dataStore.order._id, line: lineItem });
+ obs.subscribe((orderData) => {
+ this.getOrder();
+ });
} else {
- console.log('Open order, adding...', lineItem);
+ this.createOrder(lineItem);
}
}
- createOrder() {
+ createOrder(lineItem: LineItem) {
var order:Order = {
address: this.dataStore.user.address,
session: this.dataStore.user.session,
closed: false,
lines: []
};
- let obs = this.http.post<{message: string}>('http://localhost:3000/api/order', {order: order});
-
+ let obs = this.http.post<{message: string, order: Order}>('http://localhost:3000/api/order', {order: order});
obs.subscribe((orderData) => {
console.log('Create order', orderData);
- this.getOrder(this.dataStore.user.session);
+ this.dataStore.order = orderData.order;
+ this._orderUpdated.next(Object.assign({}, this.dataStore).order);
+ this.addToOrder(lineItem);
});
return obs;
+ }
+ cancelOrder(id: string) {
+ let obs = this.http.delete<{message: string}>('http://localhost:3000/api/order/'+id);
+
+ obs.subscribe((OrderResponse) => {
+ console.log('Order deleted');
+ //this.getOrder();
+ this.dataStore.order = {
+ address: '',
+ session: '',
+ timestamp: '',
+ closed: false,
+ lines: [
+ {
+ qty: 1,
+ name: '',
+ cost:0
+ }
+ ]
+ };
+ this._orderUpdated.next(Object.assign({}, this.dataStore).order);
+ });
+
+ return obs;
}
}
diff --git a/src/assets/zec-roboto.png b/src/assets/zec-roboto.png
new file mode 100644
index 0000000..f0c56a0
Binary files /dev/null and b/src/assets/zec-roboto.png differ