diff --git a/backend/app.js b/backend/app.js index dd00a65..eb77cb0 100644 --- a/backend/app.js +++ b/backend/app.js @@ -82,7 +82,7 @@ function hexToString(hexString) { function sendPin(pin, address) { //var memo = URLSafeBase64.encode(Buffer.from('ZGO pin: '.concat(pin))); - var memo = Buffer.from('ZGO pin: '.concat(pin)).toString('hex'); + var memo = Buffer.from('ZGo PIN: '.concat(pin)).toString('hex'); //console.log(typeof(memo)); var amounts = [ { @@ -175,7 +175,8 @@ var blockInterval = setInterval( function() { address: doc.address, blocktime: txData.blocktime, expiration: new Date(exptime * 1000), - amount: txData.amount + amount: txData.amount, + session: doc.session }); payment.save(function(error) { @@ -350,9 +351,8 @@ app.get('/api/getowner', (req, res, next) => { }); app.post('/api/addowner', (req, res, next) => { - // TODO: confirm passing owner works console.log('Post: /api/addowner'); - const owner = new ownermodel(req.body); + const owner = new ownermodel(req.body.owner); owner.save(); res.status(201).json({ message: 'Owner added successfully' diff --git a/backend/models/owner.js b/backend/models/owner.js index eba6d48..08fd47a 100644 --- a/backend/models/owner.js +++ b/backend/models/owner.js @@ -13,7 +13,7 @@ const ownerSchema = mongoose.Schema({ city: {type: String, required: true}, state: {type: String, required: true}, postal: {type: String, required: true}, - phone: {type: String, required: true}, + phone: {type: String}, website: {type: String}, paid: {type: Boolean, required: true, default: false} }); diff --git a/backend/models/payment.js b/backend/models/payment.js index f5517db..576b709 100644 --- a/backend/models/payment.js +++ b/backend/models/payment.js @@ -4,7 +4,8 @@ const paymentSchema = mongoose.Schema({ address: {type: String, required: true}, blocktime: {type: Number, required: true}, expiration: {type: Date, required: true}, - amount: {type: Number, required: true} + amount: {type: Number, required: true}, + session: {type: String, required: true} }); module.exports = mongoose.model('Payment', paymentSchema); diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 9b564aa..905da6a 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -34,6 +34,7 @@ import { ScanComponent } from './scan/scan.component'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { BusinessComponent } from './business/business.component'; import { SearchOptionsPipe } from './searchoptions.pipe'; +import { PaymentComponent } from './payment/payment.component'; @NgModule({ declarations: [ @@ -52,7 +53,8 @@ import { SearchOptionsPipe } from './searchoptions.pipe'; ScanComponent, ListOrdersComponent, BusinessComponent, - SearchOptionsPipe + SearchOptionsPipe, + PaymentComponent ], imports: [ BrowserModule, diff --git a/src/app/business/business.component.css b/src/app/business/business.component.css index 19740e6..7f5fde1 100644 --- a/src/app/business/business.component.css +++ b/src/app/business/business.component.css @@ -2,6 +2,10 @@ font-family: 'Spartan', sans-serif; } mat-card.centercard{ - max-width: 450px; + max-width: 500px; border: 1px solid #CCCCCC; } + +::ng-deep .mat-step-label{ + font-size: 13px; +} diff --git a/src/app/business/business.component.html b/src/app/business/business.component.html index 6159d13..406f70c 100644 --- a/src/app/business/business.component.html +++ b/src/app/business/business.component.html @@ -1,43 +1,78 @@
- -

Business Information

- - Business Name - - - - Address - - - - City - - - - State/Province - - - - Postal Code - - - - Country - - - - {{ctry.name}} - - - - - E-mail - - - - Website - - + +

Business sign-up

+ + +

We do not have a business associated with this Zcash address, please enter your information below:

+ + + Business Name + + + + Address + + + + City + + + + State/Province + + + + Postal Code + + + + Country + + + + {{ctry.name}} + + + + + E-mail + + + + Website + + + + + + + +
+ +

Please select the length of session that you need:

+ + + Session + + + {{ticket.viewValue}} + + + + + + + +
+ +

{{barMessage}}

+ + +
+ +
diff --git a/src/app/business/business.component.ts b/src/app/business/business.component.ts index 724c4fb..d0a5cf0 100644 --- a/src/app/business/business.component.ts +++ b/src/app/business/business.component.ts @@ -1,11 +1,18 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, ViewChild, AfterViewInit } from '@angular/core'; import { FormBuilder, Validators, FormGroup, FormControl } from '@angular/forms'; +import { MatDialog, MatDialogConfig} from '@angular/material/dialog'; +import { ProgressBarMode } from '@angular/material/progress-bar'; +import { Router } from '@angular/router'; import { Observable } from 'rxjs'; import { filter, startWith, map, switchMap } from 'rxjs/operators'; +import { MatStepper } from '@angular/material/stepper'; import { Country } from '../country.model'; import { Owner } from '../owner.model'; +import { User } from '../user.model'; import { UserService } from '../user.service'; +import { FullnodeService } from '../fullnode.service'; import { SearchOptionsPipe } from '../searchoptions.pipe'; +import { ScanComponent } from '../scan/scan.component'; @Component({ selector: 'app-business', @@ -14,16 +21,68 @@ import { SearchOptionsPipe } from '../searchoptions.pipe'; }) export class BusinessComponent implements OnInit { + @ViewChild('stepper', { static: false}) stepper: MatStepper|undefined; + nodeAddress: string = ''; + tickets = [ + { + value: 0.005, + viewValue: '1 day: 0.005 ZEC' + },{ + value: 0.025, + viewValue: '1 week: 0.025 ZEC' + },{ + value: 0.1, + viewValue: '1 month: 0.1 ZEC' + } + ]; bizForm: FormGroup; + payForm: FormGroup; + barMessage = 'Awaiting for transaction'; + barMode: ProgressBarMode = 'indeterminate'; + barValue = 0; countries: Country[] = []; + owner: Owner = { + address: '', + currency: 'usd', + tax: false, + taxValue: 0, + vat: false, + vatValue: 0, + phone: '', + paid: false, + name: '', + street: '', + city: '', + state: '', + postal: '', + country: '', + email: '', + website: '' + } public countriesUpdate: Observable; - testSearch = 'uni'; + public ownerUpdate: Observable; + public addrUpdate: Observable; + public userUpdate: Observable; + sessionId = ''; + ownerKnown = false; constructor( private fb: FormBuilder, - private userService: UserService + private userService: UserService, + private fullnodeService: FullnodeService, + private dialog: MatDialog, + private router: Router ) { this.countriesUpdate = userService.countriesUpdate; + this.ownerUpdate = userService.ownerUpdate; + this.userUpdate = userService.userUpdate; + this.userUpdate.subscribe(userInfo => { + this.sessionId = userInfo.session; + }); + this.addrUpdate = fullnodeService.addrUpdate; + this.addrUpdate.subscribe(nodeAdd => { + this.nodeAddress = nodeAdd; + }); this.bizForm = fb.group({ name: ['', Validators.required], street: ['', Validators.required], @@ -31,16 +90,74 @@ export class BusinessComponent implements OnInit { state: ['', Validators.required], postal: ['', Validators.required], country: ['', Validators.required], - email: ['', Validators.required], - website: ['', Validators.required] + email: ['', [Validators.email, Validators.required]], + website: [''] + }); + this.payForm= fb.group({ + session: ['', Validators.required] }); this.userService.getCountries(); this.countriesUpdate.subscribe((countries) => { this.countries = countries; }); + this.ownerUpdate.subscribe((owner) => { + this.owner = owner; + }); } ngOnInit(): void { } + ngAfterViewInit(): void { + this.ownerUpdate.subscribe(ownerData => { + if(ownerData.name.length > 0 && this.stepper!.selectedIndex == 0){ + this.stepper!.next(); + } + }); + } + + save() { + this.owner = { + address: '', + currency: 'usd', + tax: false, + taxValue: 0, + vat: false, + vatValue: 0, + phone: '', + paid: false, + name: this.bizForm.get('name')!.value, + street: this.bizForm.get('street')!.value, + city: this.bizForm.get('city')!.value, + state: this.bizForm.get('state')!.value, + postal: this.bizForm.get('postal')!.value, + country: this.bizForm.get('country')!.value, + email: this.bizForm.get('email')!.value, + website: this.bizForm.get('website')!.value + }; + this.userService.addOwner(this.owner); + this.stepper!.next(); + } + + pay(){ + const dialogConfig = new MatDialogConfig(); + + dialogConfig.disableClose = true; + dialogConfig.autoFocus = true; + dialogConfig.data = { + totalZec: this.payForm.get('session')!.value, + addr: this.nodeAddress, + session: this.sessionId, + pay: true + }; + + const dialogRef = this.dialog.open(ScanComponent, dialogConfig); + dialogRef.afterClosed().subscribe(val => { + console.log('Awaiting payment'); + if(val){ + this.stepper!.next(); + } + }); + } + } diff --git a/src/app/login/login.component.ts b/src/app/login/login.component.ts index 5d9defd..0785074 100644 --- a/src/app/login/login.component.ts +++ b/src/app/login/login.component.ts @@ -172,7 +172,7 @@ export class LoginComponent implements OnInit, AfterViewInit { }); if (this.txs.length > 0) { this.barMode = 'determinate'; - this.barValue = (this.txs[0].confirmations / 6) * 100; + this.barValue = (this.txs[0].confirmations / 2) * 100; this.confirmedMemo = true; this.barMessage = 'Login memo found, awaiting confirmations'; } @@ -187,7 +187,8 @@ export class LoginComponent implements OnInit, AfterViewInit { dialogConfig.data = { totalZec: 1e-8, addr: this.nodeAddress, - session: this.localToken + session: this.localToken, + pay: false }; const dialogRef = this.dialog.open(ScanComponent, dialogConfig); diff --git a/src/app/scan/scan.component.html b/src/app/scan/scan.component.html index 97e166b..864d305 100644 --- a/src/app/scan/scan.component.html +++ b/src/app/scan/scan.component.html @@ -1,5 +1,5 @@
-

Scan to connect your wallet

+

Scan the QR code

diff --git a/src/app/scan/scan.component.ts b/src/app/scan/scan.component.ts index 1667fa1..c4742a9 100644 --- a/src/app/scan/scan.component.ts +++ b/src/app/scan/scan.component.ts @@ -17,17 +17,23 @@ export class ScanComponent implements OnInit{ total: number; session: string; codeString: string = ''; + pay: boolean = false; zcashUrl: SafeUrl; constructor( private dialogRef: MatDialogRef, private sanitizer: DomSanitizer, - @Inject(MAT_DIALOG_DATA) public data: { totalZec: number, addr: string, session: string} + @Inject(MAT_DIALOG_DATA) public data: { totalZec: number, addr: string, session: string, pay: boolean} ) { this.address = data.addr; this.total = data.totalZec; this.session = data.session; - this.codeString = `zcash:${this.address}?amount=${this.total.toFixed(8)}&memo=${URLSafeBase64.encode(Buffer.from('ZGO::'.concat(this.session)))}`; + this.pay = data.pay; + if (this.pay) { + this.codeString = `zcash:${this.address}?amount=${this.total.toFixed(8)}&memo=${URLSafeBase64.encode(Buffer.from('ZGOp::'.concat(this.session)))}`; + } else { + this.codeString = `zcash:${this.address}?amount=${this.total.toFixed(8)}&memo=${URLSafeBase64.encode(Buffer.from('ZGO::'.concat(this.session)))}`; + } this.zcashUrl = this.sanitizer.bypassSecurityTrustUrl(this.codeString); } diff --git a/src/app/user.service.ts b/src/app/user.service.ts index e3e529d..00e2a27 100644 --- a/src/app/user.service.ts +++ b/src/app/user.service.ts @@ -143,10 +143,12 @@ export class UserService{ } addOwner(owner: Owner) { + owner.address = this.dataStore.user.address; let obs = this.http.post<{message: string}>(this.beUrl+'api/addowner', {owner: owner}, {headers: this.reqHeaders}); obs.subscribe((responseData) => { console.log(responseData.message); + this.getOwner(this.dataStore.user.address); }); return obs;