Implement receipt QR code
This commit is contained in:
parent
934e28446c
commit
8e98bff2ae
13 changed files with 172 additions and 14 deletions
|
@ -540,7 +540,7 @@ app.get('/api/receipt', (req, res, next) => {
|
|||
});
|
||||
} else {
|
||||
res.status(204).json({
|
||||
message: 'no session received',
|
||||
message: 'no valid ID received',
|
||||
order: null
|
||||
});
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ import { BusinessComponent } from './business/business.component';
|
|||
import { SearchOptionsPipe } from './searchoptions.pipe';
|
||||
import { TermsComponent } from './terms/terms.component';
|
||||
import { ReceiptComponent } from './receipt/receipt.component';
|
||||
import { ReceiptQRComponent } from './receipt-qr/receipt-qr.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
|
@ -57,7 +58,8 @@ import { ReceiptComponent } from './receipt/receipt.component';
|
|||
BusinessComponent,
|
||||
SearchOptionsPipe,
|
||||
TermsComponent,
|
||||
ReceiptComponent
|
||||
ReceiptComponent,
|
||||
ReceiptQRComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
|
|
|
@ -7,6 +7,7 @@ import { UserService } from '../user.service';
|
|||
import { OrderService } from './order.service';
|
||||
import { CancelComponent } from '../cancel/cancel.component';
|
||||
import { CheckoutComponent} from '../checkout/checkout.component';
|
||||
import { ReceiptQRComponent} from '../receipt-qr/receipt-qr.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-order',
|
||||
|
@ -97,8 +98,20 @@ export class OrderComponent implements OnInit{
|
|||
const dialogRef = this.dialog.open(CheckoutComponent, dialogConfig);
|
||||
dialogRef.afterClosed().subscribe((val) => {
|
||||
if (val) {
|
||||
const dialogConfig2 = new MatDialogConfig();
|
||||
dialogConfig2.disableClose = true;
|
||||
dialogConfig2.autoFocus = true;
|
||||
dialogConfig2.data = {
|
||||
order: this.order._id
|
||||
};
|
||||
console.log('Payment confirmed!');
|
||||
this.orderService.closeOrder();
|
||||
const dialogRef2 = this.dialog.open(ReceiptQRComponent, dialogConfig2);
|
||||
dialogRef2.afterClosed().subscribe( val => {
|
||||
if (val) {
|
||||
console.log('Receipt closed.');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
console.log('Returning to order');
|
||||
}
|
||||
|
|
4
src/app/receipt-qr/receipt-qr.component.css
Normal file
4
src/app/receipt-qr/receipt-qr.component.css
Normal file
|
@ -0,0 +1,4 @@
|
|||
|
||||
.text {
|
||||
font-family: 'Spartan', sans-serif;
|
||||
}
|
13
src/app/receipt-qr/receipt-qr.component.html
Normal file
13
src/app/receipt-qr/receipt-qr.component.html
Normal file
|
@ -0,0 +1,13 @@
|
|||
<div align="center" mat-dialog-title>
|
||||
<h4 class="text">Scan for your Receipt</h4>
|
||||
</div>
|
||||
|
||||
<mat-dialog-content>
|
||||
<div class="qrcode" id="receipt-qr"> </div>
|
||||
</mat-dialog-content>
|
||||
|
||||
<mat-dialog-actions>
|
||||
<button mat-raised-button class="text" (click)="close()">
|
||||
<mat-icon class="icon">close</mat-icon>Close
|
||||
</button>
|
||||
</mat-dialog-actions>
|
25
src/app/receipt-qr/receipt-qr.component.spec.ts
Normal file
25
src/app/receipt-qr/receipt-qr.component.spec.ts
Normal file
|
@ -0,0 +1,25 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { ReceiptQRComponent } from './receipt-qr.component';
|
||||
|
||||
describe('ReceiptQRComponent', () => {
|
||||
let component: ReceiptQRComponent;
|
||||
let fixture: ComponentFixture<ReceiptQRComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ ReceiptQRComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ReceiptQRComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
38
src/app/receipt-qr/receipt-qr.component.ts
Normal file
38
src/app/receipt-qr/receipt-qr.component.ts
Normal file
|
@ -0,0 +1,38 @@
|
|||
import { Inject, Component, OnInit, ViewEncapsulation} from '@angular/core';
|
||||
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog';
|
||||
import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
|
||||
|
||||
var QRCode = require('easyqrcodejs');
|
||||
|
||||
@Component({
|
||||
selector: 'app-receipt-qr',
|
||||
templateUrl: './receipt-qr.component.html',
|
||||
styleUrls: ['./receipt-qr.component.css']
|
||||
})
|
||||
export class ReceiptQRComponent implements OnInit {
|
||||
receiptUrl: SafeUrl;
|
||||
codeString: string = '';
|
||||
|
||||
constructor(
|
||||
private dialogRef: MatDialogRef<ReceiptQRComponent>,
|
||||
private sanitizer: DomSanitizer,
|
||||
@Inject(MAT_DIALOG_DATA) public data: { order: string}
|
||||
) {
|
||||
this.codeString = `https://zgo.cash/receipt/${data.order}`;
|
||||
this.receiptUrl = this.sanitizer.bypassSecurityTrustUrl(this.codeString);
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
var qrcode = new QRCode(document.getElementById("receipt-qr"), {
|
||||
text: this.codeString,
|
||||
logo: "/assets/zgo-prp.png",
|
||||
logoWidth: 80,
|
||||
logoHeight: 80
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
close() {
|
||||
this.dialogRef.close(true);
|
||||
}
|
||||
}
|
|
@ -2,6 +2,8 @@ import { Injectable } from '@angular/core';
|
|||
import { Subject, BehaviorSubject, Observable } from 'rxjs';
|
||||
import { HttpClient, HttpParams, HttpHeaders } from '@angular/common/http';
|
||||
import { Order } from './order/order.model';
|
||||
import { Owner } from './owner.model';
|
||||
import { UserService } from './user.service';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
|
@ -51,7 +53,9 @@ export class ReceiptService {
|
|||
};
|
||||
private _orderUpdated: BehaviorSubject<Order> = new BehaviorSubject(this.dataStore.order);
|
||||
public readonly orderUpdate: Observable<Order> = this._orderUpdated.asObservable();
|
||||
public ownerUpdate: Observable<Owner>;
|
||||
public _nameUpdated: BehaviorSubject<string> = new BehaviorSubject(this.dataStore.owner.name);
|
||||
public readonly nameUpdate: Observable<string>= this._nameUpdated.asObservable();
|
||||
public readonly ownerUpdate;
|
||||
private apiKey = 'Le2adeic8Thah4Aeng4daem6i';
|
||||
private reqHeaders: HttpHeaders;
|
||||
|
||||
|
@ -61,19 +65,21 @@ export class ReceiptService {
|
|||
) {
|
||||
this.reqHeaders = new HttpHeaders().set('Authorization', this.apiKey);
|
||||
this.ownerUpdate = userService.ownerUpdate;
|
||||
this.ownerUpdate.subscribe((owner) => {
|
||||
this.dataStore.owner = owner;
|
||||
});
|
||||
}
|
||||
|
||||
getOrderById(id:string) {
|
||||
const params = new HttpParams().append('id', id);
|
||||
let obs = this.http.get<{message: string, order: any}>(this.beUrl+'api/order', { headers:this.reqHeaders, params:params, observe: 'response'});
|
||||
let obs = this.http.get<{message: string, order: any}>(this.beUrl+'api/receipt', { headers:this.reqHeaders, params:params, observe: 'response'});
|
||||
|
||||
obs.subscribe((OrderDataResponse) => {
|
||||
if (OrderDataResponse.status == 200) {
|
||||
this.dataStore.order = OrderDataResponse.body!.order;
|
||||
this._orderUpdated.next(Object.assign({}, this.dataStore).order);
|
||||
this.userService.getOwner(this.dataStore.order.address);
|
||||
this.ownerUpdate.subscribe((owner) => {
|
||||
this.dataStore.owner = owner;
|
||||
this._nameUpdated.next(Object.assign({}, this.dataStore).owner.name);
|
||||
});
|
||||
} else {
|
||||
console.log('No order found');
|
||||
}
|
||||
|
@ -81,4 +87,5 @@ export class ReceiptService {
|
|||
|
||||
return obs;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -28,3 +28,9 @@
|
|||
span.tt{
|
||||
font-family: 'Roboto-Mono', monospace;
|
||||
}
|
||||
img.total{
|
||||
margin-bottom:-2px;
|
||||
}
|
||||
.small{
|
||||
font-size: 10px;
|
||||
}
|
||||
|
|
|
@ -4,19 +4,40 @@
|
|||
</span>
|
||||
<span class="spacer"></span>
|
||||
<span align="center">
|
||||
<p class="text">Name</p>
|
||||
<p class="text">{{name}}</p>
|
||||
</span>
|
||||
</mat-toolbar>
|
||||
<div align="center">
|
||||
<mat-card>
|
||||
<mat-card-title>
|
||||
Receipt
|
||||
Total: <img class="total" src="/assets/spartan-zec.png" height="18px" />{{order.totalZec | number: '1.0-6'}}
|
||||
</mat-card-title>
|
||||
<mat-card-subtitle>
|
||||
Date
|
||||
{{order.timestamp | date}}
|
||||
</mat-card-subtitle>
|
||||
<mat-card-content>
|
||||
<p>receipt works! orderID:{{orderId}}</p>
|
||||
<p class="small">Order ID: {{orderId}}</p>
|
||||
<p>Zcash Price: {{order.price | currency: order.currency.toUpperCase()}}</p>
|
||||
<div align="center">
|
||||
<table>
|
||||
<tr>
|
||||
<th align="left">
|
||||
Item
|
||||
</th>
|
||||
<th align="center">
|
||||
Qty.
|
||||
</th>
|
||||
<th align="right">
|
||||
Price ({{order.currency.toUpperCase()}})
|
||||
</th>
|
||||
</tr>
|
||||
<tr *ngFor="let item of order.lines">
|
||||
<td align="left">{{item.name}}</td>
|
||||
<td align="center">{{item.qty}}</td>
|
||||
<td align="right">{{(item.qty * item.cost) | currency: order.currency.toUpperCase()}} </td>
|
||||
<tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { Order} from '../order/order.model';
|
||||
import { OrderService } from '../order/order.service';
|
||||
import { ReceiptService } from '../receipt.service';
|
||||
import { Observable } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'app-receipt',
|
||||
|
@ -10,14 +11,42 @@ import { OrderService } from '../order/order.service';
|
|||
})
|
||||
export class ReceiptComponent implements OnInit {
|
||||
orderId;
|
||||
//order:Order;
|
||||
public orderUpdate: Observable<Order>;
|
||||
public nameUpdate: Observable<string>;
|
||||
name: string = '';
|
||||
order:Order = {
|
||||
address: '',
|
||||
session: '',
|
||||
timestamp: '',
|
||||
closed: false,
|
||||
currency: '',
|
||||
price: 0,
|
||||
total: 0,
|
||||
totalZec: 0,
|
||||
lines: [
|
||||
{
|
||||
qty: 1,
|
||||
name: '',
|
||||
cost:0
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
constructor(
|
||||
private _ActiveRoute:ActivatedRoute,
|
||||
public orderService: OrderService
|
||||
public receiptService: ReceiptService
|
||||
) {
|
||||
this.orderId = this._ActiveRoute.snapshot.paramMap.get("orderId");
|
||||
this.orderUpdate = receiptService.orderUpdate;
|
||||
this.nameUpdate = receiptService.nameUpdate;
|
||||
receiptService.getOrderById(this.orderId!);
|
||||
this.orderUpdate.subscribe(order => {
|
||||
this.order = order;
|
||||
});
|
||||
|
||||
this.nameUpdate.subscribe(name => {
|
||||
this.name = name;
|
||||
});
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 13 KiB |
BIN
src/assets/zgo-prp.png
Normal file
BIN
src/assets/zgo-prp.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 529 KiB |
Loading…
Reference in a new issue