Merge pull request #87 from poanetwork/feature/#79-new-style

(Feature) New style implementation
This commit is contained in:
Gabriel Rodríguez Alsina 2018-12-19 11:14:43 -03:00 committed by GitHub
commit e7577427fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
148 changed files with 3790 additions and 1678 deletions

View File

@ -43,8 +43,8 @@
"scripts": {
"predeploy": "npm run build",
"deploy": "gh-pages -d build -o origin",
"build-css": "node-sass-chokidar src/index/index.scss -o src/index",
"watch-css": "npm run build-css && node-sass-chokidar src/index/index.scss -o src/index --watch --recursive",
"build-css": "node-sass-chokidar src/assets/stylesheets/index.scss -o src/assets/stylesheets",
"watch-css": "npm run build-css && node-sass-chokidar src/assets/stylesheets/index.scss -o src/assets/stylesheets --watch --recursive",
"start-js": "react-scripts start",
"start": "npm-run-all -p watch-css start-js",
"build-js": "react-scripts build",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -3,7 +3,7 @@
<msapplication>
<tile>
<square150x150logo src="/mstile-150x150.png"/>
<TileColor>#da532c</TileColor>
<TileColor>#5c3698</TileColor>
</tile>
</msapplication>
</browserconfig>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 456 B

BIN
public/favicons/favicon-32x32.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 574 B

BIN
public/favicons/favicon.ico Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -5,30 +5,14 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<!--
manifest.json provides metadata used when your web app is added to the
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/favicons/manifest.json">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicons/favicon.ico">
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>POA Network Ceremony DApp</title>
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>
</body>
</html>

View File

@ -1,28 +0,0 @@
.App {
text-align: center;
}
.App-logo {
animation: App-logo-spin infinite 20s linear;
height: 80px;
}
.App-header {
background-color: #222;
height: 150px;
padding: 20px;
color: white;
}
.App-title {
font-size: 1.5em;
}
.App-intro {
font-size: large;
}
@keyframes App-logo-spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}

View File

