diff --git a/app/components/Delegation.css b/app/components/Delegation.css new file mode 100644 index 0000000..e69de29 diff --git a/app/components/DelegationChain.jsx b/app/components/DelegationChain.jsx new file mode 100644 index 0000000..447f2d8 --- /dev/null +++ b/app/components/DelegationChain.jsx @@ -0,0 +1,63 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import { emphasize } from '@material-ui/core/styles/colorManipulator'; +import Breadcrumbs from '@material-ui/lab/Breadcrumbs'; +import EthAddress from './EthAddress'; + +const styles = theme => ({ + root: { + padding: theme.spacing.unit, + }, + chip: { + backgroundColor: theme.palette.grey[100], + height: 24, + color: theme.palette.grey[800], + fontWeight: theme.typography.fontWeightRegular, + '&:hover, &:focus': { + backgroundColor: theme.palette.grey[300], + }, + '&:active': { + boxShadow: theme.shadows[1], + backgroundColor: emphasize(theme.palette.grey[300], 0.12), + }, + }, + avatar: { + background: 'none', + marginRight: -theme.spacing.unit * 1.5, + }, +}); + +function CustomBreadcrumb(props) { + const { classes, ...rest } = props; + return ; +} + +CustomBreadcrumb.propTypes = { + classes: PropTypes.object.isRequired, +}; + +const StyledBreadcrumb = withStyles(styles)(CustomBreadcrumb); + +function DelegationChain(props) { + const { classes, delegation } = props; + + return ( + + {delegation.map((value) => { + + })} + + ); +} + +DelegationChain.propTypes = { + classes: PropTypes.object.isRequired, + delegation: PropTypes.array.isRequired +}; + +export default withStyles(styles)(DelegationChain); diff --git a/app/components/DelegationFactoryUI.jsx b/app/components/DelegationFactoryUI.jsx new file mode 100644 index 0000000..0857f81 --- /dev/null +++ b/app/components/DelegationFactoryUI.jsx @@ -0,0 +1,89 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import DelegationFactory from 'Embark/contracts/DelegationFactory'; +import EthAddress from './EthAddress'; +import { FormLabel, Paper, Grid } from '@material-ui/core'; +import TransactionSendButton from './TransactionSendButton'; + +const styles = theme => ({ + root: { + display: 'flex', + } +}); + +const zeroIfNull = (address) => { + return address ? address : "0x0000000000000000000000000000000000000000" +} + +const sendTransaction = (parent, controller, defaultDelegate) => { + try { + return (!controller && !defaultDelegate) ? + DelegationFactory.methods.createDelegation(zeroIfNull(parent)) : + DelegationFactory.methods.createDelegation( + zeroIfNull(parent), + zeroIfNull(controller), + zeroIfNull(defaultDelegate) + ) + } catch(e) { + return null; + } + +} + +class DelegationFactoryUI extends React.Component { + + constructor(props) { + super(props); + this.state = { + parent: null, + controller: null, + defaultDelegate: null + }; + } + + render() { + const { classes, account } = this.props; + const { parent, controller, defaultDelegate } = this.state; + const tx = sendTransaction(parent,controller,defaultDelegate); + return ( + + + + Parent Delegation + this.setState({parent})} /> + + + Controller + this.setState({controller})} /> + + + Default Delegate + this.setState({defaultDelegate})} /> + + + + {console.log("txHash",txHash)}} + onResult={(result) => {console.log("result",result)}} + onReceipt={(receipt) => {console.log("receipt",receipt)}} + onError={(error) => {console.log("error",error)}} + /> + + + + + + + ); + } +} + +DelegationFactoryUI.propTypes = { + classes: PropTypes.object.isRequired +}; + +export default withStyles(styles)(DelegationFactoryUI); diff --git a/app/components/Delegation.jsx b/app/components/DelegationUI.jsx similarity index 58% rename from app/components/Delegation.jsx rename to app/components/DelegationUI.jsx index a4f3bed..eb77d31 100644 --- a/app/components/Delegation.jsx +++ b/app/components/DelegationUI.jsx @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import EthAddress from './EthAddress'; import Breadcrumbs from '@material-ui/lab/Breadcrumbs'; -class Delegation extends React.Component { +class DelegationUI extends React.Component { static propTypes = { className: PropTypes.string, Delegation: PropTypes.object.isRequired, @@ -17,33 +17,45 @@ class Delegation extends React.Component { constructor(props) { super(props); this.state = { - delegation = [], - editDelegate = null, - editDelegation = [], + delegation: [], + delegateChain: [], + editDelegate: null, + editDelegation: [], }; } componentDidMount() { - this.delegationOf(this.props.account); + this.delegateChainOf(this.props.account); } - delegationOf(delegate) { - const delegation = this.state.delegation; - if(!delegation.includes(delegate)){ - delegation.push(delegate); - this.setState({delegation}); + delegation() { + const delegateChain = this.state.delegateChain; + if(!delegateChain.includes(delegate)){ + delegateChain.push(delegate); + this.setState({delegateChain}); this.props.Delegation.methods.delegatedTo(delegate).then((delegatedTo) => { - this.delegationOf(delegatedTo); + this.delegateChainOf(delegatedTo); + }); + } + } + + delegateChainOf(delegate) { + const delegateChain = this.state.delegateChain; + if(!delegateChain.includes(delegate)){ + delegateChain.push(delegate); + this.setState({delegateChain}); + this.props.Delegation.methods.delegatedTo(delegate).then((delegatedTo) => { + this.delegateChainOf(delegatedTo); }); } } editDelegationOf(delegate) { - const delegation = this.state.editDelegation; - if(!delegation.includes(delegate)){ + const delegateChain = this.state.editDelegation; + if(!delegateChain.includes(delegate)){ editDelegation.push(delegate); this.setState({editDelegation}); this.props.Delegation.methods.delegatedTo(delegate).then((delegatedTo) => { @@ -59,31 +71,30 @@ class Delegation extends React.Component { Delegation, className, } = this.props; - const { delegation, editDelegate } = this.state; + const { delegateChain, editDelegate } = this.state; return (
-

Delegation Address:

+

Delegation:

- -
- Current delegation: + Delegate Chain: { - delegation.map((value) => { + delegateChain.map((value) => { return }) }
-

Set Delegate:

- { +

Delegate Set

+ { this.setState({editDelegate}); - if(editDelegate != delegation[0]) { + if(editDelegate != delegateChain[0]) { + this.setState({editDelegation : []}); this.editDelegationOf(editDelegate); } }} /> @@ -98,10 +109,11 @@ class Delegation extends React.Component { }
+
) } } -export default Delegation; +export default DelegationUI; diff --git a/app/components/TransactionSendButton.jsx b/app/components/TransactionSendButton.jsx new file mode 100644 index 0000000..f91cfdb --- /dev/null +++ b/app/components/TransactionSendButton.jsx @@ -0,0 +1,91 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { Button, CircularProgress } from '@material-ui/core'; + +class TransactionSendButton extends React.Component { + constructor(props) { + super(props); + this.state = { + txWaiting: false + }; + } + + static propTypes = { + sendTransaction: PropTypes.object.isRequired, + onSend: PropTypes.func, + onReceipt: PropTypes.func, + onResult: PropTypes.func, + onError: PropTypes.func, + account: PropTypes.string, + text: PropTypes.any, + icon: PropTypes.any, + size: PropTypes.string, + variant: PropTypes.string, + disabled: PropTypes.bool + } + + static defaultProps = { + account: null, + className: 'tx-send', + variant: 'text', + size: 'small', + icon: (
), + text: ('Send Transaction'), + onSend: () => {}, + onResult: () => {}, + onReceipt: () => {}, + onError: () => {}, + disabled: false + } + + submitTransaction(e) { + e.preventDefault(); + const { sendTransaction, account, onSend, onReceipt, onResult, onError } = this.props; + try{ + sendTransaction.estimateGas({ from: account }).then((estimatedGas) => { + this.setState({ txWaiting: true }); + sendTransaction.send({ + from: account, + gasLimit: estimatedGas + }).once('transactionHash', (txHash) => { + onSend(txHash); + }).once('receipt', (receipt) =>{ + onReceipt(receipt); + }).then((result) => { + onResult(result); + }).catch((error) => { + onError(error); + }).finally(() => { + this.setState({ txWaiting: false }); + }); + }).catch((error) => { + onError(error); + }); + } catch(error) { + onError(error); + } + + } + + render() { + const { txWaiting } = this.state; + const { size, variant, account, text, icon, disabled, className } = this.props; + return ( + + ) + } +} + +export default TransactionSendButton; \ No newline at end of file diff --git a/app/dapp.js b/app/dapp.js index 972f9e4..3e67b49 100644 --- a/app/dapp.js +++ b/app/dapp.js @@ -5,18 +5,20 @@ import Delegation from 'Embark/contracts/Delegation'; import { HashRouter, Route, Redirect, Link } from "react-router-dom"; import './dapp.css'; -import Delegation from './components/Delegation'; +import DelegationUI from './components/DelegationUI'; +import DelegationFactoryUI from './components/DelegationFactoryUI'; +import { CssBaseline, AppBar, Toolbar, Typography } from '@material-ui/core'; class App extends React.Component { constructor(props) { super(props); - this.handleSelect = this.handleSelect.bind(this); + //this.handleSelect = this.handleSelect.bind(this); this.state = { error: null, - account: null + defaultAccount: null }; } @@ -25,13 +27,13 @@ class App extends React.Component { if (err) { return this.setState({ error: err.message || err }); } - this.setState({ account: web3.eth.defaultAccount, blockchainEnabled: true }) + this.setState({ defaultAccount: web3.eth.defaultAccount, blockchainEnabled: true }) }); } render() { - const { blockchainEnabled, account } = this.state; + const { blockchainEnabled, defaultAccount } = this.state; if (!blockchainEnabled) { return (
Waiting for blockchain.
@@ -45,8 +47,19 @@ class App extends React.Component { } return ( - ( - + + + + + Topic Democracy + + + + ( + + )} /> + ( + )} /> ) diff --git a/package.json b/package.json index 2276a7b..4eebe25 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ }, "dependencies": { "@material-ui/core": "^3.9.3", - "@material-ui/icons": "^3.0.2" + "@material-ui/icons": "^3.0.2", + "@material-ui/lab": "^3.0.0-alpha.30" } }