,
+};
+
+const AdvancedForm = (props: Props) => {
+ const {
+ account,
+ network,
+ } = props.selectedAccount;
+
+ const {
+ networkSymbol,
+ currency,
+ gasPrice,
+ gasLimit,
+ recommendedGasPrice,
+ calculatingGasLimit,
+ nonce,
+ data,
+ errors,
+ warnings,
+ infos,
+ advanced,
+ } = props.sendForm;
+
+ const {
+ toggleAdvanced,
+ onGasPriceChange,
+ onGasLimitChange,
+ onNonceChange,
+ onDataChange,
+ } = props.sendFormActions;
+
+ if (!advanced) {
+ return (
+
+ );
+ }
+
+ const nonceTooltip = (
+
+ TODO
+
+ );
+
+ let gasLimitTooltipCurrency: string;
+ let gasLimitTooltipValue: string;
+ if (networkSymbol !== currency) {
+ gasLimitTooltipCurrency = 'tokens';
+ gasLimitTooltipValue = network.defaultGasLimitTokens;
+ } else {
+ gasLimitTooltipCurrency = networkSymbol;
+ gasLimitTooltipValue = network.defaultGasLimit;
+ }
+
+ const gasLimitTooltip = (
+
+ Gas limit is the amount of gas to send with your transaction.
+ TX fee = gas price * gas limit & is paid to miners for including your TX in a block.
+ Increasing this number will not get your TX mined faster.
+ Default value for sending { gasLimitTooltipCurrency } is { gasLimitTooltipValue }
+
+ );
+
+ const gasPriceTooltip = (
+
+ Gas Price is the amount you pay per unit of gas.
+
TX fee = gas price * gas limit & is paid to miners for including your TX in a block.
+ Higher the gas price = faster transaction, but more expensive. Recommended is
{ recommendedGasPrice } GWEI.
+
Read more
+
+ );
+
+ const dataTooltip = (
+
+ Data is usually used when you send transactions to contracts.
+
+ );
+
+
+ return (
+
+
Advanced settings
+
+ {/*
+
+ Nonce
+
}
+ overlay={ nonceTooltip }
+ placement="top">
+
+
+
+
onNonceChange(event.target.value) } />
+ { errors.nonce ? (
{ errors.nonce } ) : null }
+ { warnings.nonce ? (
{ warnings.nonce } ) : null }
+
*/}
+
+
+ Gas limit
+ }
+ overlay={gasLimitTooltip}
+ placement="top"
+ >
+
+
+
+ 0}
+ onChange={event => onGasLimitChange(event.target.value)}
+ />
+ { errors.gasLimit ? ({ errors.gasLimit } ) : null }
+ { warnings.gasLimit ? ({ warnings.gasLimit } ) : null }
+ { calculatingGasLimit ? (Calculating... ) : null }
+
+
+
+ Gas price
+ }
+ overlay={gasPriceTooltip}
+ placement="top"
+ >
+
+
+
+ onGasPriceChange(event.target.value)}
+ />
+ { errors.gasPrice ? ({ errors.gasPrice } ) : null }
+
+
+
+
+
+ Data
+ }
+ overlay={dataTooltip}
+ placement="top"
+ >
+
+
+
+
+
+
+ { props.children }
+
+
+
+ );
+};
+
+export default AdvancedForm;
\ No newline at end of file
diff --git a/src/js/views/Device/views/Account/components/Send/components/CoinSelectOption.js b/src/js/views/Device/views/Account/components/Send/components/CoinSelectOption.js
new file mode 100644
index 00000000..075688da
--- /dev/null
+++ b/src/js/views/Device/views/Account/components/Send/components/CoinSelectOption.js
@@ -0,0 +1,51 @@
+/* @flow */
+
+
+import * as React from 'react';
+
+type Props = {
+ children: React.Node,
+ className: string,
+ isDisabled: boolean,
+ isFocused: boolean,
+ isSelected: boolean,
+ onFocus: Function,
+ onSelect: Function,
+ option: any,
+}
+
+export default class CoinSelectOption extends React.Component {
+ constructor(props: Props) {
+ super(props);
+ }
+
+ handleMouseDown(event: MouseEvent) {
+ event.preventDefault();
+ event.stopPropagation();
+ this.props.onSelect(this.props.option, event);
+ }
+
+ handleMouseEnter(event: MouseEvent) {
+ this.props.onFocus(this.props.option, event);
+ }
+
+ handleMouseMove(event: MouseEvent) {
+ if (this.props.isFocused) return;
+ this.props.onFocus(this.props.option, event);
+ }
+
+ render() {
+ const css = `${this.props.className} ${this.props.option.value}`;
+ return (
+
+ { this.props.children }
+
+ );
+ }
+}
\ No newline at end of file
diff --git a/src/js/views/Device/views/Account/components/Send/components/FeeSelect.js b/src/js/views/Device/views/Account/components/Send/components/FeeSelect.js
new file mode 100644
index 00000000..2974970a
--- /dev/null
+++ b/src/js/views/Device/views/Account/components/Send/components/FeeSelect.js
@@ -0,0 +1,61 @@
+/* @flow */
+
+
+import * as React from 'react';
+import PropTypes from 'prop-types';
+
+
+export const FeeSelectValue = (props: any): any => (
+
+
+ { props.value.value }
+ { props.value.label }
+
+
+);
+
+type Props = {
+ children: React.Node,
+ className: string,
+ isDisabled: boolean,
+ isFocused: boolean,
+ isSelected: boolean,
+ onFocus: Function,
+ onSelect: Function,
+ option: any,
+}
+
+export class FeeSelectOption extends React.Component {
+ constructor(props: Props) {
+ super(props);
+ }
+
+ handleMouseDown(event: MouseEvent) {
+ event.preventDefault();
+ event.stopPropagation();
+ this.props.onSelect(this.props.option, event);
+ }
+
+ handleMouseEnter(event: MouseEvent) {
+ this.props.onFocus(this.props.option, event);
+ }
+
+ handleMouseMove(event: MouseEvent) {
+ if (this.props.isFocused) return;
+ this.props.onFocus(this.props.option, event);
+ }
+
+ render() {
+ return (
+
+ { this.props.option.value }
+ { this.props.option.label }
+
+ );
+ }
+}
diff --git a/src/js/views/Device/views/Account/components/Send/components/PendingTransactions.js b/src/js/views/Device/views/Account/components/Send/components/PendingTransactions.js
new file mode 100644
index 00000000..e7783bdd
--- /dev/null
+++ b/src/js/views/Device/views/Account/components/Send/components/PendingTransactions.js
@@ -0,0 +1,95 @@
+/* @flow */
+
+
+import React from 'react';
+import ColorHash from 'color-hash';
+import { H2 } from 'components/common/Heading';
+import ScaleText from 'react-scale-text';
+
+import { findAccountTokens } from 'reducers/TokensReducer';
+
+import type { Coin } from 'reducers/LocalStorageReducer';
+import type { Token } from 'reducers/TokensReducer';
+import type { Props as BaseProps } from './index';
+
+type Props = {
+ pending: $PropertyType<$ElementType, 'pending'>,
+ tokens: $PropertyType<$ElementType, 'tokens'>,
+ network: Coin
+}
+
+type Style = {
+ +color: string,
+ +background: string,
+ +borderColor: string
+}
+
+const PendingTransactions = (props: Props) => {
+ const pending = props.pending.filter(tx => !tx.rejected);
+ if (pending.length < 1) return null;
+
+ const tokens: Array = props.tokens;
+
+ const bgColorFactory = new ColorHash({ lightness: 0.7 });
+ const textColorFactory = new ColorHash();
+
+ const pendingTxs: React$Element = pending.map((tx, i) => {
+ let iconColor: Style;
+ let symbol: string;
+ let name: string;
+ const isSmartContractTx: boolean = tx.currency !== props.network.symbol;
+ if (isSmartContractTx) {
+ const token: ?Token = tokens.find(t => t.symbol === tx.currency);
+ if (!token) {
+ iconColor = {
+ color: '#ffffff',
+ background: '#000000',
+ borderColor: '#000000',
+ };
+ symbol = 'Unknown';
+ name = 'Unknown';
+ } else {
+ const bgColor: string = bgColorFactory.hex(token.name);
+ iconColor = {
+ color: textColorFactory.hex(token.name),
+ background: bgColor,
+ borderColor: bgColor,
+ };
+ symbol = token.symbol.toUpperCase();
+ name = token.name;
+ }
+ } else {
+ iconColor = {
+ color: textColorFactory.hex(tx.network),
+ background: bgColorFactory.hex(tx.network),
+ borderColor: bgColorFactory.hex(tx.network),
+ };
+ symbol = props.network.symbol;
+ name = props.network.name;
+ }
+
+ return (
+
+
+
+
{ isSmartContractTx ? tx.amount : tx.total } { symbol }
+
+ );
+ });
+
+
+ return (
+
+
Pending transactions
+ { pendingTxs }
+
+ );
+};
+
+export default PendingTransactions;
\ No newline at end of file
diff --git a/src/js/views/Device/views/Account/components/Send/index.js b/src/js/views/Device/views/Account/components/Send/index.js
new file mode 100644
index 00000000..f2f028a4
--- /dev/null
+++ b/src/js/views/Device/views/Account/components/Send/index.js
@@ -0,0 +1,205 @@
+/* @flow */
+
+import React, { Component } from 'react';
+import styled from 'styled-components';
+import Select from 'react-select';
+import { H2 } from 'components/common/Heading';
+import { calculate, validation } from 'actions/SendFormActions';
+import type { Token } from 'flowtype';
+import AdvancedForm from './components/AdvancedForm';
+import PendingTransactions from './components/PendingTransactions';
+import { FeeSelectValue, FeeSelectOption } from './components/FeeSelect';
+import SelectedAccount from '../SelectedAccount';
+
+
+import type { Props } from './index';
+
+export default class SendContainer extends Component {
+ componentWillReceiveProps(newProps: Props) {
+ calculate(this.props, newProps);
+ validation(newProps);
+
+ this.props.saveSessionStorage();
+ }
+
+ render() {
+ return (
+
+
+
+ );
+ }
+}
+
+const StyledH2 = styled(H2)`
+ padding: 20px 48px;
+`;
+
+const Send = (props: Props) => {
+ const device = props.wallet.selectedDevice;
+ const {
+ account,
+ network,
+ discovery,
+ tokens,
+ } = props.selectedAccount;
+
+ if (!device || !account || !discovery || !network) return null;
+
+ const {
+ address,
+ amount,
+ setMax,
+ networkSymbol,
+ currency,
+ feeLevels,
+ selectedFeeLevel,
+ gasPriceNeedsUpdate,
+ total,
+ errors,
+ warnings,
+ infos,
+ advanced,
+ data,
+ sending,
+ } = props.sendForm;
+
+ const {
+ onAddressChange,
+ onAmountChange,
+ onSetMax,
+ onCurrencyChange,
+ onFeeLevelChange,
+ updateFeeLevels,
+ onSend,
+ } = props.sendFormActions;
+
+ const fiatRate = props.fiat.find(f => f.network === network);
+
+ const tokensSelectData = tokens.map(t => ({ value: t.symbol, label: t.symbol }));
+ tokensSelectData.unshift({ value: network.symbol, label: network.symbol });
+
+ const setMaxClassName: string = setMax ? 'set-max enabled' : 'set-max';
+
+ let updateFeeLevelsButton = null;
+ if (gasPriceNeedsUpdate) {
+ updateFeeLevelsButton = (
+ Recommended fees updated. Click here to use them
+ );
+ }
+
+ let addressClassName: ?string;
+ if (errors.address) {
+ addressClassName = 'not-valid';
+ } else if (warnings.address) {
+ addressClassName = 'warning';
+ } else if (address.length > 0) {
+ addressClassName = 'valid';
+ }
+
+ let buttonDisabled: boolean = Object.keys(errors).length > 0 || total === '0' || amount.length === 0 || address.length === 0 || sending;
+ let buttonLabel: string = 'Send';
+ if (networkSymbol !== currency && amount.length > 0 && !errors.amount) {
+ buttonLabel += ` ${amount} ${currency.toUpperCase()}`;
+ } else if (networkSymbol === currency && total !== '0') {
+ buttonLabel += ` ${total} ${network.symbol}`;
+ }
+
+ if (!device.connected) {
+ buttonLabel = 'Device is not connected';
+ buttonDisabled = true;
+ } else if (!device.available) {
+ buttonLabel = 'Device is unavailable';
+ buttonDisabled = true;
+ } else if (!discovery.completed) {
+ buttonLabel = 'Loading accounts';
+ buttonDisabled = true;
+ }
+
+ return (
+
+ Send Ethereum or tokens
+
+ Address
+ onAddressChange(event.target.value)}
+ />
+
+ { errors.address ? ({ errors.address } ) : null }
+ { warnings.address ? ({ warnings.address } ) : null }
+ { infos.address ? ({ infos.address } ) : null }
+
+
+
+
Amount
+
+
onAmountChange(event.target.value)}
+ />
+
+
Set max
+
+
+
+ { errors.amount ? (
{ errors.amount } ) : null }
+ { warnings.amount ? (
{ warnings.amount } ) : null }
+
+
+
+ Fee{ updateFeeLevelsButton }
+ 0}
+ optionClassName="fee-option"
+ options={feeLevels}
+ />
+
+
+
+ onSend()}>{ buttonLabel }
+
+
+
+
+
+ );
+};
diff --git a/src/js/views/Device/views/Account/components/Sign/index.js b/src/js/views/Device/views/Account/components/Sign/index.js
new file mode 100644
index 00000000..566cfa69
--- /dev/null
+++ b/src/js/views/Device/views/Account/components/Sign/index.js
@@ -0,0 +1,66 @@
+import React from 'react';
+import styled from 'styled-components';
+
+import { H2 } from 'components/common/Heading';
+import colors from 'config/colors';
+
+const Wrapper = styled.div`
+ display: flex;
+ flex: 1;
+ flex-direction: row;
+ background: ${colors.WHITE};
+ padding: 50px;
+`;
+
+const StyledH2 = styled(H2)`
+ padding-bottom: 10px;
+`;
+
+const Column = styled.div`
+ display: flex;
+ flex: 1;
+ flex-direction: column;
+`;
+
+const Sign = styled(Column)``;
+
+const Verify = styled(Column)`
+ padding-left: 20px;
+`;
+
+const Label = styled.div`
+ color: ${colors.LABEL};
+ padding: 5px 0px;
+`;
+
+const Textarea = styled.textarea`
+ resize: vertical;
+ width: 100%;
+`;
+
+const Input = styled.input``;
+
+const SignVerify = () => (
+
+
+ Sign message
+ Message
+
+ Address
+
+ Signature
+
+
+
+ Verify message
+ Message
+
+ Address
+
+ Signature
+
+
+
+);
+
+export default SignVerify;
\ No newline at end of file
diff --git a/src/js/views/Device/views/Account/components/Summary/Container.js b/src/js/views/Device/views/Account/components/Summary/Container.js
new file mode 100644
index 00000000..d0e83030
--- /dev/null
+++ b/src/js/views/Device/views/Account/components/Summary/Container.js
@@ -0,0 +1,52 @@
+/* @flow */
+
+
+import React, { Component, PropTypes } from 'react';
+import { bindActionCreators } from 'redux';
+import { connect } from 'react-redux';
+
+import type { MapStateToProps, MapDispatchToProps } from 'react-redux';
+import * as SummaryActions from 'actions/SummaryActions';
+import * as TokenActions from 'actions/TokenActions';
+
+import type { State, Dispatch } from 'flowtype';
+import Summary from './index';
+import type { StateProps as BaseStateProps, DispatchProps as BaseDispatchProps } from '../SelectedAccount';
+
+type OwnProps = { }
+
+type StateProps = BaseStateProps & {
+ tokens: $ElementType,
+ summary: $ElementType,
+ fiat: $ElementType,
+ localStorage: $ElementType,
+};
+
+type DispatchProps = BaseDispatchProps & {
+ onDetailsToggle: typeof SummaryActions.onDetailsToggle,
+ addToken: typeof TokenActions.add,
+ loadTokens: typeof TokenActions.load,
+ removeToken: typeof TokenActions.remove,
+}
+
+export type Props = StateProps & BaseStateProps & DispatchProps & BaseDispatchProps;
+
+const mapStateToProps: MapStateToProps = (state: State, own: OwnProps): StateProps => ({
+ className: 'summary',
+ selectedAccount: state.selectedAccount,
+ wallet: state.wallet,
+
+ tokens: state.tokens,
+ summary: state.summary,
+ fiat: state.fiat,
+ localStorage: state.localStorage,
+});
+
+const mapDispatchToProps: MapDispatchToProps = (dispatch: Dispatch): DispatchProps => ({
+ onDetailsToggle: bindActionCreators(SummaryActions.onDetailsToggle, dispatch),
+ addToken: bindActionCreators(TokenActions.add, dispatch),
+ loadTokens: bindActionCreators(TokenActions.load, dispatch),
+ removeToken: bindActionCreators(TokenActions.remove, dispatch),
+});
+
+export default connect(mapStateToProps, mapDispatchToProps)(Summary);
\ No newline at end of file
diff --git a/src/js/views/Device/views/Account/components/Summary/components/Details/index.js b/src/js/views/Device/views/Account/components/Summary/components/Details/index.js
new file mode 100644
index 00000000..77a7d9db
--- /dev/null
+++ b/src/js/views/Device/views/Account/components/Summary/components/Details/index.js
@@ -0,0 +1,75 @@
+/* @flow */
+
+
+import React from 'react';
+import BigNumber from 'bignumber.js';
+
+import type { Coin } from 'reducers/LocalStorageReducer';
+import type { Props as BaseProps } from './index';
+
+type Props = {
+ // coin: $PropertyType<$ElementType, 'coin'>,
+ coin: Coin,
+ summary: $ElementType,
+ balance: string,
+ network: string,
+ fiat: $ElementType,
+ onToggle: $ElementType
+}
+
+const SummaryDetails = (props: Props): ?React$Element => {
+ if (!props.summary.details) {
+ return (
+
+ );
+ }
+
+ const selectedCoin = props.coin;
+ const fiatRate = props.fiat.find(f => f.network === selectedCoin.network);
+
+ let balanceColumn = null;
+ let rateColumn = null;
+
+ if (fiatRate) {
+ const accountBalance = new BigNumber(props.balance);
+ const fiatValue = new BigNumber(fiatRate.value);
+ const fiat = accountBalance.times(fiatValue).toFixed(2);
+
+ balanceColumn = (
+
+
Balance
+
${ fiat }
+
{ props.balance } { selectedCoin.symbol }
+
+ );
+
+ rateColumn = (
+
+
Rate
+
${ fiatValue.toFixed(2) }
+
1.00 { selectedCoin.symbol }
+
+ );
+ } else {
+ balanceColumn = (
+
+
Balance
+
{ props.balance } { selectedCoin.symbol }
+
+ );
+ }
+
+ return (
+
+
+
+ { balanceColumn }
+ { rateColumn }
+
+
+ );
+};
+
+export default SummaryDetails;
\ No newline at end of file
diff --git a/src/js/views/Device/views/Account/components/Summary/components/Tokens/index.js b/src/js/views/Device/views/Account/components/Summary/components/Tokens/index.js
new file mode 100644
index 00000000..c6dc05c6
--- /dev/null
+++ b/src/js/views/Device/views/Account/components/Summary/components/Tokens/index.js
@@ -0,0 +1,54 @@
+/* @flow */
+
+
+import React from 'react';
+import ColorHash from 'color-hash';
+import ScaleText from 'react-scale-text';
+import * as stateUtils from 'reducers/utils';
+import BigNumber from 'bignumber.js';
+
+import type { Props as BaseProps } from './index';
+
+type Props = {
+ pending: $PropertyType<$ElementType, 'pending'>,
+ tokens: $ElementType,
+ removeToken: $ElementType
+}
+
+const SummaryTokens = (props: Props) => {
+ if (!props.tokens || props.tokens.length < 1) return null;
+
+ const bgColor = new ColorHash({ lightness: 0.7 });
+ const textColor = new ColorHash();
+
+ const tokens = props.tokens.map((token, index) => {
+ const iconColor = {
+ color: textColor.hex(token.name),
+ background: bgColor.hex(token.name),
+ borderColor: bgColor.hex(token.name),
+ };
+
+ const pendingAmount: BigNumber = stateUtils.getPendingAmount(props.pending, token.symbol, true);
+ const balance: string = new BigNumber(token.balance).minus(pendingAmount).toString(10);
+ return (
+
+
+
{ token.name }
+
{ balance } { token.symbol }
+
props.removeToken(token)} />
+
+ );
+ });
+
+ return (
+
+ { tokens }
+
+ );
+};
+
+export default SummaryTokens;
\ No newline at end of file
diff --git a/src/js/views/Device/views/Account/components/Summary/index.js b/src/js/views/Device/views/Account/components/Summary/index.js
new file mode 100644
index 00000000..4ce20314
--- /dev/null
+++ b/src/js/views/Device/views/Account/components/Summary/index.js
@@ -0,0 +1,120 @@
+/* @flow */
+import styled from 'styled-components';
+import React, { Component } from 'react';
+import { H2 } from 'components/common/Heading';
+import BigNumber from 'bignumber.js';
+import { Async as AsyncSelect } from 'react-select';
+import Tooltip from 'rc-tooltip';
+
+import { resolveAfter } from 'utils/promiseUtils';
+import { Notification } from 'components/common/Notification';
+import * as stateUtils from 'reducers/utils';
+import type { NetworkToken } from 'reducers/LocalStorageReducer';
+import SelectedAccount from '../SelectedAccount';
+import SummaryDetails from './components/Details';
+import SummaryTokens from './components/Tokens';
+
+import type { Props } from './index';
+
+const StyledH2 = styled(H2)`
+ padding: 20px 48px;
+`;
+
+const Summary = (props: Props) => {
+ const device = props.wallet.selectedDevice;
+ const {
+ account,
+ network,
+ tokens,
+ pending,
+ } = props.selectedAccount;
+
+ // flow
+ if (!device || !account || !network) return null;
+
+ const tokensTooltip = (
+
+ Insert token name, symbol or address to be able to send it.
+
+ );
+ const explorerLink: string = `${network.explorer.address}${account.address}`;
+
+ const pendingAmount: BigNumber = stateUtils.getPendingAmount(pending, network.symbol);
+ const balance: string = new BigNumber(account.balance).minus(pendingAmount).toString(10);
+
+ return (
+
+
+ Account #{ parseInt(account.index) + 1 }
+ See full transaction history
+
+
+
+
+
+ Tokens
+ }
+ overlay={tokensTooltip}
+ placement="top"
+ >
+
+
+
+ {/* 0x58cda554935e4a1f2acbe15f8757400af275e084 Lahod */}
+ {/* 0x58cda554935e4a1f2acbe15f8757400af275e084 T01 */}
+
+
props.addToken(token, account)}
+ loadOptions={input => props.loadTokens(input, account.network)}
+ filterOptions={
+ (options: Array, search: string, values: Array) => options.map((o) => {
+ const added = tokens.find(t => t.symbol === o.symbol);
+ if (added) {
+ return {
+ ...o,
+ name: `${o.name} (Already added)`,
+ disabled: true,
+ };
+ }
+ return o;
+ })
+ }
+ valueKey="symbol"
+ labelKey="name"
+ placeholder="Search for token"
+ searchPromptText="Type token name or address"
+ noResultsText="Token not found"
+ />
+
+
+
+
+
+
+ );
+};
+
+export default (props: Props) => (
+
+
+
+);
\ No newline at end of file
diff --git a/src/js/views/Device/views/Account/components/Tabs/index.js b/src/js/views/Device/views/Account/components/Tabs/index.js
new file mode 100644
index 00000000..f8b85375
--- /dev/null
+++ b/src/js/views/Device/views/Account/components/Tabs/index.js
@@ -0,0 +1,105 @@
+/* @flow */
+
+
+import React, { Component } from 'react';
+import { NavLink } from 'react-router-dom';
+
+
+type Props = {
+ pathname: string;
+}
+type State = {
+ style: {
+ width: number,
+ left: number
+ };
+}
+
+class Indicator extends Component {
+ reposition: () => void;
+
+ state: State;
+
+ constructor(props: Props) {
+ super(props);
+
+ this.state = {
+ style: {
+ width: 0,
+ left: 0,
+ },
+ };
+
+ this.reposition = this.reposition.bind(this);
+ }
+
+ handleResize() {
+ this.reposition();
+ }
+
+ componentDidMount() {
+ this.reposition();
+ window.addEventListener('resize', this.reposition, false);
+ }
+
+ componentWillUnmount() {
+ window.removeEventListener('resize', this.reposition, false);
+ }
+
+ componentDidUpdate(newProps: Props) {
+ this.reposition();
+ }
+
+ reposition() {
+ const tabs = document.querySelector('.account-tabs');
+ if (!tabs) return;
+ const active = tabs.querySelector('.active');
+ if (!active) return;
+ const bounds = active.getBoundingClientRect();
+
+ const left = bounds.left - tabs.getBoundingClientRect().left;
+
+ if (this.state.style.left !== left) {
+ this.setState({
+ style: {
+ width: bounds.width,
+ left,
+ },
+ });
+ }
+ }
+
+ render() {
+ return (
+ { this.props.pathname }
+ );
+ }
+}
+
+const AccountTabs = (props: any) => {
+ const urlParams = props.match.params;
+ const basePath = `/device/${urlParams.device}/network/${urlParams.network}/account/${urlParams.account}`;
+
+ return (
+
+ {/*
+ History
+ */}
+
+ Summary
+
+
+ Send
+
+
+ Receive
+
+ {/*
+ Sign & Verify
+ */}
+
+
+ );
+};
+
+export default AccountTabs;
\ No newline at end of file
diff --git a/src/js/views/Landing/Container.js b/src/js/views/Landing/Container.js
index e1cc0226..90b22630 100644
--- a/src/js/views/Landing/Container.js
+++ b/src/js/views/Landing/Container.js
@@ -36,7 +36,6 @@ const mapStateToProps: MapStateToProps = (state: St
wallet: state.wallet,
connect: state.connect,
router: state.router,
- wallet: state.wallet,
devices: state.devices,
});
diff --git a/src/js/views/Landing/components/InstallBridge.js b/src/js/views/Landing/components/InstallBridge.js
index 57171754..0799d407 100644
--- a/src/js/views/Landing/components/InstallBridge.js
+++ b/src/js/views/Landing/components/InstallBridge.js
@@ -37,12 +37,6 @@ export default class InstallBridge extends Component {
};
}
- onChange(value: InstallTarget) {
- this.setState({
- target: value,
- });
- }
-
componentWillUpdate() {
if (this.props.browserState.osname && !this.state.target) {
const currentTarget: ?InstallTarget = installers.find(i => i.id === this.props.browserState.osname);
@@ -52,6 +46,12 @@ export default class InstallBridge extends Component {
}
}
+ onChange(value: InstallTarget) {
+ this.setState({
+ target: value,
+ });
+ }
+
render() {
if (!this.state.target) {
return ;