finalize Dapp

This commit is contained in:
Roman Storm 2017-12-13 16:39:17 -08:00
parent 4c182341ca
commit e10d79c852
8 changed files with 201 additions and 128 deletions

View File

@ -28,7 +28,8 @@ export default class AllValidators extends Component {
);
})
let validators = [];
filtered.forEach((validator, index) => {
let confirmations = [];
for(let [index, validator] of filtered.entries()) {
let childrenWithProps = React.Children.map(this.props.children, (child) => {
return React.cloneElement(child, { miningkey: validator.address });
})
@ -45,8 +46,11 @@ export default class AllValidators extends Component {
expirationDate={validator.expirationDate}
createdDate={validator.createdDate}
updatedDate={validator.updatedDate}
metadataContract={this.props.web3Config.metadataContract}
methodToCall={this.props.methodToCall}
>{childrenWithProps}</Validator>)
})
}
return (<div className="container">
{validators}
</div>)

View File

@ -1,104 +1,127 @@
import React, {Component, Children} from 'react';
const Validator = ({
address,
firstName,
lastName,
fullAddress,
us_state,
postal_code,
licenseId,
expirationDate,
createdDate,
updatedDate,
children
}) => (
<div className="validators-i">
<div className="validators-header">
<div className="left">
{address}
</div>
<div className="right">
{children}
</div>
</div>
<div className="validators-body">
<div className="validators-notary left">
<p className="validators-title">Notary</p>
<div className="validators-table">
<div className="validators-table-tr">
<p className="validators-table-td left">
Full Name
</p>
<p className="validators-table-td right">
{firstName} {lastName}
</p>
class Validator extends Component {
constructor(props) {
super(props);
this.state = {
confirmation: null
}
this.props.metadataContract.getConfirmations({miningKey: this.props.address}).then((confirmation) => {
this.setState({confirmation})
})
}
render(){
let {
address,
firstName,
lastName,
fullAddress,
us_state,
postal_code,
licenseId,
expirationDate,
createdDate,
updatedDate,
children,
} = this.props;
let confirmations = this.props.methodToCall === 'getAllValidatorsData' ? '' : <div className="confirmations">
<div>{this.state.confirmation} confirmations</div>
</div>
return(
<div className="validators-i">
<div className="validators-header">
<div className="left">
<div>
{address}
</div>
{confirmations}
</div>
<div className="validators-table-tr">
<p className="validators-table-td left">
Address
</p>
<p className="validators-table-td right">
{fullAddress}
</p>
<div>
</div>
<div className="validators-table-tr">
<p className="validators-table-td left">
State
</p>
<p className="validators-table-td right">
{us_state}
</p>
<div className="right">
{children}
</div>
<div className="validators-table-tr">
<p className="validators-table-td left">
Zip Code
</p>
<p className="validators-table-td right">
{postal_code}
</p>
</div>
<div className="validators-body">
<div className="validators-notary left">
<p className="validators-title">Notary</p>
<div className="validators-table">
<div className="validators-table-tr">
<p className="validators-table-td left">
Full Name
</p>
<p className="validators-table-td right">
{firstName} {lastName}
</p>
</div>
<div className="validators-table-tr">
<p className="validators-table-td left">
Address
</p>
<p className="validators-table-td right">
{fullAddress}
</p>
</div>
<div className="validators-table-tr">
<p className="validators-table-td left">
State
</p>
<p className="validators-table-td right">
{us_state}
</p>
</div>
<div className="validators-table-tr">
<p className="validators-table-td left">
Zip Code
</p>
<p className="validators-table-td right">
{postal_code}
</p>
</div>
</div>
</div>
<div className="validators-license right">
<p className="validators-title">Notary license</p>
<div className="validators-table">
<div className="validators-table-tr">
<p className="validators-table-td left">
License ID
</p>
<p className="validators-table-td right">
{licenseId}
</p>
</div>
<div className="validators-table-tr">
<p className="validators-table-td left">
License Expiration
</p>
<p className="validators-table-td right">
{expirationDate}
</p>
</div>
<div className="validators-table-tr">
<p className="validators-table-td left">
Miner Creation Date
</p>
<p className="validators-table-td right">
{createdDate}
</p>
</div>
<div className="validators-table-tr">
<p className="validators-table-td left">
Pending Change Requested Date
</p>
<p className="validators-table-td right">
{updatedDate}
</p>
</div>
</div>
</div>
</div>
</div>
<div className="validators-license right">
<p className="validators-title">Notary license</p>
<div className="validators-table">
<div className="validators-table-tr">
<p className="validators-table-td left">
License ID
</p>
<p className="validators-table-td right">
{licenseId}
</p>
</div>
<div className="validators-table-tr">
<p className="validators-table-td left">
License Expiration
</p>
<p className="validators-table-td right">
{expirationDate}
</p>
</div>
<div className="validators-table-tr">
<p className="validators-table-td left">
Miner Creation Date
</p>
<p className="validators-table-td right">
{createdDate}
</p>
</div>
<div className="validators-table-tr">
<p className="validators-table-td left">
Pending Change Requested Date
</p>
<p className="validators-table-td right">
{updatedDate}
</p>
</div>
</div>
</div>
</div>
</div>
)
)
}
}
export default Validator;

