Commit 4bb45a35 authored by Pieterjan Vanhoof's avatar Pieterjan Vanhoof Committed by GitHub

Add sending and receiving modals (#54)

- Added sending modal
- Added receiving modal
- Added build and send functions to the API service
- Removed send/receive from wallet menu
- Fixed login (only returns status code 200 when OK)
parents a17b5dd1 14bbbb2d
......@@ -33,6 +33,7 @@
"@angular/platform-browser-dynamic": "^4.1.2",
"@angular/platform-server": "^4.1.2",
"@angular/router": "^4.1.2",
"@ng-bootstrap/ng-bootstrap": "^1.0.0-alpha.25",
"angular2-material-datepicker": "^0.5.0",
"bootstrap": "^4.0.0-alpha.6",
"core-js": "^2.4.1",
......
......@@ -3,6 +3,7 @@ import { BrowserModule } from '@angular/platform-browser';
import { FormsModule, ReactiveFormsModule } from "@angular/forms";
import { HttpModule } from '@angular/http';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import {NgbModule} from '@ng-bootstrap/ng-bootstrap';
import { SharedModule } from './shared/shared.module';
......@@ -14,6 +15,9 @@ import { LoginComponent } from './login/login.component';
import { ApiService } from './shared/services/api.service';
import { GlobalService } from './shared/services/global.service';
import { SendComponent } from './wallet/send/send.component';
import { ReceiveComponent } from './wallet/receive/receive.component';
@NgModule({
imports: [
......@@ -23,11 +27,18 @@ import { GlobalService } from './shared/services/global.service';
ReactiveFormsModule,
FormsModule,
HttpModule,
NgbModule.forRoot(),
SharedModule.forRoot()
],
declarations: [
AppComponent,
LoginComponent
LoginComponent,
SendComponent,
ReceiveComponent
],
entryComponents: [
SendComponent,
ReceiveComponent
],
providers: [ ApiService, GlobalService ],
bootstrap: [ AppComponent ]
......
......@@ -83,7 +83,6 @@ export class LoginComponent implements OnInit {
.subscribe(
response => {
if (response.status >= 200 && response.status < 400) {
let responseMessage = response.json();
this.globalService.setWalletName(walletLoad.name)
this.globalService.setCoinType(1);
this.router.navigate(['/wallet']);
......
export class TransactionBuilding {
constructor(walletName: string, coinType: number, accountName: string, password: string, destinationAddress: string, amount: string, feeType: string, allowUnconfirmed: boolean) {
this.walletName = walletName;
this.coinType = coinType;
this.accountName = accountName;
this.password = password;
this.destinationAddress = destinationAddress;
this.amount = amount;
this.feeType = feeType;
this.allowUnconfirmed = allowUnconfirmed;
}
walletName: string;
coinType: number;
accountName: string;
password: string;
destinationAddress: string;
amount: string;
feeType: string;
allowUnconfirmed: boolean;
}
export class TransactionSending {
constructor(hex: string) {
this.hex = hex;
}
hex: string;
}
......@@ -5,10 +5,24 @@ import { Pipe, PipeTransform } from '@angular/core';
})
export class CoinNotationPipe implements PipeTransform {
private coinUnit = "BTC";
private coinNotation: number;
transform(value: any): any {
if (!value) return value;
let coinNotation = Number(value).toFixed(8);
return coinNotation;
this.coinNotation = value;
switch (this.coinUnit) {
case "BTC":
this.coinNotation = Number(value.toFixed(8));
return this.coinNotation = this.coinNotation / 100000000;
case "mBTC":
this.coinNotation = Number(value.toFixed(8));
return this.coinNotation = this.coinNotation / 100000;
case "uBTC":
this.coinNotation = Number(value.toFixed(8));
return this.coinNotation = this.coinNotation / 100;
}
}
}
......@@ -9,6 +9,8 @@ import { WalletRecovery } from '../classes/wallet-recovery';
import { WalletLoad } from '../classes/wallet-load';
import { WalletInfo } from '../classes/wallet-info';
import { Mnemonic } from '../classes/mnemonic';
import { TransactionBuilding } from '../classes/transaction-building';
import { TransactionSending } from '../classes/transaction-sending';
/**
* For information on the API specification have a look at our Github:
......@@ -106,4 +108,16 @@ export class ApiService {
.get(this.webApiUrl + '/wallet/address', new RequestOptions({headers: this.headers, search: params}))
.map((response: Response) => response);
}
buildTransaction(data: TransactionBuilding): Observable<any> {
return this.http
.post(this.webApiUrl + '/wallet/build-transaction/', JSON.stringify(data), {headers: this.headers})
.map((response: Response) => response);
}
sendTransaction(data: TransactionSending): Observable<any> {
return this.http
.post(this.webApiUrl + '/wallet/send-transaction/', JSON.stringify(data), {headers: this.headers})
.map((response: Response) => response);
}
}
......@@ -15,7 +15,7 @@
</div>
</div>
</div>
<div class="row">
<div class="row" id="transactions">
<div class="col">
<div>Transactions</div>
<table *ngIf="transactions; else noTransactions">
......@@ -29,7 +29,7 @@
<!--<td *ngIf="{{ transaction.amount }} < 0">SENT</td>
<td *ngIf="{{ transaction.amount }} > 0">RECEIVED</td>-->
<td *ngIf="i<5">{{ transaction.timestamp }}</td>
<td *ngIf="i<5">{{ transaction.amount }}</td>
<td *ngIf="i<5">{{ transaction.amount | coinNotation | coinAbbreviation }}</td>
<td *ngIf="i<5">{{ transaction.confirmed }}</td>
<td *ngIf="i<5">{{ transaction.txId }}</td>
</tr>
......
import { Component, OnInit } from '@angular/core';
import { Component, OnInit, Input } from '@angular/core';
import {NgbModal, NgbActiveModal} from '@ng-bootstrap/ng-bootstrap';
import { ApiService } from '../../shared/services/api.service';
import { GlobalService } from '../../shared/services/global.service';
import { WalletInfo } from '../../shared/classes/wallet-info';
import { SendComponent } from '../send/send.component';
import { ReceiveComponent } from '../receive/receive.component';
@Component({
selector: 'dashboard-component',
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.css'],
styleUrls: ['./dashboard.component.css']
})
export class DashboardComponent {
constructor(private apiService: ApiService, private globalService: GlobalService) {}
constructor(private apiService: ApiService, private globalService: GlobalService, private modalService: NgbModal) {}
private balanceResponse: any;
private confirmedBalance: number;
......@@ -24,11 +29,11 @@ export class DashboardComponent {
};
private openSendDialog() {
const modalRef = this.modalService.open(SendComponent);
};
private openReceiveDialog() {
const modalRef = this.modalService.open(ReceiveComponent);
};
private getWalletBalance() {
......
......@@ -10,7 +10,7 @@
<!--<td *ngIf="{{ transaction.amount }} < 0; else received">SENT</td>
<td #received>RECEIVED</td>-->
<td>{{ transaction.timestamp }}</td>
<td>{{ transaction.amount }}</td>
<td>{{ transaction.amount | coinNotation | coinAbbreviation }}</td>
<td>{{ transaction.confirmed }}</td>
<td>{{ transaction.txId }}</td>
</tr>
......
......@@ -2,8 +2,6 @@
<div class="container">
<ul class="navbar-nav mr-auto" routerLinkActive="active">
<li class="nav-item"><a class="nav-link" routerLink="dashboard">Dashboard</a></li>
<li class="nav-item"><a class="nav-link" routerLink="send">Send</a></li>
<li class="nav-item"><a class="nav-link" routerLink="receive">Receive</a></li>
<li class="nav-item"><a class="nav-link" routerLink="history">History</a></li>
<li class="nav-item"><a class="nav-link" (click)="logOut()">Logout</a></li>
</ul>
......
<div class="content-wrapper">
<div class="content-wrapper" id="receiveForm">
<h1>Receive</h1>
<div>
<div>
......@@ -10,6 +10,7 @@
<td>{{ address }}</td>
</tr>
</table>
<button type="button" class="btn" (click)="activeModal.close('Close click')">Close</button>
</div>
</div>
</div>
......@@ -5,6 +5,8 @@ import { GlobalService } from '../../shared/services/global.service';
import { WalletInfo } from '../../shared/classes/wallet-info';
import {NgbModal, NgbActiveModal} from '@ng-bootstrap/ng-bootstrap';
@Component({
selector: 'receive-component',
templateUrl: './receive.component.html',
......@@ -12,7 +14,7 @@ import { WalletInfo } from '../../shared/classes/wallet-info';
})
export class ReceiveComponent {
constructor(private apiService: ApiService, private globalService: GlobalService) {}
constructor(private apiService: ApiService, private globalService: GlobalService, public activeModal: NgbActiveModal) {}
private address: any;
private errorMessage: string;
......
<div class="content-wrapper">
<div class="content-wrapper" id="sendForm">
<h1>Send</h1>
<form (ngSubmit)="onSubmit()" #sendForm="ngForm">
<form [formGroup]="sendForm" (ngSubmit)="send()">
<div class="form-group">
<label for="toAddress">Pay To: </label>
<input type="text" class="form-control" id="name" required name="toAddress">
<label>Pay To: </label>
<input class="form-control" formControlName="address" type="text" placeholder="Please enter the recipients address.">
<div *ngIf="formErrors.address" class="alert alert-danger">{{formErrors.address}}</div>
</div>
<div class="form-group">
<label for="amount">Amount</label>
<input type="text" class="form-control" id="amount" required name="amount">
<label>Amount</label>
<input class="form-control" formControlName="amount" type="text" placeholder="Please enter the amount you want to send.">
<div *ngIf="formErrors.amount" class="alert alert-danger">{{formErrors.amount}}</div>
</div>
<button type="submit" class="btn btn-success">Submit</button>
<button type="submit" [disabled]="!sendForm.valid" class="btn btn-success">Send</button>
<button type="button" class="btn" (click)="activeModal.close('Close click')">Close</button>
</form>
</div>
import { Component } from '@angular/core';
import { ApiService } from '../../shared/services/api.service';
import { GlobalService } from '../../shared/services/global.service';
import { FormGroup, FormControl, Validators, FormBuilder } from '@angular/forms';
import {NgbModal, NgbActiveModal} from '@ng-bootstrap/ng-bootstrap';
import { TransactionBuilding } from '../../shared/classes/transaction-building';
import { TransactionSending } from '../../shared/classes/transaction-sending';
@Component({
selector: 'send-component',
......@@ -8,6 +15,104 @@ import { ApiService } from '../../shared/services/api.service';
})
export class SendComponent {
constructor(private apiService: ApiService) {}
constructor(private apiService: ApiService, private globalService: GlobalService, public activeModal: NgbActiveModal, private fb: FormBuilder) {
this.buildSendForm();
}
private sendForm: FormGroup;
private responseMessage: any;
private errorMessage: string;
private buildSendForm(): void {
this.sendForm = this.fb.group({
"address": ["", Validators.required],
"amount": ["", Validators.required]
});
this.sendForm.valueChanges
.subscribe(data => this.onValueChanged(data));
this.onValueChanged();
}
onValueChanged(data?: any) {
if (!this.sendForm) { return; }
const form = this.sendForm;
for (const field in this.formErrors) {
this.formErrors[field] = '';
const control = form.get(field);
if (control && control.dirty && !control.valid) {
const messages = this.validationMessages[field];
for (const key in control.errors) {
this.formErrors[field] += messages[key] + ' ';
}
}
}
}
formErrors = {
'address': '',
'amount': ''
};
validationMessages = {
'address': {
'required': 'An address is required.'
},
'amount': {
'required': 'An amount is required.'
}
};
private send() {
let transaction = new TransactionBuilding(
this.globalService.getWalletName(),
this.globalService.getCoinType(),
"account 0",
"123",
this.sendForm.get("address").value,
this.sendForm.get("amount").value,
"medium",
true
);
this.apiService
.buildTransaction(transaction)
.subscribe(
response => {
if (response.status >= 200 && response.status < 400){
this.responseMessage = response.json();
console.log(this.responseMessage);
}
},
error => {
if (error.status >= 400) {
this.errorMessage = error;
console.log(this.errorMessage);
}
},
() => this.sendTransaction(this.responseMessage.hex)
);
};
private sendTransaction(hex: string) {
let transaction = new TransactionSending(hex);
this.apiService
.sendTransaction(transaction)
.subscribe(
response => {
if (response.status >= 200 && response.status < 400){
console.log(response.status);
this.activeModal.close("Close clicked");
}
},
error => {
if (error.status >= 400) {
this.errorMessage = error;
console.log(this.errorMessage);
}
}
);
}
}
......@@ -13,8 +13,6 @@ const routes: Routes = [
children: [
{ path: '', redirectTo:'dashboard', pathMatch:'full' },
{ path: 'dashboard', component: DashboardComponent},
{ path: 'send', component: SendComponent},
{ path: 'receive', component: ReceiveComponent},
{ path: 'history', component: HistoryComponent}
]
},
......
......@@ -5,8 +5,6 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { WalletComponent } from './wallet.component';
import { MenuComponent } from './menu/menu.component';
import { DashboardComponent } from './dashboard/dashboard.component';
import { SendComponent } from './send/send.component';
import { ReceiveComponent } from './receive/receive.component';
import { HistoryComponent } from './history/history.component';
import {SharedModule} from '../shared/shared.module';
......@@ -24,8 +22,6 @@ import { WalletRoutingModule } from './wallet-routing.module';
WalletComponent,
MenuComponent,
DashboardComponent,
ReceiveComponent,
SendComponent,
HistoryComponent
],
exports: []
......
......@@ -4,6 +4,11 @@
font-family: "Lato";
}
/* Temporary min td with */
td {
min-width: 150px;
}
.content-wrapper {
width: 100%;
height: 100%;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment