diff --git a/src/explorer/details.js b/src/explorer/details.js new file mode 100644 index 0000000..983f859 --- /dev/null +++ b/src/explorer/details.js @@ -0,0 +1,127 @@ +import React from 'react' +import PropTypes from 'prop-types' +import { Row, Col, Box, Button } from 'adminlte-2-react' +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' + +let _this +class Details extends React.Component { + constructor (props) { + super(props) + + _this = this + + this.state = { + entry: {}, + entryData: {} + } + } + + render () { + const { entry, entryData } = _this.state + return ( + <> + + + + + +

+ + Details +

+ {entry._id && ( + +

+ IS VALID: + {entry.isValid} +

+

+ APP ID: + {entry.appId || 'none'} +

+

+ CREATE AT: + {new Date(entry.createdAt).toLocaleString()} +

+

+ ID: + {entry._id} +

+

+ HASH: + {entry.hash} +

+

+ TRANSACTION ID : + {entry.key} +

+ {entryData && ( + <> + VALUE : +

+ - Message : {entryData.message} +

+

+ - Signature : {entryData.signature} +

+

+ - Data : {entryData.data} +

+ + )} +
+ )} + + +
+
+ +
+
+ +
+ + ) + } + + componentDidMount () { + _this.handleData() + } + + componentDidUpdate () { + if (_this.props.entry._id !== _this.state.entry._id) { + _this.handleData() + } + } + + handleData () { + try { + const { entry } = _this.props + _this.setState({ + entry, + entryData: entry.value + }) + } catch (err) { + console.warn('Error in handleData()', err) + } + } + + handleClose () { + _this.props.onClose() + } +} +Details.propTypes = { + entry: PropTypes.object, + onClose: PropTypes.func +} +export default Details diff --git a/src/explorer/explorer.css b/src/explorer/explorer.css new file mode 100644 index 0000000..e64a17c --- /dev/null +++ b/src/explorer/explorer.css @@ -0,0 +1,10 @@ +.btn-close-entry{ + width: 150px; +} +.action-handler{ + color: #3c8dbc; + cursor: pointer; +} +.details-data-content{ + text-align: left; +} \ No newline at end of file diff --git a/src/explorer/index.js b/src/explorer/index.js new file mode 100644 index 0000000..f0b81fd --- /dev/null +++ b/src/explorer/index.js @@ -0,0 +1,207 @@ +import React from 'react' +import { Row, Col, Content, Box, DataTable } from 'adminlte-2-react' +import Details from './details' +import './explorer.css' +const axios = require('axios').default + +const SERVER = 'https://p2wdb.fullstack.cash/' +const EXPLORER_URL = 'https://explorer.bitcoin.com/bch/tx/' + +let _this +class Explorer extends React.Component { + constructor (props) { + super(props) + _this = this + this.state = { + showEntry: false, + data: [], + entries: [], + entryData: null + } + + this.firstColumns = [ + { title: 'Created At', data: 'createdAt' }, + { + title: 'Transaction', + data: 'txid', + render: txid => ( + + {txid.subString} + + ) + }, + { + title: 'Hash', + data: 'hash', + render: hash => ( + + {hash.subString} + + ) + }, + { title: 'App Id', data: 'appId' } + ] + } + + render () { + const { data, entryData } = _this.state + return ( + + + {entryData && ( + +
+ + )} + + + { + _this.handleEvents(data) + } + }} + /> + + + + + ) + } + + async componentDidMount () { + _this.handleEntries() + + // Get data and update table + // every 20 seconds + setInterval(() => { + _this.handleEntries() + }, 20000) + } + + async handleEntries () { + const entries = await _this.getEntries() + _this.generateDataTable(entries) + } + + // REST petition to Get data fron the pw2db + async getEntries () { + try { + const options = { + method: 'GET', + url: `${SERVER}entry/all/${0}`, + data: {} + } + const result = await axios.request(options) + _this.setState({ + entries: result.data.data + }) + return result.data.data + } catch (err) { + console.warn('Error in getEntries() ', err) + } + } + + // Generate table content + generateDataTable (dataArr) { + try { + const data = [] + + for (let i = 0; i < dataArr.length; i++) { + const entry = dataArr[i] + const row = { + // createdAt row data + createdAt: new Date(entry.createdAt).toLocaleString(), + // Transaction id row data + txid: { + subString: _this.cutString(entry.key), + txid: entry.key + }, + // Hash row data + hash: { + subString: _this.cutString(entry.hash), + hash: entry.hash, + data: entry + }, + // App id row data + appId: entry.appId || 'none' + } + data.push(row) + } + _this.setState({ + data + }) + } catch (err) { + console.warn('Error in generateDataTable() ', err) + } + } + + cutString (txid) { + try { + const subTxid = txid.slice(0, 4) + const subTxid2 = txid.slice(-4) + return `${subTxid}...${subTxid2}` + } catch (err) { + console.warn('Error in cutString() ', err) + } + } + + handleTxIdClick (txid) { + try { + window.open(`${EXPLORER_URL}${txid}`, '_blank') + } catch (err) { + console.warn('Error in handleTxIdClick() ', err) + } + } + + handleHashClick (data) { + try { + data.isValid = data.isValid.toString() + _this.setState({ + entryData: data + }) + } catch (err) { + _this.setState({ + entryData: null + }) + console.warn('Error in handleHashClick() ', err) + } + } + + handleEvents (eventData) { + try { + const { txid, hash, data } = eventData + + if (txid) { + _this.handleTxIdClick(txid) + } + if (hash && data) { + _this.handleHashClick(data) + } + } catch (err) { + console.warn('Error in handleEvents() ', err) + } + } + + handleClose () { + _this.setState({ + entryData: null + }) + } +} + +export default Explorer diff --git a/src/gatsby-ipfs-web-wallet/components/menu-components.js b/src/gatsby-ipfs-web-wallet/components/menu-components.js index e23e2f6..3c863db 100644 --- a/src/gatsby-ipfs-web-wallet/components/menu-components.js +++ b/src/gatsby-ipfs-web-wallet/components/menu-components.js @@ -24,11 +24,17 @@ import Wallet from 'gatsby-ipfs-web-wallet/src/components/admin-lte/wallet' import Tokens from 'gatsby-ipfs-web-wallet/src/components/admin-lte/tokens' import Configure from 'gatsby-ipfs-web-wallet/src/components/admin-lte/configure' import SendReceive from 'gatsby-ipfs-web-wallet/src/components/admin-lte/send-receive' +import Explorer from '../../explorer' const { Item } = Sidebar const MenuComponents = props => { return [ + { + key: 'Explorer', + component: , + menuItem: + }, { key: 'Tokens', component: , @@ -58,9 +64,7 @@ const MenuComponents = props => { { key: 'TX History', component: , - menuItem: ( - - ) + menuItem: }, { key: 'Demo Component',