diff options
Diffstat (limited to 'ui/app/pages/settings/contact-list-tab/edit-contact')
3 files changed, 183 insertions, 0 deletions
diff --git a/ui/app/pages/settings/contact-list-tab/edit-contact/edit-contact.component.js b/ui/app/pages/settings/contact-list-tab/edit-contact/edit-contact.component.js new file mode 100644 index 000000000..e9c2fed6f --- /dev/null +++ b/ui/app/pages/settings/contact-list-tab/edit-contact/edit-contact.component.js @@ -0,0 +1,135 @@ +import React, { PureComponent } from 'react' +import PropTypes from 'prop-types' +import Identicon from '../../../../components/ui/identicon' +import Button from '../../../../components/ui/button/button.component' +import TextField from '../../../../components/ui/text-field' +import { isValidAddress } from '../../../../helpers/utils/util' +import PageContainerFooter from '../../../../components/ui/page-container/page-container-footer' + +export default class EditContact extends PureComponent { + + static contextTypes = { + t: PropTypes.func, + } + + static propTypes = { + addToAddressBook: PropTypes.func, + removeFromAddressBook: PropTypes.func, + history: PropTypes.object, + name: PropTypes.string, + address: PropTypes.string, + memo: PropTypes.string, + viewRoute: PropTypes.string, + listRoute: PropTypes.string, + setAccountLabel: PropTypes.func, + } + + state = { + newName: '', + newAddress: '', + newMemo: '', + error: '', + } + + render () { + const { t } = this.context + const { history, name, addToAddressBook, removeFromAddressBook, address, memo, viewRoute, listRoute, setAccountLabel } = this.props + + return ( + <div className="settings-page__content-row address-book__edit-contact"> + <div className="settings-page__header address-book__header--edit"> + <Identicon address={address} diameter={60}/> + <Button + type="link" + className="settings-page__address-book-button" + onClick={() => { + removeFromAddressBook(address) + history.push(listRoute) + }} + > + {t('deleteAccount')} + </Button> + </div> + <div className="address-book__edit-contact__content"> + <div className="address-book__view-contact__group"> + <div className="address-book__view-contact__group__label"> + { t('userName') } + </div> + <TextField + type="text" + id="nickname" + placeholder={this.context.t('addAlias')} + value={this.state.newName || name} + onChange={e => this.setState({ newName: e.target.value })} + fullWidth + margin="dense" + /> + </div> + + <div className="address-book__view-contact__group"> + <div className="address-book__view-contact__group__label"> + { t('ethereumPublicAddress') } + </div> + <TextField + type="text" + id="address" + placeholder={address} + value={this.state.newAddress || address} + error={this.state.error} + onChange={e => this.setState({ newAddress: e.target.value })} + fullWidth + margin="dense" + /> + </div> + + <div className="address-book__view-contact__group"> + <div className="address-book__view-contact__group__label--capitalized"> + { t('memo') } + </div> + <TextField + type="text" + id="memo" + placeholder={memo} + value={this.state.newMemo || memo} + onChange={e => this.setState({ newMemo: e.target.value })} + fullWidth + margin="dense" + multiline={true} + rows={3} + classes={{ + inputMultiline: 'address-book__view-contact__text-area', + inputRoot: 'address-book__view-contact__text-area-wrapper', + }} + /> + </div> + </div> + <PageContainerFooter + cancelText={this.context.t('cancel')} + onSubmit={() => { + if (this.state.newAddress !== '' && this.state.newAddress !== address) { + // if the user makes a valid change to the address field, remove the original address + if (isValidAddress(this.state.newAddress)) { + removeFromAddressBook(address) + addToAddressBook(this.state.newAddress, this.state.newName || name, this.state.newMemo || memo) + setAccountLabel(this.state.newAddress, this.state.newName || name) + history.push(listRoute) + } else { + this.setState({ error: 'invalid address' }) + } + } else { + // update name + addToAddressBook(address, this.state.newName || name, this.state.newMemo || memo) + setAccountLabel(address, this.state.newName || name) + history.push(listRoute) + } + }} + onCancel={() => { + history.push(`${viewRoute}/${address}`) + }} + submitText={this.context.t('save')} + submitButtonType={'confirm'} + /> + </div> + ) + } +} diff --git a/ui/app/pages/settings/contact-list-tab/edit-contact/edit-contact.container.js b/ui/app/pages/settings/contact-list-tab/edit-contact/edit-contact.container.js new file mode 100644 index 000000000..8841ff791 --- /dev/null +++ b/ui/app/pages/settings/contact-list-tab/edit-contact/edit-contact.container.js @@ -0,0 +1,47 @@ +import EditContact from './edit-contact.component' +import { compose } from 'recompose' +import { connect } from 'react-redux' +import { withRouter } from 'react-router-dom' +import { getAddressBookEntry } from '../../../../selectors/selectors' +import { + CONTACT_VIEW_ROUTE, + CONTACT_MY_ACCOUNTS_ROUTE, + CONTACT_MY_ACCOUNTS_VIEW_ROUTE, + CONTACT_MY_ACCOUNTS_EDIT_ROUTE, + CONTACT_LIST_ROUTE, +} from '../../../../helpers/constants/routes' +import { addToAddressBook, removeFromAddressBook, setAccountLabel } from '../../../../store/actions' + +const mapStateToProps = (state, ownProps) => { + const { location } = ownProps + const { pathname } = location + const pathNameTail = pathname.match(/[^/]+$/)[0] + const pathNameTailIsAddress = pathNameTail.includes('0x') + const address = pathNameTailIsAddress ? pathNameTail.toLowerCase() : ownProps.match.params.id + + const { memo, name } = getAddressBookEntry(state, address) || state.metamask.identities[address] + + const showingMyAccounts = Boolean(pathname.match(CONTACT_MY_ACCOUNTS_EDIT_ROUTE)) + + return { + address, + name, + memo, + viewRoute: showingMyAccounts ? CONTACT_MY_ACCOUNTS_VIEW_ROUTE : CONTACT_VIEW_ROUTE, + listRoute: showingMyAccounts ? CONTACT_MY_ACCOUNTS_ROUTE : CONTACT_LIST_ROUTE, + showingMyAccounts, + } +} + +const mapDispatchToProps = dispatch => { + return { + addToAddressBook: (recipient, nickname, memo) => dispatch(addToAddressBook(recipient, nickname, memo)), + removeFromAddressBook: (addressToRemove) => dispatch(removeFromAddressBook(addressToRemove)), + setAccountLabel: (address, label) => dispatch(setAccountLabel(address, label)), + } +} + +export default compose( + withRouter, + connect(mapStateToProps, mapDispatchToProps) +)(EditContact) diff --git a/ui/app/pages/settings/contact-list-tab/edit-contact/index.js b/ui/app/pages/settings/contact-list-tab/edit-contact/index.js new file mode 100644 index 000000000..fe5ee206a --- /dev/null +++ b/ui/app/pages/settings/contact-list-tab/edit-contact/index.js @@ -0,0 +1 @@ +export { default } from './edit-contact.container' |