New component for receipts on order lists
This commit is contained in:
parent
7ef92aee12
commit
7930d6410b
12 changed files with 572 additions and 178 deletions
|
@ -42,6 +42,7 @@ import { ReceiptQRComponent } from './receipt-qr/receipt-qr.component';
|
|||
import { InvoiceComponent } from './invoice/invoice.component';
|
||||
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
|
||||
import { PromptInvoiceComponent } from './prompt-invoice/prompt-invoice.component';
|
||||
import { PromptReceiptComponent } from './prompt-receipt/prompt-receipt.component';
|
||||
import { NotifierComponent } from './notifier/notifier.component';
|
||||
|
||||
@NgModule({
|
||||
|
@ -67,6 +68,7 @@ import { NotifierComponent } from './notifier/notifier.component';
|
|||
ReceiptQRComponent,
|
||||
InvoiceComponent,
|
||||
PromptInvoiceComponent,
|
||||
PromptReceiptComponent,
|
||||
NotifierComponent
|
||||
],
|
||||
imports: [
|
||||
|
|
|
@ -3,6 +3,12 @@
|
|||
font-family: Roboto Mono !important;
|
||||
}
|
||||
|
||||
.zecSign {
|
||||
margin-bottom: -4px;
|
||||
font-size: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
.invoiceHeader {
|
||||
display: flex;
|
||||
font-family: Spartan;
|
||||
|
@ -21,7 +27,6 @@
|
|||
font-family: Roboto Mono !important;
|
||||
padding: 10px;
|
||||
max-width: 600px;
|
||||
background: #ebecf0;
|
||||
}
|
||||
|
||||
.invoiceHdrTxt1 {
|
||||
|
@ -98,8 +103,6 @@
|
|||
float: right;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.zecData {
|
||||
width: auto;
|
||||
font-family: Spartan !important;
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
|
||||
<div style="display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;">
|
||||
<div class="container">
|
||||
<div class="invoiceHeader">
|
||||
<img class="logo" src="/assets/logo-new-white.png" height="40px" />
|
||||
{{name}}
|
||||
|
@ -13,7 +16,7 @@
|
|||
<div style="height: 10px;"></div>
|
||||
<div class="zecData">Zcash Price: {{order.price | number: '1.02' | currency: order.currency.toUpperCase()}}</div>
|
||||
<div style="height: 2px;"></div>
|
||||
<div class="zecData">Total: <img class="total" src="/assets/zec_rv.png" height="18px" />{{order.totalZec | number: '1.08'}}
|
||||
<div class="zecData">Total: <img class="zecSign" src="/assets/zec_rv.png" />{{order.totalZec | number: '1.08'}}
|
||||
</div>
|
||||
<div>
|
||||
<div style="height: 10px;"></div>
|
||||
|
@ -59,7 +62,7 @@
|
|||
</th>
|
||||
<th width="30%"
|
||||
class="detailLineRight">
|
||||
{{ order.total | number : '1.02' | currency: order.currency.toUpperCase()}}
|
||||
{{ order.total | currency: order.currency.toUpperCase()}}
|
||||
</th>
|
||||
</tr>
|
||||
</table>
|
||||
|
@ -109,3 +112,5 @@
|
|||
</div>
|
||||
</mat-card-actions>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -122,6 +122,20 @@
|
|||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div style="display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 5px;
|
||||
height: 25px;
|
||||
background: lightblue;
|
||||
cursor: pointer;">
|
||||
<button style="background: #ff5722;
|
||||
color: white;"
|
||||
(click)="invoice(order)">Invoice</button>
|
||||
|
||||
<button style="background: #ff5722;
|
||||
color: white;"
|
||||
(click)="receipt(order)">Receipt</button>
|
||||
</div>
|
||||
</mat-expansion-panel>
|
||||
</mat-accordion>
|
||||
<p class="text" *ngIf = "orders.length <= 0">No orders</p>
|
||||
|
|
|
@ -6,6 +6,10 @@ import { UserService } from '../user.service';
|
|||
import { Owner } from '../owner.model';
|
||||
import { OrderService } from '../order/order.service';
|
||||
|
||||
import { MatDialog, MatDialogConfig} from '@angular/material/dialog';
|
||||
import { PromptInvoiceComponent } from '../prompt-invoice/prompt-invoice.component';
|
||||
import { PromptReceiptComponent } from '../prompt-receipt/prompt-receipt.component';
|
||||
|
||||
import { faTimes } from '@fortawesome/free-solid-svg-icons';
|
||||
import { faTimesCircle } from '@fortawesome/free-solid-svg-icons';
|
||||
import { faCheck } from '@fortawesome/free-solid-svg-icons';
|
||||
|
@ -20,12 +24,14 @@ import { faTrash } from '@fortawesome/free-solid-svg-icons';
|
|||
})
|
||||
|
||||
export class ListOrdersComponent implements OnInit, OnDestroy{
|
||||
// orderId;
|
||||
public todayTotal: number = 0;
|
||||
public total: number = 0;
|
||||
public orders: Order[] = [];
|
||||
public ownerUpdate: Observable<Owner>;
|
||||
public ordersUpdate: Observable<Order[]>;
|
||||
|
||||
|
||||
// ------------------------------------
|
||||
//
|
||||
faTimes = faTimes;
|
||||
|
@ -40,8 +46,9 @@ export class ListOrdersComponent implements OnInit, OnDestroy{
|
|||
|
||||
constructor(
|
||||
public orderService: OrderService,
|
||||
public userService: UserService
|
||||
){
|
||||
public userService: UserService,
|
||||
private dialog: MatDialog)
|
||||
{
|
||||
this.ownerUpdate = userService.ownerUpdate;
|
||||
this.orderService.getAllOrders();
|
||||
this.ordersUpdate = orderService.allOrdersUpdate;
|
||||
|
@ -83,4 +90,46 @@ export class ListOrdersComponent implements OnInit, OnDestroy{
|
|||
|
||||
}
|
||||
|
||||
invoice(order : Order) {
|
||||
// var zec = this.total/this.price;
|
||||
// this.order.totalZec = parseFloat(zec.toFixed(8));
|
||||
const dialogConfig = new MatDialogConfig();
|
||||
|
||||
console.log("Order data:");
|
||||
console.log(order);
|
||||
console.log("order.total = " + order.total);
|
||||
|
||||
dialogConfig.disableClose = true;
|
||||
dialogConfig.autoFocus = true;
|
||||
dialogConfig.data = {
|
||||
orderId: order._id
|
||||
};
|
||||
|
||||
const dialogRef = this.dialog.open(PromptInvoiceComponent, dialogConfig);
|
||||
dialogRef.afterClosed().subscribe((val) => {
|
||||
console.log('Returning to order list');
|
||||
});
|
||||
}
|
||||
|
||||
receipt(order : Order) {
|
||||
// var zec = this.total/this.price;
|
||||
// this.order.totalZec = parseFloat(zec.toFixed(8));
|
||||
const dialogConfig = new MatDialogConfig();
|
||||
|
||||
console.log("Order data:");
|
||||
console.log(order);
|
||||
console.log("order.total = " + order.total);
|
||||
|
||||
dialogConfig.disableClose = true;
|
||||
dialogConfig.autoFocus = true;
|
||||
dialogConfig.data = {
|
||||
orderId: order._id
|
||||
};
|
||||
|
||||
const dialogRef = this.dialog.open(PromptReceiptComponent, dialogConfig);
|
||||
dialogRef.afterClosed().subscribe((val) => {
|
||||
console.log('Returning to order list');
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
49
src/app/prompt-receipt/prompt-receipt.component.css
Normal file
49
src/app/prompt-receipt/prompt-receipt.component.css
Normal file
|
@ -0,0 +1,49 @@
|
|||
|
||||
::ng-deep .invoice {
|
||||
font-family: "Spartan";
|
||||
background: #ff5722;
|
||||
font-weight: 700;
|
||||
font-size: 18px;
|
||||
text-align: center;
|
||||
color: white;
|
||||
line-height: 20px;
|
||||
padding: 10px;
|
||||
|
||||
}
|
||||
|
||||
::ng-deep .invoice-content {
|
||||
font-family: Roboto mono;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.copy-button {
|
||||
color: dodgerblue;
|
||||
font-size: 20px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.urlLabel {
|
||||
font-family: "Spartan";
|
||||
font-size: 14px;
|
||||
color: dimgray;
|
||||
}
|
||||
|
||||
.urlDetail {
|
||||
font-family: "Spartan";
|
||||
font-size: 14px;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.urlCopyBtn {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.qr-code{
|
||||
border-radius: 0.5rem;
|
||||
border-bottom-left-radius: 0.5rem;
|
||||
border-bottom-right-radius: 0.5rem;
|
||||
}
|
||||
|
||||
|
57
src/app/prompt-receipt/prompt-receipt.component.html
Normal file
57
src/app/prompt-receipt/prompt-receipt.component.html
Normal file
|
@ -0,0 +1,57 @@
|
|||
<div class="container" style="margin-top: 10px;">
|
||||
|
||||
<div class="invoice" >
|
||||
Send the receipt link to your client:
|
||||
</div>
|
||||
|
||||
<table style="width:100%;
|
||||
margin-top: 10px;">
|
||||
<thead style="width: 100%;">
|
||||
<tr>
|
||||
<th class="urlLabel"
|
||||
style="text-align: left;"
|
||||
width="94%">Receipt URL:
|
||||
</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<td class="urlDetail"
|
||||
style="text-align: left;"
|
||||
width="94%">
|
||||
<div>
|
||||
<textarea
|
||||
style="border: none;
|
||||
outline: none;
|
||||
width: 95%;"
|
||||
cdkTextareaAutosize
|
||||
cdkAutosizeMinRows="1"
|
||||
cdkAutosizeMaxRows="4">{{ receiptUrl }}
|
||||
</textarea>
|
||||
</div>
|
||||
|
||||
</td>
|
||||
<td class="urlCopyBtn">
|
||||
<a (click)='copyUrl()' >
|
||||
<fa-icon [icon]="faCopy"
|
||||
class="copy-button">
|
||||
</fa-icon>
|
||||
</a>
|
||||
</td>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<mat-dialog-actions>
|
||||
<table cellspacing="0" width="100%">
|
||||
<tr>
|
||||
<td align="right">
|
||||
<button mat-raised-button class="text" (click)="close()">
|
||||
<mat-icon class="icon">close</mat-icon>Close
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</mat-dialog-actions>
|
||||
</div>
|
25
src/app/prompt-receipt/prompt-receipt.component.spec.ts
Normal file
25
src/app/prompt-receipt/prompt-receipt.component.spec.ts
Normal file
|
@ -0,0 +1,25 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { PromptReceiptComponent } from './prompt-receipt.component';
|
||||
|
||||
describe('PromptReceiptComponent', () => {
|
||||
let component: PromptReceiptComponent;
|
||||
let fixture: ComponentFixture<PromptReceiptComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ PromptReceiptComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(PromptReceiptComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
62
src/app/prompt-receipt/prompt-receipt.component.ts
Normal file
62
src/app/prompt-receipt/prompt-receipt.component.ts
Normal file
|
@ -0,0 +1,62 @@
|
|||
import { Inject, Component, OnInit} from '@angular/core';
|
||||
import { MatDialogRef, MAT_DIALOG_DATA} from '@angular/material/dialog';
|
||||
|
||||
import { NotifierService } from '../notifier.service';
|
||||
|
||||
import { faCopy } from '@fortawesome/free-solid-svg-icons';
|
||||
|
||||
var URLSafeBase64 = require('urlsafe-base64');
|
||||
var Buffer = require('buffer/').Buffer;
|
||||
|
||||
@Component({
|
||||
selector: 'app-prompt-receipt',
|
||||
templateUrl: './prompt-receipt.component.html',
|
||||
styleUrls: ['./prompt-receipt.component.css']
|
||||
})
|
||||
|
||||
export class PromptReceiptComponent implements OnInit {
|
||||
orderId: string;
|
||||
receiptUrl: string;
|
||||
|
||||
// ------------------------------------
|
||||
//
|
||||
faCopy = faCopy;
|
||||
// ------------------------------------
|
||||
|
||||
constructor(
|
||||
private dialogRef: MatDialogRef<PromptReceiptComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public data: {orderId: string},
|
||||
private notifierService : NotifierService ) {
|
||||
this.orderId = data.orderId;
|
||||
this.receiptUrl = 'https://app.zgo.cash/receipt/'+this.orderId;
|
||||
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
|
||||
confirm() {
|
||||
this.dialogRef.close(true);
|
||||
}
|
||||
|
||||
close() {
|
||||
this.dialogRef.close(false);
|
||||
}
|
||||
|
||||
copyUrl() {
|
||||
// console.log("Inside copyUrl()");
|
||||
if (navigator.clipboard) {
|
||||
};
|
||||
try {
|
||||
navigator.clipboard.writeText(this.receiptUrl);
|
||||
this.notifierService
|
||||
.showNotification("Receipt's URL copied to Clipboard!!","Close",'success');
|
||||
|
||||
} catch (err) {
|
||||
// console.error("Error", err);
|
||||
this.notifierService
|
||||
.showNotification("Functionality not available for your browser. Use send button instead.","Close",'error');
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,36 +1,112 @@
|
|||
* {
|
||||
font-family: 'Spartan', sans-serif;
|
||||
|
||||
.invoice {
|
||||
font-family: Roboto Mono !important;
|
||||
}
|
||||
|
||||
.spacer{
|
||||
flex: 1 1 auto;
|
||||
.zecSign {
|
||||
margin-bottom: -4px;
|
||||
font-size: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
.mat-card{
|
||||
font-family: 'Spartan', sans-serif;
|
||||
border: 1px solid #FF7522;
|
||||
width: 80%;
|
||||
text-align: left;
|
||||
margin: 5px;
|
||||
max-width: 500px;
|
||||
|
||||
.invoiceHeader {
|
||||
display: flex;
|
||||
font-family: Spartan;
|
||||
font-weight: 700;
|
||||
font-size: 26px;
|
||||
color: white;
|
||||
justify-content: space-between;
|
||||
line-height: 40px;
|
||||
padding: 10px;
|
||||
vertical-align: center;
|
||||
max-width: 600px;
|
||||
background: #ff5722;
|
||||
}
|
||||
.mat-card-title{
|
||||
font-size: 16px;
|
||||
|
||||
.invoiceDetail {
|
||||
font-family: Roboto Mono !important;
|
||||
padding: 10px;
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
.invoiceHdrTxt1 {
|
||||
font-family: Spartan !important;
|
||||
text-align: center;
|
||||
font-size: 30px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.mat-card-subtitle{
|
||||
|
||||
.invoiceHdrTxt2 {
|
||||
font-family: Spartan !important;
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.invoiceHdrTxt3 {
|
||||
font-family: Spartan !important;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
font-weight: 200;
|
||||
font-weight: 300;
|
||||
}
|
||||
.mat-card-content{
|
||||
font-size: 14px;
|
||||
text-align: justify;
|
||||
|
||||
.detailTitle1 {
|
||||
border-top: solid 2px;
|
||||
border-bottom: solid 2px;
|
||||
border-color: navy;
|
||||
text-align: left;
|
||||
}
|
||||
span.tt{
|
||||
font-family: 'Roboto-Mono', monospace;
|
||||
|
||||
.detailTitle2 {
|
||||
border-top: solid 2px;
|
||||
border-bottom: solid 2px;
|
||||
border-color: navy;
|
||||
text-align: right;
|
||||
}
|
||||
img.total{
|
||||
margin-bottom:-2px;
|
||||
|
||||
.detailLineRight {
|
||||
border-top: solid 2px;
|
||||
border-bottom: solid 2px;
|
||||
border-color: navy;
|
||||
text-align: right;
|
||||
}
|
||||
.small{
|
||||
font-size: 10px;
|
||||
|
||||
.detailLineLeft {
|
||||
border-top: solid 2px;
|
||||
border-bottom: solid 2px;
|
||||
border-color: navy;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.invoice-title {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
background: lightcyan;
|
||||
line-height: 30px;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.invoice-detail {
|
||||
line-height: 20px;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
padding-top: 4px;
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
|
||||
.invoice-total {
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.qrcode {
|
||||
display: flex;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.zecData {
|
||||
width: auto;
|
||||
font-family: Spartan !important;
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
text-align: right;
|
||||
}
|
||||
|
|
|
@ -1,44 +1,95 @@
|
|||
<mat-toolbar color="primary">
|
||||
<span align="center">
|
||||
<div style="display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;">
|
||||
<div class="container">
|
||||
<div class="invoiceHeader">
|
||||
<img class="logo" src="/assets/logo-new-white.png" height="40px" />
|
||||
</span>
|
||||
<span class="spacer"></span>
|
||||
<span align="center">
|
||||
<p class="text">{{name}}</p>
|
||||
</span>
|
||||
</mat-toolbar>
|
||||
<div align="center">
|
||||
<mat-card>
|
||||
<mat-card-title>
|
||||
Total: <img class="total" src="/assets/spartan-zec.png" height="18px" />{{order.totalZec | number: '1.0-6'}}
|
||||
</mat-card-title>
|
||||
<mat-card-subtitle>
|
||||
{{order.timestamp | date}}
|
||||
</mat-card-subtitle>
|
||||
<mat-card-content>
|
||||
<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">
|
||||
{{name}}
|
||||
</div>
|
||||
<div class="invoiceDetail"
|
||||
*ngIf="!error"
|
||||
id="invoice">
|
||||
<div class="invoiceHdrTxt1">Receipt</div>
|
||||
<div class="invoiceHdrTxt2">Order ID: {{orderId}}</div>
|
||||
<div class="invoiceHdrTxt3">Date:{{order.timestamp | date}}
|
||||
</div>
|
||||
<div style="height: 10px;"></div>
|
||||
<div class="zecData">Zcash Price: {{order.price | number: '1.02' | currency: order.currency.toUpperCase()}}</div>
|
||||
<div style="height: 2px;"></div>
|
||||
<div class="zecData">Total: <img class="zecSign" src="/assets/zec_rv.png" />{{order.totalZec | number: '1.08'}}
|
||||
</div>
|
||||
<div>
|
||||
<div style="height: 10px;"></div>
|
||||
<table style="width: 100%;"
|
||||
cellspacing="0">
|
||||
<tr class="invoice-title">
|
||||
<th width="55%"
|
||||
class="detailTitle1">
|
||||
Item
|
||||
</th>
|
||||
<th align="center">
|
||||
<th width="15%"
|
||||
class="detailTitle1">
|
||||
Qty.
|
||||
</th>
|
||||
<th align="right">
|
||||
<th width="30%"
|
||||
class="detailTitle2">
|
||||
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>
|
||||
<tr class="invoice-detail"
|
||||
*ngFor="let item of order.lines">
|
||||
<td width="55%"
|
||||
align="left">
|
||||
{{item.name}}
|
||||
</td>
|
||||
<td width="15%"
|
||||
align="center">
|
||||
{{item.qty}}
|
||||
</td>
|
||||
<td width="30%"
|
||||
align="right">
|
||||
{{( item.qty * item.cost ) | number : '1.02' | currency: order.currency.toUpperCase()}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="invoice-title">
|
||||
<th width="55%"
|
||||
class="detailLineRight">
|
||||
Total:
|
||||
</th>
|
||||
<th width="15%"
|
||||
class="detailLineLeft">
|
||||
|
||||
</th>
|
||||
<th width="30%"
|
||||
class="detailLineRight">
|
||||
{{ order.total | currency: order.currency.toUpperCase()}}
|
||||
</th>
|
||||
</tr>
|
||||
</table>
|
||||
<div style="height: 15px;"></div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
<div align="center" *ngIf="error">
|
||||
<div style="height: 10px;"></div>
|
||||
<div style="font-family: Spartan !important;
|
||||
font-size: 20px;
|
||||
padding: 4px;
|
||||
height: 24px;">
|
||||
Incorrect Receipt ID.
|
||||
</div>
|
||||
<div style="font-family: Spartan !important;
|
||||
font-size: 16px;
|
||||
padding: 4px;">
|
||||
No information available.
|
||||
</div>
|
||||
<div style="height: 10px;"></div>
|
||||
<mat-card-actions>
|
||||
<div align="center">
|
||||
<button mat-raised-button [routerLink]="['/']" color="primary">OK</button>
|
||||
</div>
|
||||
</mat-card-actions>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -14,6 +14,7 @@ export class ReceiptComponent implements OnInit {
|
|||
public orderUpdate: Observable<Order>;
|
||||
public nameUpdate: Observable<string>;
|
||||
name: string = '';
|
||||
error: boolean = false;
|
||||
order:Order = {
|
||||
address: '',
|
||||
session: '',
|
||||
|
|
Loading…
Reference in a new issue