1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-23 09:52:26 +01:00

Refactor new-account.js (#7312)

* Start refactor

* Use import syntax

* Add create-account.component

* Continue refactor

* Add new line

* Start using JSX and make tabs a bit more DRY

* 👋 bye-bye hyperscript

* These can be disabled when active

* Start JSX in new account component

* 👋 bye-bye hyperscript

* Move newAccountNumber into container

* Validate newAccountNumber prop
This commit is contained in:
ricky 2019-10-29 12:12:41 -04:00 committed by GitHub
parent 95618d2cdb
commit 7181779576
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 228 additions and 244 deletions

View File

@ -50,6 +50,7 @@
color: $curious-blue;
border-bottom: 3px solid $curious-blue;
cursor: initial;
pointer-events: none;
}
}
}

View File

@ -0,0 +1,79 @@
import React, { Component } from 'react'
import { Switch, Route, matchPath } from 'react-router-dom'
import PropTypes from 'prop-types'
import classnames from 'classnames'
import NewAccountCreateForm from './new-account.container'
import NewAccountImportForm from './import-account'
import ConnectHardwareForm from './connect-hardware'
import {
NEW_ACCOUNT_ROUTE,
IMPORT_ACCOUNT_ROUTE,
CONNECT_HARDWARE_ROUTE,
} from '../../helpers/constants/routes'
export default class CreateAccountPage extends Component {
renderTabs () {
const { history, location: { pathname }} = this.props
const getClassNames = path => classnames('new-account__tabs__tab', {
'new-account__tabs__selected': matchPath(pathname, {
path,
exact: true,
}),
})
return (
<div className="new-account__tabs">
<div className={getClassNames(NEW_ACCOUNT_ROUTE)} onClick={() => history.push(NEW_ACCOUNT_ROUTE)}>{
this.context.t('create')
}</div>
<div className={getClassNames(IMPORT_ACCOUNT_ROUTE)} onClick={() => history.push(IMPORT_ACCOUNT_ROUTE)}>{
this.context.t('import')
}</div>
<div className={getClassNames(CONNECT_HARDWARE_ROUTE)} onClick={() => history.push(CONNECT_HARDWARE_ROUTE)}>{
this.context.t('connect')
}</div>
</div>
)
}
render () {
return (
<div className="new-account">
<div className="new-account__header">
<div className={`new-account__header ${this.context.t('newAccount')}`}>
{this.renderTabs()}
</div>
</div>
<div className="new-account__form">
<Switch>
<Route
exact={true}
path={NEW_ACCOUNT_ROUTE}
component={NewAccountCreateForm}
/>
<Route
exact={true}
path={IMPORT_ACCOUNT_ROUTE}
component={NewAccountImportForm}
/>
<Route
exact={true}
path={CONNECT_HARDWARE_ROUTE}
component={ConnectHardwareForm}
/>
</Switch>
</div>
</div>
)
}
}
CreateAccountPage.propTypes = {
location: PropTypes.object,
history: PropTypes.object,
t: PropTypes.func,
}
CreateAccountPage.contextTypes = {
t: PropTypes.func,
}

View File

@ -0,0 +1,20 @@
import { connect } from 'react-redux'
import actions from '../../store/actions'
import { getCurrentViewContext } from '../../selectors/selectors'
import CreateAccountPage from './create-account.component'
const mapStateToProps = state => ({
displayedForm: getCurrentViewContext(state),
})
const mapDispatchToProps = dispatch => ({
displayForm: form => dispatch(actions.setNewAccountForm(form)),
showQrView: (selected, identity) => dispatch(actions.showQrView(selected, identity)),
showExportPrivateKeyModal: () => {
dispatch(actions.showModal({ name: 'EXPORT_PRIVATE_KEY' }))
},
hideModal: () => dispatch(actions.hideModal()),
setAccountLabel: (address, label) => dispatch(actions.setAccountLabel(address, label)),
})
export default connect(mapStateToProps, mapDispatchToProps)(CreateAccountPage)

View File

@ -1,113 +1 @@
const Component = require('react').Component
const { Switch, Route, matchPath } = require('react-router-dom')
const PropTypes = require('prop-types')
const h = require('react-hyperscript')
const connect = require('react-redux').connect
const actions = require('../../store/actions')
const { getCurrentViewContext } = require('../../selectors/selectors')
const classnames = require('classnames')
const NewAccountCreateForm = require('./new-account')
const NewAccountImportForm = require('./import-account')
const ConnectHardwareForm = require('./connect-hardware')
const {
NEW_ACCOUNT_ROUTE,
IMPORT_ACCOUNT_ROUTE,
CONNECT_HARDWARE_ROUTE,
} = require('../../helpers/constants/routes')
class CreateAccountPage extends Component {
renderTabs () {
const { history, location } = this.props
return h('div.new-account__tabs', [
h('div.new-account__tabs__tab', {
className: classnames('new-account__tabs__tab', {
'new-account__tabs__selected': matchPath(location.pathname, {
path: NEW_ACCOUNT_ROUTE, exact: true,
}),
}),
onClick: () => history.push(NEW_ACCOUNT_ROUTE),
}, [
this.context.t('create'),
]),
h('div.new-account__tabs__tab', {
className: classnames('new-account__tabs__tab', {
'new-account__tabs__selected': matchPath(location.pathname, {
path: IMPORT_ACCOUNT_ROUTE, exact: true,
}),
}),
onClick: () => history.push(IMPORT_ACCOUNT_ROUTE),
}, [
this.context.t('import'),
]),
h(
'div.new-account__tabs__tab',
{
className: classnames('new-account__tabs__tab', {
'new-account__tabs__selected': matchPath(location.pathname, {
path: CONNECT_HARDWARE_ROUTE,
exact: true,
}),
}),
onClick: () => history.push(CONNECT_HARDWARE_ROUTE),
},
this.context.t('connect')
),
])
}
render () {
return h('div.new-account', {}, [
h('div.new-account__header', [
h('div.new-account__title', this.context.t('newAccount')),
this.renderTabs(),
]),
h('div.new-account__form', [
h(Switch, [
h(Route, {
exact: true,
path: NEW_ACCOUNT_ROUTE,
component: NewAccountCreateForm,
}),
h(Route, {
exact: true,
path: IMPORT_ACCOUNT_ROUTE,
component: NewAccountImportForm,
}),
h(Route, {
exact: true,
path: CONNECT_HARDWARE_ROUTE,
component: ConnectHardwareForm,
}),
]),
]),
])
}
}
CreateAccountPage.propTypes = {
location: PropTypes.object,
history: PropTypes.object,
t: PropTypes.func,
}
CreateAccountPage.contextTypes = {
t: PropTypes.func,
}
const mapStateToProps = state => ({
displayedForm: getCurrentViewContext(state),
})
const mapDispatchToProps = dispatch => ({
displayForm: form => dispatch(actions.setNewAccountForm(form)),
showQrView: (selected, identity) => dispatch(actions.showQrView(selected, identity)),
showExportPrivateKeyModal: () => {
dispatch(actions.showModal({ name: 'EXPORT_PRIVATE_KEY' }))
},
hideModal: () => dispatch(actions.hideModal()),
setAccountLabel: (address, label) => dispatch(actions.setAccountLabel(address, label)),
})
module.exports = connect(mapStateToProps, mapDispatchToProps)(CreateAccountPage)
export { default } from './create-account.container'

View File

@ -0,0 +1,91 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { DEFAULT_ROUTE } from '../../helpers/constants/routes'
import Button from '../../components/ui/button'
export default class NewAccountCreateForm extends Component {
constructor (props, context) {
super(props)
const { newAccountNumber = 0 } = props
this.state = {
newAccountName: '',
defaultAccountName: context.t('newAccountNumberName', [newAccountNumber]),
}
}
render () {
const { newAccountName, defaultAccountName } = this.state
const { history, createAccount } = this.props
const createClick = _ => {
createAccount(newAccountName || defaultAccountName)
.then(() => {
this.context.metricsEvent({
eventOpts: {
category: 'Accounts',
action: 'Add New Account',
name: 'Added New Account',
},
})
history.push(DEFAULT_ROUTE)
})
.catch((e) => {
this.context.metricsEvent({
eventOpts: {
category: 'Accounts',
action: 'Add New Account',
name: 'Error',
},
customVariables: {
errorMessage: e.message,
},
})
})
}
return (
<div className="new-account-create-form">
<div className="new-account-create-form__input-label">
{this.context.t('accountName')}
</div>
<div className="new-account-create-form__input-wrapper">
<input className="new-account-create-form__input"
value={newAccountName}
placeholder={defaultAccountName}
onChange={event => this.setState({ newAccountName: event.target.value })}
/>
</div>
<div className="new-account-create-form__buttons">
<Button
type="default"
large={true}
className="new-account-create-form__button"
onClick={() => history.push(DEFAULT_ROUTE)}
>{this.context.t('cancel')}</Button>
<Button
type="secondary"
large={true}
className="new-account-create-form__button"
onClick={createClick}
>{this.context.t('create')}</Button>
</div>
</div>
)
}
}
NewAccountCreateForm.propTypes = {
hideModal: PropTypes.func,
showImportPage: PropTypes.func,
showConnectPage: PropTypes.func,
createAccount: PropTypes.func,
numberOfExistingAccounts: PropTypes.number,
newAccountNumber: PropTypes.number,
history: PropTypes.object,
t: PropTypes.func,
}
NewAccountCreateForm.contextTypes = {
t: PropTypes.func,
metricsEvent: PropTypes.func,
}

View File

@ -0,0 +1,35 @@
import { connect } from 'react-redux'
import actions from '../../store/actions'
import NewAccountCreateForm from './new-account.component'
const mapStateToProps = state => {
const { metamask: { network, selectedAddress, identities = {} } } = state
const numberOfExistingAccounts = Object.keys(identities).length
const newAccountNumber = numberOfExistingAccounts + 1
return {
network,
address: selectedAddress,
numberOfExistingAccounts,
newAccountNumber,
}
}
const mapDispatchToProps = dispatch => {
return {
toCoinbase: address => dispatch(actions.buyEth({ network: '1', address, amount: 0 })),
hideModal: () => dispatch(actions.hideModal()),
createAccount: newAccountName => {
return dispatch(actions.addNewAccount())
.then(newAccountAddress => {
if (newAccountName) {
dispatch(actions.setAccountLabel(newAccountAddress, newAccountName))
}
})
},
showImportPage: () => dispatch(actions.showImportPage()),
showConnectPage: () => dispatch(actions.showConnectPage()),
}
}
export default connect(mapStateToProps, mapDispatchToProps)(NewAccountCreateForm)

View File

@ -1,130 +0,0 @@
const { Component } = require('react')
const PropTypes = require('prop-types')
const h = require('react-hyperscript')
const connect = require('react-redux').connect
const actions = require('../../store/actions')
const { DEFAULT_ROUTE } = require('../../helpers/constants/routes')
import Button from '../../components/ui/button'
class NewAccountCreateForm extends Component {
constructor (props, context) {
super(props)
const { numberOfExistingAccounts = 0 } = props
const newAccountNumber = numberOfExistingAccounts + 1
this.state = {
newAccountName: '',
defaultAccountName: context.t('newAccountNumberName', [newAccountNumber]),
}
}
render () {
const { newAccountName, defaultAccountName } = this.state
const { history, createAccount } = this.props
return h('div.new-account-create-form', [
h('div.new-account-create-form__input-label', {}, [
this.context.t('accountName'),
]),
h('div.new-account-create-form__input-wrapper', {}, [
h('input.new-account-create-form__input', {
value: newAccountName,
placeholder: defaultAccountName,
onChange: event => this.setState({ newAccountName: event.target.value }),
}, []),
]),
h('div.new-account-create-form__buttons', {}, [
h(Button, {
type: 'default',
large: true,
className: 'new-account-create-form__button',
onClick: () => history.push(DEFAULT_ROUTE),
}, [this.context.t('cancel')]),
h(Button, {
type: 'secondary',
large: true,
className: 'new-account-create-form__button',
onClick: () => {
createAccount(newAccountName || defaultAccountName)
.then(() => {
this.context.metricsEvent({
eventOpts: {
category: 'Accounts',
action: 'Add New Account',
name: 'Added New Account',
},
})
history.push(DEFAULT_ROUTE)
})
.catch((e) => {
this.context.metricsEvent({
eventOpts: {
category: 'Accounts',
action: 'Add New Account',
name: 'Error',
},
customVariables: {
errorMessage: e.message,
},
})
})
},
}, [this.context.t('create')]),
]),
])
}
}
NewAccountCreateForm.propTypes = {
hideModal: PropTypes.func,
showImportPage: PropTypes.func,
showConnectPage: PropTypes.func,
createAccount: PropTypes.func,
numberOfExistingAccounts: PropTypes.number,
history: PropTypes.object,
t: PropTypes.func,
}
const mapStateToProps = state => {
const { metamask: { network, selectedAddress, identities = {} } } = state
const numberOfExistingAccounts = Object.keys(identities).length
return {
network,
address: selectedAddress,
numberOfExistingAccounts,
}
}
const mapDispatchToProps = dispatch => {
return {
toCoinbase: address => dispatch(actions.buyEth({ network: '1', address, amount: 0 })),
hideModal: () => dispatch(actions.hideModal()),
createAccount: newAccountName => {
return dispatch(actions.addNewAccount())
.then(newAccountAddress => {
if (newAccountName) {
dispatch(actions.setAccountLabel(newAccountAddress, newAccountName))
}
})
},
showImportPage: () => dispatch(actions.showImportPage()),
showConnectPage: () => dispatch(actions.showConnectPage()),
}
}
NewAccountCreateForm.contextTypes = {
t: PropTypes.func,
metricsEvent: PropTypes.func,
}
module.exports = connect(mapStateToProps, mapDispatchToProps)(NewAccountCreateForm)

View File

@ -31,7 +31,7 @@ const MobileSyncPage = require('../mobile-sync')
const AddTokenPage = require('../add-token')
const ConfirmAddTokenPage = require('../confirm-add-token')
const ConfirmAddSuggestedTokenPage = require('../confirm-add-suggested-token')
const CreateAccountPage = require('../create-account')
import CreateAccountPage from '../create-account'
const Loading = require('../../components/ui/loading-screen')
const LoadingNetwork = require('../../components/app/loading-network-screen').default