@ -1,17 +1,21 @@
import React, { Component } from 'react'
import getWeb3 from './getWeb3'
import KeysManager from './keysManager'
import Keys from './Keys'
import swal from 'sweetalert'
import './index/index.css'
import addressGenerator from './addressGenerator'
import JSzip from 'jszip'
import FileSaver from 'file-saver'
import { constants } from './constants'
import networkAddresses from './addresses'
import Header from './Header'
import Footer from './Footer'
import Loading from './Loading'
import JSzip from 'jszip'
import Keys from './components/Keys'
import KeysManager from './utils/keysManager'
import React, { Component } from 'react'
import addressGenerator from './utils/addressGenerator'
import getWeb3 from './utils/getWeb3'
import networkAddresses from './utils/addresses'
import swal from 'sweetalert'
import { BaseLoader } from './components/BaseLoader'
import { Footer } from './components/Footer'
import { Header } from './components/Header'
import { Home } from './components/Home'
import { Loading } from './components/Loading'
import { constants } from './utils/constants'
import { getNetworkBranch } from './utils/utils'
import './assets/stylesheets/index.css'
function generateElement(msg) {
let errorNode = document.createElement('div')
@ -31,22 +35,27 @@ class App extends Component {
this.state = {
web3Config: {},
mining: null,
isDisabledBtn: props.generateKeysIsDisabled
isDisabledBtn: props.generateKeysIsDisabled,
networkBranch: ''
}
this.keysManager = null
getWeb3()
.then(async web3Config => {
return networkAddresses(web3Config)
})
.then(async config => {
const { web3Config, addresses } = config
this.keysManager = new KeysManager()
await this.keysManager.init({
web3: web3Config.web3Instance,
netId: web3Config.netId,
addresses
})
this.setState({
networkBranch: getNetworkBranch(web3Config.netId),
isDisabledBtn: false,
web3Config
})
@ -62,6 +71,7 @@ class App extends Component {
}
})
}
componentDidMount() {
if (window.location.hash.indexOf('just-generate-keys') !== -1) {
this.setState({ loading: true })
@ -77,6 +87,7 @@ class App extends Component {
}, 150)
}
}
async generateKeys(cb) {
const mining = await addressGenerator()
const voting = await addressGenerator()
@ -93,6 +104,7 @@ class App extends Component {
payout
}
}
async generateZip({ mining, voting, payout, netIdName }) {
const zip = new JSzip()
zip.file(`${netIdName}_keys/mining_key_${mining.jsonStore.address}.json`, JSON.stringify(mining.jsonStore))
@ -107,6 +119,7 @@ class App extends Component {
FileSaver.saveAs(blob, `poa_network_validator_keys.zip`)
})
}
async onClick() {
this.setState({ loading: true })
const initialKey = this.state.web3Config.defaultAccount
@ -116,7 +129,7 @@ class App extends Component {
} catch (e) {
isValid = false
}
console.log(isValid)
if (Number(isValid) !== 1) {
this.setState({ loading: false })
const invalidKeyMsg = `The key is an invalid Initial key<br/>
@ -142,7 +155,6 @@ class App extends Component {
sender: initialKey
})
.then(async receipt => {
console.log(receipt)
if (receipt.status === true || receipt.status === '0x1') {
this.setState({ loading: false })
swal('Congratulations!', 'Your keys are generated!', 'success')
@ -169,7 +181,6 @@ class App extends Component {
}
})
.catch(error => {
console.error(error.message)
this.setState({ loading: false, keysGenerated: false })
let content = document.createElement('div')
let msg
@ -189,35 +200,28 @@ class App extends Component {
})
}
}
render() {
let loader = this.state.loading ? <Loading netId={this.state.web3Config.netId} /> : ''
let createKeyBtn = (
<div className="create-keys">
<h1>Create keys from initial key</h1>
<h2>
In this application, you will create mining, payout and voting keys. The app will make your initial key
unusable after the process. Please proceed with care, don't lose your keys and follow instructions.
</h2>
<div className="create-keys-button-container">
<button className="create-keys-button" onClick={this.onClick} disabled={this.state.isDisabledBtn}>
Generate keys
</button>
</div>
</div>
)
let content
if (this.state.keysGenerated) {
content = <Keys mining={this.state.mining} voting={this.state.voting} payout={this.state.payout} />
} else {
content = createKeyBtn
}
return (
<div className="App">
<Header netId={this.state.web3Config.netId} />
{loader}
<section className="content">{content}</section>
<Footer netId={this.state.web3Config.netId} />
return this.state.networkBranch ? (
<div className="lo-App">
{this.state.loading ? <Loading networkBranch={this.state.networkBranch} /> : null}
<Header networkBranch={this.state.networkBranch} />
<section className="lo-App_Content">
{this.state.keysGenerated ? (
<Keys
mining={this.state.mining}
networkBranch={this.state.networkBranch}
payout={this.state.payout}
voting={this.state.voting}
/>
) : (
<Home disabled={this.state.isDisabledBtn} networkBranch={this.state.networkBranch} onClick={this.onClick} />
)}
</section>
<Footer networkBranch={this.state.networkBranch} />
</div>
) : (
<BaseLoader />
)
}
}

View File

@ -1,32 +0,0 @@
import React from 'react'
import moment from 'moment'
import { constants } from './constants'
const Footer = ({ netId }) => {
const footerClassName = netId in constants.NETWORKS && constants.NETWORKS[netId].TESTNET ? 'sokol' : ''
return (
<footer className={`footer ${footerClassName}`}>
<div className="container">
<p className="footer-rights">{moment().format('YYYY')} POA Network. All rights reserved.</p>
<a href="/poa-dapps-keys-generation" className="footer-logo" />
<div className="socials">
<a href="https://twitter.com/poanetwork" className="socials-i socials-i_twitter">
Twitter
</a>
<a href="https://poa.network" className="socials-i socials-i_oracles">
POA Network
</a>
<a href="https://t.me/oraclesnetwork" className="socials-i socials-i_telegram">
Telegram
</a>
<a href="https://github.com/poanetwork/" className="socials-i socials-i_github">
GitHub
</a>
</div>
</div>
</footer>
)
}
export default Footer

View File

@ -1,17 +0,0 @@
import React from 'react'
import { constants } from './constants'
let Header = ({ netId }) => {
const thisIsTestnet = netId in constants.NETWORKS && constants.NETWORKS[netId].TESTNET
const headerClassName = thisIsTestnet ? 'sokol' : ''
const logoClassName = thisIsTestnet ? 'header-logo-sokol' : 'header-logo'
return (
<header className={`header ${headerClassName}`}>
<div className="container">
<a href="/poa-dapps-keys-generation" className={logoClassName} />
</div>
</header>
)
}
export default Header

View File

@ -1,296 +0,0 @@
import React, { Component } from 'react'
import Tooltip from 'rc-tooltip'
import 'rc-tooltip/assets/bootstrap.css'
const encodeJson = json => {
const encoded = window.encodeURIComponent(JSON.stringify(json))
return `data:application/json;charset=utf-8,${encoded}`
}
export default class Keys extends Component {
constructor(props) {
super(props)
this.onVisibleChange = this.onVisibleChange.bind(this)
this.onCopyBtnClick = this.onCopyBtnClick.bind(this)
this.state = {
copyBtns: {
copyMiningPass: {
visible: false,
text: 'Copy'
},
copyVotingPass: {
visible: false,
text: 'Copy'
},
copyPayoutPass: {
visible: false,
text: 'Copy'
},
copyMiningKey: {
visible: false,
text: 'Copy'
},
copyVotingKey: {
visible: false,
text: 'Copy'
},
copyPayoutKey: {
visible: false,
text: 'Copy'
}
}
}
}
componentWillUpdate(nextProps, nextState) {
if (this.refs.miningKeyAddress) {
const Clipboard = require('clipboard')
// this.clipboard = new Clipboard(this.refs.copyBtn);
new Clipboard(this.refs.miningKeyAddress)
new Clipboard(this.refs.miningKeyPass)
new Clipboard(this.refs.payoutKeyAddress)
new Clipboard(this.refs.payoutKeyPass)
new Clipboard(this.refs.votingKeyAddress)
new Clipboard(this.refs.votingKeyPass)
}
}
onVisibleChange(id) {
console.log(id)
let copyBtns = this.state.copyBtns
copyBtns[id].visible = !copyBtns[id].visible
copyBtns[id].text = 'Copy'
this.setState({
copyBtns
})
// const id = e.target.id;
}
onCopyBtnClick(e) {
const id = e.target.id
let copyBtns = this.state.copyBtns
copyBtns[id].text = 'Copied!'
this.setState({
copyBtns
})
}
render() {
return (
<div className="container">
<div className="keys">
<div className="keys-i">
<p className="keys-title">Mining key</p>
<div className="keys-hash-container">
<p className="keys-hash" id="miningKey">
0x
{this.props.mining.jsonStore.address}
</p>
<Tooltip
visible={this.state.copyBtns.copyMiningKey.visible}
animation="zoom"
trigger="hover"
onVisibleChange={() => {
this.onVisibleChange('copyMiningKey')
}}
placement="right"
overlay={this.state.copyBtns.copyMiningKey.text}
>
<span
id="copyMiningKey"
onClick={this.onCopyBtnClick}
className="copy"
ref="miningKeyAddress"
data-clipboard-text={'0x' + this.props.mining.jsonStore.address}
/>
</Tooltip>
</div>
<p className="keys-hash">
<label className="password-label">Password:</label>
<input
disabled={true}
defaultValue={this.props.mining.password}
type="password"
id="miningKeyPass"
className="pass"
/>
<Tooltip
visible={this.state.copyBtns.copyMiningPass.visible}
animation="zoom"
trigger="hover"
onVisibleChange={() => {
this.onVisibleChange('copyMiningPass')
}}
placement="right"
overlay={this.state.copyBtns.copyMiningPass.text}
>
<span
id="copyMiningPass"
onClick={this.onCopyBtnClick}
className="copy"
ref="miningKeyPass"
data-clipboard-text={this.props.mining.password}
/>
</Tooltip>
</p>
<p className="keys-description">
Download this key and use it in your mining node to validate blocks in the network. Mined coins will be
deposited to your payout account.
</p>
<div className="keys-footer">
<a
className="keys-download"
id="miningKeyDownload"
href={encodeJson(this.props.mining.jsonStore)}
download={`mining_${this.props.mining.jsonStore.address}.json`}
>
Download Mining Key
</a>
</div>
</div>
<div className="keys-i">
<p className="keys-title">Payout key</p>
<div className="keys-hash-container">
<p className="keys-hash" id="payoutKey">
0x
{this.props.payout.jsonStore.address}
</p>
<Tooltip
visible={this.state.copyBtns.copyPayoutKey.visible}
animation="zoom"
trigger="hover"
onVisibleChange={() => {
this.onVisibleChange('copyPayoutKey')
}}
placement="right"
overlay={this.state.copyBtns.copyPayoutKey.text}
>
<span
id="copyPayoutKey"
onClick={this.onCopyBtnClick}
className="copy"
ref="payoutKeyAddress"
data-clipboard-text={'0x' + this.props.payout.jsonStore.address}
/>
</Tooltip>
</div>
<p className="keys-hash">
<label className="password-label">Password:</label>
<input
type="password"
disabled={true}
id="payoutKeyPass"
className="pass"
defaultValue={this.props.payout.password}
/>
<Tooltip
visible={this.state.copyBtns.copyPayoutPass.visible}
animation="zoom"
trigger="hover"
onVisibleChange={() => {
this.onVisibleChange('copyPayoutPass')
}}
placement="right"
overlay={this.state.copyBtns.copyPayoutPass.text}
>
<span
id="copyPayoutPass"
onClick={this.onCopyBtnClick}
className="copy"
ref="payoutKeyPass"
data-clipboard-text={this.props.payout.password}
/>
</Tooltip>
</p>
<p className="keys-description">
Download this key and use it on your client node/wallet to spend earned coins.
</p>
<div className="keys-footer">
<a
className="keys-download"
id="payoutKeyDownload"
href={encodeJson(this.props.payout.jsonStore)}
download={`payout_${this.props.payout.jsonStore.address}.json`}
>
Download Payout Key
</a>
</div>
</div>
<div className="keys-i">
<p className="keys-title">Voting key</p>
<div className="keys-hash-container">
<p className="keys-hash" id="votingKey">
0x
{this.props.voting.jsonStore.address}
</p>
<Tooltip
visible={this.state.copyBtns.copyVotingKey.visible}
animation="zoom"
trigger="hover"
onVisibleChange={() => {
this.onVisibleChange('copyVotingKey')
}}
placement="right"
overlay={this.state.copyBtns.copyVotingKey.text}
>
<span
id="copyVotingKey"
onClick={this.onCopyBtnClick}
className="copy"
ref="votingKeyAddress"
data-clipboard-text={'0x' + this.props.voting.jsonStore.address}
/>
</Tooltip>
</div>
<p className="keys-hash">
<label className="password-label">Password:</label>
<input
type="password"
disabled={true}
id="votingKeyPass"
className="pass"
defaultValue={this.props.voting.password}
/>
<Tooltip
visible={this.state.copyBtns.copyVotingPass.visible}
animation="zoom"
trigger="hover"
onVisibleChange={() => {
this.onVisibleChange('copyVotingPass')
}}
placement="right"
overlay={this.state.copyBtns.copyVotingPass.text}
>
<span
id="copyVotingPass"
onClick={this.onCopyBtnClick}
className="copy"
ref="votingKeyPass"
data-clipboard-text={this.props.voting.password}
/>
</Tooltip>
</p>
<p className="keys-description">
Download this key and use it on your client node to vote for necessary ballots, such as adding or removing
miners from the network.
</p>
<div className="keys-footer">
<a
className="keys-download"
id="votingKeyDownload"
href={encodeJson(this.props.voting.jsonStore)}
download={`voting_${this.props.voting.jsonStore.address}.json`}
>
Download Voting Key
</a>
</div>
</div>
</div>
<div className="keys-note">
<p className="keys-note-title">Important</p>
<p className="keys-note-description">
Do not close this tab until you download all keys and save passwords. Keep keys secure and protected. If you
lose your keys, you will need to get a new initial key using Voting DAPP.
</p>
</div>
</div>
)
}
}

View File

@ -1,30 +0,0 @@
import React from 'react'
import { constants } from './constants'
const styles = netId => {
const core = {
backgroundColor: 'rgba(35, 29, 115, 0.8)'
}
const sokol = {
backgroundColor: 'rgba(47, 109, 99, 0.8)'
}
if (netId in constants.NETWORKS) {
return constants.NETWORKS[netId].TESTNET ? sokol : core
}
return core
}
const Loading = ({ netId }) => (
<div className="loading-container" style={styles(netId)}>
<div className="loading">
<div className="loading-i" />
<div className="loading-i" />
<div className="loading-i" />
<div className="loading-i" />
<div className="loading-i" />
<div className="loading-i" />
</div>
</div>
)
export default Loading

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14">
<path fill="#fec042" fill-rule="evenodd" d="M13 10a1 1 0 0 1-1-1V2H5a1 1 0 0 1 0-2h8a1 1 0 0 1 1 1v8a1 1 0 0 1-1 1zm-3-5v8a1 1 0 0 1-1 1H1a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h8a1 1 0 0 1 1 1zM8 6H2v6h6V6z"/>
</svg>

After

Width:  |  Height:  |  Size: 277 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14">
<path fill="#5C34A2" fill-rule="evenodd" d="M13 10a1 1 0 0 1-1-1V2H5a1 1 0 0 1 0-2h8a1 1 0 0 1 1 1v8a1 1 0 0 1-1 1zm-3-5v8a1 1 0 0 1-1 1H1a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h8a1 1 0 0 1 1 1zM8 6H2v6h6V6z"/>
</svg>

After

Width:  |  Height:  |  Size: 277 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14">
<path fill="#8ce1d7" fill-rule="evenodd" d="M13 10a1 1 0 0 1-1-1V2H5a1 1 0 0 1 0-2h8a1 1 0 0 1 1 1v8a1 1 0 0 1-1 1zm-3-5v8a1 1 0 0 1-1 1H1a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h8a1 1 0 0 1 1 1zM8 6H2v6h6V6z"/>
</svg>

After

Width:  |  Height:  |  Size: 277 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 285 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 504 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 404 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 381 KiB

View File

@ -0,0 +1,43 @@
#ECSS (Enduring CSS) will be used
http://ecss.io/
##ECSS naming convention
.namespace-ModuleOrComponent_ChildNode-variant {}
- namespace: This is a required part of every selector. The micro-namespace should be all lowercase/train-case. It is typically an abbreviation to denote context or originating logic.
- ModuleOrComponent: This is a upper camel case/pascal case. It should always be preceded by a hyphen character (-).
- ChildNode: This is an optional section of the selector. It should be upper camel case/pascal case and preceded by an underscore (_).
- variant: This is a further optional section of the selector. It should be written all lowercase/train-case.
For example:
.hm-Item_Header {}
.hm-Item_Header-bg1 {} /* Image background 1 */
##ECSS component states
.is-Suspended {}
.is-Live {}
.is-Selected {}
.is-Busy {}
etc.
#CSS Overrides
Should be self contained.
For example:
.ip-Carousel {
font-size: $text13;
/* The override is here for when this key-selector sits within a ip-HomeCallouts element */
.ip-HomeCallouts & {
font-size: $text15;
}
}

View File

@ -0,0 +1 @@
Holds what we might call the boilerplate stuff for the project: reset (or Normalize.css, or whatever), typography, etc.

View File

@ -0,0 +1,11 @@
.hidden {
display: none;
}
.display-block {
display: block;
}
.display-inline {
display: inline;
}

View File

@ -0,0 +1,16 @@
.background-blur {
animation-duration: 0.25s;
animation-fill-mode: forwards;
animation-iteration-count: 1;
animation-name: sw-ModalAnimation_in;
animation-timing-function: linear;
}
@keyframes sw-ModalAnimation_in {
0% {
filter: blur(0);
}
100% {
filter: blur(2px);
}
}

View File

@ -0,0 +1,6 @@
@import 'reset';
@import 'normalize';
@import 'display';
@import 'effects';
@import 'typography';

View File

@ -0,0 +1,341 @@
/*! normalize.css v8.0.0 | MIT License | github.com/necolas/normalize.css */
/* Document
========================================================================== */
/**
* 1. Correct the line height in all browsers.
* 2. Prevent adjustments of font size after orientation changes in iOS.
*/
html {
line-height: 1.15; /* 1 */
-webkit-text-size-adjust: 100%; /* 2 */
}
/* Sections
========================================================================== */
/**
* Remove the margin in all browsers.
*/
body {
margin: 0;
}
/**
* Correct the font size and margin on `h1` elements within `section` and
* `article` contexts in Chrome, Firefox, and Safari.
*/
h1 {
font-size: 2em;
margin: 0.67em 0;
}
/* Grouping content
========================================================================== */
/**
* 1. Add the correct box sizing in Firefox.
* 2. Show the overflow in Edge and IE.
*/
hr {
box-sizing: content-box; /* 1 */
height: 0; /* 1 */
overflow: visible; /* 2 */
}
/**
* 1. Correct the inheritance and scaling of font size in all browsers.
* 2. Correct the odd `em` font sizing in all browsers.
*/
pre {
font-family: monospace, monospace; /* 1 */
font-size: 1em; /* 2 */
}
/* Text-level semantics
========================================================================== */
/**
* Remove the gray background on active links in IE 10.
*/
a {
background-color: transparent;
}
/**
* 1. Remove the bottom border in Chrome 57-
* 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
*/
abbr[title] {
border-bottom: none; /* 1 */
text-decoration: underline; /* 2 */
text-decoration: underline dotted; /* 2 */
}
/**
* Add the correct font weight in Chrome, Edge, and Safari.
*/
b,
strong {
font-weight: bolder;
}
/**
* 1. Correct the inheritance and scaling of font size in all browsers.
* 2. Correct the odd `em` font sizing in all browsers.
*/
code,
kbd,
samp {
font-family: monospace, monospace; /* 1 */
font-size: 1em; /* 2 */
}
/**
* Add the correct font size in all browsers.
*/
small {
font-size: 80%;
}
/**
* Prevent `sub` and `sup` elements from affecting the line height in
* all browsers.
*/
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
/* Embedded content
========================================================================== */
/**
* Remove the border on images inside links in IE 10.
*/
img {
border-style: none;
}
/* Forms
========================================================================== */
/**
* 1. Change the font styles in all browsers.
* 2. Remove the margin in Firefox and Safari.
*/
button,
input,
optgroup,
select,
textarea {
font-family: inherit; /* 1 */
font-size: 100%; /* 1 */
line-height: 1.15; /* 1 */
margin: 0; /* 2 */
}
/**
* Show the overflow in IE.
* 1. Show the overflow in Edge.
*/
button,
input { /* 1 */
overflow: visible;
}
/**
* Remove the inheritance of text transform in Edge, Firefox, and IE.
* 1. Remove the inheritance of text transform in Firefox.
*/
button,
select { /* 1 */
text-transform: none;
}
/**
* Correct the inability to style clickable types in iOS and Safari.
*/
button,
[type="button"],
[type="reset"],
[type="submit"] {
-webkit-appearance: button;
}
/**
* Remove the inner border and padding in Firefox.
*/
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
border-style: none;
padding: 0;
}
/**
* Restore the focus styles unset by the previous rule.
*/
button:-moz-focusring,
[type="button"]:-moz-focusring,
[type="reset"]:-moz-focusring,
[type="submit"]:-moz-focusring {
outline: 1px dotted ButtonText;
}
/**
* Correct the padding in Firefox.
*/
fieldset {
padding: 0.35em 0.75em 0.625em;
}
/**
* 1. Correct the text wrapping in Edge and IE.
* 2. Correct the color inheritance from `fieldset` elements in IE.
* 3. Remove the padding so developers are not caught out when they zero out
* `fieldset` elements in all browsers.
*/
legend {
box-sizing: border-box; /* 1 */
color: inherit; /* 2 */
display: table; /* 1 */
max-width: 100%; /* 1 */
padding: 0; /* 3 */
white-space: normal; /* 1 */
}
/**
* Add the correct vertical alignment in Chrome, Firefox, and Opera.
*/
progress {
vertical-align: baseline;
}
/**
* Remove the default vertical scrollbar in IE 10+.
*/
textarea {
overflow: auto;
}
/**
* 1. Add the correct box sizing in IE 10.
* 2. Remove the padding in IE 10.
*/
[type="checkbox"],
[type="radio"] {
box-sizing: border-box; /* 1 */
padding: 0; /* 2 */
}
/**
* Correct the cursor style of increment and decrement buttons in Chrome.
*/
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
/**
* 1. Correct the odd appearance in Chrome and Safari.
* 2. Correct the outline style in Safari.
*/
[type="search"] {
-webkit-appearance: textfield; /* 1 */
outline-offset: -2px; /* 2 */
}
/**
* Remove the inner padding in Chrome and Safari on macOS.
*/
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
/**
* 1. Correct the inability to style clickable types in iOS and Safari.
* 2. Change font properties to `inherit` in Safari.
*/
::-webkit-file-upload-button {
-webkit-appearance: button; /* 1 */
font: inherit; /* 2 */
}
/* Interactive
========================================================================== */
/*
* Add the correct display in Edge, IE 10+, and Firefox.
*/
details {
display: block;
}
/*
* Add the correct display in all browsers.
*/
summary {
display: list-item;
}
/* Misc
========================================================================== */
/**
* Add the correct display in IE 10+.
*/
template {
display: none;
}
/**
* Add the correct display in IE 10.
*/
[hidden] {
display: none;
}

View File

@ -0,0 +1,3 @@
* {
box-sizing: border-box;
}

View File

@ -0,0 +1,8 @@
@import url('https://fonts.googleapis.com/css?family=Nunito:300,400,600,700');
body {
-webkit-font-smoothing: antialiased;
color: $base-text-color;
font-family: "Nunito", sans-serif;
font-size: $base-font-size;
}

View File

@ -0,0 +1 @@
All kinds of specific modules like a slider, a loader, a widget, etc.

View File

@ -0,0 +1,14 @@
.lo-App {
align-items: center;
display: flex;
flex-direction: column;
justify-content: center;
min-height: fit-content;
width: 100%;
}
.lo-App_Content {
@include content-layout-width();
display: flex;
flex-grow: 1;
}

View File

@ -0,0 +1,13 @@
.ld-BaseLoader {
align-items: center;
background-color: rgba(#fff, 0.8);
bottom: 0;
display: flex;
flex-direction: column;
justify-content: center;
left: 0;
position: fixed;
right: 0;
top: 0;
z-index: 1000000;
}

View File

@ -0,0 +1,48 @@
$sw-ButtonDownload-height: 44px !default;
.sw-ButtonDownload {
@include button-base($poa-purple, $sw-ButtonDownload-height);
@include button-focus-active-hover($poa-purple);
@include button-disabled($poa-purple);
@include button-shadow($poa-purple);
&#{ & }-core {
background-color: $poa-purple;
@include button-focus-active-hover($poa-purple);
@include button-shadow($poa-purple);
}
&#{ & }-sokol {
background-color: $sokol-cyan;
@include button-focus-active-hover($sokol-cyan);
@include button-shadow($sokol-cyan);
}
&#{ & }-dai {
background-color: $xdai-orange;
@include button-focus-active-hover($xdai-orange);
@include button-shadow($xdai-orange);
}
.ky-Keys_Block & {
margin-top: auto;
@media (min-width: $breakpoint-lg) {
max-width: fit-content;
}
}
}
.sw-ButtonDownload_Text {
@include button-text(#fff, 16px);
margin-right: 65px;
}
.sw-ButtonDownload_Icon {
display: block;
height: 16px;
width: 18px;
}

View File

@ -0,0 +1,48 @@
$sw-ButtonGenerate-height: 44px !default;
.sw-ButtonGenerate {
@include button-base($poa-purple, $sw-ButtonGenerate-height);
@include button-focus-active-hover($poa-purple);
@include button-disabled($poa-purple);
@include button-shadow($poa-purple);
&#{ & }-core {
background-color: $poa-purple;
@include button-focus-active-hover($poa-purple);
@include button-shadow($poa-purple);
}
&#{ & }-sokol {
background-color: $sokol-cyan;
@include button-focus-active-hover($sokol-cyan);
@include button-shadow($sokol-cyan);
}
&#{ & }-dai {
background-color: $xdai-orange;
@include button-focus-active-hover($xdai-orange);
@include button-shadow($xdai-orange);
}
.hm-Home & {
width: 100%;
@media (min-width: $breakpoint-md) {
width: auto;
}
}
}
.sw-ButtonGenerate_Text {
@include button-text(#fff, 16px);
margin-right: 65px;
}
.sw-ButtonGenerate_Icon {
display: block;
height: 16px;
width: 18px;
}

View File

@ -0,0 +1,56 @@
.sw-Footer {
align-items: center;
background-color: $poa-purple;
color: #fff;
display: flex;
justify-content: center;
min-height: 50px;
overflow: hidden;
padding: 16px 0;
transition: background-color 0.25s ease-out;
width: 100%;
&#{ & }-core {
background-color: $poa-purple;
}
&#{ & }-sokol {
background-color: $sokol-cyan;
}
&#{ & }-dai {
background-color: $xdai-gray;
}
}
.sw-Footer_Content {
@include content-layout-width();
align-items: center;
display: flex;
flex-direction: column;
justify-content: center;
@media (min-width: $breakpoint-md) {
flex-direction: row;
justify-content: space-between;
}
}
.sw-Footer_Text {
color: #fff;
flex-grow: 1;
font-size: 11px;
font-weight: 300;
line-height: 1.2;
margin: 0;
padding: 15px 0 0 0;
text-align: center;
@media (min-width: $breakpoint-md) {
padding-top: 0;
}
.sw-Footer-dai & {
color: #333;
}
}

View File

@ -0,0 +1,27 @@
.sw-Header {
align-items: center;
background-color: $poa-purple;
color: #fff;
display: flex;
height: 70px;
justify-content: center;
overflow: hidden;
transition: background-color 0.25s ease-out;
width: 100%;
&#{ & }-core {
background-color: $poa-purple;
}
&#{ & }-sokol {
background-color: $sokol-cyan;
}
&#{ & }-dai {
background-color: $xdai-gray;
}
}
.sw-Header_Content {
@include content-layout-width();
}

View File

@ -0,0 +1,45 @@
.hm-Home {
align-items: center;
display: flex;
flex-direction: column;
max-width: 100%;
padding-bottom: 50px;
padding-top: 50px;
text-align: center;
@media (min-width: $breakpoint-xl) {
flex-direction: row;
justify-content: space-between;
text-align: left;
}
}
.hm-Home_TextContainer {
align-items: center;
display: flex;
flex-direction: column;
flex-grow: 1;
order: 2;
@media (min-width: $breakpoint-xl) {
align-items: flex-start;
order: 1;
padding: 0 45px 0 0;
}
}
.hm-Home_Title {
color: #333;
font-size: 24px;
font-weight: 400;
line-height: 1.2;
margin: 0 0 24px;
}
.hm-Home_Text {
color: #777;
font-size: 14px;
font-weight: 400;
line-height: 1.71;
margin: 0 0 30px;
}

View File

@ -0,0 +1,7 @@
.sw-IconGithub {
@include brand-icon-styles();
.ft-SocialIcons & {
margin-right: 10px;
}
}

View File

@ -0,0 +1,3 @@
.sw-IconPOA {
@include brand-icon-styles();
}

View File

@ -0,0 +1,7 @@
.sw-IconTelegram {
@include brand-icon-styles();
.ft-SocialIcons & {
margin-right: 10px;
}
}

View File

@ -0,0 +1,7 @@
.sw-IconTwitter {
@include brand-icon-styles();
.ft-SocialIcons & {
margin-right: 10px;
}
}

View File

@ -0,0 +1,180 @@
$ky-Keys-gap: 40px;
@mixin keys-color-variants-base($property) {
&#{ & }-core {
#{ $property }: $poa-purple;
}
&#{ & }-sokol {
#{ $property }: $sokol-cyan;
}
}
@mixin keys-color-variants($property) {
@include keys-color-variants-base($property);
&#{ & }-dai {
#{ $property }: $xdai-orange;
}
}
@mixin keys-color-variants-dai-dark($property) {
@include keys-color-variants-base($property);
&#{ & }-dai {
#{ $property }: #333;
}
}
.ky-Keys {
padding-bottom: $ky-Keys-gap;
padding-top: $ky-Keys-gap;
@media (min-width: $breakpoint-md) {
display: grid;
grid-column-gap: $ky-Keys-gap;
grid-row-gap: $ky-Keys-gap;
grid-template-columns: 1fr 1fr;
}
}
.ky-Keys_Block {
border-radius: 10px;
border: 1px solid $base-border-color;
display: flex;
flex-direction: column;
margin-bottom: $ky-Keys-gap;
padding: 30px 35px 30px 30px;
@media (min-width: $breakpoint-md) {
margin-bottom: 0;
}
@include keys-color-variants-base('border-color');
}
.ky-Keys_BlockTitle {
color: #333;
font-size: 18px;
font-weight: 400;
line-height: 1.2;
margin: 0 0 25px;
text-align: left;
@include keys-color-variants-dai-dark('color');
}
.ky-Keys_HashContainer {
display: flex;
margin-bottom: 15px;
}
.ky-Keys_Hash {
color: $poa-purple;
font-size: 14px;
font-weight: 400;
line-height: 1.2;
margin: 0;
text-align: left;
word-break: break-word;
@include keys-color-variants-dai-dark('color');
}
.ky-Keys_Copy {
background-image: url('#{ $base-images-path }/Keys/poa.svg');
background-position: 50% 50%;
background-repeat: no-repeat;
background-size: 14px 14px;
cursor: pointer;
height: 20px;
width: 20px;
&#{ & }-core {
background-image: url('#{ $base-images-path }/Keys/poa.svg');
}
&#{ & }-sokol {
background-image: url('#{ $base-images-path }/Keys/sokol.svg');
}
&#{ & }-dai {
background-image: url('#{ $base-images-path }/Keys/dai.svg');
}
.ky-Keys_HashContainer & {
margin-left: 3px;
margin-top: -4px;
}
.ky-Keys_PasswordContainer & {
margin-left: 3px;
}
}
.ky-Keys_PasswordContainer {
align-items: center;
display: flex;
margin-bottom: 25px;
}
.ky-Keys_PasswordLabel {
color: #333;
font-size: 14px;
font-weight: 400;
line-height: 1.2;
text-align: left;
.ky-Keys_PasswordContainer & {
margin-right: 5px;
}
}
.ky-Keys_PasswordInput {
background-color: transparent;
border: none;
color: #333;
font-size: 14px;
font-weight: 400;
line-height: 1.2;
margin: 0;
padding: 0;
text-align: left;
}
.ky-Keys_Description {
color: #777;
font-size: 12px;
font-weight: 400;
line-height: 1.5;
margin: 0 0 25px;
text-align: left;
}
.ky-Keys_Warning {
color: $poa-purple;
font-size: 14px;
font-weight: 400;
line-height: 1.5;
margin: 0;
text-align: left;
@include keys-color-variants-dai-dark('color');
}
.ky-Keys_WarningIcon {
height: 48px;
margin-bottom: 30px;
width: 48px;
}
.ky-Keys_WarningIconPath {
@include keys-color-variants('fill');
}

View File

@ -0,0 +1,79 @@
.ld-Loading {
align-items: center;
background-color: rgba($poa-purple, 0.5);
bottom: 0;
display: flex;
flex-direction: column;
justify-content: center;
left: 0;
position: fixed;
right: 0;
top: 0;
z-index: 1000000;
&#{ & }-core {
background-color: rgba($poa-purple, 0.5);
}
&#{ & }-sokol {
background-color: rgba($sokol-cyan, 0.5);
}
&#{ & }-dai {
background-color: rgba($xdai-orange, 0.5);
}
}
.ld-Loading_Animation {
display: flex;
justify-content: space-between;
width: 206px;
}
.ld-Loading_Image {
margin-bottom: 40px;
width: 120px;
}
.ld-Loading_AnimationItem {
animation-duration: 2s;
animation-fill-mode: forwards;
animation-iteration-count: infinite;
animation-name: fadeOut;
animation-timing-function: linear;
background-color: #fff;
border-radius: 50%;
height: 9px;
opacity: .2;
width: 9px;
&:nth-child(2) {
animation-delay: .1s;
}
&:nth-child(3) {
animation-delay: .2s;
}
&:nth-child(4) {
animation-delay: .3s;
}
&:nth-child(5) {
animation-delay: .4s;
}
&:nth-child(6) {
animation-delay: .5s;
}
}
@keyframes fadeOut {
0% {
opacity: .2;
}
20% {
opacity: 1;
transform: scale(1);
}
100% {
opacity: .2;
transform: scale(0.3);
}
}

View File

@ -0,0 +1,20 @@
.sw-LogoDai {
display: block;
text-decoration: none;
.sw-Header & {
height: 58px;
width: 167px;
}
.sw-Footer & {
width: 120px;
}
}
.sw-LogoDai_Image {
display: block;
height: 100%;
width: 100%;
}

View File

@ -0,0 +1,20 @@
.sw-LogoPOA {
display: block;
text-decoration: none;
.sw-Header & {
height: 26px;
width: 167px;
}
.sw-Footer & {
width: 130px;
}
}
.sw-LogoPOA_Image {
display: block;
height: 100%;
width: 100%;
}

View File

@ -0,0 +1,20 @@
.sw-LogoSokol {
display: block;
text-decoration: none;
.sw-Header & {
height: 30px;
width: 178px;
}
.sw-Footer & {
height: 26px;
}
}
.sw-LogoSokol_Image {
display: block;
height: 100%;
width: 100%;
}

View File

@ -0,0 +1,31 @@
.hm-MainImage {
align-items: center;
display: flex;
max-width: 100%;
order: 1;
@media (min-width: $breakpoint-xl) {
order: 2;
}
}
.hm-MainImage_Img {
@include aspect-ratio(520px, 408px);
background-position: 50% 50%;
background-repeat: no-repeat;
background-size: cover;
width: 520px;
&,
&#{ & }-core {
@include image-retina('#{ $base-images-path }/MainImage/poa/image', 'png');
}
&#{ & }-sokol {
@include image-retina('#{ $base-images-path }/MainImage/sokol/image', 'png');
}
&#{ & }-dai {
@include image-retina('#{ $base-images-path }/MainImage/dai/image', 'png');
}
}

View File

@ -0,0 +1,12 @@
$ft-SocialIcons_Icon-dimensions: 30px !default;
.ft-SocialIcons {
align-items: center;
display: flex;
justify-content: space-between;
padding-top: 15px;
@media (min-width: $breakpoint-md) {
padding-top: 0;
}
}

View File

@ -0,0 +1,18 @@
@import "App";
@import "BaseLoader";
@import "ButtonDownload";
@import "ButtonGenerate";
@import "Footer";
@import "Header";
@import "Home";
@import "IconGithub";
@import "IconPOA";
@import "IconTelegram";
@import "IconTwitter";
@import "Keys";
@import "Loading";
@import "LogoDai";
@import "LogoPOA";
@import "LogoSokol";
@import "MainImage";
@import "SocialIcons";

View File

@ -0,0 +1 @@
All Sass tools and helpers well use across the project: variables, mixins, functions, placeholders, etc.

View File

@ -0,0 +1,9 @@
@mixin brand-icon-styles() {
align-items: center;
border-radius: 3px;
display: flex;
font-size: 0;
justify-content: center;
line-height: 0;
transition: background-color 0.25s ease-out;
}

View File

@ -0,0 +1,56 @@
@mixin button-base($button-background-color, $button-height) {
align-items: center;
background-color: $button-background-color;
border-radius: 5px;
border: none;
cursor: pointer;
display: flex;
height: $button-height;
justify-content: space-between;
line-height: $button-height;
outline: none;
padding: 0 15px;
text-decoration: none;
transition: background-color 0.25s ease-out;
}
@mixin button-shadow($button-shadow-color) {
box-shadow: 0 5px 10px 0 rgba($button-shadow-color, 0.3);
}
@mixin button-text($text-color: #fff, $font-size: 16px) {
color: $text-color;
display: block;
font-size: $font-size;
font-weight: 400;
line-height: 1.2;
text-align: left;
white-space: nowrap;
}
@mixin button-focus-active-hover($button-background-color) {
&:focus,
&:active,
&:hover {
background-color: darken($button-background-color, 10%);
}
&[disabled] {
&:focus,
&.active,
&:hover {
background-color: $button-background-color;
}
}
}
@mixin button-disabled($button-background-color) {
&[disabled] {
cursor: not-allowed;
opacity: 0.7;
}
}

View File

@ -0,0 +1,16 @@
@mixin content-layout-width() {
max-width: 100%;
padding-left: $container-horizontal-padding-mobile;
padding-right: $container-horizontal-padding-mobile;
width: $container-max-width;
@media (min-width: $breakpoint-md) {
padding-left: $container-horizontal-padding-tablet;
padding-right: $container-horizontal-padding-tablet;
}
@media (min-width: $breakpoint-xl) {
padding-left: $container-horizontal-padding-desktop;
padding-right: $container-horizontal-padding-desktop;
}
}

View File

@ -0,0 +1,7 @@
@import 'variables';
@import 'mixins';
@import 'typography';
@import 'brand-icons-mixins';
@import 'button-mixins';
@import 'content-layout';

View File

@ -0,0 +1,117 @@
// avoid text selection
@mixin not-selectable-text() {
/* Firefox all */
-moz-user-select: none;
/* IE 10+ */
-ms-user-select: none;
/* Chrome all / Safari all */
-webkit-user-select: none;
/* Likely future */
user-select: none;
}
// use for retina background images @1x / @2x / @3x
@mixin image-retina($filename, $extension) {
background-image: url($filename + '.' + $extension);
@media (-webkit-min-device-pixel-ratio: 2),
(-moz-min-device-pixel-ratio: 2),
(min-resolution: 192dpi),
(min-resolution: 2dppx) {
& {
background-image: url($filename + '@2x.' + $extension);
}
}
@media (-webkit-min-device-pixel-ratio: 3),
(-moz-min-device-pixel-ratio: 3),
(min-resolution: 288dpi),
(min-resolution: 3dppx) {
& {
background-image: url($filename + '@3x.' + $extension);
}
}
}
@mixin aspect-ratio($width, $height) {
position: relative;
&:before {
content: "";
display: block;
padding-top: ($height / $width) * 100%;
width: 100%;
}
> .content-ratio {
bottom: 0;
left: 0;
position: absolute;
right: 0;
top: 0;
}
}
// placeholder color
@mixin placeholder-color($color) {
&::-webkit-input-placeholder {
/* WebKit browsers */
color: $color !important;
opacity: 1 !important;
}
&:-moz-placeholder {
/* Mozilla Firefox 4 to 18 */
color: $color !important;
opacity: 1 !important;
}
&::-moz-placeholder {
/* Mozilla Firefox 19+ */
color: $color !important;
opacity: 1 !important;
}
&:-ms-input-placeholder {
/* Internet Explorer 10+ */
color: $color !important;
opacity: 1 !important;
}
}
// placeholder font size
@mixin placeholder-font-size($font-size) {
&::-webkit-input-placeholder {
/* WebKit browsers */
font-size: $font-size !important;
}
&:-moz-placeholder {
/* Mozilla Firefox 4 to 18 */
font-size: $font-size !important;
}
&::-moz-placeholder {
/* Mozilla Firefox 19+ */
font-size: $font-size !important;
}
&:-ms-input-placeholder {
/* Internet Explorer 10+ */
font-size: $font-size !important;
}
}
// placeholder font style
@mixin placeholder-font-style($font-style) {
&::-webkit-input-placeholder {
/* WebKit browsers */
font-style: $font-style !important;
}
&:-moz-placeholder {
/* Mozilla Firefox 4 to 18 */
font-style: $font-style !important;
}
&::-moz-placeholder {
/* Mozilla Firefox 19+ */
font-style: $font-style !important;
}
&:-ms-input-placeholder {
/* Internet Explorer 10+ */
font-style: $font-style !important;
}
}

View File

@ -0,0 +1,31 @@
.text-light {
font-weight: 300;
}
.text-normal {
font-weight: 400;
}
.text-bold {
font-weight: 700;
}
.text-semibold {
font-weight: 600;
}
.text-italic {
font-style: italic;
}
.text-left {
text-align: left;
}
.text-right {
text-align: right;
}
.text-center {
text-align: center;
}

View File

@ -0,0 +1,35 @@
// brand colors
$poa-purple: #5a2da5;
$sokol-cyan: #8ce1d7;
$xdai-orange: #fec042;
$xdai-gray: #f2f6f8;
// base colors
$base-border-color: #dfdfdf;
$base-title-color: #333;
$base-text-color: #777;
$base-text-color-light: #9b9b9b;
// typography
$base-font-size: 14px;
// paths
$base-images-path: '../../assets/images';
// layout
$container-max-width: 1000px;
$container-horizontal-padding-desktop: 20px;
$container-horizontal-padding-tablet: 20px;
$container-horizontal-padding-mobile: 10px;
// responsive breakpoints
$breakpoint-xs: 320px;
$breakpoint-sm: 480px;
$breakpoint-md: 768px;
$breakpoint-lg: 992px;
$breakpoint-xl: 1024px;
$breakpoint-xxl: 1280px;
$breakpoint-xxxl: 1366px;
// z-index
$z-index-max: 12345678;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,6 @@
@import 'helpers/index';
@import 'vendors/index';
@import 'base/index';
@import 'layout/index';
@import 'pages/index';
@import 'components/index';

View File

@ -0,0 +1 @@
Some styles for the main sections of the layout (header, footer, and so on). It can also contain the _grid file for the grid system used to build the layout.

View File

@ -0,0 +1,13 @@
html,
body,
#root,
html.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown),
body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown) {
// swal2-shown above are for when sweet alert is showing
height: 100%;
}
#root {
display: flex;
overflow: auto;
}

View File

@ -0,0 +1 @@
@import "base";

View File

@ -0,0 +1 @@
Page-specific styles, For example: for the home page you can have a _home.scss.

View File

View File

@ -0,0 +1 @@
Contains all the CSS files from external libraries and frameworks: Bootstrap, jQuery, etc.

View File

@ -0,0 +1 @@
@import 'rc-tooltip.scss';

View File

@ -0,0 +1,222 @@
.rc-tooltip.rc-tooltip-zoom-enter,
.rc-tooltip.rc-tooltip-zoom-leave {
display: block;
}
.rc-tooltip-zoom-enter,
.rc-tooltip-zoom-appear {
opacity: 0;
-webkit-animation-duration: 0.3s;
animation-duration: 0.3s;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
-webkit-animation-timing-function: cubic-bezier(0.18, 0.89, 0.32, 1.28);
animation-timing-function: cubic-bezier(0.18, 0.89, 0.32, 1.28);
-webkit-animation-play-state: paused;
animation-play-state: paused;
}
.rc-tooltip-zoom-leave {
-webkit-animation-duration: 0.3s;
animation-duration: 0.3s;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
-webkit-animation-timing-function: cubic-bezier(0.6, -0.3, 0.74, 0.05);
animation-timing-function: cubic-bezier(0.6, -0.3, 0.74, 0.05);
-webkit-animation-play-state: paused;
animation-play-state: paused;
}
.rc-tooltip-zoom-enter.rc-tooltip-zoom-enter-active,
.rc-tooltip-zoom-appear.rc-tooltip-zoom-appear-active {
-webkit-animation-name: rcToolTipZoomIn;
animation-name: rcToolTipZoomIn;
-webkit-animation-play-state: running;
animation-play-state: running;
}
.rc-tooltip-zoom-leave.rc-tooltip-zoom-leave-active {
-webkit-animation-name: rcToolTipZoomOut;
animation-name: rcToolTipZoomOut;
-webkit-animation-play-state: running;
animation-play-state: running;
}
@-webkit-keyframes rcToolTipZoomIn {
0% {
opacity: 0;
-webkit-transform-origin: 50% 50%;
transform-origin: 50% 50%;
-webkit-transform: scale(0, 0);
transform: scale(0, 0);
}
100% {
opacity: 1;
-webkit-transform-origin: 50% 50%;
transform-origin: 50% 50%;
-webkit-transform: scale(1, 1);
transform: scale(1, 1);
}
}
@keyframes rcToolTipZoomIn {
0% {
opacity: 0;
-webkit-transform-origin: 50% 50%;
transform-origin: 50% 50%;
-webkit-transform: scale(0, 0);
transform: scale(0, 0);
}
100% {
opacity: 1;
-webkit-transform-origin: 50% 50%;
transform-origin: 50% 50%;
-webkit-transform: scale(1, 1);
transform: scale(1, 1);
}
}
@-webkit-keyframes rcToolTipZoomOut {
0% {
opacity: 1;
-webkit-transform-origin: 50% 50%;
transform-origin: 50% 50%;
-webkit-transform: scale(1, 1);
transform: scale(1, 1);
}
100% {
opacity: 0;
-webkit-transform-origin: 50% 50%;
transform-origin: 50% 50%;
-webkit-transform: scale(0, 0);
transform: scale(0, 0);
}
}
@keyframes rcToolTipZoomOut {
0% {
opacity: 1;
-webkit-transform-origin: 50% 50%;
transform-origin: 50% 50%;
-webkit-transform: scale(1, 1);
transform: scale(1, 1);
}
100% {
opacity: 0;
-webkit-transform-origin: 50% 50%;
transform-origin: 50% 50%;
-webkit-transform: scale(0, 0);
transform: scale(0, 0);
}
}
.rc-tooltip {
position: absolute;
z-index: 1070;
display: block;
visibility: visible;
font-size: 12px;
line-height: 1.5;
opacity: 0.9;
}
.rc-tooltip-hidden {
display: none;
}
.rc-tooltip-placement-top,
.rc-tooltip-placement-topLeft,
.rc-tooltip-placement-topRight {
padding: 5px 0 9px 0;
}
.rc-tooltip-placement-right,
.rc-tooltip-placement-rightTop,
.rc-tooltip-placement-rightBottom {
padding: 0 5px 0 9px;
}
.rc-tooltip-placement-bottom,
.rc-tooltip-placement-bottomLeft,
.rc-tooltip-placement-bottomRight {
padding: 9px 0 5px 0;
}
.rc-tooltip-placement-left,
.rc-tooltip-placement-leftTop,
.rc-tooltip-placement-leftBottom {
padding: 0 9px 0 5px;
}
.rc-tooltip-inner {
padding: 8px 10px;
color: #fff;
text-align: left;
text-decoration: none;
background-color: #373737;
border-radius: 6px;
box-shadow: 0 0 4px rgba(0, 0, 0, 0.17);
min-height: 34px;
}
.rc-tooltip-arrow {
position: absolute;
width: 0;
height: 0;
border-color: transparent;
border-style: solid;
}
.rc-tooltip-placement-top .rc-tooltip-arrow,
.rc-tooltip-placement-topLeft .rc-tooltip-arrow,
.rc-tooltip-placement-topRight .rc-tooltip-arrow {
bottom: 4px;
margin-left: -5px;
border-width: 5px 5px 0;
border-top-color: #373737;
}
.rc-tooltip-placement-top .rc-tooltip-arrow {
left: 50%;
}
.rc-tooltip-placement-topLeft .rc-tooltip-arrow {
left: 15%;
}
.rc-tooltip-placement-topRight .rc-tooltip-arrow {
right: 15%;
}
.rc-tooltip-placement-right .rc-tooltip-arrow,
.rc-tooltip-placement-rightTop .rc-tooltip-arrow,
.rc-tooltip-placement-rightBottom .rc-tooltip-arrow {
left: 4px;
margin-top: -5px;
border-width: 5px 5px 5px 0;
border-right-color: #373737;
}
.rc-tooltip-placement-right .rc-tooltip-arrow {
top: 50%;
}
.rc-tooltip-placement-rightTop .rc-tooltip-arrow {
top: 15%;
margin-top: 0;
}
.rc-tooltip-placement-rightBottom .rc-tooltip-arrow {
bottom: 15%;
}
.rc-tooltip-placement-left .rc-tooltip-arrow,
.rc-tooltip-placement-leftTop .rc-tooltip-arrow,
.rc-tooltip-placement-leftBottom .rc-tooltip-arrow {
right: 4px;
margin-top: -5px;
border-width: 5px 0 5px 5px;
border-left-color: #373737;
}
.rc-tooltip-placement-left .rc-tooltip-arrow {
top: 50%;
}
.rc-tooltip-placement-leftTop .rc-tooltip-arrow {
top: 15%;
margin-top: 0;
}
.rc-tooltip-placement-leftBottom .rc-tooltip-arrow {
bottom: 15%;
}
.rc-tooltip-placement-bottom .rc-tooltip-arrow,
.rc-tooltip-placement-bottomLeft .rc-tooltip-arrow,
.rc-tooltip-placement-bottomRight .rc-tooltip-arrow {
top: 4px;
margin-left: -5px;
border-width: 0 5px 5px;
border-bottom-color: #373737;
}
.rc-tooltip-placement-bottom .rc-tooltip-arrow {
left: 50%;
}
.rc-tooltip-placement-bottomLeft .rc-tooltip-arrow {
left: 15%;
}
.rc-tooltip-placement-bottomRight .rc-tooltip-arrow {
right: 15%;
}

View File

@ -0,0 +1,10 @@
import React from 'react'
import loadingImg from './loading.gif'
export const BaseLoader = () => {
return (
<div className={`ld-BaseLoader`}>
<img className={`ld-BaseLoader_Image`} src={loadingImg} alt="" />
</div>
)
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18">
<path fill="#FFF" fill-rule="evenodd" d="M17 18H1a1 1 0 0 1-1-1v-2a1 1 0 0 1 2 0v1h14v-1a1 1 0 0 1 2 0v2a1 1 0 0 1-1 1zm-7.134-4.332a1.08 1.08 0 0 1-.78.315C9.056 13.985 9.03 14 9 14c-.03 0-.056-.015-.086-.017a1.08 1.08 0 0 1-.78-.315L4.298 9.833a1.087 1.087 0 0 1 0-1.535 1.087 1.087 0 0 1 1.535 0L8 10.466V1a1 1 0 0 1 2 0v9.466l2.167-2.168a1.087 1.087 0 0 1 1.535 0 1.087 1.087 0 0 1 0 1.535l-3.836 3.835z"/>
</svg>

After

Width:  |  Height:  |  Size: 486 B

View File

@ -0,0 +1,25 @@
import React from 'react'
import icon from './icon.svg'
export const ButtonDownload = ({
download = undefined,
extraClassName = '',
href = '',
id = '',
networkBranch = '',
onClick = null,
text = 'Download'
}) => {
return (
<a
className={`sw-ButtonDownload ${extraClassName} ${'sw-ButtonDownload-' + networkBranch}`}
download={download}
href={href}
id={id}
onClick={onClick}
>
<span className="sw-ButtonDownload_Text">{text}</span>
<img src={icon} alt="" className="sw-ButtonDownload_Icon" />
</a>
)
}

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="16">
<path fill="#FFF" fill-rule="evenodd" d="M13 10a4.974 4.974 0 0 1-2.797-.855l-3.33 3.33c-.044.084-.088.169-.159.239-.07.071-.155.115-.239.159l-2.602 2.602c-.044.084-.088.169-.159.239a.956.956 0 0 1-.733.275.949.949 0 0 1-.694-.275c-.048-.049-.073-.109-.109-.165L.286 13.657a.969.969 0 1 1 1.371-1.371l1.356 1.356 1.629-1.629-1.356-1.356a.969.969 0 1 1 1.371-1.371l1.356 1.356 2.843-2.844A5 5 0 1 1 13 10zm0-8a3 3 0 1 0 0 6 3 3 0 0 0 0-6z"/>
</svg>

After

Width:  |  Height:  |  Size: 516 B

View File

@ -0,0 +1,16 @@
import React from 'react'
import icon from './icon.svg'
export const ButtonGenerate = ({ extraClassName = '', networkBranch = '', onClick = null, disabled = false }) => {
return (
<button
className={`sw-ButtonGenerate ${extraClassName} ${'sw-ButtonGenerate-' + networkBranch}`}
disabled={disabled}
onClick={onClick}
type="button"
>
<span className="sw-ButtonGenerate_Text">Generate Keys</span>
<img src={icon} alt="" className="sw-ButtonGenerate_Icon" />
</button>
)
}

View File

@ -0,0 +1,17 @@
import React from 'react'
import moment from 'moment'
import { Logo } from '../Logo'
import { SocialIcons } from '../SocialIcons'
import { constants } from '../../utils/constants'
export const Footer = ({ extraClassName = '', networkBranch = false }) => {
return (
<footer className={`sw-Footer ${extraClassName} ${networkBranch ? 'sw-Footer-' + networkBranch : ''}`}>
<div className="sw-Footer_Content">
<Logo networkBranch={networkBranch} href={constants.baseURL} />
<p className="sw-Footer_Text">{moment().format('YYYY')} POA Network. All rights reserved.</p>
<SocialIcons networkBranch={networkBranch} />
</div>
</footer>
)
}

View File

@ -0,0 +1,13 @@
import React from 'react'
import { constants } from '../../utils/constants'
import { Logo } from '../Logo'
export const Header = ({ extraClassName = '', networkBranch = '' }) => {
return (
<header className={`sw-Header ${extraClassName} ${'sw-Header-' + networkBranch}`}>
<div className="sw-Header_Content">
<Logo networkBranch={networkBranch} href={constants.baseURL} />
</div>
</header>
)
}

View File

@ -0,0 +1,19 @@
import React from 'react'
import { ButtonGenerate } from '../ButtonGenerate'
import { MainImage } from '../MainImage'
export const Home = ({ extraClassName = '', networkBranch = false, onClick = null, disabled = false }) => {
return (
<div className={`hm-Home ${extraClassName}`}>
<div className="hm-Home_TextContainer">
<h1 className="hm-Home_Title">Create keys from initial key</h1>
<p className="hm-Home_Text">
In this application, you will create mining, payout and voting keys. The app will make your initial key
unusable after the process. Please proceed with care, don't lose your keys and follow instructions.
</p>
<ButtonGenerate onClick={onClick} disabled={disabled} networkBranch={networkBranch} />
</div>
<MainImage networkBranch={networkBranch} />
</div>
)
}

View File

@ -0,0 +1,39 @@
import React from 'react'
export const IconGithub = ({
backgroundColor = '#fff',
color = '#000',
height = 30,
iconHeight = 16,
iconWidth = 16,
text = '',
url = '',
width = 30
}) => {
return (
<a
className={`sw-IconGithub`}
href={url}
rel="noopener noreferrer"
style={{ backgroundColor: backgroundColor, height: height, width: width }}
target="_blank"
title={text}
>
<svg
className={`sw-IconGithub_SVG`}
style={{ height: iconHeight, width: iconWidth }}
viewBox="0 0 16 16"
xmlns="http://www.w3.org/2000/svg"
>
<path
fill={color}
fillRule="evenodd"
d="M14.928 4.084a8.067 8.067 0 0 0-2.912-2.985A7.673 7.673 0 0 0 8-.001a7.67 7.67 0 0 0-4.016 1.1 8.06 8.06 0 0 0-2.912 2.985C.356 5.34-.001 6.712-.001 8.201c0 1.787.508 3.394 1.526 4.821 1.017 1.428 2.332 2.416 3.943 2.964.188.035.327.01.417-.075a.422.422 0 0 0 .135-.32l-.005-.577c-.003-.363-.005-.68-.005-.95l-.24.042a2.985 2.985 0 0 1-.578.038 4.418 4.418 0 0 1-.724-.075 1.6 1.6 0 0 1-.698-.32 1.359 1.359 0 0 1-.458-.657l-.105-.246a2.64 2.64 0 0 0-.328-.544c-.149-.2-.3-.335-.453-.406l-.073-.053a.78.78 0 0 1-.135-.129.572.572 0 0 1-.094-.15c-.021-.049-.004-.09.052-.122.056-.032.156-.048.302-.048l.209.032c.138.028.31.113.515.256.205.142.374.328.506.555.159.292.352.515.578.668.225.153.453.229.682.229.229 0 .427-.017.594-.053.167-.036.323-.089.469-.16.062-.477.232-.844.51-1.1a6.938 6.938 0 0 1-1.068-.193 4.188 4.188 0 0 1-.979-.416 2.828 2.828 0 0 1-.839-.716c-.222-.284-.404-.658-.547-1.121-.142-.463-.213-.997-.213-1.602 0-.862.274-1.595.823-2.2-.257-.648-.233-1.374.073-2.179.201-.064.5-.016.896.144.396.161.686.298.87.412.184.113.332.21.443.288a7.225 7.225 0 0 1 2-.278c.687 0 1.354.093 2.001.278l.395-.256a5.53 5.53 0 0 1 .959-.47c.368-.142.649-.182.844-.117.312.804.34 1.53.083 2.178.549.605.823 1.338.823 2.2 0 .605-.071 1.141-.213 1.607-.143.467-.327.84-.553 1.122a2.926 2.926 0 0 1-.843.71 4.194 4.194 0 0 1-.98.416c-.316.086-.672.15-1.068.193.362.32.542.826.542 1.516v2.253c0 .129.044.235.13.321.087.085.224.11.412.074 1.611-.548 2.926-1.536 3.943-2.963 1.018-1.427 1.526-3.035 1.526-4.822 0-1.488-.358-2.86-1.073-4.116z"
/>
</svg>
<span style={{ fontSize: 0 }} className="sw-IconGithub_Text">
{text}
</span>
</a>
)
}

View File

@ -0,0 +1,37 @@
import React from 'react'
export const IconPOA = ({
backgroundColor = '#fff',
color = '#000',
height = 30,
iconHeight = 8,
iconWidth = 18,
text = '',
url = '',
width = 30
}) => {
return (
<a
className={`sw-IconPOA`}
href={url}
rel="noopener noreferrer"
style={{ backgroundColor: backgroundColor, height: height, width: width }}
target="_blank"
title={text}
>
<svg
className="sw-IconPOA_SVG"
style={{ height: iconHeight, width: iconWidth }}
viewBox="0 0 125 40"
xmlns="http://www.w3.org/2000/svg"
>
<g fill={color} fillRule="evenodd">
<path d="M61.4 0C50.482 0 41.6 8.883 41.6 19.8c0 10.918 8.882 19.8 19.8 19.8 10.918 0 19.8-8.882 19.8-19.8C81.2 8.883 72.318 0 61.4 0M21.206 31.718h2.505c8.06 0 14.949-6.26 15.24-14.323C39.254 8.95 32.476 1.98 24.103 1.98H3.127C2.504 1.98 2 2.485 2 3.108v34.044c0 .622.504 1.128 1.127 1.128H18.88c.615 0 1.117-.494 1.127-1.11l.073-4.343a1.127 1.127 0 0 1 1.126-1.109M98.002 1.271l-21.295 34.65c-.388.745.16 1.629 1.014 1.632l17.47.067 25.129-.067c.852-.003 1.401-.887 1.013-1.632l-21.294-34.65c-.425-.815-1.612-.815-2.037 0" />
</g>
</svg>
<span style={{ fontSize: 0 }} className="sw-IconPOA_Text">
{text}
</span>
</a>
)
}

View File

@ -0,0 +1,42 @@
import React from 'react'
export const IconTelegram = ({
backgroundColor = '#fff',
color = '#000',
height = 30,
iconHeight = 16,
iconWidth = 16,
text = '',
url = '',
width = 30
}) => {
return (
<a
className={`sw-IconTelegram`}
href={url}
rel="noopener noreferrer"
style={{ backgroundColor: backgroundColor, height: height, width: width }}
target="_blank"
title={text}
>
<svg
className="sw-IconTelegram_SVG"
style={{ height: iconHeight, width: iconWidth }}
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
clipRule="evenodd"
d="M18.384,22.779c0.322,0.228 0.737,0.285 1.107,0.145c0.37,-0.141 0.642,-0.457 0.724,-0.84c0.869,-4.084 2.977,-14.421 3.768,-18.136c0.06,-0.28 -0.04,-0.571 -0.26,-0.758c-0.22,-0.187 -0.525,-0.241 -0.797,-0.14c-4.193,1.552 -17.106,6.397 -22.384,8.35c-0.335,0.124 -0.553,0.446 -0.542,0.799c0.012,0.354 0.25,0.661 0.593,0.764c2.367,0.708 5.474,1.693 5.474,1.693c0,0 1.452,4.385 2.209,6.615c0.095,0.28 0.314,0.5 0.603,0.576c0.288,0.075 0.596,-0.004 0.811,-0.207c1.216,-1.148 3.096,-2.923 3.096,-2.923c0,0 3.572,2.619 5.598,4.062Zm-11.01,-8.677l1.679,5.538l0.373,-3.507c0,0 6.487,-5.851 10.185,-9.186c0.108,-0.098 0.123,-0.262 0.033,-0.377c-0.089,-0.115 -0.253,-0.142 -0.376,-0.064c-4.286,2.737 -11.894,7.596 -11.894,7.596Z"
fill={color}
fillRule="evenodd"
strokeLinejoin="round"
strokeMiterlimit="1.41421"
/>
</svg>
<span style={{ fontSize: 0 }} className="sw-IconTelegram_Text">
{text}
</span>
</a>
)
}

View File

@ -0,0 +1,39 @@
import React from 'react'
export const IconTwitter = ({
backgroundColor = '#fff',
color = '#000',
height = 30,
iconHeight = 16,
iconWidth = 16,
text = '',
url = '',
width = 30
}) => {
return (
<a
className={`sw-IconTwitter`}
href={url}
rel="noopener noreferrer"
style={{ backgroundColor: backgroundColor, height: height, width: width }}
target="_blank"
title={text}
>
<svg
className="sw-IconTwitter_SVG"
style={{ height: iconHeight, width: iconWidth }}
viewBox="0 0 16 12"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M15.086.222a6.236 6.236 0 0 1-1.955.735A3.089 3.089 0 0 0 10.885 0c-1.7 0-3.077 1.357-3.077 3.03 0 .237.027.469.079.69A8.781 8.781 0 0 1 1.545.554a2.974 2.974 0 0 0-.416 1.523c0 1.052.544 1.979 1.368 2.522a3.117 3.117 0 0 1-1.393-.381v.038c0 1.468 1.061 2.692 2.468 2.972a3.18 3.18 0 0 1-1.39.051 3.074 3.074 0 0 0 2.874 2.105 6.24 6.24 0 0 1-3.822 1.296c-.248 0-.493-.014-.734-.041A8.814 8.814 0 0 0 5.217 12c5.66 0 8.755-4.617 8.755-8.621l-.01-.393A6.153 6.153 0 0 0 15.5 1.42a6.246 6.246 0 0 1-1.767.477A3.048 3.048 0 0 0 15.086.222z"
fillRule="evenodd"
fill={color}
/>
</svg>
<span style={{ fontSize: 0 }} className="sw-IconTwitter_Text">
{text}
</span>
</a>
)
}

View File

@ -0,0 +1,295 @@
import React, { Component } from 'react'
import Tooltip from 'rc-tooltip'
import { ButtonDownload } from '../ButtonDownload'
const encodeJson = json => {
const encoded = window.encodeURIComponent(JSON.stringify(json))
return `data:application/json;charset=utf-8,${encoded}`
}
export default class Keys extends Component {
constructor(props) {
super(props)
this.onVisibleChange = this.onVisibleChange.bind(this)
this.onCopyBtnClick = this.onCopyBtnClick.bind(this)
this.state = {
copyBtns: {
copyMiningPass: {
visible: false,
text: 'Copy'
},
copyVotingPass: {
visible: false,
text: 'Copy'
},
copyPayoutPass: {
visible: false,
text: 'Copy'
},
copyMiningKey: {
visible: false,
text: 'Copy'
},
copyVotingKey: {
visible: false,
text: 'Copy'
},
copyPayoutKey: {
visible: false,
text: 'Copy'
}
}
}
}
componentWillUpdate(nextProps, nextState) {
if (this.refs.miningKeyAddress) {
const Clipboard = require('clipboard')
new Clipboard(this.refs.miningKeyAddress)
new Clipboard(this.refs.miningKeyPass)
new Clipboard(this.refs.payoutKeyAddress)
new Clipboard(this.refs.payoutKeyPass)
new Clipboard(this.refs.votingKeyAddress)
new Clipboard(this.refs.votingKeyPass)
}
}
onVisibleChange(id) {
let copyBtns = this.state.copyBtns
copyBtns[id].visible = !copyBtns[id].visible
copyBtns[id].text = 'Copy'
this.setState({
copyBtns
})
}
onCopyBtnClick(e) {
const id = e.target.id
let copyBtns = this.state.copyBtns
copyBtns[id].text = 'Copied!'
this.setState({
copyBtns
})
}
render() {
const { networkBranch } = this.props
return (
<div className={`ky-Keys`}>
<div className="ky-Keys_Block">
<h2 className="ky-Keys_BlockTitle">Mining key</h2>
<div className="ky-Keys_HashContainer">
<p className={`ky-Keys_Hash ky-Keys_Hash-${networkBranch}`} id="miningKey">
0x
{this.props.mining.jsonStore.address}
</p>
<Tooltip
visible={this.state.copyBtns.copyMiningKey.visible}
animation="zoom"
trigger="hover"
onVisibleChange={() => {
this.onVisibleChange('copyMiningKey')
}}
placement="right"
overlay={this.state.copyBtns.copyMiningKey.text}
>
<span
className={`ky-Keys_Copy ky-Keys_Copy-${networkBranch}`}
data-clipboard-text={'0x' + this.props.mining.jsonStore.address}
id="copyMiningKey"
onClick={this.onCopyBtnClick}
ref="miningKeyAddress"
/>
</Tooltip>
</div>
<div className="ky-Keys_PasswordContainer">
<label className="ky-Keys_PasswordLabel">Password:</label>
<input
className="ky-Keys_PasswordInput"
defaultValue={this.props.mining.password}
disabled={true}
id="miningKeyPass"
size={this.props.mining.password.length}
type="password"
/>
<Tooltip
animation="zoom"
trigger="hover"
visible={this.state.copyBtns.copyMiningPass.visible}
onVisibleChange={() => {
this.onVisibleChange('copyMiningPass')
}}
placement="right"
overlay={this.state.copyBtns.copyMiningPass.text}
>
<span
id="copyMiningPass"
onClick={this.onCopyBtnClick}
className={`ky-Keys_Copy ky-Keys_Copy-${networkBranch}`}
ref="miningKeyPass"
data-clipboard-text={this.props.mining.password}
/>
</Tooltip>
</div>
<p className="ky-Keys_Description">
Download this key and use it in your mining node to validate blocks in the network. Mined coins will be
deposited to your payout account.
</p>
<ButtonDownload
download={`mining_${this.props.mining.jsonStore.address}.json`}
href={encodeJson(this.props.mining.jsonStore)}
id="miningKeyDownload"
networkBranch={networkBranch}
text="Download Mining Key"
/>
</div>
<div className="ky-Keys_Block">
<h2 className="ky-Keys_BlockTitle">Payout key</h2>
<div className="ky-Keys_HashContainer">
<p className={`ky-Keys_Hash ky-Keys_Hash-${networkBranch}`} id="payoutKey">
0x
{this.props.payout.jsonStore.address}
</p>
<Tooltip
visible={this.state.copyBtns.copyPayoutKey.visible}
animation="zoom"
trigger="hover"
onVisibleChange={() => {
this.onVisibleChange('copyPayoutKey')
}}
placement="right"
overlay={this.state.copyBtns.copyPayoutKey.text}
>
<span
className={`ky-Keys_Copy ky-Keys_Copy-${networkBranch}`}
data-clipboard-text={'0x' + this.props.payout.jsonStore.address}
id="copyPayoutKey"
onClick={this.onCopyBtnClick}
ref="payoutKeyAddress"
/>
</Tooltip>
</div>
<div className="ky-Keys_PasswordContainer">
<label className="ky-Keys_PasswordLabel">Password:</label>
<input
className="ky-Keys_PasswordInput"
defaultValue={this.props.payout.password}
disabled={true}
id="payoutKeyPass"
size={this.props.payout.password.length}
type="password"
/>
<Tooltip
visible={this.state.copyBtns.copyPayoutPass.visible}
animation="zoom"
trigger="hover"
onVisibleChange={() => {
this.onVisibleChange('copyPayoutPass')
}}
placement="right"
overlay={this.state.copyBtns.copyPayoutPass.text}
>
<span
id="copyPayoutPass"
onClick={this.onCopyBtnClick}
className={`ky-Keys_Copy ky-Keys_Copy-${networkBranch}`}
ref="payoutKeyPass"
data-clipboard-text={this.props.payout.password}
/>
</Tooltip>
</div>
<p className="ky-Keys_Description">
Download this key and use it on your client node/wallet to spend earned coins.
</p>
<ButtonDownload
download={`payout_${this.props.payout.jsonStore.address}.json`}
href={encodeJson(this.props.payout.jsonStore)}
id="payoutKeyDownload"
networkBranch={networkBranch}
text="Download Payout Key"
/>
</div>
<div className="ky-Keys_Block">
<h2 className="ky-Keys_BlockTitle">Voting key</h2>
<div className="ky-Keys_HashContainer">
<p className={`ky-Keys_Hash ky-Keys_Hash-${networkBranch}`} id="votingKey">
0x
{this.props.voting.jsonStore.address}
</p>
<Tooltip
visible={this.state.copyBtns.copyVotingKey.visible}
animation="zoom"
trigger="hover"
onVisibleChange={() => {
this.onVisibleChange('copyVotingKey')
}}
placement="right"
overlay={this.state.copyBtns.copyVotingKey.text}
>
<span
id="copyVotingKey"
onClick={this.onCopyBtnClick}
className={`ky-Keys_Copy ky-Keys_Copy-${networkBranch}`}
ref="votingKeyAddress"
data-clipboard-text={'0x' + this.props.voting.jsonStore.address}
/>
</Tooltip>
</div>
<div className="ky-Keys_PasswordContainer">
<label className="ky-Keys_PasswordLabel">Password:</label>
<input
className="ky-Keys_PasswordInput"
defaultValue={this.props.voting.password}
disabled={true}
id="votingKeyPass"
size={this.props.voting.password.length}
type="password"
/>
<Tooltip
visible={this.state.copyBtns.copyVotingPass.visible}
animation="zoom"
trigger="hover"
onVisibleChange={() => {
this.onVisibleChange('copyVotingPass')
}}
placement="right"
overlay={this.state.copyBtns.copyVotingPass.text}
>
<span
id="copyVotingPass"
onClick={this.onCopyBtnClick}
className={`ky-Keys_Copy ky-Keys_Copy-${networkBranch}`}
ref="votingKeyPass"
data-clipboard-text={this.props.voting.password}
/>
</Tooltip>
</div>
<p className="ky-Keys_Description">
Download this key and use it on your client node to vote for necessary ballots, such as adding or removing
miners from the network.
</p>
<ButtonDownload
download={`voting_${this.props.voting.jsonStore.address}.json`}
href={encodeJson(this.props.voting.jsonStore)}
id="votingKeyDownload"
networkBranch={networkBranch}
text="Download Voting Key"
/>
</div>
<div className={`ky-Keys_Block ky-Keys_Block-${networkBranch}`}>
<svg className="ky-Keys_WarningIcon" xmlns="http://www.w3.org/2000/svg" width="48" height="48">
<path
className={`ky-Keys_WarningIconPath ky-Keys_WarningIconPath-${networkBranch}`}
fill="#5C34A2"
fillRule="evenodd"
d="M24 48C10.745 48 0 37.255 0 24S10.745 0 24 0s24 10.745 24 24-10.745 24-24 24zm0-46C11.85 2 2 11.85 2 24s9.85 22 22 22 22-9.85 22-22S36.15 2 24 2zm0 35a1 1 0 1 1 0-2 1 1 0 0 1 0 2zm0-6a1 1 0 0 1-1-1V12a1 1 0 0 1 2 0v18a1 1 0 0 1-1 1z"
/>
</svg>
<h2 className={`ky-Keys_BlockTitle ky-Keys_BlockTitle-${networkBranch}`}>Important</h2>
<p className={`ky-Keys_Warning ky-Keys_Warning-${networkBranch}`}>
Do not close this tab until you download all keys and save passwords. Keep keys secure and protected. If you
lose your keys, you will need to get a new initial key using Voting DAPP.
</p>
</div>
</div>
)
}
}

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 52 26">
<path fill="#FFF" fill-rule="evenodd" d="M8.938 17.812h-.813v2.376h-.003l.003.015c0 .44-.364.797-.812.797h-6.5A.805.805 0 0 1 0 20.203l.003-.015H0V5.813h.003c0-.006-.003-.011-.003-.016C0 5.357.364 5 .813 5h8.125c3.589 0 6.499 2.868 6.499 6.406s-2.91 6.406-6.499 6.406zM25.188 5c4.487 0 8.125 3.582 8.125 8s-3.638 8-8.125 8c-4.488 0-8.126-3.582-8.126-8s3.638-8 8.126-8zM52 20.493a.498.498 0 0 1-.503.494H33.064c-.022.003-.041.013-.064.013a.5.5 0 0 1-.5-.5c0-.109.042-.204.101-.286l-.009-.017 9.151-14.809h.02a.493.493 0 0 1 .965 0h.021L52 20.296l-.032.043c.017.05.032.1.032.154z"/>
</svg>

After

Width:  |  Height:  |  Size: 654 B

View File

@ -0,0 +1,30 @@
import React from 'react'
import xDaiLogo from './xdai.svg'
import poaLogo from './core.svg'
import sokolLogo from './sokol.svg'
const getLogoSrc = networkBranch => {
return (
{
core: poaLogo,
sokol: sokolLogo,
dai: xDaiLogo
}[networkBranch] || poaLogo
)
}
export const Loading = ({ networkBranch }) => {
return (
<div className={`ld-Loading ld-Loading-${networkBranch}`}>
<img className={`ld-Loading_Image ld-Loading_Image-${networkBranch}`} src={getLogoSrc(networkBranch)} alt="" />
<div className="ld-Loading_Animation">
<div className="ld-Loading_AnimationItem" />
<div className="ld-Loading_AnimationItem" />
<div className="ld-Loading_AnimationItem" />
<div className="ld-Loading_AnimationItem" />
<div className="ld-Loading_AnimationItem" />
<div className="ld-Loading_AnimationItem" />
</div>
</div>
)
}

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 38 26">
<path fill="#FFF" fill-rule="evenodd" d="M36.528 20H24.272c-.167 0-.334-.028-.499-.068l.018.068h-5.287l-1.607-5.969H.969A.96.96 0 0 1 0 13.078c0-.005.003-.01.003-.016H0V5.906C0 4.853.86 4 1.922 4l.016.002V4h30.275c1.061 0 2.153.855 2.437 1.91l3.285 12.18c.285 1.055-.345 1.91-1.407 1.91zM7.723 6.866H3.361l1.169 4.298h4.362L7.723 6.866zm7.209 0h-4.361l1.169 4.298h4.361l-1.169-4.298zm11.743 10.985h1.923l-.517-1.911h-1.922l.516 1.911zm5.201-10.985h-8.17l2.194 8.119h8.171l-2.195-8.119zm2.453 9.074h-1.922l.516 1.911h1.923l-.517-1.911zm-33.61.047v-.05h12.969v.003h1.557L16.342 20H1.938v-.002L1.922 20A1.914 1.914 0 0 1 0 18.094v-1.188h.005c0-.006-.005-.01-.005-.015 0-.439.308-.793.719-.904z"/>
</svg>

After

Width:  |  Height:  |  Size: 766 B

View File

@ -0,0 +1,24 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 45 52">
<defs>
<filter id="a" width="44" height="52" x="0" y="0" filterUnits="userSpaceOnUse">
<feOffset dy="3" in="SourceAlpha"/>
<feGaussianBlur result="blurOut" stdDeviation="2.449"/>
<feFlood flood-color="#D2D5D7" result="floodOut"/>
<feComposite in="floodOut" in2="blurOut" operator="atop"/>
<feComponentTransfer>
<feFuncA slope=".5" type="linear"/>
</feComponentTransfer>
<feMerge>
<feMergeNode/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
<linearGradient id="b" x1="0%" x2="0%" y1="100%" y2="0%">
<stop offset="0%" stop-color="#FFAD45"/>
<stop offset="100%" stop-color="#FFD342"/>
</linearGradient>
</defs>
<path fill="#FFF" fill-rule="evenodd" d="M17.771 40.253c-3.368-2.101-9.884-6.163-10.841-6.762C5 32.154 5 30.021 5 30.021l.001-16.044S5 11.656 6.947 10.492l10.824-6.751c3.729-2.324 3.729-2.324 7.464.004l10.808 6.741c1.957 1.23 1.956 3.487 1.956 3.487v16.049s.001 2.235-1.956 3.485L25.232 40.25c-3.732 2.33-3.732 2.33-7.461.003z" filter="url(#a)"/>
<path fill="#FFF" fill-rule="evenodd" d="M30.055 13.884l-6.233 8.128 6.229 8.122h-4.644L21.5 25.039l-3.907 5.095h-4.644l6.229-8.122-6.233-8.128h4.644l3.911 5.1 3.911-5.1h4.644z"/>
<path fill="url(#b)" d="M30.055 13.884l-6.233 8.128 6.229 8.122h-4.644L21.5 25.039l-3.907 5.095h-4.644l6.229-8.122-6.233-8.128h4.644l3.911 5.1 3.911-5.1h4.644z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1,17 @@
import React from 'react'
import { LogoPOA } from '../LogoPOA'
import { LogoSokol } from '../LogoSokol'
import { LogoDai } from '../LogoDai'
export const Logo = ({ href = null, extraClass = '', networkBranch = '' }) => {
switch (networkBranch) {
case 'sokol':
return <LogoSokol href={href} extraClass={extraClass} />
case 'dai':
case 'dai-test':
return <LogoDai href={href} extraClass={extraClass} />
case 'poa':
default:
return <LogoPOA href={href} extraClass={extraClass} />
}
}

View File

@ -0,0 +1,10 @@
import React from 'react'
import logoSokol from './logo.svg'
export const LogoDai = ({ href = null, extraClass = '' }) => {
return (
<a href={href} className={`sw-LogoDai ${extraClass}`}>
<img className="sw-LogoDai_Image" src={logoSokol} alt="" />
</a>
)
}

View File

@ -0,0 +1,94 @@
<svg
height="52"
width="152"
xmlns="http://www.w3.org/2000/svg"
>
<defs>
<filter
id="a"
width="44"
height="52"
x="0"
y="0"
filterUnits="userSpaceOnUse"
>
<feOffset
dy="3"
in="SourceAlpha"
/>
<feGaussianBlur
result="blurOut"
stdDeviation="2.449"
/>
<feFlood
flood-color="#D2D5D7"
result="floodOut"
/>
<feComposite
in="floodOut"
in2="blurOut"
operator="atop"
/>
<feComponentTransfer>
<feFuncA
slope=".5"
type="linear"
/>
</feComponentTransfer>
<feMerge>
<feMergeNode />
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
<linearGradient
id="b"
x1="0%"
x2="0%"
y1="100%"
y2="0%"
>
<stop
offset="0%"
stop-color="#FFAD45"
/>
<stop
offset="100%"
stop-color="#FFD342"
/>
</linearGradient>
<style type="text/css">
@import url('https://fonts.googleapis.com/css?family=Nunito:400');
text {
font-family: "Nunito", sans-serif;
}
</style>
</defs>
<path
fill="#FFF"
fill-rule="evenodd"
d="M17.771 40.253c-3.368-2.101-9.884-6.163-10.841-6.762C5 32.154 5 30.021 5 30.021l.001-16.044S5 11.656 6.947 10.492l10.824-6.751c3.729-2.324 3.729-2.324 7.464.004l10.808 6.741c1.957 1.23 1.956 3.487 1.956 3.487v16.049s.001 2.235-1.956 3.485L25.232 40.25c-3.732 2.33-3.732 2.33-7.461.003z"
filter="url(#a)"
/>
<path
fill="#FFF"
fill-rule="evenodd"
d="M30.055 13.884l-6.233 8.128 6.229 8.122h-4.644L21.5 25.039l-3.907 5.095h-4.644l6.229-8.122-6.233-8.128h4.644l3.911 5.1 3.911-5.1h4.644z"
/>
<path
fill="url(#b)"
d="M30.055 13.884l-6.233 8.128 6.229 8.122h-4.644L21.5 25.039l-3.907 5.095h-4.644l6.229-8.122-6.233-8.128h4.644l3.911 5.1 3.911-5.1h4.644z"
/>
<text
fill="#333"
font-family="Nunito"
font-size="14"
font-weight="400"
x="48"
y="26"
>Ceremony App</text>
<path
fill="#333"
fill-rule="evenodd"
d="M151 9a1 1 0 0 1 1 1v24a1 1 0 0 1-2 0V10a1 1 0 0 1 1-1z"
/>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -0,0 +1,10 @@
import React from 'react'
import logoPOA from './logo.svg'
export const LogoPOA = ({ href = null, extraClass = '' }) => {
return (
<a href={href} className={`sw-LogoPOA ${extraClass}`}>
<img className="sw-LogoPOA_Image" src={logoPOA} alt="" />
</a>
)
}

View File

@ -0,0 +1,32 @@
<svg
height="26"
width="167"
xmlns="http://www.w3.org/2000/svg"
>
<defs>
<style type="text/css">
@import url('https://fonts.googleapis.com/css?family=Nunito:400');
text {
font-family: "Nunito", sans-serif;
}
</style>
</defs>
<path
d="M8.938 17.812h-.813v2.376h-.003l.003.015c0 .44-.364.797-.812.797h-6.5A.805.805 0 0 1 0 20.203l.003-.015H0V5.812h.003L0 5.797C0 5.357.364 5 .813 5h8.125c3.589 0 6.499 2.868 6.499 6.406s-2.91 6.406-6.499 6.406zM25.188 5c4.487 0 8.125 3.582 8.125 8s-3.638 8-8.125 8c-4.488 0-8.126-3.582-8.126-8s3.638-8 8.126-8zM52 20.493a.498.498 0 0 1-.503.494H33.064c-.022.003-.041.013-.064.013a.5.5 0 0 1-.5-.5c0-.109.042-.204.101-.286l-.009-.017 9.151-14.809h.02a.493.493 0 0 1 .965 0h.021L52 20.296l-.032.043c.017.05.032.1.032.154z"
fill-rule="evenodd"
fill="#FFF"
/>
<text
fill="#fff"
font-family="Nunito"
font-size="14"
font-weight="300"
x="63"
y="17"
>Ceremony App</text>
<path
d="M166 0a1 1 0 0 1 1 1v24a1 1 0 0 1-2 0V1a1 1 0 0 1 1-1z"
fill-rule="evenodd"
fill="#60DB97"
/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,10 @@
import React from 'react'
import logoSokol from './logo.svg'
export const LogoSokol = ({ href = null, extraClass = '' }) => {
return (
<a href={href} className={`sw-LogoSokol ${extraClass}`}>
<img className="sw-LogoSokol_Image" src={logoSokol} alt="" />
</a>
)
}

View File

@ -0,0 +1,32 @@
<svg
height="26"
width="151"
xmlns="http://www.w3.org/2000/svg"
>
<defs>
<style type="text/css">
@import url('https://fonts.googleapis.com/css?family=Nunito:400');
text {
font-family: "Nunito", sans-serif;
}
</style>
</defs>
<path
fill="#FFF"
fill-rule="evenodd"
d="M36.528 20H24.272c-.167 0-.334-.028-.499-.068l.018.068h-5.287l-1.607-5.969H.969A.96.96 0 0 1 0 13.078l.003-.015H0V5.906C0 4.853.86 4 1.922 4l.016.002V4h30.275c1.061 0 2.153.855 2.437 1.91l3.285 12.18c.285 1.055-.345 1.91-1.407 1.91zM7.723 6.866H3.361l1.169 4.298h4.362L7.723 6.866zm7.209 0h-4.361l1.169 4.298h4.361l-1.169-4.298zm11.743 10.985h1.923l-.517-1.911h-1.922l.516 1.911zm5.201-10.985h-8.17l2.194 8.119h8.171l-2.195-8.119zm2.453 9.074h-1.922l.516 1.911h1.923l-.517-1.911zm-33.61.047v-.05h12.969v.003h1.557L16.342 20H1.938v-.002L1.922 20A1.914 1.914 0 0 1 0 18.094v-1.188h.005c0-.006-.005-.01-.005-.015 0-.439.308-.793.719-.904z"
/>
<text
fill="#FFF"
font-family="Nunito"
font-size="14"
font-weight="300"
x="47"
y="17"
>Ceremony App</text>
<path
fill="#FFF"
fill-rule="evenodd"
d="M150 0a1 1 0 0 1 1 1v24a1 1 0 0 1-2 0V1a1 1 0 0 1 1-1z"
/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

Some files were not shown because too many files have changed in this diff Show More