mirror of
https://github.com/trezor/trezor-wallet
synced 2024-11-24 09:18:09 +00:00
Merge branch 'styled-components-refactor' of https://github.com/satoshilabs/trezor-wallet into styled-components-refactor
This commit is contained in:
commit
dfb4473bcc
94
src/components/Checkbox/index.js
Normal file
94
src/components/Checkbox/index.js
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
import React, { PureComponent } from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import colors from 'config/colors';
|
||||||
|
import Icon from 'components/Icon';
|
||||||
|
import icons from 'config/icons';
|
||||||
|
import { FONT_SIZE } from 'config/variables';
|
||||||
|
|
||||||
|
const Wrapper = styled.div`
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
cursor: pointer;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Tick = styled.div`
|
||||||
|
`;
|
||||||
|
|
||||||
|
const IconWrapper = styled.div`
|
||||||
|
display: flex;
|
||||||
|
border-radius: 2px;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
color: ${props => (props.checked ? colors.WHITE : colors.GREEN_PRIMARY)};
|
||||||
|
background: ${props => (props.checked ? colors.GREEN_PRIMARY : colors.WHITE)};
|
||||||
|
border: 1px solid ${props => (props.checked ? colors.GREEN_PRIMARY : colors.DIVIDER)};
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus {
|
||||||
|
border: 1px solid ${colors.TEXT_PRIMARY};
|
||||||
|
background: ${props => (props.checked ? colors.TEXT_PRIMARY : colors.WHITE)};
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Label = styled.div`
|
||||||
|
display: flex;
|
||||||
|
padding-left: 10px;
|
||||||
|
justify-content: center;
|
||||||
|
${colors.TEXT_SECONDARY};
|
||||||
|
font-size: ${FONT_SIZE.SMALL};
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus {
|
||||||
|
color: ${props => (props.checked ? colors.TEXT_PRIMARY : colors.TEXT_PRIMARY)};
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
class Checkbox extends PureComponent {
|
||||||
|
handleKeyboard(e) {
|
||||||
|
if (e.keyCode === 32) {
|
||||||
|
this.props.onClick(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
checked,
|
||||||
|
children,
|
||||||
|
onClick,
|
||||||
|
} = this.props;
|
||||||
|
return (
|
||||||
|
<Wrapper
|
||||||
|
onClick={onClick}
|
||||||
|
onKeyUp={e => this.handleKeyboard(e)}
|
||||||
|
tabIndex={0}
|
||||||
|
>
|
||||||
|
<IconWrapper checked={checked}>
|
||||||
|
{checked && (
|
||||||
|
<Tick>
|
||||||
|
<Icon size={26} color={checked ? colors.WHITE : colors.GREEN_PRIMARY} icon={icons.SUCCESS} />
|
||||||
|
</Tick>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</IconWrapper>
|
||||||
|
<Label checked={checked}>{children}</Label>
|
||||||
|
</Wrapper>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Checkbox.propTypes = {
|
||||||
|
onClick: PropTypes.func.isRequired,
|
||||||
|
checked: PropTypes.bool,
|
||||||
|
children: PropTypes.string,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Checkbox;
|
@ -18,7 +18,7 @@ const Wrapper = styled.div`
|
|||||||
display: flex;
|
display: flex;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const LinkWrapper = styled(Link)`
|
const StyledLink = styled(Link)`
|
||||||
margin: 0 6px;
|
margin: 0 6px;
|
||||||
margin-right: 20px;
|
margin-right: 20px;
|
||||||
`;
|
`;
|
||||||
@ -30,9 +30,9 @@ const Copy = styled.div`
|
|||||||
const Footer = ({ toggle }) => (
|
const Footer = ({ toggle }) => (
|
||||||
<Wrapper>
|
<Wrapper>
|
||||||
<Copy>© {getYear(new Date())}</Copy>
|
<Copy>© {getYear(new Date())}</Copy>
|
||||||
<LinkWrapper href="http://satoshilabs.com" target="_blank" rel="noreferrer noopener" className="satoshi" isGreen>SatoshiLabs</LinkWrapper>
|
<StyledLink href="http://satoshilabs.com" target="_blank" rel="noreferrer noopener" isGreen>SatoshiLabs</StyledLink>
|
||||||
<LinkWrapper href="tos.pdf" target="_blank" rel="noreferrer noopener" isGreen>Terms</LinkWrapper>
|
<StyledLink href="tos.pdf" target="_blank" rel="noreferrer noopener" isGreen>Terms</StyledLink>
|
||||||
<LinkWrapper onClick={toggle} isGreen>Show Log</LinkWrapper>
|
<StyledLink onClick={toggle} isGreen>Show Log</StyledLink>
|
||||||
</Wrapper>
|
</Wrapper>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ import colors from 'config/colors';
|
|||||||
const baseStyles = css`
|
const baseStyles = css`
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
text-rendering: optimizeLegibility;
|
text-rendering: optimizeLegibility;
|
||||||
color: ${colors.BLACK};
|
color: ${colors.TEXT_PRIMARY};
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ import React from 'react';
|
|||||||
import styled, { css } from 'styled-components';
|
import styled, { css } from 'styled-components';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import Paragraph from 'components/Paragraph';
|
import Paragraph from 'components/Paragraph';
|
||||||
|
import { FONT_SIZE } from 'config/variables';
|
||||||
import { DASH, GREEN_COLOR } from 'config/animations';
|
import { DASH, GREEN_COLOR } from 'config/animations';
|
||||||
import colors from 'config/colors';
|
import colors from 'config/colors';
|
||||||
|
|
||||||
@ -36,14 +37,15 @@ const CircleWrapper = styled.circle`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
const StyledParagraph = styled(Paragraph)`
|
const StyledParagraph = styled(Paragraph)`
|
||||||
|
font-size: ${props => (props.isSmallText ? FONT_SIZE.SMALLER : FONT_SIZE.BASE)};
|
||||||
color: ${props => (props.isWhiteText ? colors.WHITE : colors.TEXT_PRIMARY)};
|
color: ${props => (props.isWhiteText ? colors.WHITE : colors.TEXT_PRIMARY)};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const Loader = ({
|
const Loader = ({
|
||||||
className, text, isWhiteText = false, size = 100,
|
className, text, isWhiteText = false, isSmallText, size = 100,
|
||||||
}) => (
|
}) => (
|
||||||
<Wrapper className={className} size={size}>
|
<Wrapper className={className} size={size}>
|
||||||
<StyledParagraph isWhiteText={isWhiteText}>{text}</StyledParagraph>
|
<StyledParagraph isSmallText={isSmallText} isWhiteText={isWhiteText}>{text}</StyledParagraph>
|
||||||
<SvgWrapper viewBox="25 25 50 50">
|
<SvgWrapper viewBox="25 25 50 50">
|
||||||
<CircleWrapper
|
<CircleWrapper
|
||||||
cx="50"
|
cx="50"
|
||||||
@ -70,6 +72,7 @@ const Loader = ({
|
|||||||
|
|
||||||
Loader.propTypes = {
|
Loader.propTypes = {
|
||||||
isWhiteText: PropTypes.bool,
|
isWhiteText: PropTypes.bool,
|
||||||
|
isSmallText: PropTypes.bool,
|
||||||
className: PropTypes.string,
|
className: PropTypes.string,
|
||||||
text: PropTypes.string,
|
text: PropTypes.string,
|
||||||
size: PropTypes.number,
|
size: PropTypes.number,
|
||||||
|
@ -8,6 +8,7 @@ const Wrapper = styled.p`
|
|||||||
font-size: ${FONT_SIZE.BASE};
|
font-size: ${FONT_SIZE.BASE};
|
||||||
line-height: ${LINE_HEIGHT.BASE};
|
line-height: ${LINE_HEIGHT.BASE};
|
||||||
color: ${colors.TEXT_SECONDARY};
|
color: ${colors.TEXT_SECONDARY};
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
${props => props.isSmaller && css`
|
${props => props.isSmaller && css`
|
||||||
font-size: ${FONT_SIZE.SMALLER};
|
font-size: ${FONT_SIZE.SMALLER};
|
||||||
|
52
src/components/buttons/PinButton/index.js
Normal file
52
src/components/buttons/PinButton/index.js
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import colors from 'config/colors';
|
||||||
|
|
||||||
|
const Wrapper = styled.button`
|
||||||
|
width: 80px;
|
||||||
|
height: 80px;
|
||||||
|
margin-top: 15px;
|
||||||
|
margin-left: 10px;
|
||||||
|
font-size: 22px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: ${colors.TEXT_PRIMARY};
|
||||||
|
border: 1px solid ${colors.DIVIDER};
|
||||||
|
background: ${colors.WHITE};
|
||||||
|
transition: all 0.3s;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
margin-left: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: ${colors.TEXT_PRIMARY};
|
||||||
|
background-color: ${colors.WHITE};
|
||||||
|
border-color: ${colors.TEXT_SECONDARY};
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
color: ${colors.TEXT_PRIMARY};
|
||||||
|
background: ${colors.DIVIDER};
|
||||||
|
border-color: ${colors.DIVIDER};
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const PinButton = ({
|
||||||
|
children, className, onClick,
|
||||||
|
}) => (
|
||||||
|
<Wrapper
|
||||||
|
className={className}
|
||||||
|
onClick={onClick}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</Wrapper>
|
||||||
|
);
|
||||||
|
|
||||||
|
PinButton.propTypes = {
|
||||||
|
className: PropTypes.string,
|
||||||
|
children: PropTypes.string.isRequired,
|
||||||
|
onClick: PropTypes.func,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PinButton;
|
@ -107,7 +107,7 @@ class Input extends Component {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<StyledInput
|
<StyledInput
|
||||||
hasAddon={!!this.props.sideAddon}
|
hasAddon={!!this.props.sideAddons}
|
||||||
type={this.props.type}
|
type={this.props.type}
|
||||||
placeholder={this.props.placeholder}
|
placeholder={this.props.placeholder}
|
||||||
autoComplete={this.props.autoComplete}
|
autoComplete={this.props.autoComplete}
|
||||||
@ -119,7 +119,7 @@ class Input extends Component {
|
|||||||
borderColor={this.getColor(this.props.state)}
|
borderColor={this.getColor(this.props.state)}
|
||||||
/>
|
/>
|
||||||
</InputIconWrapper>
|
</InputIconWrapper>
|
||||||
{this.props.sideAddon}
|
{this.props.sideAddons && this.props.sideAddons.map(sideAddon => sideAddon)}
|
||||||
</InputWrapper>
|
</InputWrapper>
|
||||||
{this.props.bottomText && (
|
{this.props.bottomText && (
|
||||||
<BottomText
|
<BottomText
|
||||||
@ -146,7 +146,7 @@ Input.propTypes = {
|
|||||||
state: PropTypes.string,
|
state: PropTypes.string,
|
||||||
bottomText: PropTypes.string,
|
bottomText: PropTypes.string,
|
||||||
inputLabel: PropTypes.string,
|
inputLabel: PropTypes.string,
|
||||||
sideAddon: PropTypes.node,
|
sideAddons: PropTypes.arrayOf(PropTypes.node),
|
||||||
};
|
};
|
||||||
|
|
||||||
Input.defaultProps = {
|
Input.defaultProps = {
|
54
src/components/inputs/PinInput/index.js
Normal file
54
src/components/inputs/PinInput/index.js
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import styled, { css } from 'styled-components';
|
||||||
|
import colors from 'config/colors';
|
||||||
|
import Icon from 'components/Icon';
|
||||||
|
import { FONT_SIZE, FONT_WEIGHT } from 'config/variables';
|
||||||
|
import icons from 'config/icons';
|
||||||
|
|
||||||
|
const Wrapper = styled.div`
|
||||||
|
position: relative;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const StyledInput = styled.input`
|
||||||
|
letter-spacing: 7px;
|
||||||
|
width: 100%;
|
||||||
|
font-weight: ${FONT_WEIGHT.BIGGER};
|
||||||
|
font-size: ${FONT_SIZE.BIGGER};
|
||||||
|
padding: 5px 31px 10px 20px;
|
||||||
|
color: ${colors.TEXT_PRIMARY};
|
||||||
|
background: transparent;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const StyledIcon = styled(Icon)`
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
right: 15px;
|
||||||
|
cursor: pointer;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Input = ({
|
||||||
|
onChange,
|
||||||
|
onDeleteClick,
|
||||||
|
value,
|
||||||
|
}) => (
|
||||||
|
<Wrapper>
|
||||||
|
<StyledInput
|
||||||
|
disabled
|
||||||
|
type="password"
|
||||||
|
maxLength="9"
|
||||||
|
autoComplete="off"
|
||||||
|
value={value}
|
||||||
|
onChange={onChange}
|
||||||
|
/>
|
||||||
|
<StyledIcon onClick={() => onDeleteClick()} color={colors.TEXT_PRIMARY} icon={icons.BACK} />
|
||||||
|
</Wrapper>
|
||||||
|
);
|
||||||
|
|
||||||
|
Input.propTypes = {
|
||||||
|
onDeleteClick: PropTypes.func.isRequired,
|
||||||
|
value: PropTypes.string.isRequired,
|
||||||
|
onChange: PropTypes.func,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Input;
|
@ -1,19 +0,0 @@
|
|||||||
/* @flow */
|
|
||||||
|
|
||||||
|
|
||||||
import React from 'react';
|
|
||||||
import type { Props } from './index';
|
|
||||||
|
|
||||||
const InvalidPin = (props: Props) => {
|
|
||||||
if (!props.modal.opened) return null;
|
|
||||||
|
|
||||||
const { device } = props.modal;
|
|
||||||
return (
|
|
||||||
<div className="pin">
|
|
||||||
<h3>Entered PIN for { device.label } is not correct</h3>
|
|
||||||
<p>Retrying...</p>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default InvalidPin;
|
|
@ -1,20 +0,0 @@
|
|||||||
/* @flow */
|
|
||||||
|
|
||||||
|
|
||||||
import React from 'react';
|
|
||||||
import type { Props } from './index';
|
|
||||||
|
|
||||||
const Confirmation = (props: Props) => {
|
|
||||||
if (!props.modal.opened) return null;
|
|
||||||
const { device } = props.modal;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="confirm-tx">
|
|
||||||
<div className="header">
|
|
||||||
<h3>Complete the action on { device.label } device</h3>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Confirmation;
|
|
@ -1,145 +0,0 @@
|
|||||||
/* @flow */
|
|
||||||
|
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
|
||||||
|
|
||||||
import type { Props } from './index';
|
|
||||||
|
|
||||||
type State = {
|
|
||||||
pin: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class Pin extends Component<Props, State> {
|
|
||||||
keyboardHandler: (event: KeyboardEvent) => void;
|
|
||||||
|
|
||||||
state: State;
|
|
||||||
|
|
||||||
constructor(props: Props) {
|
|
||||||
super(props);
|
|
||||||
|
|
||||||
this.state = {
|
|
||||||
pin: '',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
onPinAdd = (input: number): void => {
|
|
||||||
let pin: string = this.state.pin;
|
|
||||||
if (pin.length < 9) {
|
|
||||||
pin += input;
|
|
||||||
this.setState({
|
|
||||||
pin,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onPinBackspace = (): void => {
|
|
||||||
this.setState({
|
|
||||||
pin: this.state.pin.substring(0, this.state.pin.length - 1),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
keyboardHandler(event: KeyboardEvent): void {
|
|
||||||
const { onPinSubmit } = this.props.modalActions;
|
|
||||||
const { pin } = this.state;
|
|
||||||
|
|
||||||
event.preventDefault();
|
|
||||||
switch (event.keyCode) {
|
|
||||||
case 13:
|
|
||||||
// enter,
|
|
||||||
onPinSubmit(pin);
|
|
||||||
break;
|
|
||||||
// backspace
|
|
||||||
case 8:
|
|
||||||
this.onPinBackspace();
|
|
||||||
break;
|
|
||||||
|
|
||||||
// numeric and numpad
|
|
||||||
case 49:
|
|
||||||
case 97:
|
|
||||||
this.onPinAdd(1);
|
|
||||||
break;
|
|
||||||
case 50:
|
|
||||||
case 98:
|
|
||||||
this.onPinAdd(2);
|
|
||||||
break;
|
|
||||||
case 51:
|
|
||||||
case 99:
|
|
||||||
this.onPinAdd(3);
|
|
||||||
break;
|
|
||||||
case 52:
|
|
||||||
case 100:
|
|
||||||
this.onPinAdd(4);
|
|
||||||
break;
|
|
||||||
case 53:
|
|
||||||
case 101:
|
|
||||||
this.onPinAdd(5);
|
|
||||||
break;
|
|
||||||
case 54:
|
|
||||||
case 102:
|
|
||||||
this.onPinAdd(6);
|
|
||||||
break;
|
|
||||||
case 55:
|
|
||||||
case 103:
|
|
||||||
this.onPinAdd(7);
|
|
||||||
break;
|
|
||||||
case 56:
|
|
||||||
case 104:
|
|
||||||
this.onPinAdd(8);
|
|
||||||
break;
|
|
||||||
case 57:
|
|
||||||
case 105:
|
|
||||||
this.onPinAdd(9);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
componentWillMount(): void {
|
|
||||||
this.keyboardHandler = this.keyboardHandler.bind(this);
|
|
||||||
window.addEventListener('keydown', this.keyboardHandler, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillUnmount(): void {
|
|
||||||
window.removeEventListener('keydown', this.keyboardHandler, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
if (!this.props.modal.opened) return null;
|
|
||||||
|
|
||||||
const { onPinSubmit } = this.props.modalActions;
|
|
||||||
const { device } = this.props.modal;
|
|
||||||
const { pin } = this.state;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="pin">
|
|
||||||
{/* <button className="close-modal transparent"></button> */}
|
|
||||||
<h3>Enter { device.label } PIN</h3>
|
|
||||||
<p>The PIN layout is displayed on your TREZOR.</p>
|
|
||||||
|
|
||||||
<div className="pin-input-row">
|
|
||||||
<input type="password" autoComplete="off" maxLength="9" disabled value={pin} />
|
|
||||||
<button type="button" className="pin-backspace transparent" onClick={event => this.onPinBackspace()} />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="pin-row">
|
|
||||||
<button type="button" data-value="7" onClick={event => this.onPinAdd(7)}>•</button>
|
|
||||||
<button type="button" data-value="8" onClick={event => this.onPinAdd(8)}>•</button>
|
|
||||||
<button type="button" data-value="9" onClick={event => this.onPinAdd(9)}>•</button>
|
|
||||||
</div>
|
|
||||||
<div className="pin-row">
|
|
||||||
<button type="button" data-value="4" onClick={event => this.onPinAdd(4)}>•</button>
|
|
||||||
<button type="button" data-value="5" onClick={event => this.onPinAdd(5)}>•</button>
|
|
||||||
<button type="button" data-value="6" onClick={event => this.onPinAdd(6)}>•</button>
|
|
||||||
</div>
|
|
||||||
<div className="pin-row">
|
|
||||||
<button type="button" data-value="1" onClick={event => this.onPinAdd(1)}>•</button>
|
|
||||||
<button type="button" data-value="2" onClick={event => this.onPinAdd(2)}>•</button>
|
|
||||||
<button type="button" data-value="3" onClick={event => this.onPinAdd(3)}>•</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div><button className="submit" type="button" onClick={event => onPinSubmit(pin)}>Enter PIN</button></div>
|
|
||||||
<p>Not sure how PIN works? <a className="green" href="http://doc.satoshilabs.com/trezor-user/enteringyourpin.html" target="_blank" rel="noreferrer noopener">Learn more</a></p>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,14 +1,16 @@
|
|||||||
/* @flow */
|
import styled from 'styled-components';
|
||||||
import React, { Component } from 'react';
|
import H3 from 'components/Heading';
|
||||||
|
import colors from 'config/colors';
|
||||||
import { findAccount } from 'reducers/AccountsReducer';
|
import P from 'components/Paragraph';
|
||||||
|
import { FONT_SIZE } from 'config/variables';
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
const Wrapper = styled.div`
|
const Wrapper = styled.div`
|
||||||
width: 370px;
|
width: 390px;
|
||||||
padding: 24px 48px;
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const Header = styled.div`
|
const Header = styled.div`
|
||||||
|
padding: 24px 48px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const Content = styled.div`
|
const Content = styled.div`
|
||||||
@ -18,11 +20,11 @@ const Content = styled.div`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
const Label = styled.div`
|
const Label = styled.div`
|
||||||
font-size: 10px;
|
font-size: ${FONT_SIZE.SMALLER};
|
||||||
color: ${colors.TEXT_SECONDARY};
|
color: ${colors.TEXT_SECONDARY};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const ConfirmAddress = (props: Props) => {
|
const ConfirmAddress = (props) => {
|
||||||
const {
|
const {
|
||||||
account,
|
account,
|
||||||
network,
|
network,
|
||||||
@ -30,16 +32,16 @@ const ConfirmAddress = (props: Props) => {
|
|||||||
if (!account || !network) return null;
|
if (!account || !network) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="confirm-address">
|
<Wrapper>
|
||||||
<div className="header">
|
<Header>
|
||||||
<h3>Confirm address on TREZOR</h3>
|
<H3>Confirm address on TREZOR</H3>
|
||||||
<p>Please compare your address on device with address shown bellow.</p>
|
<P>Please compare your address on device with address shown bellow.</P>
|
||||||
</div>
|
</Header>
|
||||||
<div className="content">
|
<Content>
|
||||||
<p>{ account.address }</p>
|
<P>{ account.address }</P>
|
||||||
<label>{ network.symbol } account #{ (account.index + 1) }</label>
|
<Label>{ network.symbol } account #{ (account.index + 1) }</Label>
|
||||||
</div>
|
</Content>
|
||||||
</div>
|
</Wrapper>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ const ConfirmSignTx = (props) => {
|
|||||||
<Header>
|
<Header>
|
||||||
<Icon icon={icons.T1} size={60} color={colors.TEXT_SECONDARY} />
|
<Icon icon={icons.T1} size={60} color={colors.TEXT_SECONDARY} />
|
||||||
<H3>Confirm transaction on { device.label } device</H3>
|
<H3>Confirm transaction on { device.label } device</H3>
|
||||||
<P>Details are shown on display</P>
|
<P isSmaller>Details are shown on display</P>
|
||||||
</Header>
|
</Header>
|
||||||
<Content>
|
<Content>
|
||||||
<Label>Send</Label>
|
<Label>Send</Label>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* @flow */
|
/* @flow */
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { H3 } from 'components/Heading';
|
import { H2 } from 'components/Heading';
|
||||||
import P from 'components/Paragraph';
|
import P from 'components/Paragraph';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import Icon from 'components/Icon';
|
import Icon from 'components/Icon';
|
||||||
@ -102,8 +102,8 @@ class ConfirmUnverifiedAddress extends Component<Props> {
|
|||||||
<StyledLink onClick={onCancel}>
|
<StyledLink onClick={onCancel}>
|
||||||
<Icon size={20} color={colors.TEXT_SECONDARY} icon={icons.CLOSE} />
|
<Icon size={20} color={colors.TEXT_SECONDARY} icon={icons.CLOSE} />
|
||||||
</StyledLink>
|
</StyledLink>
|
||||||
<H3>{ deviceStatus }</H3>
|
<H2>{ deviceStatus }</H2>
|
||||||
<P>To prevent phishing attacks, you should verify the address on your TREZOR first. { claim } to continue with the verification process.</P>
|
<StyledP isSmaller>To prevent phishing attacks, you should verify the address on your TREZOR first. { claim } to continue with the verification process.</StyledP>
|
||||||
<Row>
|
<Row>
|
||||||
<StyledButton onClick={() => this.verifyAddress()}>Try again</StyledButton>
|
<StyledButton onClick={() => this.verifyAddress()}>Try again</StyledButton>
|
||||||
<StyledButton isWhite onClick={() => this.showUnverifiedAddress()}>Show unverified address</StyledButton>
|
<StyledButton isWhite onClick={() => this.showUnverifiedAddress()}>Show unverified address</StyledButton>
|
||||||
|
@ -4,7 +4,7 @@ import styled from 'styled-components';
|
|||||||
import { H3 } from 'components/Heading';
|
import { H3 } from 'components/Heading';
|
||||||
import P from 'components/Paragraph';
|
import P from 'components/Paragraph';
|
||||||
import Button from 'components/buttons/Button';
|
import Button from 'components/buttons/Button';
|
||||||
import Input from 'components/Input';
|
import Input from 'components/inputs/Input';
|
||||||
import { getDuplicateInstanceNumber } from 'reducers/utils';
|
import { getDuplicateInstanceNumber } from 'reducers/utils';
|
||||||
import { FONT_SIZE } from 'config/variables';
|
import { FONT_SIZE } from 'config/variables';
|
||||||
import Icon from 'components/Icon';
|
import Icon from 'components/Icon';
|
||||||
|
@ -130,6 +130,7 @@ export default class RememberDevice extends Component<Props, State> {
|
|||||||
<ButtonContent>
|
<ButtonContent>
|
||||||
<Text>Forget</Text>
|
<Text>Forget</Text>
|
||||||
<StyledLoader
|
<StyledLoader
|
||||||
|
isSmallText
|
||||||
isWhiteText
|
isWhiteText
|
||||||
size={28}
|
size={28}
|
||||||
text={this.state.countdown.toString()}
|
text={this.state.countdown.toString()}
|
||||||
|
@ -17,10 +17,11 @@ import * as CONNECT from 'actions/constants/TrezorConnect';
|
|||||||
import type { MapStateToProps, MapDispatchToProps } from 'react-redux';
|
import type { MapStateToProps, MapDispatchToProps } from 'react-redux';
|
||||||
import type { State, Dispatch } from 'flowtype';
|
import type { State, Dispatch } from 'flowtype';
|
||||||
|
|
||||||
import Pin from 'components/modals/Pin';
|
import Pin from 'components/modals/pin/Pin';
|
||||||
import InvalidPin from 'components/modals/InvalidPin';
|
import InvalidPin from 'components/modals/pin/Invalid';
|
||||||
import Passphrase from 'components/modals/Passphrase';
|
|
||||||
import PassphraseType from 'components/modals/PassphraseType';
|
import Passphrase from 'components/modals/passphrase/Passphrase';
|
||||||
|
import PassphraseType from 'components/modals/passphrase/Type';
|
||||||
|
|
||||||
import ConfirmSignTx from 'components/modals/confirm/SignTx';
|
import ConfirmSignTx from 'components/modals/confirm/SignTx';
|
||||||
import ConfirmUnverifiedAddress from 'components/modals/confirm/UnverifiedAddress';
|
import ConfirmUnverifiedAddress from 'components/modals/confirm/UnverifiedAddress';
|
||||||
@ -52,7 +53,6 @@ export type Props = StateProps & DispatchProps;
|
|||||||
|
|
||||||
const duration = 300;
|
const duration = 300;
|
||||||
|
|
||||||
|
|
||||||
const Fade = ({ children, ...props }) => (
|
const Fade = ({ children, ...props }) => (
|
||||||
<CSSTransition
|
<CSSTransition
|
||||||
{...props}
|
{...props}
|
||||||
@ -132,7 +132,7 @@ class Modal extends Component<Props> {
|
|||||||
if (opened) {
|
if (opened) {
|
||||||
ch = (
|
ch = (
|
||||||
<Fade key="1">
|
<Fade key="1">
|
||||||
<ModalContainer className="modal-container">
|
<ModalContainer>
|
||||||
<ModalWindow>
|
<ModalWindow>
|
||||||
{ component }
|
{ component }
|
||||||
</ModalWindow>
|
</ModalWindow>
|
||||||
|
@ -1,11 +1,47 @@
|
|||||||
/* @flow */
|
/* @flow */
|
||||||
|
|
||||||
|
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import raf from 'raf';
|
import raf from 'raf';
|
||||||
|
import colors from 'config/colors';
|
||||||
|
import P from 'components/Paragraph';
|
||||||
|
import { FONT_SIZE } from 'config/variables';
|
||||||
|
import { H2 } from 'components/Heading';
|
||||||
|
import Link from 'components/Link';
|
||||||
|
import Checkbox from 'components/Checkbox';
|
||||||
|
import Button from 'components/buttons/Button';
|
||||||
|
import Input from 'components/inputs/Input';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
import type { Props } from './index';
|
import type { Props } from './index';
|
||||||
|
|
||||||
|
const Wrapper = styled.div`
|
||||||
|
padding: 24px 48px;
|
||||||
|
max-width: 390px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Label = styled.div`
|
||||||
|
${colors.TEXT_SECONDARY};
|
||||||
|
font-size: ${FONT_SIZE.SMALL};
|
||||||
|
padding-bottom: 5px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const PassphraseError = styled.div``;
|
||||||
|
|
||||||
|
const Row = styled.div`
|
||||||
|
position: relative;
|
||||||
|
text-align: left;
|
||||||
|
padding-top: 24px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Footer = styled.div`
|
||||||
|
display: flex;
|
||||||
|
padding-top: 10px;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
`;
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
deviceLabel: string;
|
deviceLabel: string;
|
||||||
singleInput: boolean;
|
singleInput: boolean;
|
||||||
@ -233,18 +269,16 @@ export default class PinModal extends Component<Props, State> {
|
|||||||
//let passphraseInputType: string = visible || passphraseFocused ? "text" : "password";
|
//let passphraseInputType: string = visible || passphraseFocused ? "text" : "password";
|
||||||
//let passphraseRevisionInputType: string = visible || passphraseRevisionFocused ? "text" : "password";
|
//let passphraseRevisionInputType: string = visible || passphraseRevisionFocused ? "text" : "password";
|
||||||
|
|
||||||
|
|
||||||
const showPassphraseCheckboxFn: Function = visible ? this.onPassphraseHide : this.onPassphraseShow;
|
const showPassphraseCheckboxFn: Function = visible ? this.onPassphraseHide : this.onPassphraseShow;
|
||||||
|
console.log('passphraseInputType', passphraseInputType);
|
||||||
return (
|
return (
|
||||||
<div className="passphrase">
|
<Wrapper>
|
||||||
{/* <button className="close-modal transparent" onClick={ event => this.submit(true) }></button> */}
|
{/* ?<H2>Enter { deviceLabel } passphrase</H2> */}
|
||||||
<h3>Enter { deviceLabel } passphrase</h3>
|
{/* <P isSmaller>Note that passphrase is case-sensitive.</P> */}
|
||||||
<p>Note that passphrase is case-sensitive.</p>
|
<Row>
|
||||||
<div className="row">
|
<Label>Passphrase</Label>
|
||||||
<label>Passphrase</label>
|
<Input
|
||||||
<input
|
innerRef={(element) => { this.passphraseInput = element; }}
|
||||||
ref={(element) => { this.passphraseInput = element; }}
|
|
||||||
onChange={event => this.onPassphraseChange('passphrase', event.currentTarget.value)}
|
onChange={event => this.onPassphraseChange('passphrase', event.currentTarget.value)}
|
||||||
type={passphraseInputType}
|
type={passphraseInputType}
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
@ -252,17 +286,16 @@ export default class PinModal extends Component<Props, State> {
|
|||||||
autoCapitalize="off"
|
autoCapitalize="off"
|
||||||
spellCheck="false"
|
spellCheck="false"
|
||||||
data-lpignore="true"
|
data-lpignore="true"
|
||||||
onFocus={event => this.onPassphraseFocus('passphrase')}
|
onFocus={() => this.onPassphraseFocus('passphrase')}
|
||||||
onBlur={event => this.onPassphraseBlur('passphrase')}
|
onBlur={() => this.onPassphraseBlur('passphrase')}
|
||||||
|
|
||||||
tabIndex="1"
|
tabIndex="1"
|
||||||
/>
|
/>
|
||||||
</div>
|
</Row>
|
||||||
{ singleInput ? null : (
|
{!singleInput && (
|
||||||
<div className="row">
|
<Row>
|
||||||
<label>Re-enter passphrase</label>
|
<Label>Re-enter passphrase</Label>
|
||||||
<input
|
<Input
|
||||||
ref={(element) => { this.passphraseRevisionInput = element; }}
|
innerRef={(element) => { this.passphraseRevisionInput = element; }}
|
||||||
onChange={event => this.onPassphraseChange('revision', event.currentTarget.value)}
|
onChange={event => this.onPassphraseChange('revision', event.currentTarget.value)}
|
||||||
type={passphraseRevisionInputType}
|
type={passphraseRevisionInputType}
|
||||||
autoComplete="off"
|
autoComplete="off"
|
||||||
@ -270,39 +303,26 @@ export default class PinModal extends Component<Props, State> {
|
|||||||
autoCapitalize="off"
|
autoCapitalize="off"
|
||||||
spellCheck="false"
|
spellCheck="false"
|
||||||
data-lpignore="true"
|
data-lpignore="true"
|
||||||
onFocus={event => this.onPassphraseFocus('revision')}
|
onFocus={() => this.onPassphraseFocus('revision')}
|
||||||
onBlur={event => this.onPassphraseBlur('revision')}
|
onBlur={() => this.onPassphraseBlur('revision')}
|
||||||
|
|
||||||
tabIndex="2"
|
tabIndex="2"
|
||||||
/>
|
/>
|
||||||
{ !match && passphraseRevisionTouched ? <span className="error">Passphrases do not match</span> : null }
|
{!match && passphraseRevisionTouched && <PassphraseError className="error">Passphrases do not match</PassphraseError> }
|
||||||
</div>
|
</Row>
|
||||||
) }
|
) }
|
||||||
|
<Row>
|
||||||
|
<Checkbox onClick={showPassphraseCheckboxFn} checked={visible}>Show passphrase</Checkbox>
|
||||||
<div className="row">
|
</Row>
|
||||||
<label className="custom-checkbox">
|
<Row>
|
||||||
<input type="checkbox" tabIndex="3" onChange={showPassphraseCheckboxFn} checked={visible} />
|
<Button type="button" tabIndex="4" disabled={!match} onClick={event => this.submit()}>Enter</Button>
|
||||||
<span className="indicator" />
|
</Row>
|
||||||
Show passphrase
|
<Footer>
|
||||||
</label>
|
<P isSmaller>If you want to access your default account</P>
|
||||||
{/* <label className="custom-checkbox">
|
<P isSmaller>
|
||||||
<input type="checkbox" className="save_passphrase" tabIndex="4" onChange={ savePassphraseCheckboxFn } checked={ passphraseCached } />
|
<Link isGreen onClick={() => this.submit(true)}>Leave passphrase blank</Link>
|
||||||
<span className="indicator"></span>
|
</P>
|
||||||
<span>Save passphrase for current session (i)</span>
|
</Footer>
|
||||||
</label> */}
|
</Wrapper>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<button type="button" className="submit" tabIndex="4" disabled={!match} onClick={event => this.submit()}>Enter</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<p>If you want to access your default account</p>
|
|
||||||
<p><a className="green" onClick={event => this.submit(true)}>Leave passphrase blank</a></p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
29
src/components/modals/passphrase/Type/index.js
Normal file
29
src/components/modals/passphrase/Type/index.js
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import Icon from 'components/Icon';
|
||||||
|
import colors from 'config/colors';
|
||||||
|
import icons from 'config/icons';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import { H3 } from 'components/Heading';
|
||||||
|
|
||||||
|
const Wrapper = styled.div`
|
||||||
|
width: 360px;
|
||||||
|
padding: 24px 48px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Header = styled.div``;
|
||||||
|
|
||||||
|
const Confirmation = (props) => {
|
||||||
|
if (!props.modal.opened) return null;
|
||||||
|
const { device } = props.modal;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Wrapper>
|
||||||
|
<Header>
|
||||||
|
<Icon icon={icons.T1} size={60} color={colors.TEXT_SECONDARY} />
|
||||||
|
<H3>Complete the action on { device.label } device</H3>
|
||||||
|
</Header>
|
||||||
|
</Wrapper>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Confirmation;
|
24
src/components/modals/pin/Invalid/index.js
Normal file
24
src/components/modals/pin/Invalid/index.js
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import { H3 } from 'components/Heading';
|
||||||
|
import P from 'components/Paragraph';
|
||||||
|
|
||||||
|
import type { Props } from './index';
|
||||||
|
|
||||||
|
const Wrapper = styled.div`
|
||||||
|
padding: 24px 48px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const InvalidPin = (props: Props) => {
|
||||||
|
if (!props.modal.opened) return null;
|
||||||
|
|
||||||
|
const { device } = props.modal;
|
||||||
|
return (
|
||||||
|
<Wrapper>
|
||||||
|
<H3>Entered PIN for { device.label } is not correct</H3>
|
||||||
|
<P isSmaller>Retrying...</P>
|
||||||
|
</Wrapper>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default InvalidPin;
|
180
src/components/modals/pin/Pin/index.js
Normal file
180
src/components/modals/pin/Pin/index.js
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
/* @flow */
|
||||||
|
import P from 'components/Paragraph';
|
||||||
|
import { H2 } from 'components/Heading';
|
||||||
|
import React, { Component } from 'react';
|
||||||
|
import Link from 'components/Link';
|
||||||
|
import colors from 'config/colors';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import PinInput from 'components/inputs/PinInput';
|
||||||
|
import PinButton from 'components/buttons/PinButton';
|
||||||
|
import Button from 'components/buttons/Button';
|
||||||
|
import type { Props } from './index';
|
||||||
|
|
||||||
|
type State = {
|
||||||
|
pin: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Wrapper = styled.div`
|
||||||
|
padding: 24px 48px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const InputRow = styled.div`
|
||||||
|
margin-top: 24px;
|
||||||
|
max-width: 260px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const PinRow = styled.div``;
|
||||||
|
|
||||||
|
const StyledP = styled(P)`
|
||||||
|
padding-top: 5px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const StyledLink = styled(Link)`
|
||||||
|
padding-left: 5px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Footer = styled.div`
|
||||||
|
margin: 20px 0 10px 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
`;
|
||||||
|
|
||||||
|
class Pin extends Component<Props, State> {
|
||||||
|
keyboardHandler: (event: KeyboardEvent) => void;
|
||||||
|
|
||||||
|
state: State;
|
||||||
|
|
||||||
|
constructor(props: Props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
pin: '',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
onPinAdd = (input: number): void => {
|
||||||
|
let pin: string = this.state.pin;
|
||||||
|
if (pin.length < 9) {
|
||||||
|
pin += input;
|
||||||
|
this.setState({
|
||||||
|
pin,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onPinBackspace = (): void => {
|
||||||
|
this.setState({
|
||||||
|
pin: this.state.pin.substring(0, this.state.pin.length - 1),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
keyboardHandler(event: KeyboardEvent): void {
|
||||||
|
const { onPinSubmit } = this.props.modalActions;
|
||||||
|
const { pin } = this.state;
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
switch (event.keyCode) {
|
||||||
|
case 13:
|
||||||
|
// enter,
|
||||||
|
onPinSubmit(pin);
|
||||||
|
break;
|
||||||
|
// backspace
|
||||||
|
case 8:
|
||||||
|
this.onPinBackspace();
|
||||||
|
break;
|
||||||
|
|
||||||
|
// numeric and numpad
|
||||||
|
case 49:
|
||||||
|
case 97:
|
||||||
|
this.onPinAdd(1);
|
||||||
|
break;
|
||||||
|
case 50:
|
||||||
|
case 98:
|
||||||
|
this.onPinAdd(2);
|
||||||
|
break;
|
||||||
|
case 51:
|
||||||
|
case 99:
|
||||||
|
this.onPinAdd(3);
|
||||||
|
break;
|
||||||
|
case 52:
|
||||||
|
case 100:
|
||||||
|
this.onPinAdd(4);
|
||||||
|
break;
|
||||||
|
case 53:
|
||||||
|
case 101:
|
||||||
|
this.onPinAdd(5);
|
||||||
|
break;
|
||||||
|
case 54:
|
||||||
|
case 102:
|
||||||
|
this.onPinAdd(6);
|
||||||
|
break;
|
||||||
|
case 55:
|
||||||
|
case 103:
|
||||||
|
this.onPinAdd(7);
|
||||||
|
break;
|
||||||
|
case 56:
|
||||||
|
case 104:
|
||||||
|
this.onPinAdd(8);
|
||||||
|
break;
|
||||||
|
case 57:
|
||||||
|
case 105:
|
||||||
|
this.onPinAdd(9);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
componentWillMount(): void {
|
||||||
|
this.keyboardHandler = this.keyboardHandler.bind(this);
|
||||||
|
window.addEventListener('keydown', this.keyboardHandler, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount(): void {
|
||||||
|
window.removeEventListener('keydown', this.keyboardHandler, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
if (!this.props.modal.opened) return null;
|
||||||
|
const { onPinSubmit } = this.props.modalActions;
|
||||||
|
const { device } = this.props.modal;
|
||||||
|
const { pin } = this.state;
|
||||||
|
return (
|
||||||
|
<Wrapper>
|
||||||
|
<H2>Enter { device.label } PIN</H2>
|
||||||
|
<P isSmaller>The PIN layout is displayed on your TREZOR.</P>
|
||||||
|
<InputRow>
|
||||||
|
<PinInput value={pin} onDeleteClick={() => this.onPinBackspace()} />
|
||||||
|
</InputRow>
|
||||||
|
<PinRow>
|
||||||
|
<PinButton type="button" data-value="7" onClick={() => this.onPinAdd(7)}>• </PinButton>
|
||||||
|
<PinButton type="button" data-value="8" onClick={() => this.onPinAdd(8)}>•</PinButton>
|
||||||
|
<PinButton type="button" data-value="9" onClick={() => this.onPinAdd(9)}>•</PinButton>
|
||||||
|
</PinRow>
|
||||||
|
<PinRow>
|
||||||
|
<PinButton type="button" data-value="4" onClick={() => this.onPinAdd(4)}>• </PinButton>
|
||||||
|
<PinButton type="button" data-value="5" onClick={() => this.onPinAdd(5)}>•</PinButton>
|
||||||
|
<PinButton type="button" data-value="6" onClick={() => this.onPinAdd(6)}>•</PinButton>
|
||||||
|
</PinRow>
|
||||||
|
<PinRow>
|
||||||
|
<PinButton type="button" data-value="1" onClick={() => this.onPinAdd(1)}>• </PinButton>
|
||||||
|
<PinButton type="button" data-value="2" onClick={() => this.onPinAdd(2)}>•</PinButton>
|
||||||
|
<PinButton type="button" data-value="3" onClick={() => this.onPinAdd(3)}>•</PinButton>
|
||||||
|
</PinRow>
|
||||||
|
<Footer>
|
||||||
|
<Button type="button" onClick={() => onPinSubmit(pin)}>Enter PIN</Button>
|
||||||
|
<StyledP isSmaller>Not sure how PIN works?
|
||||||
|
<StyledLink
|
||||||
|
isGreen
|
||||||
|
href="http://doc.satoshilabs.com/trezor-user/enteringyourpin.html"
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer noopener"
|
||||||
|
>Learn more
|
||||||
|
</StyledLink>
|
||||||
|
</StyledP>
|
||||||
|
</Footer>
|
||||||
|
</Wrapper>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Pin;
|
@ -2,6 +2,9 @@ export default {
|
|||||||
CHECKED: [
|
CHECKED: [
|
||||||
'M692.8 313.92l-1.92-1.92c-6.246-7.057-15.326-11.484-25.44-11.484s-19.194 4.427-25.409 11.448l-0.031 0.036-196.48 224-3.84 1.6-3.84-1.92-48.64-57.28c-7.010-7.905-17.193-12.862-28.533-12.862-21.031 0-38.080 17.049-38.080 38.080 0 7.495 2.165 14.485 5.905 20.377l-0.092-0.155 100.8 148.16c5.391 8.036 14.386 13.292 24.618 13.44h8.662c17.251-0.146 32.385-9.075 41.163-22.529l0.117-0.191 195.2-296.32c4.473-6.632 7.141-14.803 7.141-23.597 0-11.162-4.297-21.32-11.326-28.911l0.025 0.028z',
|
'M692.8 313.92l-1.92-1.92c-6.246-7.057-15.326-11.484-25.44-11.484s-19.194 4.427-25.409 11.448l-0.031 0.036-196.48 224-3.84 1.6-3.84-1.92-48.64-57.28c-7.010-7.905-17.193-12.862-28.533-12.862-21.031 0-38.080 17.049-38.080 38.080 0 7.495 2.165 14.485 5.905 20.377l-0.092-0.155 100.8 148.16c5.391 8.036 14.386 13.292 24.618 13.44h8.662c17.251-0.146 32.385-9.075 41.163-22.529l0.117-0.191 195.2-296.32c4.473-6.632 7.141-14.803 7.141-23.597 0-11.162-4.297-21.32-11.326-28.911l0.025 0.028z',
|
||||||
],
|
],
|
||||||
|
BACK: [
|
||||||
|
'M656.224 402.304l-66.848 66.176-66.848-66.176-50.144 49.6 66.912 66.176-66.912 66.176 50.176 49.632 66.848-66.176 66.848 66.176 50.112-49.632-66.816-66.176 66.816-66.176-50.144-49.6zM337.824 256h540.928c27.2 0 49.248 21.824 49.248 48.768v414.464c0 26.944-22.048 48.768-49.248 48.768h-540.608c-13.856 0-27.072-5.792-36.416-15.936l-192.896-209.664c-17.248-18.752-17.088-47.488 0.352-66.048l192.576-204.8c9.344-9.92 22.4-15.552 36.064-15.552z',
|
||||||
|
],
|
||||||
HELP: [
|
HELP: [
|
||||||
'M693.024 330.944c-99.968-99.936-262.080-99.936-362.048 0s-99.968 262.112 0 362.080c99.968 100 262.144 99.936 362.048 0 99.968-99.904 99.968-262.176 0-362.080zM501.216 717.952c-27.808 0-50.496-22.464-50.496-50.048 0-28.32 22.176-50.528 50.496-50.528 27.616 0 50.048 22.656 50.048 50.528 0.032 27.168-22.88 50.048-50.048 50.048zM536.416 542.464v27.744c0 13.504-5.28 18.784-18.784 18.784h-36.224c-13.504 0-18.72-5.28-18.72-18.784v-61.984c0-15.68 16.064-20.352 30.208-24.48 3.456-1.056 7.040-2.080 10.496-3.264 18.336-6.592 29.696-14.816 29.696-35.296 0-6.656 0-26.816-32.832-26.816-20.224 0-38.624 7.776-49.6 12.416-6.208 2.624-9.28 3.904-12.384 3.904-6.336 0-12.32-5.088-13.248-10.304l-12.608-32.96c-1.824-3.776-1.824-6.784-1.824-9.216 0-24.288 75.552-37.664 100.608-37.664 63.104 0 105.504 40.672 105.504 101.152 0.032 65.44-49.12 85.952-80.288 96.768z',
|
'M693.024 330.944c-99.968-99.936-262.080-99.936-362.048 0s-99.968 262.112 0 362.080c99.968 100 262.144 99.936 362.048 0 99.968-99.904 99.968-262.176 0-362.080zM501.216 717.952c-27.808 0-50.496-22.464-50.496-50.048 0-28.32 22.176-50.528 50.496-50.528 27.616 0 50.048 22.656 50.048 50.528 0.032 27.168-22.88 50.048-50.048 50.048zM536.416 542.464v27.744c0 13.504-5.28 18.784-18.784 18.784h-36.224c-13.504 0-18.72-5.28-18.72-18.784v-61.984c0-15.68 16.064-20.352 30.208-24.48 3.456-1.056 7.040-2.080 10.496-3.264 18.336-6.592 29.696-14.816 29.696-35.296 0-6.656 0-26.816-32.832-26.816-20.224 0-38.624 7.776-49.6 12.416-6.208 2.624-9.28 3.904-12.384 3.904-6.336 0-12.32-5.088-13.248-10.304l-12.608-32.96c-1.824-3.776-1.824-6.784-1.824-9.216 0-24.288 75.552-37.664 100.608-37.664 63.104 0 105.504 40.672 105.504 101.152 0.032 65.44-49.12 85.952-80.288 96.768z',
|
||||||
],
|
],
|
||||||
|
@ -3,6 +3,7 @@ export const FONT_SIZE = {
|
|||||||
SMALLER: '12px',
|
SMALLER: '12px',
|
||||||
SMALL: '14px',
|
SMALL: '14px',
|
||||||
BASE: '16px',
|
BASE: '16px',
|
||||||
|
BIGGER: '32px',
|
||||||
BIGGEST: '36px',
|
BIGGEST: '36px',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
@import './colors.less';
|
@import './colors.less';
|
||||||
@import './mixins.less';
|
@import './mixins.less';
|
||||||
@import './content.less';
|
@import './content.less';
|
||||||
@import './modal.less';
|
|
||||||
|
|
||||||
@import './reactSelect.less';
|
@import './reactSelect.less';
|
||||||
@import './rcTooltip.less';
|
@import './rcTooltip.less';
|
||||||
|
@ -1,168 +0,0 @@
|
|||||||
.modal-container {
|
|
||||||
h3 {
|
|
||||||
color: @color_text_primary;
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: 500;
|
|
||||||
margin-top: 14px;
|
|
||||||
}
|
|
||||||
p {
|
|
||||||
margin: 5px 0px;
|
|
||||||
font-weight: normal;
|
|
||||||
color: @color_text_secondary;
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.confirm-address {
|
|
||||||
width: 390px; // address overflow
|
|
||||||
|
|
||||||
.header {
|
|
||||||
padding: 24px 48px;
|
|
||||||
&:before {
|
|
||||||
.icomoon-T1;
|
|
||||||
font-size: 52px;
|
|
||||||
color: @color_text_secondary;
|
|
||||||
}
|
|
||||||
h3 {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.content {
|
|
||||||
border-top: 1px solid @color_divider;
|
|
||||||
background: @color_main;
|
|
||||||
padding: 24px 48px;
|
|
||||||
|
|
||||||
label {
|
|
||||||
font-size: 12px;
|
|
||||||
color: @color_text_secondary;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: 400;
|
|
||||||
color: @color_text_primary;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.close-modal {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
right: 0;
|
|
||||||
padding: 12px;
|
|
||||||
|
|
||||||
&:after {
|
|
||||||
.icomoon-close;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.pin {
|
|
||||||
padding: 24px 48px;
|
|
||||||
.pin-row {
|
|
||||||
button {
|
|
||||||
width: 80px;
|
|
||||||
height: 80px;
|
|
||||||
margin-top: 15px;
|
|
||||||
margin-left: 10px;
|
|
||||||
font-size: 22px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: @color_text_primary;
|
|
||||||
border: 1px solid @color_divider;
|
|
||||||
background: @color_white;
|
|
||||||
transition: all 0.3s;
|
|
||||||
&:first-child {
|
|
||||||
margin-left: 0px;
|
|
||||||
}
|
|
||||||
&:hover {
|
|
||||||
color: @color_text_primary;
|
|
||||||
border-color: @color_text_secondary;
|
|
||||||
}
|
|
||||||
&:active {
|
|
||||||
color: @color_text_primary;
|
|
||||||
background: @color_divider;
|
|
||||||
border-color: @color_divider;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.pin-input-row {
|
|
||||||
margin-top: 24px;
|
|
||||||
display: inline-block;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
input {
|
|
||||||
letter-spacing: 6px;
|
|
||||||
line-height: 48px;
|
|
||||||
font-weight: 600;
|
|
||||||
font-size: 32px;
|
|
||||||
height: auto;
|
|
||||||
padding: 0px 31px;
|
|
||||||
color: @color_text_primary;
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pin-backspace {
|
|
||||||
position: absolute;
|
|
||||||
right: 14px;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
margin: auto 0;
|
|
||||||
padding: 0;
|
|
||||||
&:after {
|
|
||||||
.icomoon-back;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: @color_green_primary;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.passphrase {
|
|
||||||
padding: 24px 48px;
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
max-width: 260px;
|
|
||||||
word-break: break-all;
|
|
||||||
}
|
|
||||||
|
|
||||||
.row {
|
|
||||||
position: relative;
|
|
||||||
text-align: left;
|
|
||||||
padding-top: 24px;
|
|
||||||
label:not(.custom-checkbox) {
|
|
||||||
display: block;
|
|
||||||
padding-bottom: 6px;
|
|
||||||
color: @color_text_secondary;
|
|
||||||
}
|
|
||||||
|
|
||||||
.error {
|
|
||||||
position: absolute;
|
|
||||||
left: 0px;
|
|
||||||
bottom: -19px;
|
|
||||||
font-size: 12px;
|
|
||||||
color: @color_error_primary;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type="text"],
|
|
||||||
input[type="password"] {
|
|
||||||
width: 260px;
|
|
||||||
// box-shadow: none;
|
|
||||||
// border-radius: 0px;
|
|
||||||
// border: 1px solid @color_divider;
|
|
||||||
height: auto;
|
|
||||||
|
|
||||||
.placeholder({
|
|
||||||
color: @color_divider;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
.submit {
|
|
||||||
width: 100%;
|
|
||||||
margin-top: 24px;
|
|
||||||
margin-bottom: 14px;
|
|
||||||
}
|
|
||||||
}
|
|
@ -114,11 +114,7 @@ class DeviceMenu extends Component<Props> {
|
|||||||
/>
|
/>
|
||||||
<ButtonWrapper>
|
<ButtonWrapper>
|
||||||
{isWebUSB(transport) && (
|
{isWebUSB(transport) && (
|
||||||
<StyledButton
|
<StyledButton isWebUsb>Check for devices</StyledButton>
|
||||||
className="trezor-webusb-button"
|
|
||||||
isWebUsb
|
|
||||||
>Check for devices
|
|
||||||
</StyledButton>
|
|
||||||
)}
|
)}
|
||||||
</ButtonWrapper>
|
</ButtonWrapper>
|
||||||
</Wrapper>
|
</Wrapper>
|
||||||
|
Loading…
Reference in New Issue
Block a user