diff options
Diffstat (limited to 'ui/app/components/app/confirm-page-container')
22 files changed, 949 insertions, 0 deletions
diff --git a/ui/app/components/app/confirm-page-container/confirm-detail-row/confirm-detail-row.component.js b/ui/app/components/app/confirm-page-container/confirm-detail-row/confirm-detail-row.component.js new file mode 100644 index 000000000..18571eccb --- /dev/null +++ b/ui/app/components/app/confirm-page-container/confirm-detail-row/confirm-detail-row.component.js @@ -0,0 +1,84 @@ +import React from 'react' +import PropTypes from 'prop-types' +import classnames from 'classnames' +import UserPreferencedCurrencyDisplay from '../../user-preferenced-currency-display' +import { PRIMARY, SECONDARY } from '../../../../helpers/constants/common' + +const ConfirmDetailRow = props => { + const { + label, + primaryText, + secondaryText, + onHeaderClick, + primaryValueTextColor, + headerText, + headerTextClassName, + value, + } = props + + return ( + <div className="confirm-detail-row"> + <div className="confirm-detail-row__label"> + { label } + </div> + <div className="confirm-detail-row__details"> + <div + className={classnames('confirm-detail-row__header-text', headerTextClassName)} + onClick={() => onHeaderClick && onHeaderClick()} + > + { headerText } + </div> + { + primaryText + ? ( + <div + className="confirm-detail-row__primary" + style={{ color: primaryValueTextColor }} + > + { primaryText } + </div> + ) : ( + <UserPreferencedCurrencyDisplay + className="confirm-detail-row__primary" + type={PRIMARY} + value={value} + showEthLogo + ethLogoHeight="18" + style={{ color: primaryValueTextColor }} + hideLabel + /> + ) + } + { + secondaryText + ? ( + <div className="confirm-detail-row__secondary"> + { secondaryText } + </div> + ) : ( + <UserPreferencedCurrencyDisplay + className="confirm-detail-row__secondary" + type={SECONDARY} + value={value} + showEthLogo + hideLabel + /> + ) + } + </div> + </div> + ) +} + +ConfirmDetailRow.propTypes = { + headerText: PropTypes.string, + headerTextClassName: PropTypes.string, + label: PropTypes.string, + onHeaderClick: PropTypes.func, + primaryValueTextColor: PropTypes.string, + primaryText: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), + secondaryText: PropTypes.string, + value: PropTypes.string, +} + +export default ConfirmDetailRow diff --git a/ui/app/components/app/confirm-page-container/confirm-detail-row/index.js b/ui/app/components/app/confirm-page-container/confirm-detail-row/index.js new file mode 100644 index 000000000..056afff04 --- /dev/null +++ b/ui/app/components/app/confirm-page-container/confirm-detail-row/index.js @@ -0,0 +1 @@ +export { default } from './confirm-detail-row.component' diff --git a/ui/app/components/app/confirm-page-container/confirm-detail-row/index.scss b/ui/app/components/app/confirm-page-container/confirm-detail-row/index.scss new file mode 100644 index 000000000..1672ef8c6 --- /dev/null +++ b/ui/app/components/app/confirm-page-container/confirm-detail-row/index.scss @@ -0,0 +1,50 @@ +.confirm-detail-row { + padding: 14px 0; + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + + &__label { + font-size: .75rem; + font-weight: 500; + color: $scorpion; + text-transform: uppercase; + } + + &__details { + flex: 1; + text-align: end; + min-width: 0; + } + + &__primary { + font-size: 1.5rem; + justify-content: flex-end; + } + + &__secondary { + color: $oslo-gray; + justify-content: flex-end; + } + + &__header-text { + font-size: .75rem; + text-transform: uppercase; + margin-bottom: 6px; + color: $scorpion; + + &--edit { + color: $curious-blue; + cursor: pointer; + } + + &--total { + font-size: .625rem; + } + } + + .advanced-gas-inputs__gas-edit-rows { + margin-bottom: 16px; + } +} diff --git a/ui/app/components/app/confirm-page-container/confirm-detail-row/tests/confirm-detail-row.component.test.js b/ui/app/components/app/confirm-page-container/confirm-detail-row/tests/confirm-detail-row.component.test.js new file mode 100644 index 000000000..c8507985d --- /dev/null +++ b/ui/app/components/app/confirm-page-container/confirm-detail-row/tests/confirm-detail-row.component.test.js @@ -0,0 +1,64 @@ +import React from 'react' +import assert from 'assert' +import { shallow } from 'enzyme' +import ConfirmDetailRow from '../confirm-detail-row.component.js' +import sinon from 'sinon' + +const propsMethodSpies = { + onHeaderClick: sinon.spy(), +} + +describe('Confirm Detail Row Component', function () { + let wrapper + + beforeEach(() => { + wrapper = shallow( + <ConfirmDetailRow + errorType={'mockErrorType'} + label={'mockLabel'} + showError={false} + primaryText = {'mockFiatText'} + secondaryText = {'mockEthText'} + primaryValueTextColor= {'mockColor'} + onHeaderClick= {propsMethodSpies.onHeaderClick} + headerText = {'mockHeaderText'} + headerTextClassName = {'mockHeaderClass'} + /> + ) + }) + + describe('render', () => { + it('should render a div with a confirm-detail-row class', () => { + assert.equal(wrapper.find('div.confirm-detail-row').length, 1) + }) + + it('should render the label as a child of the confirm-detail-row__label', () => { + assert.equal(wrapper.find('.confirm-detail-row > .confirm-detail-row__label').childAt(0).text(), 'mockLabel') + }) + + it('should render the headerText as a child of the confirm-detail-row__header-text', () => { + assert.equal(wrapper.find('.confirm-detail-row__details > .confirm-detail-row__header-text').childAt(0).text(), 'mockHeaderText') + }) + + it('should render the primaryText as a child of the confirm-detail-row__primary', () => { + assert.equal(wrapper.find('.confirm-detail-row__details > .confirm-detail-row__primary').childAt(0).text(), 'mockFiatText') + }) + + it('should render the ethText as a child of the confirm-detail-row__secondary', () => { + assert.equal(wrapper.find('.confirm-detail-row__details > .confirm-detail-row__secondary').childAt(0).text(), 'mockEthText') + }) + + it('should set the fiatTextColor on confirm-detail-row__primary', () => { + assert.equal(wrapper.find('.confirm-detail-row__primary').props().style.color, 'mockColor') + }) + + it('should assure the confirm-detail-row__header-text classname is correct', () => { + assert.equal(wrapper.find('.confirm-detail-row__header-text').props().className, 'confirm-detail-row__header-text mockHeaderClass') + }) + + it('should call onHeaderClick when headerText div gets clicked', () => { + wrapper.find('.confirm-detail-row__header-text').props().onClick() + assert.equal(assert.equal(propsMethodSpies.onHeaderClick.callCount, 1)) + }) + }) +}) diff --git a/ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-content.component.js b/ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-content.component.js new file mode 100644 index 000000000..8a5f90c76 --- /dev/null +++ b/ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-content.component.js @@ -0,0 +1,110 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import classnames from 'classnames' +import { Tabs, Tab } from '../../../ui/tabs' +import { ConfirmPageContainerSummary, ConfirmPageContainerWarning } from '.' +import ErrorMessage from '../../../ui/error-message' + +export default class ConfirmPageContainerContent extends Component { + static propTypes = { + action: PropTypes.string, + dataComponent: PropTypes.node, + detailsComponent: PropTypes.node, + errorKey: PropTypes.string, + errorMessage: PropTypes.string, + hideSubtitle: PropTypes.bool, + identiconAddress: PropTypes.string, + nonce: PropTypes.string, + assetImage: PropTypes.string, + subtitle: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), + subtitleComponent: PropTypes.node, + summaryComponent: PropTypes.node, + title: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), + titleComponent: PropTypes.node, + warning: PropTypes.string, + } + + renderContent () { + const { detailsComponent, dataComponent } = this.props + + if (detailsComponent && dataComponent) { + return this.renderTabs() + } else { + return detailsComponent || dataComponent + } + } + + renderTabs () { + const { detailsComponent, dataComponent } = this.props + + return ( + <Tabs> + <Tab name="Details"> + { detailsComponent } + </Tab> + <Tab name="Data"> + { dataComponent } + </Tab> + </Tabs> + ) + } + + render () { + const { + action, + errorKey, + errorMessage, + title, + titleComponent, + subtitle, + subtitleComponent, + hideSubtitle, + identiconAddress, + nonce, + assetImage, + summaryComponent, + detailsComponent, + dataComponent, + warning, + } = this.props + + return ( + <div className="confirm-page-container-content"> + { + warning && ( + <ConfirmPageContainerWarning warning={warning} /> + ) + } + { + summaryComponent || ( + <ConfirmPageContainerSummary + className={classnames({ + 'confirm-page-container-summary--border': !detailsComponent || !dataComponent, + })} + action={action} + title={title} + titleComponent={titleComponent} + subtitle={subtitle} + subtitleComponent={subtitleComponent} + hideSubtitle={hideSubtitle} + identiconAddress={identiconAddress} + nonce={nonce} + assetImage={assetImage} + /> + ) + } + { this.renderContent() } + { + (errorKey || errorMessage) && ( + <div className="confirm-page-container-content__error-container"> + <ErrorMessage + errorMessage={errorMessage} + errorKey={errorKey} + /> + </div> + ) + } + </div> + ) + } +} diff --git a/ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-summary/confirm-page-container-summary.component.js b/ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-summary/confirm-page-container-summary.component.js new file mode 100644 index 000000000..0cc4d8262 --- /dev/null +++ b/ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-summary/confirm-page-container-summary.component.js @@ -0,0 +1,71 @@ +import React from 'react' +import PropTypes from 'prop-types' +import classnames from 'classnames' +import Identicon from '../../../../ui/identicon' + +const ConfirmPageContainerSummary = props => { + const { + action, + title, + titleComponent, + subtitle, + subtitleComponent, + hideSubtitle, + className, + identiconAddress, + nonce, + assetImage, + } = props + + return ( + <div className={classnames('confirm-page-container-summary', className)}> + <div className="confirm-page-container-summary__action-row"> + <div className="confirm-page-container-summary__action"> + { action } + </div> + { + nonce && ( + <div className="confirm-page-container-summary__nonce"> + { `#${nonce}` } + </div> + ) + } + </div> + <div className="confirm-page-container-summary__title"> + { + identiconAddress && ( + <Identicon + className="confirm-page-container-summary__identicon" + diameter={36} + address={identiconAddress} + image={assetImage} + /> + ) + } + <div className="confirm-page-container-summary__title-text"> + { titleComponent || title } + </div> + </div> + { + hideSubtitle || <div className="confirm-page-container-summary__subtitle"> + { subtitleComponent || subtitle } + </div> + } + </div> + ) +} + +ConfirmPageContainerSummary.propTypes = { + action: PropTypes.string, + title: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), + titleComponent: PropTypes.node, + subtitle: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), + subtitleComponent: PropTypes.node, + hideSubtitle: PropTypes.bool, + className: PropTypes.string, + identiconAddress: PropTypes.string, + nonce: PropTypes.string, + assetImage: PropTypes.string, +} + +export default ConfirmPageContainerSummary diff --git a/ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-summary/index.js b/ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-summary/index.js new file mode 100644 index 000000000..ed1b28cf2 --- /dev/null +++ b/ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-summary/index.js @@ -0,0 +1 @@ +export { default } from './confirm-page-container-summary.component' diff --git a/ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-summary/index.scss b/ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-summary/index.scss new file mode 100644 index 000000000..7f0f5d37a --- /dev/null +++ b/ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-summary/index.scss @@ -0,0 +1,54 @@ +.confirm-page-container-summary { + padding: 16px 24px 0; + background-color: #f9fafa; + height: 133px; + box-sizing: border-box; + + &__action-row { + display: flex; + justify-content: space-between; + } + + &__action { + text-transform: uppercase; + color: $oslo-gray; + font-size: .75rem; + padding: 3px 8px; + border: 1px solid $oslo-gray; + border-radius: 4px; + display: inline-block; + } + + &__nonce { + color: $oslo-gray; + } + + &__title { + padding: 4px 0; + display: flex; + align-items: center; + } + + &__identicon { + flex: 0 0 auto; + margin-right: 8px; + } + + &__title-text { + font-size: 2.25rem; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + + &__subtitle { + color: $oslo-gray; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + + &--border { + border-bottom: 1px solid $geyser; + } +} diff --git a/ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-warning/confirm-page-container-warning.component.js b/ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-warning/confirm-page-container-warning.component.js new file mode 100644 index 000000000..79901c8fc --- /dev/null +++ b/ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-warning/confirm-page-container-warning.component.js @@ -0,0 +1,22 @@ +import React from 'react' +import PropTypes from 'prop-types' + +const ConfirmPageContainerWarning = props => { + return ( + <div className="confirm-page-container-warning"> + <img + className="confirm-page-container-warning__icon" + src="/images/alert.svg" + /> + <div className="confirm-page-container-warning__warning"> + { props.warning } + </div> + </div> + ) +} + +ConfirmPageContainerWarning.propTypes = { + warning: PropTypes.string, +} + +export default ConfirmPageContainerWarning diff --git a/ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-warning/index.js b/ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-warning/index.js new file mode 100644 index 000000000..6e48bd144 --- /dev/null +++ b/ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-warning/index.js @@ -0,0 +1 @@ +export { default } from './confirm-page-container-warning.component' diff --git a/ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-warning/index.scss b/ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-warning/index.scss new file mode 100644 index 000000000..50545a1a2 --- /dev/null +++ b/ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-warning/index.scss @@ -0,0 +1,18 @@ +.confirm-page-container-warning { + background-color: #fffcdb; + display: flex; + justify-content: center; + align-items: center; + border-bottom: 1px solid $geyser; + padding: 12px 24px; + + &__icon { + flex: 0 0 auto; + margin-right: 16px; + } + + &__warning { + font-size: .75rem; + color: #5f5922; + } +} diff --git a/ui/app/components/app/confirm-page-container/confirm-page-container-content/index.js b/ui/app/components/app/confirm-page-container/confirm-page-container-content/index.js new file mode 100644 index 000000000..4dfd89d92 --- /dev/null +++ b/ui/app/components/app/confirm-page-container/confirm-page-container-content/index.js @@ -0,0 +1,3 @@ +export { default } from './confirm-page-container-content.component' +export { default as ConfirmPageContainerSummary } from './confirm-page-container-summary' +export { default as ConfirmPageContainerWarning } from './confirm-page-container-warning' diff --git a/ui/app/components/app/confirm-page-container/confirm-page-container-content/index.scss b/ui/app/components/app/confirm-page-container/confirm-page-container-content/index.scss new file mode 100644 index 000000000..602a46848 --- /dev/null +++ b/ui/app/components/app/confirm-page-container/confirm-page-container-content/index.scss @@ -0,0 +1,68 @@ +@import 'confirm-page-container-warning/index'; + +@import 'confirm-page-container-summary/index'; + +.confirm-page-container-content { + overflow-y: auto; + flex: 1; + + &__error-container { + padding: 0 16px 16px 16px; + } + + &__details { + box-sizing: border-box; + padding: 0 24px; + } + + &__data { + padding: 16px; + color: $oslo-gray; + } + + &__data-box { + background-color: #f9fafa; + padding: 12px; + font-size: .75rem; + margin-bottom: 16px; + word-wrap: break-word; + max-height: 200px; + overflow-y: auto; + + &-label { + text-transform: uppercase; + padding: 8px 0 12px; + font-size: 12px; + } + } + + &__data-field { + display: flex; + flex-direction: row; + + &-label { + font-weight: 500; + padding-right: 16px; + } + + &:not(:last-child) { + margin-bottom: 5px; + } + } + + &__gas-fee { + border-bottom: 1px solid $geyser; + + .advanced-gas-inputs__gas-edit-rows { + margin-bottom: 16px; + } + } + + &__function-type { + font-size: .875rem; + font-weight: 500; + text-transform: capitalize; + color: $black; + padding-left: 5px; + } +} diff --git a/ui/app/components/app/confirm-page-container/confirm-page-container-header/confirm-page-container-header.component.js b/ui/app/components/app/confirm-page-container/confirm-page-container-header/confirm-page-container-header.component.js new file mode 100644 index 000000000..84ca40da5 --- /dev/null +++ b/ui/app/components/app/confirm-page-container/confirm-page-container-header/confirm-page-container-header.component.js @@ -0,0 +1,63 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import { + ENVIRONMENT_TYPE_POPUP, + ENVIRONMENT_TYPE_NOTIFICATION, +} from '../../../../../../app/scripts/lib/enums' +import NetworkDisplay from '../../network-display' + +export default class ConfirmPageContainer extends Component { + static contextTypes = { + t: PropTypes.func, + } + + static propTypes = { + showEdit: PropTypes.bool, + onEdit: PropTypes.func, + children: PropTypes.node, + } + + renderTop () { + const { onEdit, showEdit } = this.props + const windowType = window.METAMASK_UI_TYPE + const isFullScreen = windowType !== ENVIRONMENT_TYPE_NOTIFICATION && + windowType !== ENVIRONMENT_TYPE_POPUP + + if (!showEdit && isFullScreen) { + return null + } + + return ( + <div className="confirm-page-container-header__row"> + <div + className="confirm-page-container-header__back-button-container" + style={{ + visibility: showEdit ? 'initial' : 'hidden', + }} + > + <img + src="/images/caret-left.svg" + /> + <span + className="confirm-page-container-header__back-button" + onClick={() => onEdit()} + > + { this.context.t('edit') } + </span> + </div> + { !isFullScreen && <NetworkDisplay /> } + </div> + ) + } + + render () { + const { children } = this.props + + return ( + <div className="confirm-page-container-header"> + { this.renderTop() } + { children } + </div> + ) + } +} diff --git a/ui/app/components/app/confirm-page-container/confirm-page-container-header/index.js b/ui/app/components/app/confirm-page-container/confirm-page-container-header/index.js new file mode 100644 index 000000000..71feb6931 --- /dev/null +++ b/ui/app/components/app/confirm-page-container/confirm-page-container-header/index.js @@ -0,0 +1 @@ +export { default } from './confirm-page-container-header.component' diff --git a/ui/app/components/app/confirm-page-container/confirm-page-container-header/index.scss b/ui/app/components/app/confirm-page-container/confirm-page-container-header/index.scss new file mode 100644 index 000000000..be77edbdf --- /dev/null +++ b/ui/app/components/app/confirm-page-container/confirm-page-container-header/index.scss @@ -0,0 +1,27 @@ +.confirm-page-container-header { + display: flex; + flex-direction: column; + flex: 0 0 auto; + + &__row { + display: flex; + justify-content: space-between; + border-bottom: 1px solid $geyser; + padding: 4px 13px 4px 13px; + flex: 0 0 auto; + } + + &__back-button-container { + display: flex; + justify-content: center; + align-items: center; + } + + &__back-button { + color: #2f9ae0; + font-size: 1rem; + cursor: pointer; + font-weight: 400; + padding-left: 5px; + } +} diff --git a/ui/app/components/app/confirm-page-container/confirm-page-container-navigation/confirm-page-container-navigation.component.js b/ui/app/components/app/confirm-page-container/confirm-page-container-navigation/confirm-page-container-navigation.component.js new file mode 100755 index 000000000..8327f997b --- /dev/null +++ b/ui/app/components/app/confirm-page-container/confirm-page-container-navigation/confirm-page-container-navigation.component.js @@ -0,0 +1,69 @@ +import React from 'react' +import PropTypes from 'prop-types' + +const ConfirmPageContainerNavigation = props => { + const { onNextTx, totalTx, positionOfCurrentTx, nextTxId, prevTxId, showNavigation, firstTx, lastTx, ofText, requestsWaitingText } = props + + return ( + <div className="confirm-page-container-navigation" + style={{ + display: showNavigation ? 'flex' : 'none', + }} + > + <div className="confirm-page-container-navigation__container" + style={{ + visibility: prevTxId ? 'initial' : 'hidden', + }}> + <div + className="confirm-page-container-navigation__arrow" + onClick={() => onNextTx(firstTx)}> + <img src="/images/double-arrow.svg" /> + </div> + <div + className="confirm-page-container-navigation__arrow" + onClick={() => onNextTx(prevTxId)}> + <img src="/images/single-arrow.svg" /> + </div> + </div> + <div className="confirm-page-container-navigation__textcontainer"> + <div className="confirm-page-container-navigation__navtext"> + {positionOfCurrentTx} {ofText} {totalTx} + </div> + <div className="confirm-page-container-navigation__longtext"> + {requestsWaitingText} + </div> + </div> + <div + className="confirm-page-container-navigation__container" + style={{ + visibility: nextTxId ? 'initial' : 'hidden', + }}> + <div + className="confirm-page-container-navigation__arrow" + onClick={() => onNextTx(nextTxId)}> + <img className="confirm-page-container-navigation__imageflip" src="/images/single-arrow.svg" /> + </div> + <div + className="confirm-page-container-navigation__arrow" + onClick={() => onNextTx(lastTx)}> + <img className="confirm-page-container-navigation__imageflip" src="/images/double-arrow.svg" /> + </div> + </div> + </div> + ) +} + +ConfirmPageContainerNavigation.propTypes = { + totalTx: PropTypes.number, + positionOfCurrentTx: PropTypes.number, + onNextTx: PropTypes.func, + nextTxId: PropTypes.string, + prevTxId: PropTypes.string, + showNavigation: PropTypes.bool, + firstTx: PropTypes.string, + lastTx: PropTypes.string, + ofText: PropTypes.string, + requestsWaitingText: PropTypes.string, +} + +export default ConfirmPageContainerNavigation diff --git a/ui/app/components/app/confirm-page-container/confirm-page-container-navigation/index.js b/ui/app/components/app/confirm-page-container/confirm-page-container-navigation/index.js new file mode 100755 index 000000000..d97c1b447 --- /dev/null +++ b/ui/app/components/app/confirm-page-container/confirm-page-container-navigation/index.js @@ -0,0 +1 @@ +export { default } from './confirm-page-container-navigation.component' diff --git a/ui/app/components/app/confirm-page-container/confirm-page-container-navigation/index.scss b/ui/app/components/app/confirm-page-container/confirm-page-container-navigation/index.scss new file mode 100755 index 000000000..0cf184c60 --- /dev/null +++ b/ui/app/components/app/confirm-page-container/confirm-page-container-navigation/index.scss @@ -0,0 +1,54 @@ +.confirm-page-container-navigation { + display: flex; + justify-content: space-between; + font: inherit; + padding: 4px 10px 4px 10px; + border-bottom: 1px solid $geyser; + flex: 0 0 auto; + + &__container { + display: flex; + } + + &__arrow { + cursor: pointer; + display: flex; + padding-left: 5px; + padding-right: 5px; + } + + &__arrow:hover { + -webkit-transform: scale(1.1); + -moz-transform: scale(1.1); + -o-transform: scale(1.1); + transform: scale(1.1); + } + + &__arrow:active { + -webkit-transform: scale(0.95); + -moz-transform: scale(0.95); + -o-transform: scale(0.95); + transform: scale(0.95); + } + + &__textcontainer { + text-align: center; + } + + &__navtext { + font-size: 9px; + font-weight: bold; + } + + &__longtext { + color: $oslo-gray; + font-size: 8px; + } + + &__imageflip { + -webkit-transform: scaleX(-1); + -moz-transform: scaleX(-1); + -o-transform: scaleX(-1); + transform: scaleX(-1); + } +}
\ No newline at end of file diff --git a/ui/app/components/app/confirm-page-container/confirm-page-container.component.js b/ui/app/components/app/confirm-page-container/confirm-page-container.component.js new file mode 100644 index 000000000..326e4f83e --- /dev/null +++ b/ui/app/components/app/confirm-page-container/confirm-page-container.component.js @@ -0,0 +1,170 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import SenderToRecipient from '../../ui/sender-to-recipient' +import { PageContainerFooter } from '../../ui/page-container' +import { ConfirmPageContainerHeader, ConfirmPageContainerContent, ConfirmPageContainerNavigation } from '.' + +export default class ConfirmPageContainer extends Component { + static contextTypes = { + t: PropTypes.func, + } + + static propTypes = { + // Header + action: PropTypes.string, + hideSubtitle: PropTypes.bool, + onEdit: PropTypes.func, + showEdit: PropTypes.bool, + subtitle: PropTypes.string, + subtitleComponent: PropTypes.node, + title: PropTypes.string, + titleComponent: PropTypes.node, + // Sender to Recipient + fromAddress: PropTypes.string, + fromName: PropTypes.string, + toAddress: PropTypes.string, + toName: PropTypes.string, + // Content + contentComponent: PropTypes.node, + errorKey: PropTypes.string, + errorMessage: PropTypes.string, + fiatTransactionAmount: PropTypes.string, + fiatTransactionFee: PropTypes.string, + fiatTransactionTotal: PropTypes.string, + ethTransactionAmount: PropTypes.string, + ethTransactionFee: PropTypes.string, + ethTransactionTotal: PropTypes.string, + onEditGas: PropTypes.func, + dataComponent: PropTypes.node, + detailsComponent: PropTypes.node, + identiconAddress: PropTypes.string, + nonce: PropTypes.string, + assetImage: PropTypes.string, + summaryComponent: PropTypes.node, + warning: PropTypes.string, + unapprovedTxCount: PropTypes.number, + // Navigation + totalTx: PropTypes.number, + positionOfCurrentTx: PropTypes.number, + nextTxId: PropTypes.string, + prevTxId: PropTypes.string, + showNavigation: PropTypes.bool, + onNextTx: PropTypes.func, + firstTx: PropTypes.string, + lastTx: PropTypes.string, + ofText: PropTypes.string, + requestsWaitingText: PropTypes.string, + // Footer + onCancelAll: PropTypes.func, + onCancel: PropTypes.func, + onSubmit: PropTypes.func, + disabled: PropTypes.bool, + } + + render () { + const { + showEdit, + onEdit, + fromName, + fromAddress, + toName, + toAddress, + disabled, + errorKey, + errorMessage, + contentComponent, + action, + title, + titleComponent, + subtitle, + subtitleComponent, + hideSubtitle, + summaryComponent, + detailsComponent, + dataComponent, + onCancelAll, + onCancel, + onSubmit, + identiconAddress, + nonce, + unapprovedTxCount, + assetImage, + warning, + totalTx, + positionOfCurrentTx, + nextTxId, + prevTxId, + showNavigation, + onNextTx, + firstTx, + lastTx, + ofText, + requestsWaitingText, + } = this.props + const renderAssetImage = contentComponent || (!contentComponent && !identiconAddress) + + return ( + <div className="page-container"> + <ConfirmPageContainerNavigation + totalTx={totalTx} + positionOfCurrentTx={positionOfCurrentTx} + nextTxId={nextTxId} + prevTxId={prevTxId} + showNavigation={showNavigation} + onNextTx={(txId) => onNextTx(txId)} + firstTx={firstTx} + lastTx={lastTx} + ofText={ofText} + requestsWaitingText={requestsWaitingText} + /> + <ConfirmPageContainerHeader + showEdit={showEdit} + onEdit={() => onEdit()} + > + <SenderToRecipient + senderName={fromName} + senderAddress={fromAddress} + recipientName={toName} + recipientAddress={toAddress} + assetImage={renderAssetImage ? assetImage : undefined} + /> + </ConfirmPageContainerHeader> + { + contentComponent || ( + <ConfirmPageContainerContent + action={action} + title={title} + titleComponent={titleComponent} + subtitle={subtitle} + subtitleComponent={subtitleComponent} + hideSubtitle={hideSubtitle} + summaryComponent={summaryComponent} + detailsComponent={detailsComponent} + dataComponent={dataComponent} + errorMessage={errorMessage} + errorKey={errorKey} + identiconAddress={identiconAddress} + nonce={nonce} + assetImage={assetImage} + warning={warning} + /> + ) + } + <PageContainerFooter + onCancel={() => onCancel()} + cancelText={this.context.t('reject')} + onSubmit={() => onSubmit()} + submitText={this.context.t('confirm')} + submitButtonType="confirm" + disabled={disabled} + > + {unapprovedTxCount > 1 && ( + <a onClick={() => onCancelAll()}> + {this.context.t('rejectTxsN', [unapprovedTxCount])} + </a> + )} + </PageContainerFooter> + </div> + ) + } +} diff --git a/ui/app/components/app/confirm-page-container/index.js b/ui/app/components/app/confirm-page-container/index.js new file mode 100644 index 000000000..28b17614e --- /dev/null +++ b/ui/app/components/app/confirm-page-container/index.js @@ -0,0 +1,10 @@ +export { default } from './confirm-page-container.component' +export { default as ConfirmPageContainerHeader } from './confirm-page-container-header' +export { default as ConfirmDetailRow } from './confirm-detail-row' +export { default as ConfirmPageContainerNavigation } from './confirm-page-container-navigation' + +export { + default as ConfirmPageContainerContent, + ConfirmPageContainerSummary, + ConfirmPageContainerError, +} from './confirm-page-container-content' diff --git a/ui/app/components/app/confirm-page-container/index.scss b/ui/app/components/app/confirm-page-container/index.scss new file mode 100644 index 000000000..c0277eff5 --- /dev/null +++ b/ui/app/components/app/confirm-page-container/index.scss @@ -0,0 +1,7 @@ +@import 'confirm-page-container-content/index'; + +@import 'confirm-page-container-header/index'; + +@import 'confirm-detail-row/index'; + +@import 'confirm-page-container-navigation/index'; |