diff --git a/js/src/modals/CreateAccount/NewAccount/index.js b/js/src/modals/CreateAccount/NewAccount/index.js index 5d2a3e686..8dc314743 100644 --- a/js/src/modals/CreateAccount/NewAccount/index.js +++ b/js/src/modals/CreateAccount/NewAccount/index.js @@ -14,10 +14,4 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -import { ERRORS } from './newAccount'; - export default from './newAccount'; - -export { - ERRORS -}; diff --git a/js/src/modals/CreateAccount/NewAccount/newAccount.js b/js/src/modals/CreateAccount/NewAccount/newAccount.js index 267ed56bc..c0bcca91a 100644 --- a/js/src/modals/CreateAccount/NewAccount/newAccount.js +++ b/js/src/modals/CreateAccount/NewAccount/newAccount.js @@ -21,21 +21,10 @@ import ActionAutorenew from 'material-ui/svg-icons/action/autorenew'; import { Form, Input, IdentityIcon } from '~/ui'; +import ERRORS from '../errors'; + import styles from '../createAccount.css'; -const ERRORS = { - noName: 'you need to specify a valid name for the account', - noPhrase: 'you need to specify the recovery phrase', - noKey: 'you need to provide the raw private key', - invalidKey: 'the raw key needs to be hex, 64 characters in length and contain the prefix "0x"', - invalidPassword: 'you need to specify a password >= 8 characters', - noMatchPassword: 'the supplied passwords does not match' -}; - -export { - ERRORS -}; - export default class CreateAccount extends Component { static contextTypes = { api: PropTypes.object.isRequired, @@ -49,15 +38,15 @@ export default class CreateAccount extends Component { state = { accountName: '', accountNameError: ERRORS.noName, + accounts: null, + isValidName: false, + isValidPass: false, passwordHint: '', password1: '', - password1Error: ERRORS.invalidPassword, + password1Error: null, password2: '', - password2Error: ERRORS.noMatchPassword, - accounts: null, - selectedAddress: '', - isValidPass: false, - isValidName: false + password2Error: null, + selectedAddress: '' } componentWillMount () { @@ -230,60 +219,55 @@ export default class CreateAccount extends Component { }, this.updateParent); } - onEditPasswordHint = (event, value) => { + onEditPasswordHint = (event, passwordHint) => { this.setState({ - passwordHint: value + passwordHint }); } onEditAccountName = (event) => { - const value = event.target.value; - let error = null; + const accountName = event.target.value; + let accountNameError = null; - if (!value || value.trim().length < 2) { - error = ERRORS.noName; + if (!accountName || !accountName.trim().length) { + accountNameError = ERRORS.noName; } this.setState({ - accountName: value, - accountNameError: error, - isValidName: !error + accountName, + accountNameError, + isValidName: !accountNameError }, this.updateParent); } onEditPassword1 = (event) => { - const value = event.target.value; - let error1 = null; - let error2 = null; + const password1 = event.target.value; + let password2Error = null; - if (!value || value.trim().length < 8) { - error1 = ERRORS.invalidPassword; - } - - if (value !== this.state.password2) { - error2 = ERRORS.noMatchPassword; + if (password1 !== this.state.password2) { + password2Error = ERRORS.noMatchPassword; } this.setState({ - password1: value, - password1Error: error1, - password2Error: error2, - isValidPass: !error1 && !error2 + password1, + password1Error: null, + password2Error, + isValidPass: !password2Error }, this.updateParent); } onEditPassword2 = (event) => { - const value = event.target.value; - let error2 = null; + const password2 = event.target.value; + let password2Error = null; - if (value !== this.state.password1) { - error2 = ERRORS.noMatchPassword; + if (password2 !== this.state.password1) { + password2Error = ERRORS.noMatchPassword; } this.setState({ - password2: value, - password2Error: error2, - isValidPass: !error2 + password2, + password2Error, + isValidPass: !password2Error }, this.updateParent); } diff --git a/js/src/modals/CreateAccount/NewGeth/newGeth.js b/js/src/modals/CreateAccount/NewGeth/newGeth.js index 269075983..f8cd1fbe6 100644 --- a/js/src/modals/CreateAccount/NewGeth/newGeth.js +++ b/js/src/modals/CreateAccount/NewGeth/newGeth.js @@ -47,6 +47,7 @@ export default class NewGeth extends Component {
There are currently no importable keys available from the Geth keystore, which are not already available on your Parity instance
); } + const checkboxes = available.map((account) => { const label = (
diff --git a/js/src/modals/CreateAccount/NewImport/newImport.js b/js/src/modals/CreateAccount/NewImport/newImport.js index 84ec5b425..17a1cfd44 100644 --- a/js/src/modals/CreateAccount/NewImport/newImport.js +++ b/js/src/modals/CreateAccount/NewImport/newImport.js @@ -21,17 +21,13 @@ import EditorAttachFile from 'material-ui/svg-icons/editor/attach-file'; import { Form, Input } from '~/ui'; +import ERRORS from '../errors'; + import styles from '../createAccount.css'; const FAKEPATH = 'C:\\fakepath\\'; const STYLE_HIDDEN = { display: 'none' }; -const ERRORS = { - noName: 'you need to specify a valid name for the account', - noPassword: 'supply a valid password to confirm the transaction', - noFile: 'select a valid wallet file to import' -}; - export default class NewImport extends Component { static propTypes = { onChange: PropTypes.func.isRequired @@ -40,15 +36,15 @@ export default class NewImport extends Component { state = { accountName: '', accountNameError: ERRORS.noName, - passwordHint: '', - password: '', - passwordError: ERRORS.noPassword, - walletFile: '', - walletFileError: ERRORS.noFile, - walletJson: '', + isValidFile: false, isValidPass: false, isValidName: false, - isValidFile: false + password: '', + passwordError: null, + passwordHint: '', + walletFile: '', + walletFileError: ERRORS.noFile, + walletJson: '' } componentWillMount () { @@ -143,39 +139,34 @@ export default class NewImport extends Component { }); } - onEditPasswordHint = (event, value) => { + onEditPasswordHint = (event, passwordHint) => { this.setState({ - passwordHint: value + passwordHint }); } onEditAccountName = (event) => { - const value = event.target.value; - let error = null; + const accountName = event.target.value; + let accountNameError = null; - if (!value || value.trim().length < 2) { - error = ERRORS.noName; + if (!accountName || !accountName.trim().length) { + accountNameError = ERRORS.noName; } this.setState({ - accountName: value, - accountNameError: error, - isValidName: !error + accountName, + accountNameError, + isValidName: !accountNameError }, this.updateParent); } onEditPassword = (event) => { - let error = null; - const value = event.target.value; - - if (!value || !value.length) { - error = ERRORS.noPassword; - } + const password = event.target.value; this.setState({ - password: value, - passwordError: error, - isValidPass: !error + password, + passwordError: null, + isValidPass: true }, this.updateParent); } } diff --git a/js/src/modals/CreateAccount/RawKey/rawKey.js b/js/src/modals/CreateAccount/RawKey/rawKey.js index c0cb84617..f284cf323 100644 --- a/js/src/modals/CreateAccount/RawKey/rawKey.js +++ b/js/src/modals/CreateAccount/RawKey/rawKey.js @@ -20,7 +20,7 @@ import { Form, Input } from '~/ui'; import styles from '../createAccount.css'; -import { ERRORS } from '../NewAccount'; +import ERRORS from '../errors'; export default class RawKey extends Component { static contextTypes = { @@ -32,18 +32,18 @@ export default class RawKey extends Component { } state = { - rawKey: '', - rawKeyError: ERRORS.noKey, accountName: '', accountNameError: ERRORS.noName, + isValidKey: false, + isValidName: false, + isValidPass: false, passwordHint: '', password1: '', - password1Error: ERRORS.invalidPassword, + password1Error: null, password2: '', - password2Error: ERRORS.noMatchPassword, - isValidPass: false, - isValidName: false, - isValidKey: false + password2Error: null, + rawKey: '', + rawKeyError: ERRORS.noKey } componentWillMount () { @@ -138,7 +138,7 @@ export default class RawKey extends Component { const accountName = event.target.value; let accountNameError = null; - if (!accountName || accountName.trim().length < 2) { + if (!accountName || !accountName.trim().length) { accountNameError = ERRORS.noName; } @@ -150,38 +150,33 @@ export default class RawKey extends Component { } onEditPassword1 = (event) => { - const value = event.target.value; - let error1 = null; - let error2 = null; + const password1 = event.target.value; + let password2Error = null; - if (!value || value.trim().length < 8) { - error1 = ERRORS.invalidPassword; - } - - if (value !== this.state.password2) { - error2 = ERRORS.noMatchPassword; + if (password1 !== this.state.password2) { + password2Error = ERRORS.noMatchPassword; } this.setState({ - password1: value, - password1Error: error1, - password2Error: error2, - isValidPass: !error1 && !error2 + password1, + password1Error: null, + password2Error, + isValidPass: !password2Error }, this.updateParent); } onEditPassword2 = (event) => { - const value = event.target.value; - let error2 = null; + const password2 = event.target.value; + let password2Error = null; - if (value !== this.state.password1) { - error2 = ERRORS.noMatchPassword; + if (password2 !== this.state.password1) { + password2Error = ERRORS.noMatchPassword; } this.setState({ - password2: value, - password2Error: error2, - isValidPass: !error2 + password2, + password2Error, + isValidPass: !password2Error }, this.updateParent); } } diff --git a/js/src/modals/CreateAccount/RecoveryPhrase/recoveryPhrase.js b/js/src/modals/CreateAccount/RecoveryPhrase/recoveryPhrase.js index 2736256f1..fd5043024 100644 --- a/js/src/modals/CreateAccount/RecoveryPhrase/recoveryPhrase.js +++ b/js/src/modals/CreateAccount/RecoveryPhrase/recoveryPhrase.js @@ -21,7 +21,7 @@ import { Form, Input } from '~/ui'; import styles from '../createAccount.css'; -import { ERRORS } from '../NewAccount'; +import ERRORS from '../errors'; export default class RecoveryPhrase extends Component { static propTypes = { @@ -29,19 +29,19 @@ export default class RecoveryPhrase extends Component { } state = { - recoveryPhrase: '', - recoveryPhraseError: ERRORS.noPhrase, accountName: '', accountNameError: ERRORS.noName, - passwordHint: '', - password1: '', - password1Error: ERRORS.invalidPassword, - password2: '', - password2Error: ERRORS.noMatchPassword, - windowsPhrase: false, isValidPass: false, isValidName: false, - isValidPhrase: false + isValidPhrase: false, + passwordHint: '', + password1: '', + password1Error: null, + password2: '', + password2Error: null, + recoveryPhrase: '', + recoveryPhraseError: null, + windowsPhrase: false } componentWillMount () { @@ -99,13 +99,13 @@ export default class RecoveryPhrase extends Component { } updateParent = () => { - const { isValidName, isValidPass, isValidPhrase, accountName, passwordHint, password1, recoveryPhrase, windowsPhrase } = this.state; + const { accountName, isValidName, isValidPass, isValidPhrase, password1, passwordHint, recoveryPhrase, windowsPhrase } = this.state; const isValid = isValidName && isValidPass && isValidPhrase; this.props.onChange(isValid, { name: accountName, - passwordHint, password: password1, + passwordHint, phrase: recoveryPhrase, windowsPhrase }); @@ -134,67 +134,57 @@ export default class RecoveryPhrase extends Component { .split(' ') .map((part) => part.trim()) .filter((part) => part.length); - let recoveryPhraseError = null; - - if (!recoveryPhrase || recoveryPhrase.length < 25 || phraseParts.length < 8) { - recoveryPhraseError = ERRORS.noPhrase; - } this.setState({ recoveryPhrase: phraseParts.join(' '), - recoveryPhraseError, - isValidPhrase: !recoveryPhraseError + recoveryPhraseError: null, + isValidPhrase: true }, this.updateParent); } onEditAccountName = (event) => { - const value = event.target.value; - let error = null; + const accountName = event.target.value; + let accountNameError = null; - if (!value || value.trim().length < 2) { - error = ERRORS.noName; + if (!accountName || !accountName.trim().length) { + accountNameError = ERRORS.noName; } this.setState({ - accountName: value, - accountNameError: error, - isValidName: !error + accountName, + accountNameError, + isValidName: !accountNameError }, this.updateParent); } onEditPassword1 = (event) => { - const value = event.target.value; - let error1 = null; - let error2 = null; + const password1 = event.target.value; + let password2Error = null; - if (!value || value.trim().length < 8) { - error1 = ERRORS.invalidPassword; - } - - if (value !== this.state.password2) { - error2 = ERRORS.noMatchPassword; + if (password1 !== this.state.password2) { + password2Error = ERRORS.noMatchPassword; } this.setState({ - password1: value, - password1Error: error1, - password2Error: error2, - isValidPass: !error1 && !error2 + password1, + password1Error: null, + password2Error, + isValidPass: !password2Error }, this.updateParent); } onEditPassword2 = (event) => { - const value = event.target.value; - let error2 = null; + const password2 = event.target.value; + let password2Error = null; - if (value !== this.state.password1) { - error2 = ERRORS.noMatchPassword; + if (password2 !== this.state.password1) { + password2Error = ERRORS.noMatchPassword; } this.setState({ - password2: value, - password2Error: error2, - isValidPass: !error2 + password2, + password2Error, + isValidPass: !password2Error }, this.updateParent); } } diff --git a/js/src/modals/CreateAccount/createAccount.js b/js/src/modals/CreateAccount/createAccount.js index d7ec8487b..569d374cc 100644 --- a/js/src/modals/CreateAccount/createAccount.js +++ b/js/src/modals/CreateAccount/createAccount.js @@ -15,6 +15,7 @@ // along with Parity. If not, see . import React, { Component, PropTypes } from 'react'; +import { FormattedMessage } from 'react-intl'; import ActionDone from 'material-ui/svg-icons/action/done'; import ActionDoneAll from 'material-ui/svg-icons/action/done-all'; import ContentClear from 'material-ui/svg-icons/content/clear'; @@ -22,7 +23,7 @@ import NavigationArrowBack from 'material-ui/svg-icons/navigation/arrow-back'; import NavigationArrowForward from 'material-ui/svg-icons/navigation/arrow-forward'; import PrintIcon from 'material-ui/svg-icons/action/print'; -import { Button, Modal } from '~/ui'; +import { Button, Modal, Warning } from '~/ui'; import AccountDetails from './AccountDetails'; import AccountDetailsGeth from './AccountDetailsGeth'; @@ -86,6 +87,7 @@ export default class CreateAccount extends Component { actions={ this.renderDialogActions() } current={ stage } steps={ steps }> + { this.renderWarning() } { this.renderPage() } ); @@ -200,6 +202,22 @@ export default class CreateAccount extends Component { } } + renderWarning () { + const { createType, stage } = this.state; + + if (stage !== 1 || ['fromJSON', 'fromPresale'].includes(createType)) { + return null; + } + + return ( + + } /> + ); + } + onNext = () => { this.setState({ stage: this.state.stage + 1 diff --git a/js/src/modals/CreateAccount/errors.js b/js/src/modals/CreateAccount/errors.js new file mode 100644 index 000000000..3edd75423 --- /dev/null +++ b/js/src/modals/CreateAccount/errors.js @@ -0,0 +1,45 @@ +// Copyright 2015, 2016 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +import React from 'react'; +import { FormattedMessage } from 'react-intl'; + +export default { + noFile: + , + + noKey: + , + + noMatchPassword: + , + + noName: + , + + invalidKey: + +}; diff --git a/js/src/ui/Form/Input/input.js b/js/src/ui/Form/Input/input.js index 8351de2e6..92d313b5a 100644 --- a/js/src/ui/Form/Input/input.js +++ b/js/src/ui/Form/Input/input.js @@ -50,7 +50,7 @@ export default class Input extends Component { children: PropTypes.node, className: PropTypes.string, disabled: PropTypes.bool, - error: PropTypes.string, + error: nodeOrStringProptype(), readOnly: PropTypes.bool, floatCopy: PropTypes.bool, hint: nodeOrStringProptype(), @@ -96,8 +96,7 @@ export default class Input extends Component { render () { const { value } = this.state; - const { children, className, hideUnderline, disabled, error, label } = this.props; - const { hint, multiLine, rows, type, min, max, style } = this.props; + const { children, className, disabled, error, hideUnderline, hint, label, max, min, multiLine, rows, style, type } = this.props; const readOnly = this.props.readOnly || disabled; diff --git a/js/src/ui/Warning/index.js b/js/src/ui/Warning/index.js new file mode 100644 index 000000000..9b67b7d8a --- /dev/null +++ b/js/src/ui/Warning/index.js @@ -0,0 +1,17 @@ +// Copyright 2015, 2016 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +export default from './warning'; diff --git a/js/src/ui/Warning/warning.css b/js/src/ui/Warning/warning.css new file mode 100644 index 000000000..50caf3473 --- /dev/null +++ b/js/src/ui/Warning/warning.css @@ -0,0 +1,26 @@ +/* Copyright 2015, 2016 Parity Technologies (UK) Ltd. +/* This file is part of Parity. +/* +/* Parity is free software: you can redistribute it and/or modify +/* it under the terms of the GNU General Public License as published by +/* the Free Software Foundation, either version 3 of the License, or +/* (at your option) any later version. +/* +/* Parity is distributed in the hope that it will be useful, +/* but WITHOUT ANY WARRANTY; without even the implied warranty of +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +/* GNU General Public License for more details. +/* +/* You should have received a copy of the GNU General Public License +/* along with Parity. If not, see . +*/ + +.warning { + background: #f80; + border-radius: 0.5em; + color: white; + font-size: 0.75em; + margin-bottom: 1em; + padding: 0.75em; + text-align: center; +} diff --git a/js/src/ui/Warning/warning.js b/js/src/ui/Warning/warning.js new file mode 100644 index 000000000..af612c0c8 --- /dev/null +++ b/js/src/ui/Warning/warning.js @@ -0,0 +1,41 @@ +// Copyright 2015, 2016 Parity Technologies (UK) Ltd. +// This file is part of Parity. + +// Parity is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Parity is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Parity. If not, see . + +import React, { Component } from 'react'; + +import { nodeOrStringProptype } from '~/util/proptypes'; + +import styles from './warning.css'; + +export default class Warning extends Component { + static propTypes = { + warning: nodeOrStringProptype() + }; + + render () { + const { warning } = this.props; + + if (!warning) { + return null; + } + + return ( +
+ { warning } +
+ ); + } +} diff --git a/js/src/ui/index.js b/js/src/ui/index.js index d7875b72b..da61cc9b9 100644 --- a/js/src/ui/index.js +++ b/js/src/ui/index.js @@ -49,6 +49,7 @@ import Tags from './Tags'; import Tooltips, { Tooltip } from './Tooltips'; import TxHash from './TxHash'; import TxList from './TxList'; +import Warning from './Warning'; export { Actionbar, @@ -99,5 +100,6 @@ export { Tooltips, TxHash, TxList, - TypedInput + TypedInput, + Warning };