View File

@ -114,7 +114,9 @@ export default class Metadata {
for (let key of miningKeys) {
let pendingChange = await this.getPendingChange({miningKey: key})
pendingChange.address = key;
pendingChanges.push(pendingChange)
if(pendingChange.postal_code > 0){
pendingChanges.push(pendingChange)
}
}
return pendingChanges
}
@ -125,5 +127,18 @@ export default class Metadata {
//
return await this.metadataInstance.methods.confirmPendingChange(miningKeyToConfirm).send({from: senderVotingKey});
}
async getConfirmations({miningKey}) {
return await this.metadataInstance.methods.confirmations(miningKey).call();
}
async getMinThreshold({miningKey}) {
let validatorData = await this.metadataInstance.methods.validators(miningKey).call();
return validatorData.minThreshold;
}
async finalize({miningKeyToConfirm, senderVotingKey}) {
return await this.metadataInstance.methods.finalize(miningKeyToConfirm).send({from: senderVotingKey});
}
}

View File

@ -36,7 +36,7 @@ class AppMainRouter extends Component {
this.onPendingChangesRender = this.onPendingChangesRender.bind(this);
this.onAllValidatorsRender = this.onAllValidatorsRender.bind(this)
this.onConfirmPendingChange = this.onConfirmPendingChange.bind(this);
this.onSubmit = this.onSubmit.bind(this);
this.onFinalize = this.onFinalize.bind(this);
this.onSearch = this.onSearch.bind(this);
this.state = {
showSearch: true,
@ -72,34 +72,30 @@ class AppMainRouter extends Component {
})
}
onRouteChange(){
const rootPath = this.rootPath + "/";
if(history.location.pathname !== rootPath){
const setMetadata = this.rootPath + "/set";
if(history.location.pathname === setMetadata){
this.setState({showSearch: false})
} else {
this.setState({showSearch: true})
}
}
onSubmit(e){
e.preventDefault();
switch (history.location.pathname) {
case "/":
console.log('main')
break;
}
}
onSetRender() {
return this.state.votingKey ? <App web3Config={this.state}/> : '';
}
async onConfirmPendingChange(e) {
e.preventDefault();
const miningKey = e.currentTarget.getAttribute('miningkey');
async _onBtnClick({event, methodToCall, successMsg}){
event.preventDefault();
this.setState({loading: true})
const miningKey = event.currentTarget.getAttribute('miningkey');
try{
let result = await this.state.metadataContract.confirmPendingChange({
let result = await this.state.metadataContract[methodToCall]({
miningKeyToConfirm: miningKey,
senderVotingKey: this.state.votingKey
});
console.log(result);
this.setState({loading: false})
swal("Congratulations!", successMsg, "success");
} catch(error) {
this.setState({loading: false})
console.error(error.message);
swal({
icon: 'error',
@ -108,22 +104,37 @@ class AppMainRouter extends Component {
});
}
}
async onConfirmPendingChange(event) {
await this._onBtnClick({
event,
methodToCall: 'confirmPendingChange',
successMsg: 'You have successfully confirmed the change!'
});
}
async onFinalize(event){
await this._onBtnClick({
event,
methodToCall: 'finalize',
successMsg: 'You have successfully finalized the change!'
});
}
onPendingChangesRender() {
return this.state.votingKey ? <AllValidators
methodToCall="getAllPendingChanges"
searchTerm={this.state.searchTerm}
web3Config={this.state}>
<button onClick={this.onConfirmPendingChange} className="create-keys-button right">Confirm</button>
<button onClick={this.onFinalize} className="create-keys-button finalize">Finalize</button>
<button onClick={this.onConfirmPendingChange} className="create-keys-button">Confirm</button>
</AllValidators> : '';
}
onAllValidatorsRender() {
return this.state.votingKey ? <AllValidators searchTerm={this.state.searchTerm} methodToCall="getAllValidatorsData" web3Config={this.state} /> : '';
}
onSearch(term){
this.setState({searchTerm: term.target.value})
this.setState({searchTerm: term.target.value.toLowerCase()})
}
render(){
console.log('v2.02', this.rootPath)
console.log('v2.03')
const search = this.state.showSearch ? <input type="search" className="search-input" onChange={this.onSearch}/> : ''
const loading = this.state.loading ? <Loading /> : ''
return (
@ -131,18 +142,16 @@ class AppMainRouter extends Component {
<section className="content">
{loading}
<div className="search">
<div className="container">
<div className="container flex-container">
<div className="nav">
<NavLink className="nav-i" exact activeClassName="nav-i_active" to={`${this.rootPath}/`}>All</NavLink>
<NavLink className="nav-i" activeClassName="nav-i_active" to={`${this.rootPath}/set`}>Set metadata</NavLink>
<NavLink className="nav-i" activeClassName="nav-i_active" to={`${this.rootPath}/pending-changes`}>Pending changes</NavLink>
</div>
<form action="" className="search-form" onSubmit={this.onSubmit}>
{search}
</form>
{search}
</div>
</div>
<Route exact path={`${this.rootPath}/`} render={this.onAllValidatorsRender} onSubmit={this.onSubmit} web3Config={this.state}/>
<Route exact path={`${this.rootPath}/`} render={this.onAllValidatorsRender} web3Config={this.state}/>
<Route path={`${this.rootPath}/set`} render={this.onSetRender} />
<Route path={`${this.rootPath}/pending-changes`} render={this.onPendingChangesRender} />
</section>

View File

@ -36,6 +36,12 @@ body {
margin: 0 auto;
}
.flex-container {
display: flex;
justify-content: space-between;
align-items: center;
}
.content {
display: table-cell;
vertical-align: top;

View File

@ -86,6 +86,11 @@ body {
max-width: 960px;
margin: 0 auto; }
.flex-container {
display: flex;
justify-content: space-between;
align-items: center; }
.content {
display: table-cell;
vertical-align: top;
@ -350,6 +355,10 @@ button:focus {
border: 1px solid #eee;
background-color: #fff;
color: #333; }
.validators-i .confirmations {
font-weight: normal;
font-size: 12px;
padding-top: 5px; }
.validators-header {
border-bottom: 1px solid #eee;
padding: 25px 20px;
@ -360,8 +369,8 @@ button:focus {
align-items: center; }
.validators-header .left {
flex: 1; }
.validators-header .right {
flex: 0; }
.validators-header .finalize {
margin-right: 20px; }
.validators-body {
overflow: hidden;
padding: 0 20px 20px; }
@ -438,7 +447,7 @@ button:focus {
z-index: 1;
right: 0;
top: 50%;
width: 40px;
width: 80px;
height: 40px;
margin: -20px 0 0;
outline: none;

View File

@ -35,7 +35,7 @@
z-index: 1;
right: 0;
top: 50%;
width: 40px;
width: 80px;
height: 40px;
margin: -20px 0 0;
outline: none;

View File

@ -7,6 +7,12 @@
border: 1px solid #eee;
background-color: #fff;
color: #333;
.confirmations {
font-weight: normal;
font-size: 12px;
padding-top: 5px;
}
}
&-header {
@ -21,9 +27,10 @@
.left {
flex: 1;
}
.right {
flex: 0;
.finalize {
margin-right: 20px;
}
}
&-body {