aboutsummaryrefslogtreecommitdiffstats
path: root/ui/app/components/app/confirm-page-container
diff options
context:
space:
mode:
Diffstat (limited to 'ui/app/components/app/confirm-page-container')
-rw-r--r--ui/app/components/app/confirm-page-container/confirm-detail-row/confirm-detail-row.component.js84
-rw-r--r--ui/app/components/app/confirm-page-container/confirm-detail-row/index.js1
-rw-r--r--ui/app/components/app/confirm-page-container/confirm-detail-row/index.scss50
-rw-r--r--ui/app/components/app/confirm-page-container/confirm-detail-row/tests/confirm-detail-row.component.test.js64
-rw-r--r--ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-content.component.js110
-rw-r--r--ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-summary/confirm-page-container-summary.component.js71
-rw-r--r--ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-summary/index.js1
-rw-r--r--ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-summary/index.scss54
-rw-r--r--ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-warning/confirm-page-container-warning.component.js22
-rw-r--r--ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-warning/index.js1
-rw-r--r--ui/app/components/app/confirm-page-container/confirm-page-container-content/confirm-page-container-warning/index.scss18
-rw-r--r--ui/app/components/app/confirm-page-container/confirm-page-container-content/index.js3
-rw-r--r--ui/app/components/app/confirm-page-container/confirm-page-container-content/index.scss68
-rw-r--r--ui/app/components/app/confirm-page-container/confirm-page-container-header/confirm-page-container-header.component.js63
-rw-r--r--ui/app/components/app/confirm-page-container/confirm-page-container-header/index.js1
-rw-r--r--ui/app/components/app/confirm-page-container/confirm-page-container-header/index.scss27
-rwxr-xr-xui/app/components/app/confirm-page-container/confirm-page-container-navigation/confirm-page-container-navigation.component.js69
-rwxr-xr-xui/app/components/app/confirm-page-container/confirm-page-container-navigation/index.js1
-rwxr-xr-xui/app/components/app/confirm-page-container/confirm-page-container-navigation/index.scss54
-rw-r--r--ui/app/components/app/confirm-page-container/confirm-page-container.component.js170
-rw-r--r--ui/app/components/app/confirm-page-container/index.js10
-rw-r--r--ui/app/components/app/confirm-page-container/index.scss7
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';