diff --git a/embark-ui/src/components/Layout.js b/embark-ui/src/components/Layout.js index 39d929c4..25c2a392 100644 --- a/embark-ui/src/components/Layout.js +++ b/embark-ui/src/components/Layout.js @@ -39,7 +39,8 @@ const sidebarNavItems = {items: [ {url: "/embark/utilities/converter", icon: "fa fa-plug", name: "Converter"}, {url: "/embark/utilities/communication", icon: "fa fa-phone", name: "Communication"}, {url: "/embark/utilities/ens", icon: "fa fa-circle", name: "ENS"}, - {url: "/embark/utilities/sign-and-verify", icon: "fa fa-edit", name: "Sign & Verify"} + {url: "/embark/utilities/sign-and-verify", icon: "fa fa-edit", name: "Sign & Verify"}, + {url: "/embark/utilities/transaction-decoder", icon: "fa fa-edit", name: "Transaction Decoder"} ]} ]}; diff --git a/embark-ui/src/components/TransactionDecoder.js b/embark-ui/src/components/TransactionDecoder.js new file mode 100644 index 00000000..61e112ea --- /dev/null +++ b/embark-ui/src/components/TransactionDecoder.js @@ -0,0 +1,68 @@ +import React from 'react'; +import {withRouter} from 'react-router-dom'; +import { + Card, + CardHeader, + CardBody, + Form, + FormGroup, + Input, + InputGroup, + InputGroupAddon, + Button, + Alert +} from 'reactstrap'; +import ReactJson from 'react-json-view'; + +class TransactionDecoder extends React.Component { + + constructor(props) { + super(props); + this.state = { + transactionHash: this.props.transactionHash || '' + }; + } + + handleTransactionHashChange(event) { + const transactionHash = event.target.value; + this.setState({transactionHash}); + } + + fetchTransaction(e) { + e.preventDefault(); + if (this.state.transactionHash !== '') { + this.props.history.push({ + search: `hash=${this.state.transactionHash}` + }); + } + } + + render() { + return ( + + + Transaction Decoder + + + this.fetchTransaction(e)}> + + + this.handleTransactionHashChange(e)}/> + + Decode + + + + + {this.props.transactionHash && !this.props.transaction && Couldn't find transaction for hash {this.props.transactionHash}} + + + {this.props.transaction && } + + + + ); + } +} + +export default withRouter(TransactionDecoder); diff --git a/embark-ui/src/components/UtilsLayout.js b/embark-ui/src/components/UtilsLayout.js index bd09c607..dbca42ce 100644 --- a/embark-ui/src/components/UtilsLayout.js +++ b/embark-ui/src/components/UtilsLayout.js @@ -5,6 +5,7 @@ import ConverterContainer from '../containers/ConverterContainer'; import CommunicationContainer from '../containers/CommunicationContainer'; import EnsContainer from '../containers/EnsContainer'; import SignAndVerifyContainer from '../containers/SignAndVerifyContainer'; +import TransactionDecoderContainer from '../containers/TransactionDecoderContainer'; const UtilsLayout = () => ( @@ -12,6 +13,7 @@ const UtilsLayout = () => ( + ); diff --git a/embark-ui/src/containers/TransactionDecoderContainer.js b/embark-ui/src/containers/TransactionDecoderContainer.js new file mode 100644 index 00000000..d4e083ba --- /dev/null +++ b/embark-ui/src/containers/TransactionDecoderContainer.js @@ -0,0 +1,58 @@ +import React, { Component } from 'react'; +import { connect } from 'react-redux'; +import qs from 'qs'; +import {withRouter} from 'react-router-dom'; +import TransactionDecoder from '../components/TransactionDecoder'; +import { Row, Col } from 'reactstrap'; +import { transaction as transactionAction } from '../actions'; +import {getTransaction} from "../reducers/selectors"; + +const getQueryParams = (props) => { + return qs.parse(props.location.search, { + ignoreQueryPrefix: true + }); +} + +class TransactionDecoderContainer extends Component { + + componentDidMount() { + const { hash } = getQueryParams(this.props); + if (hash) { + this.props.fetchTransaction(hash); + } + } + + componentDidUpdate(prevProps) { + const hash = getQueryParams(this.props).hash; + const prevHash = getQueryParams(prevProps).hash; + + if (hash && hash !== prevHash) { + this.props.fetchTransaction(hash); + } + } + + render() { + return ( + + + + + + ); + } +} + +function mapStateToProps(state, props) { + return { + transaction: getTransaction(state, getQueryParams(props).hash), + error: state.errorMessage, + loading: state.loading + }; +} +export default withRouter(connect( + mapStateToProps, + { + fetchTransaction: transactionAction.request + } +)(TransactionDecoderContainer));