mirror of
https://github.com/status-im/topic-democracy.git
synced 2025-02-25 00:28:19 +00:00
add material components
This commit is contained in:
parent
a0e7b8f010
commit
a87ef5e518
0
app/components/Delegation.css
Normal file
0
app/components/Delegation.css
Normal file
63
app/components/DelegationChain.jsx
Normal file
63
app/components/DelegationChain.jsx
Normal file
@ -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 <EthAddress {...rest} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomBreadcrumb.propTypes = {
|
||||||
|
classes: PropTypes.object.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
|
const StyledBreadcrumb = withStyles(styles)(CustomBreadcrumb);
|
||||||
|
|
||||||
|
function DelegationChain(props) {
|
||||||
|
const { classes, delegation } = props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Breadcrumbs arial-label="Breadcrumb" maxItems={5}>
|
||||||
|
{delegation.map((value) => {
|
||||||
|
<StyledBreadcrumb
|
||||||
|
href="#"
|
||||||
|
value={value}
|
||||||
|
blockyScale={3}
|
||||||
|
/>
|
||||||
|
})}
|
||||||
|
</Breadcrumbs>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
DelegationChain.propTypes = {
|
||||||
|
classes: PropTypes.object.isRequired,
|
||||||
|
delegation: PropTypes.array.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
export default withStyles(styles)(DelegationChain);
|
89
app/components/DelegationFactoryUI.jsx
Normal file
89
app/components/DelegationFactoryUI.jsx
Normal file
@ -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 (
|
||||||
|
<Paper>
|
||||||
|
<Grid container spacing={24}>
|
||||||
|
<Grid item xs={12} sm={6}>
|
||||||
|
<FormLabel component="legend">Parent Delegation</FormLabel>
|
||||||
|
<EthAddress control={true} onChange={(parent) => this.setState({parent})} />
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12} sm={6}>
|
||||||
|
<FormLabel component="legend">Controller</FormLabel>
|
||||||
|
<EthAddress defaultValue={account} control={true} onChange={(controller) => this.setState({controller})} />
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12} sm={6}>
|
||||||
|
<FormLabel component="legend">Default Delegate</FormLabel>
|
||||||
|
<EthAddress control={true} onChange={(defaultDelegate) => this.setState({defaultDelegate})} />
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={12} sm={6}>
|
||||||
|
|
||||||
|
<TransactionSendButton
|
||||||
|
sendTransaction={tx}
|
||||||
|
disabled={!tx}
|
||||||
|
account={account}
|
||||||
|
onSend={(txHash) => {console.log("txHash",txHash)}}
|
||||||
|
onResult={(result) => {console.log("result",result)}}
|
||||||
|
onReceipt={(receipt) => {console.log("receipt",receipt)}}
|
||||||
|
onError={(error) => {console.log("error",error)}}
|
||||||
|
/>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
|
||||||
|
</Paper>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DelegationFactoryUI.propTypes = {
|
||||||
|
classes: PropTypes.object.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
export default withStyles(styles)(DelegationFactoryUI);
|
@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
|
|||||||
import EthAddress from './EthAddress';
|
import EthAddress from './EthAddress';
|
||||||
import Breadcrumbs from '@material-ui/lab/Breadcrumbs';
|
import Breadcrumbs from '@material-ui/lab/Breadcrumbs';
|
||||||
|
|
||||||
class Delegation extends React.Component {
|
class DelegationUI extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
className: PropTypes.string,
|
className: PropTypes.string,
|
||||||
Delegation: PropTypes.object.isRequired,
|
Delegation: PropTypes.object.isRequired,
|
||||||
@ -17,33 +17,45 @@ class Delegation extends React.Component {
|
|||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
delegation = [],
|
delegation: [],
|
||||||
editDelegate = null,
|
delegateChain: [],
|
||||||
editDelegation = [],
|
editDelegate: null,
|
||||||
|
editDelegation: [],
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.delegationOf(this.props.account);
|
this.delegateChainOf(this.props.account);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
delegationOf(delegate) {
|
delegation() {
|
||||||
const delegation = this.state.delegation;
|
const delegateChain = this.state.delegateChain;
|
||||||
if(!delegation.includes(delegate)){
|
if(!delegateChain.includes(delegate)){
|
||||||
delegation.push(delegate);
|
delegateChain.push(delegate);
|
||||||
this.setState({delegation});
|
this.setState({delegateChain});
|
||||||
this.props.Delegation.methods.delegatedTo(delegate).then((delegatedTo) => {
|
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) {
|
editDelegationOf(delegate) {
|
||||||
const delegation = this.state.editDelegation;
|
const delegateChain = this.state.editDelegation;
|
||||||
if(!delegation.includes(delegate)){
|
if(!delegateChain.includes(delegate)){
|
||||||
editDelegation.push(delegate);
|
editDelegation.push(delegate);
|
||||||
this.setState({editDelegation});
|
this.setState({editDelegation});
|
||||||
this.props.Delegation.methods.delegatedTo(delegate).then((delegatedTo) => {
|
this.props.Delegation.methods.delegatedTo(delegate).then((delegatedTo) => {
|
||||||
@ -59,31 +71,30 @@ class Delegation extends React.Component {
|
|||||||
Delegation,
|
Delegation,
|
||||||
className,
|
className,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const { delegation, editDelegate } = this.state;
|
const { delegateChain, editDelegate } = this.state;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={className} >
|
<div className={className} >
|
||||||
<div>
|
<div>
|
||||||
<p>Delegation Address:</p>
|
<p>Delegation:</p>
|
||||||
<EthAddress value={Delegation.options.address} />
|
<EthAddress value={Delegation.options.address} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<small>Current delegation:</small>
|
<small>Delegate Chain:</small>
|
||||||
<Breadcrumbs arial-label="Breadcrumb" maxItems={5}>
|
<Breadcrumbs arial-label="Breadcrumb" maxItems={5}>
|
||||||
{
|
{
|
||||||
delegation.map((value) => {
|
delegateChain.map((value) => {
|
||||||
return <EthAddress value={value} />
|
return <EthAddress value={value} />
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</Breadcrumbs>
|
</Breadcrumbs>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p>Set Delegate:</p>
|
<p>Delegate Set</p>
|
||||||
<EthAddress defaultValue={delegation[0]} control={true} onChange={(editDelegate) => {
|
<EthAddress defaultValue={delegateChain[0]} control={true} onChange={(editDelegate) => {
|
||||||
this.setState({editDelegate});
|
this.setState({editDelegate});
|
||||||
if(editDelegate != delegation[0]) {
|
if(editDelegate != delegateChain[0]) {
|
||||||
|
this.setState({editDelegation : []});
|
||||||
this.editDelegationOf(editDelegate);
|
this.editDelegationOf(editDelegate);
|
||||||
}
|
}
|
||||||
}} />
|
}} />
|
||||||
@ -98,10 +109,11 @@ class Delegation extends React.Component {
|
|||||||
</Breadcrumbs>
|
</Breadcrumbs>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Delegation;
|
export default DelegationUI;
|
91
app/components/TransactionSendButton.jsx
Normal file
91
app/components/TransactionSendButton.jsx
Normal file
@ -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: (<div className='.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 (
|
||||||
|
<Button
|
||||||
|
className={className}
|
||||||
|
type='submit'
|
||||||
|
size={size}
|
||||||
|
variant={variant}
|
||||||
|
disabled={(disabled || txWaiting || !account)}
|
||||||
|
onClick={(e) => this.submitTransaction(e)}>
|
||||||
|
{text}
|
||||||
|
{txWaiting ?
|
||||||
|
<CircularProgress className={classes.progress} />
|
||||||
|
:
|
||||||
|
icon }
|
||||||
|
</Button>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default TransactionSendButton;
|
27
app/dapp.js
27
app/dapp.js
@ -5,18 +5,20 @@ import Delegation from 'Embark/contracts/Delegation';
|
|||||||
import { HashRouter, Route, Redirect, Link } from "react-router-dom";
|
import { HashRouter, Route, Redirect, Link } from "react-router-dom";
|
||||||
|
|
||||||
import './dapp.css';
|
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 {
|
class App extends React.Component {
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.handleSelect = this.handleSelect.bind(this);
|
//this.handleSelect = this.handleSelect.bind(this);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
error: null,
|
error: null,
|
||||||
account: null
|
defaultAccount: null
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,13 +27,13 @@ class App extends React.Component {
|
|||||||
if (err) {
|
if (err) {
|
||||||
return this.setState({ error: err.message || 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() {
|
render() {
|
||||||
const { blockchainEnabled, account } = this.state;
|
const { blockchainEnabled, defaultAccount } = this.state;
|
||||||
if (!blockchainEnabled) {
|
if (!blockchainEnabled) {
|
||||||
return (
|
return (
|
||||||
<div>Waiting for blockchain.</div>
|
<div>Waiting for blockchain.</div>
|
||||||
@ -45,8 +47,19 @@ class App extends React.Component {
|
|||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<HashRouter hashType="noslash">
|
<HashRouter hashType="noslash">
|
||||||
<Route exact path="/:address?" render={(match) => (
|
<CssBaseline />
|
||||||
<Delegation account={account} Delegation={new EmbarkJS.Blockchain.Contract({ abi: Delegation._jsonInterface, address: match.param.address }) } />
|
<AppBar position="absolute" color="default">
|
||||||
|
<Toolbar>
|
||||||
|
<Typography variant="h6" color="inherit" noWrap>
|
||||||
|
Topic Democracy
|
||||||
|
</Typography>
|
||||||
|
</Toolbar>
|
||||||
|
</AppBar>
|
||||||
|
<Route exact path="/" render={(match) => (
|
||||||
|
<DelegationFactoryUI account={defaultAccount} />
|
||||||
|
)} />
|
||||||
|
<Route path="/:address" render={(match) => (
|
||||||
|
<DelegationUI account={defaultAccount} Delegation={new EmbarkJS.Blockchain.Contract({ abi: Delegation._jsonInterface, address: match.param.address }) } />
|
||||||
)} />
|
)} />
|
||||||
</HashRouter>
|
</HashRouter>
|
||||||
)
|
)
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@material-ui/core": "^3.9.3",
|
"@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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user