mirror of
https://github.com/oceanprotocol/commons.git
synced 2023-03-15 18:03:00 +01:00
Merge pull request #25 from oceanprotocol/feature/account-popup
Account & Faucet UI
This commit is contained in:
commit
214c5358eb
105
package-lock.json
generated
105
package-lock.json
generated
@ -2402,8 +2402,7 @@
|
|||||||
"asap": {
|
"asap": {
|
||||||
"version": "2.0.6",
|
"version": "2.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
|
||||||
"integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=",
|
"integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"asn1": {
|
"asn1": {
|
||||||
"version": "0.2.4",
|
"version": "0.2.4",
|
||||||
@ -5048,6 +5047,15 @@
|
|||||||
"sha.js": "^2.4.8"
|
"sha.js": "^2.4.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"create-react-context": {
|
||||||
|
"version": "0.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/create-react-context/-/create-react-context-0.2.2.tgz",
|
||||||
|
"integrity": "sha512-KkpaLARMhsTsgp0d2NA/R94F/eDLbhXERdIq3LvX2biCAXcDvHYoOqHfWCHf1+OLj+HKBotLG3KqaOOf+C1C+A==",
|
||||||
|
"requires": {
|
||||||
|
"fbjs": "^0.8.0",
|
||||||
|
"gud": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"cross-spawn": {
|
"cross-spawn": {
|
||||||
"version": "6.0.5",
|
"version": "6.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
|
||||||
@ -6274,6 +6282,14 @@
|
|||||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
||||||
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
|
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
|
||||||
},
|
},
|
||||||
|
"encoding": {
|
||||||
|
"version": "0.1.12",
|
||||||
|
"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
|
||||||
|
"integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=",
|
||||||
|
"requires": {
|
||||||
|
"iconv-lite": "~0.4.13"
|
||||||
|
}
|
||||||
|
},
|
||||||
"end-of-stream": {
|
"end-of-stream": {
|
||||||
"version": "1.4.1",
|
"version": "1.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
|
||||||
@ -7474,6 +7490,35 @@
|
|||||||
"bser": "^2.0.0"
|
"bser": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"fbjs": {
|
||||||
|
"version": "0.8.17",
|
||||||
|
"resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.17.tgz",
|
||||||
|
"integrity": "sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=",
|
||||||
|
"requires": {
|
||||||
|
"core-js": "^1.0.0",
|
||||||
|
"isomorphic-fetch": "^2.1.1",
|
||||||
|
"loose-envify": "^1.0.0",
|
||||||
|
"object-assign": "^4.1.0",
|
||||||
|
"promise": "^7.1.1",
|
||||||
|
"setimmediate": "^1.0.5",
|
||||||
|
"ua-parser-js": "^0.7.18"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"core-js": {
|
||||||
|
"version": "1.2.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
|
||||||
|
"integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY="
|
||||||
|
},
|
||||||
|
"promise": {
|
||||||
|
"version": "7.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
|
||||||
|
"integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
|
||||||
|
"requires": {
|
||||||
|
"asap": "~2.0.3"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"fd-slicer": {
|
"fd-slicer": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
|
||||||
@ -8982,6 +9027,11 @@
|
|||||||
"integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=",
|
"integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"gud": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/gud/-/gud-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw=="
|
||||||
|
},
|
||||||
"gzip-size": {
|
"gzip-size": {
|
||||||
"version": "5.0.0",
|
"version": "5.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.0.0.tgz",
|
||||||
@ -10476,6 +10526,26 @@
|
|||||||
"isarray": "1.0.0"
|
"isarray": "1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"isomorphic-fetch": {
|
||||||
|
"version": "2.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz",
|
||||||
|
"integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=",
|
||||||
|
"requires": {
|
||||||
|
"node-fetch": "^1.0.1",
|
||||||
|
"whatwg-fetch": ">=0.10.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"node-fetch": {
|
||||||
|
"version": "1.7.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
|
||||||
|
"integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
|
||||||
|
"requires": {
|
||||||
|
"encoding": "^0.1.11",
|
||||||
|
"is-stream": "^1.0.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"isstream": {
|
"isstream": {
|
||||||
"version": "0.1.2",
|
"version": "0.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
|
||||||
@ -13404,6 +13474,11 @@
|
|||||||
"ts-pnp": "^1.0.0"
|
"ts-pnp": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"popper.js": {
|
||||||
|
"version": "1.14.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.14.7.tgz",
|
||||||
|
"integrity": "sha512-4q1hNvoUre/8srWsH7hnoSJ5xVmIL4qgz+s4qf2TnJIMyZFUFMGH+9vE7mXynAlHSZ/NdTmmow86muD0myUkVQ=="
|
||||||
|
},
|
||||||
"portfinder": {
|
"portfinder": {
|
||||||
"version": "1.0.20",
|
"version": "1.0.20",
|
||||||
"resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.20.tgz",
|
"resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.20.tgz",
|
||||||
@ -17233,6 +17308,19 @@
|
|||||||
"resolved": "https://registry.npmjs.org/react-moment/-/react-moment-0.8.4.tgz",
|
"resolved": "https://registry.npmjs.org/react-moment/-/react-moment-0.8.4.tgz",
|
||||||
"integrity": "sha512-QhI19OcfhiAn60/O6bMR0w8ApXrPFCjv6+eV0I/P9/AswzjgEAx4L7VxMBCpS/jrythLa12Q9v88req+ys4YpA=="
|
"integrity": "sha512-QhI19OcfhiAn60/O6bMR0w8ApXrPFCjv6+eV0I/P9/AswzjgEAx4L7VxMBCpS/jrythLa12Q9v88req+ys4YpA=="
|
||||||
},
|
},
|
||||||
|
"react-popper": {
|
||||||
|
"version": "1.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-popper/-/react-popper-1.3.3.tgz",
|
||||||
|
"integrity": "sha512-ynMZBPkXONPc5K4P5yFWgZx5JGAUIP3pGGLNs58cfAPgK67olx7fmLp+AdpZ0+GoQ+ieFDa/z4cdV6u7sioH6w==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.1.2",
|
||||||
|
"create-react-context": "<=0.2.2",
|
||||||
|
"popper.js": "^1.14.4",
|
||||||
|
"prop-types": "^15.6.1",
|
||||||
|
"typed-styles": "^0.0.7",
|
||||||
|
"warning": "^4.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"react-router": {
|
"react-router": {
|
||||||
"version": "4.3.1",
|
"version": "4.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-4.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-router/-/react-router-4.3.1.tgz",
|
||||||
@ -21343,6 +21431,11 @@
|
|||||||
"mime-types": "~2.1.18"
|
"mime-types": "~2.1.18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"typed-styles": {
|
||||||
|
"version": "0.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/typed-styles/-/typed-styles-0.0.7.tgz",
|
||||||
|
"integrity": "sha512-pzP0PWoZUhsECYjABgCGQlRGL1n7tOHsgwYv3oIiEpJwGhFTuty/YNeduxQYzXXa3Ge5BdT6sHYIQYpl4uJ+5Q=="
|
||||||
|
},
|
||||||
"typedarray": {
|
"typedarray": {
|
||||||
"version": "0.0.6",
|
"version": "0.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
|
||||||
@ -21363,6 +21456,11 @@
|
|||||||
"integrity": "sha512-JjSKsAfuHBE/fB2oZ8NxtRTk5iGcg6hkYXMnZ3Wc+b2RSqejEqTaem11mHASMnFilHrax3sLK0GDzcJrekZYLw==",
|
"integrity": "sha512-JjSKsAfuHBE/fB2oZ8NxtRTk5iGcg6hkYXMnZ3Wc+b2RSqejEqTaem11mHASMnFilHrax3sLK0GDzcJrekZYLw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"ua-parser-js": {
|
||||||
|
"version": "0.7.19",
|
||||||
|
"resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.19.tgz",
|
||||||
|
"integrity": "sha512-T3PVJ6uz8i0HzPxOF9SWzWAlfN/DavlpQqepn22xgve/5QecC+XMCAtmUNnY7C9StehaV6exjUCI801lOI7QlQ=="
|
||||||
|
},
|
||||||
"uglify-js": {
|
"uglify-js": {
|
||||||
"version": "3.4.9",
|
"version": "3.4.9",
|
||||||
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz",
|
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz",
|
||||||
@ -23384,8 +23482,7 @@
|
|||||||
"whatwg-fetch": {
|
"whatwg-fetch": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz",
|
||||||
"integrity": "sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==",
|
"integrity": "sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"whatwg-mimetype": {
|
"whatwg-mimetype": {
|
||||||
"version": "2.3.0",
|
"version": "2.3.0",
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
"react-dom": "^16.8.3",
|
"react-dom": "^16.8.3",
|
||||||
"react-helmet": "^5.2.0",
|
"react-helmet": "^5.2.0",
|
||||||
"react-moment": "^0.8.4",
|
"react-moment": "^0.8.4",
|
||||||
|
"react-popper": "^1.3.3",
|
||||||
"react-router-dom": "^4.3.1",
|
"react-router-dom": "^4.3.1",
|
||||||
"react-transition-group": "^2.6.0",
|
"react-transition-group": "^2.6.0",
|
||||||
"slugify": "^1.3.4",
|
"slugify": "^1.3.4",
|
||||||
|
22
src/App.tsx
22
src/App.tsx
@ -1,6 +1,7 @@
|
|||||||
import React, { Component } from 'react'
|
import React, { Component } from 'react'
|
||||||
import Web3 from 'web3'
|
import Web3 from 'web3'
|
||||||
import { BrowserRouter as Router } from 'react-router-dom'
|
import { BrowserRouter as Router } from 'react-router-dom'
|
||||||
|
import { Logger } from '@oceanprotocol/squid'
|
||||||
import Header from './components/Header'
|
import Header from './components/Header'
|
||||||
import Footer from './components/Footer'
|
import Footer from './components/Footer'
|
||||||
import Spinner from './components/atoms/Spinner'
|
import Spinner from './components/atoms/Spinner'
|
||||||
@ -31,6 +32,11 @@ interface AppState {
|
|||||||
isLoading: boolean
|
isLoading: boolean
|
||||||
isWeb3: boolean
|
isWeb3: boolean
|
||||||
account: string
|
account: string
|
||||||
|
balance: {
|
||||||
|
eth: number
|
||||||
|
ocn: number
|
||||||
|
}
|
||||||
|
network: string
|
||||||
web3: Web3
|
web3: Web3
|
||||||
ocean: {}
|
ocean: {}
|
||||||
startLogin: () => void
|
startLogin: () => void
|
||||||
@ -62,7 +68,7 @@ class App extends Component<{}, AppState> {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// show error
|
Logger.log('requestFromFaucet', error)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// no account found
|
// no account found
|
||||||
@ -73,6 +79,11 @@ class App extends Component<{}, AppState> {
|
|||||||
isLogged: false,
|
isLogged: false,
|
||||||
isLoading: true,
|
isLoading: true,
|
||||||
isWeb3: false,
|
isWeb3: false,
|
||||||
|
balance: {
|
||||||
|
eth: 0,
|
||||||
|
ocn: 0
|
||||||
|
},
|
||||||
|
network: '',
|
||||||
web3: new Web3(
|
web3: new Web3(
|
||||||
new Web3.providers.HttpProvider(
|
new Web3.providers.HttpProvider(
|
||||||
`${nodeScheme}://${nodeHost}:${nodePort}`
|
`${nodeScheme}://${nodeHost}:${nodePort}`
|
||||||
@ -140,7 +151,7 @@ class App extends Component<{}, AppState> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// continue with default
|
Logger.log('web3 error', e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
@ -149,8 +160,13 @@ class App extends Component<{}, AppState> {
|
|||||||
isLoading: false,
|
isLoading: false,
|
||||||
ocean
|
ocean
|
||||||
})
|
})
|
||||||
|
// TODO: squid-js balance retrieval fix
|
||||||
|
const accounts = await ocean.getAccounts()
|
||||||
|
const balance = await accounts[0].getBalance()
|
||||||
|
this.setState({ balance })
|
||||||
|
// TODO: squid-js expose keeper for getNetworkName
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// show loading error / unable to initialize ocean
|
Logger.log('ocean/balance error', e)
|
||||||
this.setState({
|
this.setState({
|
||||||
isLoading: false
|
isLoading: false
|
||||||
})
|
})
|
||||||
|
@ -7,6 +7,7 @@ import Home from './routes/Home'
|
|||||||
import NotFound from './routes/NotFound'
|
import NotFound from './routes/NotFound'
|
||||||
import Publish from './routes/Publish/'
|
import Publish from './routes/Publish/'
|
||||||
import Search from './routes/Search'
|
import Search from './routes/Search'
|
||||||
|
import Faucet from './routes/Faucet'
|
||||||
import Styleguide from './routes/Styleguide'
|
import Styleguide from './routes/Styleguide'
|
||||||
|
|
||||||
const Routes = () => (
|
const Routes = () => (
|
||||||
@ -17,6 +18,7 @@ const Routes = () => (
|
|||||||
<Route component={Publish} path="/publish" />
|
<Route component={Publish} path="/publish" />
|
||||||
<Route component={Search} path="/search" />
|
<Route component={Search} path="/search" />
|
||||||
<Route component={Details} path="/asset/:did" />
|
<Route component={Details} path="/asset/:did" />
|
||||||
|
<Route component={Faucet} path="/faucet" />
|
||||||
<Route component={NotFound} />
|
<Route component={NotFound} />
|
||||||
</Switch>
|
</Switch>
|
||||||
)
|
)
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
@import '../styles/variables';
|
@import '../styles/variables';
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
// background: $brand-black
|
|
||||||
// url('@oceanprotocol/art/mantaray/mantaray-back.svg') no-repeat center -6rem;
|
|
||||||
// background-size: cover;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: $spacer / 2 0;
|
padding: $spacer / 2 0;
|
||||||
}
|
}
|
||||||
@ -94,3 +91,8 @@
|
|||||||
color: $brand-pink;
|
color: $brand-pink;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.accountStatus {
|
||||||
|
margin-left: $spacer;
|
||||||
|
margin-bottom: .2rem;
|
||||||
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { NavLink } from 'react-router-dom'
|
import { NavLink } from 'react-router-dom'
|
||||||
import { ReactComponent as Logo } from '@oceanprotocol/art/logo/logo.svg'
|
import { ReactComponent as Logo } from '@oceanprotocol/art/logo/logo.svg'
|
||||||
|
import AccountStatus from './molecules/AccountStatus/'
|
||||||
import styles from './Header.module.scss'
|
import styles from './Header.module.scss'
|
||||||
|
|
||||||
import menu from '../data/menu.json'
|
import menu from '../data/menu.json'
|
||||||
@ -27,6 +28,7 @@ const Header = () => (
|
|||||||
</NavLink>
|
</NavLink>
|
||||||
))}
|
))}
|
||||||
</nav>
|
</nav>
|
||||||
|
<AccountStatus className={styles.accountStatus} />
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
)
|
)
|
||||||
|
@ -1,48 +0,0 @@
|
|||||||
@import '../styles/variables';
|
|
||||||
|
|
||||||
.message {
|
|
||||||
margin-bottom: $spacer;
|
|
||||||
color: $brand-grey;
|
|
||||||
padding-left: 1.5rem;
|
|
||||||
position: relative;
|
|
||||||
border-bottom: .1rem solid $brand-grey-lighter;
|
|
||||||
border-top: .1rem solid $brand-grey-lighter;
|
|
||||||
padding-top: $spacer / 2;
|
|
||||||
padding-bottom: $spacer / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// default: red square
|
|
||||||
.indicator {
|
|
||||||
display: inline-block;
|
|
||||||
width: $font-size-small;
|
|
||||||
height: $font-size-small;
|
|
||||||
background: $red;
|
|
||||||
margin-right: $spacer / 8;
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: ($spacer / 2) + .3rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
// yellow triangle
|
|
||||||
.indicatorCloseEnough {
|
|
||||||
composes: indicator;
|
|
||||||
background: none;
|
|
||||||
width: 0;
|
|
||||||
height: 0;
|
|
||||||
border-left: $font-size-small / 1.75 solid transparent;
|
|
||||||
border-right: $font-size-small / 1.75 solid transparent;
|
|
||||||
border-bottom: $font-size-small solid $yellow;
|
|
||||||
}
|
|
||||||
|
|
||||||
// green circle
|
|
||||||
.indicatorActive {
|
|
||||||
composes: indicator;
|
|
||||||
border-radius: 50%;
|
|
||||||
background: $green;
|
|
||||||
}
|
|
||||||
|
|
||||||
.account {
|
|
||||||
display: inline-block;
|
|
||||||
margin-left: $spacer / 8;
|
|
||||||
background: none;
|
|
||||||
}
|
|
@ -1,62 +0,0 @@
|
|||||||
import React, { PureComponent } from 'react'
|
|
||||||
import Button from '../components/atoms/Button'
|
|
||||||
import styles from './Web3message.module.scss'
|
|
||||||
import { User } from '../context/User'
|
|
||||||
|
|
||||||
export default class Web3message extends PureComponent {
|
|
||||||
public render() {
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<User.Consumer>
|
|
||||||
{states =>
|
|
||||||
!states.isWeb3
|
|
||||||
? this.noWeb3()
|
|
||||||
: !states.isLogged
|
|
||||||
? this.unlockAccount(states)
|
|
||||||
: states.isLogged
|
|
||||||
? this.haveAccount(states.account)
|
|
||||||
: null
|
|
||||||
}
|
|
||||||
</User.Consumer>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
public noWeb3() {
|
|
||||||
return (
|
|
||||||
<div className={styles.message}>
|
|
||||||
<span className={styles.indicator} /> No Web3 Browser. For
|
|
||||||
publishing an asset you need to use a Web3-capable plugin or
|
|
||||||
browser, like{' '}
|
|
||||||
<a href="https://docs.oceanprotocol.com/tutorials/wallets/#how-to-setup-metamask">
|
|
||||||
MetaMask
|
|
||||||
</a>
|
|
||||||
.
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
public unlockAccount(states: any) {
|
|
||||||
return (
|
|
||||||
<div className={styles.message}>
|
|
||||||
<span className={styles.indicatorCloseEnough} /> Account locked.
|
|
||||||
For publishing an asset you need to unlock your Web3 account.
|
|
||||||
<Button link onClick={states.startLogin}>
|
|
||||||
Unlock account
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
public haveAccount(account: string) {
|
|
||||||
return (
|
|
||||||
<div className={styles.message}>
|
|
||||||
<span className={styles.indicatorActive} /> Connected with
|
|
||||||
account
|
|
||||||
<code className={styles.account} title={account && account}>
|
|
||||||
{`${account && account.substring(0, 20)}...`}
|
|
||||||
</code>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
@ -3,8 +3,8 @@
|
|||||||
.spinner {
|
.spinner {
|
||||||
position: relative;
|
position: relative;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-bottom: $spacer;
|
margin-top: $spacer * $line-height;
|
||||||
margin-top: $spacer * 2;
|
margin-bottom: $spacer / 2;
|
||||||
|
|
||||||
&:before {
|
&:before {
|
||||||
content: '';
|
content: '';
|
||||||
|
33
src/components/molecules/AccountStatus/Indicator.module.scss
Normal file
33
src/components/molecules/AccountStatus/Indicator.module.scss
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
@import '../../../styles/variables';
|
||||||
|
|
||||||
|
.status {
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
cursor: help;
|
||||||
|
}
|
||||||
|
|
||||||
|
// default: red square
|
||||||
|
.statusIndicator {
|
||||||
|
width: $font-size-small;
|
||||||
|
height: $font-size-small;
|
||||||
|
display: block;
|
||||||
|
background: $red;
|
||||||
|
}
|
||||||
|
|
||||||
|
// yellow triangle
|
||||||
|
.statusIndicatorCloseEnough {
|
||||||
|
composes: statusIndicator;
|
||||||
|
background: none;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border-left: $font-size-small / 1.7 solid transparent;
|
||||||
|
border-right: $font-size-small / 1.7 solid transparent;
|
||||||
|
border-bottom: $font-size-small solid $yellow;
|
||||||
|
}
|
||||||
|
|
||||||
|
// green circle
|
||||||
|
.statusIndicatorActive {
|
||||||
|
composes: statusIndicator;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: $green;
|
||||||
|
}
|
35
src/components/molecules/AccountStatus/Indicator.tsx
Normal file
35
src/components/molecules/AccountStatus/Indicator.tsx
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import cx from 'classnames'
|
||||||
|
import { User } from '../../../context/User'
|
||||||
|
import styles from './Indicator.module.scss'
|
||||||
|
|
||||||
|
const Indicator = ({
|
||||||
|
className,
|
||||||
|
togglePopover,
|
||||||
|
forwardedRef
|
||||||
|
}: {
|
||||||
|
className?: string
|
||||||
|
togglePopover: () => void
|
||||||
|
forwardedRef: (ref: HTMLElement | null) => void
|
||||||
|
}) => (
|
||||||
|
<div
|
||||||
|
className={cx(styles.status, className)}
|
||||||
|
onMouseOver={togglePopover}
|
||||||
|
onMouseOut={togglePopover}
|
||||||
|
ref={forwardedRef}
|
||||||
|
>
|
||||||
|
<User.Consumer>
|
||||||
|
{states =>
|
||||||
|
!states.isWeb3 ? (
|
||||||
|
<span className={styles.statusIndicator} />
|
||||||
|
) : !states.isLogged ? (
|
||||||
|
<span className={styles.statusIndicatorCloseEnough} />
|
||||||
|
) : states.isLogged ? (
|
||||||
|
<span className={styles.statusIndicatorActive} />
|
||||||
|
) : null
|
||||||
|
}
|
||||||
|
</User.Consumer>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
|
||||||
|
export default Indicator
|
62
src/components/molecules/AccountStatus/Popover.module.scss
Normal file
62
src/components/molecules/AccountStatus/Popover.module.scss
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
@import '../../../styles/variables';
|
||||||
|
|
||||||
|
$popoverWidth: 18rem;
|
||||||
|
|
||||||
|
.popover {
|
||||||
|
position: relative;
|
||||||
|
width: $popoverWidth;
|
||||||
|
padding: $spacer / 2;
|
||||||
|
background: $brand-black;
|
||||||
|
border-radius: .1rem;
|
||||||
|
border: .1rem solid $brand-grey-light;
|
||||||
|
box-shadow: 0 6px 16px 0 rgba($brand-black, .3);
|
||||||
|
color: $brand-grey-light;
|
||||||
|
font-size: $font-size-small;
|
||||||
|
animation: showPopup .2s ease-in forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes showPopup {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.popoverInfoline {
|
||||||
|
border-bottom: .05rem solid $brand-grey;
|
||||||
|
padding: $spacer / 3 0;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
padding-bottom: 0;
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
font-size: $font-size-small;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.address {
|
||||||
|
width: 15rem;
|
||||||
|
display: block;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.balance {
|
||||||
|
font-size: $font-size-small;
|
||||||
|
margin-left: $spacer / 2;
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
}
|
59
src/components/molecules/AccountStatus/Popover.tsx
Normal file
59
src/components/molecules/AccountStatus/Popover.tsx
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { User } from '../../../context/User'
|
||||||
|
import styles from './Popover.module.scss'
|
||||||
|
|
||||||
|
const Popover = ({
|
||||||
|
forwardedRef,
|
||||||
|
style
|
||||||
|
}: {
|
||||||
|
forwardedRef: (ref: HTMLElement | null) => void
|
||||||
|
style: React.CSSProperties
|
||||||
|
}) => (
|
||||||
|
<div className={styles.popover} ref={forwardedRef} style={style}>
|
||||||
|
<User.Consumer>
|
||||||
|
{states =>
|
||||||
|
states.account &&
|
||||||
|
states.balance && (
|
||||||
|
<div className={styles.popoverInfoline}>
|
||||||
|
<span
|
||||||
|
className={styles.balance}
|
||||||
|
title={(states.balance.eth / 1e18).toFixed(10)}
|
||||||
|
>
|
||||||
|
<strong>
|
||||||
|
{(states.balance.eth / 1e18)
|
||||||
|
.toFixed(3)
|
||||||
|
.slice(0, -1)}
|
||||||
|
</strong>{' '}
|
||||||
|
ETH
|
||||||
|
</span>
|
||||||
|
<span className={styles.balance}>
|
||||||
|
<strong>{states.balance.ocn}</strong> OCEAN
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</User.Consumer>
|
||||||
|
|
||||||
|
<div className={styles.popoverInfoline}>
|
||||||
|
<User.Consumer>
|
||||||
|
{states =>
|
||||||
|
states.account ? (
|
||||||
|
<span className={styles.address} title={states.account}>
|
||||||
|
{states.account}
|
||||||
|
</span>
|
||||||
|
) : (
|
||||||
|
<em>No account selected</em>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</User.Consumer>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styles.popoverInfoline}>
|
||||||
|
<User.Consumer>
|
||||||
|
{states => states.network && states.network}
|
||||||
|
</User.Consumer>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
|
||||||
|
export default Popover
|
54
src/components/molecules/AccountStatus/index.tsx
Normal file
54
src/components/molecules/AccountStatus/index.tsx
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
import React, { PureComponent } from 'react'
|
||||||
|
import { Manager, Reference, Popper } from 'react-popper'
|
||||||
|
import AccountPopover from './Popover'
|
||||||
|
import AccountIndicator from './Indicator'
|
||||||
|
|
||||||
|
interface AccountStatusProps {
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface AccountStatusState {
|
||||||
|
isPopoverOpen: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class AccountStatus extends PureComponent<
|
||||||
|
AccountStatusProps,
|
||||||
|
AccountStatusState
|
||||||
|
> {
|
||||||
|
public state = {
|
||||||
|
isPopoverOpen: false
|
||||||
|
}
|
||||||
|
|
||||||
|
public togglePopover() {
|
||||||
|
this.setState(prevState => ({
|
||||||
|
isPopoverOpen: !prevState.isPopoverOpen
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
public render() {
|
||||||
|
return (
|
||||||
|
<Manager>
|
||||||
|
<Reference>
|
||||||
|
{({ ref }) => (
|
||||||
|
<AccountIndicator
|
||||||
|
togglePopover={() => this.togglePopover()}
|
||||||
|
className={this.props.className}
|
||||||
|
forwardedRef={ref}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Reference>
|
||||||
|
{this.state.isPopoverOpen && (
|
||||||
|
<Popper placement="auto">
|
||||||
|
{({ ref, style, placement }) => (
|
||||||
|
<AccountPopover
|
||||||
|
forwardedRef={ref}
|
||||||
|
style={style}
|
||||||
|
data-placement={placement}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</Popper>
|
||||||
|
)}
|
||||||
|
</Manager>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
23
src/components/molecules/Web3message.module.scss
Normal file
23
src/components/molecules/Web3message.module.scss
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
@import '../../styles/variables';
|
||||||
|
|
||||||
|
.message {
|
||||||
|
margin-bottom: $spacer;
|
||||||
|
color: $brand-grey;
|
||||||
|
padding-left: 2rem;
|
||||||
|
position: relative;
|
||||||
|
border-bottom: .1rem solid $brand-grey-lighter;
|
||||||
|
border-top: .1rem solid $brand-grey-lighter;
|
||||||
|
padding-top: $spacer / 2;
|
||||||
|
padding-bottom: $spacer / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account {
|
||||||
|
display: inline-block;
|
||||||
|
margin-left: $spacer / 8;
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status {
|
||||||
|
margin-left: -($spacer);
|
||||||
|
margin-right: $spacer / 3;
|
||||||
|
}
|
60
src/components/molecules/Web3message.tsx
Normal file
60
src/components/molecules/Web3message.tsx
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
import React, { PureComponent } from 'react'
|
||||||
|
import Button from '../atoms/Button'
|
||||||
|
import AccountStatus from './AccountStatus/'
|
||||||
|
import styles from './Web3message.module.scss'
|
||||||
|
import { User } from '../../context/User'
|
||||||
|
|
||||||
|
export default class Web3message extends PureComponent {
|
||||||
|
public render() {
|
||||||
|
return (
|
||||||
|
<User.Consumer>
|
||||||
|
{states =>
|
||||||
|
!states.isWeb3
|
||||||
|
? this.noWeb3()
|
||||||
|
: !states.isLogged
|
||||||
|
? this.unlockAccount(states)
|
||||||
|
: states.isLogged
|
||||||
|
? this.haveAccount(states.account)
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
</User.Consumer>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
public noWeb3() {
|
||||||
|
return (
|
||||||
|
<div className={styles.message}>
|
||||||
|
<AccountStatus className={styles.status} /> No Web3 Browser. For
|
||||||
|
publishing an asset you need to{' '}
|
||||||
|
<a href="https://docs.oceanprotocol.com/tutorials/metamask-setup/">
|
||||||
|
setup MetaMask
|
||||||
|
</a>{' '}
|
||||||
|
or use any other Web3-capable plugin or browser.
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
public unlockAccount(states: any) {
|
||||||
|
return (
|
||||||
|
<div className={styles.message}>
|
||||||
|
<AccountStatus className={styles.status} /> Account locked. For
|
||||||
|
publishing an asset you need to unlock your Web3 account.
|
||||||
|
<Button link onClick={states.startLogin}>
|
||||||
|
Unlock account
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
public haveAccount(account: string) {
|
||||||
|
return (
|
||||||
|
<div className={styles.message}>
|
||||||
|
<AccountStatus className={styles.status} /> Connected with
|
||||||
|
account
|
||||||
|
<code className={styles.account} title={account && account}>
|
||||||
|
{`${account && account.substring(0, 20)}...`}
|
||||||
|
</code>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -7,6 +7,11 @@ export const User = React.createContext({
|
|||||||
account: '',
|
account: '',
|
||||||
web3: {},
|
web3: {},
|
||||||
ocean: {},
|
ocean: {},
|
||||||
|
balance: {
|
||||||
|
eth: 0,
|
||||||
|
ocn: 0
|
||||||
|
},
|
||||||
|
network: '',
|
||||||
startLogin: () => {
|
startLogin: () => {
|
||||||
/* empty */
|
/* empty */
|
||||||
},
|
},
|
||||||
|
@ -3,6 +3,10 @@
|
|||||||
"title": "Publish",
|
"title": "Publish",
|
||||||
"link": "/publish"
|
"link": "/publish"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"title": "Faucet",
|
||||||
|
"link": "/faucet"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"title": "About",
|
"title": "About",
|
||||||
"link": "/about"
|
"link": "/about"
|
||||||
|
15
src/routes/Faucet.module.scss
Normal file
15
src/routes/Faucet.module.scss
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
@import '../styles/variables';
|
||||||
|
|
||||||
|
.action {
|
||||||
|
text-align: center;
|
||||||
|
margin-top: $spacer * 2;
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin-top: $spacer;
|
||||||
|
color: $brand-grey-light;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.success {
|
||||||
|
color: $green;
|
||||||
|
}
|
96
src/routes/Faucet.tsx
Normal file
96
src/routes/Faucet.tsx
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
import React, { PureComponent } from 'react'
|
||||||
|
import Route from '../components/templates/Route'
|
||||||
|
import Button from '../components/atoms/Button'
|
||||||
|
import Spinner from '../components/atoms/Spinner'
|
||||||
|
import { User } from '../context/User'
|
||||||
|
import Web3message from '../components/molecules/Web3message'
|
||||||
|
import styles from './Faucet.module.scss'
|
||||||
|
|
||||||
|
interface FaucetState {
|
||||||
|
isLoading: boolean
|
||||||
|
success?: string
|
||||||
|
error?: string
|
||||||
|
eth?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class Faucet extends PureComponent<{}, FaucetState> {
|
||||||
|
public state = {
|
||||||
|
isLoading: false,
|
||||||
|
success: undefined,
|
||||||
|
error: undefined,
|
||||||
|
eth: 'xx'
|
||||||
|
}
|
||||||
|
|
||||||
|
private getTokens = async (requestFromFaucet: () => void) => {
|
||||||
|
this.setState({ isLoading: true })
|
||||||
|
|
||||||
|
try {
|
||||||
|
await requestFromFaucet()
|
||||||
|
this.setState({
|
||||||
|
isLoading: false,
|
||||||
|
success: `Successfully added ${
|
||||||
|
this.state.eth
|
||||||
|
} ETH to your account.`
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
this.setState({ isLoading: false, error })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private RequestMarkup = () => (
|
||||||
|
<User.Consumer>
|
||||||
|
{states => (
|
||||||
|
<Button
|
||||||
|
primary
|
||||||
|
onClick={() => this.getTokens(states.requestFromFaucet)}
|
||||||
|
>
|
||||||
|
Request Ether
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</User.Consumer>
|
||||||
|
)
|
||||||
|
|
||||||
|
private ActionMarkup = () => (
|
||||||
|
<div className={styles.action}>
|
||||||
|
{this.state.isLoading ? (
|
||||||
|
<Spinner message="Getting Ether..." />
|
||||||
|
) : this.state.error ? (
|
||||||
|
<div className={styles.error}>
|
||||||
|
{this.state.error}{' '}
|
||||||
|
<Button link onClick={this.reset}>
|
||||||
|
Try again
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
) : this.state.success ? (
|
||||||
|
<div className={styles.success}>{this.state.success}</div>
|
||||||
|
) : (
|
||||||
|
<this.RequestMarkup />
|
||||||
|
)}
|
||||||
|
|
||||||
|
<p>
|
||||||
|
You can only request Ether once every 24 hours for your address.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
|
||||||
|
private reset = () => {
|
||||||
|
this.setState({
|
||||||
|
error: undefined,
|
||||||
|
success: undefined,
|
||||||
|
isLoading: false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
public render() {
|
||||||
|
return (
|
||||||
|
<Route
|
||||||
|
title="Faucet"
|
||||||
|
description="Shower yourself with some Ether for the Ocean POA network."
|
||||||
|
>
|
||||||
|
<Web3message />
|
||||||
|
|
||||||
|
<this.ActionMarkup />
|
||||||
|
</Route>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
import React, { PureComponent } from 'react'
|
import React, { PureComponent } from 'react'
|
||||||
import Web3message from '../../components/Web3message'
|
import Web3message from '../../components/molecules/Web3message'
|
||||||
import Spinner from '../../components/atoms/Spinner'
|
import Spinner from '../../components/atoms/Spinner'
|
||||||
import styles from './StepRegisterContent.module.scss'
|
import styles from './StepRegisterContent.module.scss'
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user