From 36ff98fb64e8bff869d4de3c49faabbf909b2eae Mon Sep 17 00:00:00 2001 From: George Lima Date: Sat, 12 Jan 2019 14:53:42 -0300 Subject: [PATCH 01/16] fix(theme): primary color --- app/theme.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/theme.js b/app/theme.js index 1bafe92..b707b5b 100644 --- a/app/theme.js +++ b/app/theme.js @@ -7,7 +7,7 @@ import { normalize } from 'polished'; // eslint-disable-line import { DARK } from './constants/themes'; -const darkOne = '#7B00DD'; +const darkOne = '#F5CB00'; const lightOne = '#ffffff'; const brandOne = '#000'; const brandTwo = '#3B3B3F'; From f3fc18b03223390931591e8c65783c0ba72d9ef1 Mon Sep 17 00:00:00 2001 From: George Lima Date: Sat, 12 Jan 2019 14:55:05 -0300 Subject: [PATCH 02/16] type(button): make to prop nullable --- app/components/button.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/components/button.js b/app/components/button.js index 3211d82..e37e4f9 100644 --- a/app/components/button.js +++ b/app/components/button.js @@ -17,7 +17,8 @@ const DefaultButton = styled.button` outline: none; min-width: 100px; border-radius: 100px; - transition: background-color 0.1s ${props => props.theme.colors.transitionEase}; + transition: background-color 0.1s + ${props => props.theme.colors.transitionEase}; width: 100%; `; @@ -60,7 +61,7 @@ const Secondary = styled(DefaultButton)` type Props = { label: string, onClick?: () => void, - to?: string, + to?: ?string, variant?: 'primary' | 'secondary', disabled?: boolean, className?: string, From 41e0143773bc414cdf72d6d9f242d7847f32d56d Mon Sep 17 00:00:00 2001 From: George Lima Date: Sat, 12 Jan 2019 14:55:53 -0300 Subject: [PATCH 03/16] type(input): remove useless $FlowFixMe --- app/components/input.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/app/components/input.js b/app/components/input.js index a9917f2..7b4fad0 100644 --- a/app/components/input.js +++ b/app/components/input.js @@ -4,18 +4,14 @@ import React from 'react'; import styled from 'styled-components'; const getDefaultStyles = t => styled[t]` - border-radius: ${// $FlowFixMe - props => props.theme.boxBorderRadius}; + border-radius: ${props => props.theme.boxBorderRadius}; border: none; - background-color: ${// $FlowFixMe - props => props.theme.colors.inputBackground}; - color: ${// $FlowFixMe - props => props.theme.colors.text}; + background-color: ${props => props.theme.colors.inputBackground}; + color: ${props => props.theme.colors.text}; padding: 15px; width: 100%; outline: none; - font-family: ${// $FlowFixMe - props => props.theme.fontFamily}; + font-family: ${props => props.theme.fontFamily}; ::placeholder { opacity: 0.5; @@ -28,7 +24,7 @@ const Textarea = getDefaultStyles('textarea'); type Props = { inputType?: 'input' | 'textarea', value: string, - onChange: string => void, + onChange?: string => void, onFocus?: (SyntheticFocusEvent) => void, rows?: number, disabled?: boolean, @@ -36,7 +32,11 @@ type Props = { step?: number, }; -export const InputComponent = ({ inputType, onChange, ...props }: Props) => { +export const InputComponent = ({ + inputType, + onChange = () => {}, + ...props +}: Props) => { const inputTypes = { input: () => ( onChange(evt.target.value)} {...props} /> From db011dcc228e99d5302f5c3a320ebbe399c7f634 Mon Sep 17 00:00:00 2001 From: George Lima Date: Sat, 12 Jan 2019 15:00:17 -0300 Subject: [PATCH 04/16] feature(confirm): add ConfirmDialog compopnent --- app/components/confirm-dialog.js | 86 +++++++++++++++++++++++++++++++ app/components/confirm-dialog.mdx | 31 +++++++++++ 2 files changed, 117 insertions(+) create mode 100644 app/components/confirm-dialog.js create mode 100644 app/components/confirm-dialog.mdx diff --git a/app/components/confirm-dialog.js b/app/components/confirm-dialog.js new file mode 100644 index 0000000..a9e1dc5 --- /dev/null +++ b/app/components/confirm-dialog.js @@ -0,0 +1,86 @@ +// @flow +import React, { type Element } from 'react'; +import styled from 'styled-components'; + +import { TextComponent } from './text'; +import { Button } from './button'; +import { Divider } from './divider'; + +import CloseIcon from '../assets/images/close_icon.svg'; + +const Wrapper = styled.div` + display: flex; + width: ${props => `${props.width}px`}; + background-color: ${props => props.theme.colors.background}; + flex-direction: column; + align-items: center; + border-radius: 6px; + box-shadow: 0px 0px 30px 0px black; + position: relative; +`; + +const CloseIconWrapper = styled.div` + display: flex; + width: 100%; + align-items: flex-end; + justify-content: flex-end; + position: absolute; +`; + +const TitleWrapper = styled.div` + margin-top: 20px; + margin-bottom: 20px; +`; + +const CloseIconImg = styled.img` + width: 16px; + height: 16px; + margin-top: 12px; + margin-right: 12px; + cursor: pointer; +`; + +const Btn = styled(Button)` + width: 95%; + margin-bottom: 10px; +`; + +type Props = { + handleClose: () => void, + title: string, + onConfirm: () => void, + showButtons?: boolean, + width?: number, + children: Element<*>, +}; + +export const ConfirmDialogComponent = ({ + children, + title, + onConfirm, + handleClose, + showButtons, + width, +}: Props) => ( + + + + + + + + + {React.Children.map(children, _ => _)} + {showButtons && ( + <> + + + + )} + +); + +ConfirmDialogComponent.defaultProps = { + showButtons: true, + width: 460, +}; diff --git a/app/components/confirm-dialog.mdx b/app/components/confirm-dialog.mdx new file mode 100644 index 0000000..4b4708a --- /dev/null +++ b/app/components/confirm-dialog.mdx @@ -0,0 +1,31 @@ +--- +name: Confirm Dialog +--- + +import { Playground, PropsTable } from 'docz' + +import { Button } from './button.js' +import { ConfirmDialogComponent } from './confirm-dialog.js' +import { DoczWrapper } from '../theme.js' + +# Confirm Dialog + +## Properties + + + +## Basic Usage + + + + {() => ( + alert('Confirm')} + handleClose={() => alert('Close')} + > +
Confirm content
+
+ )} +
+
From c69f2c7de0d25fa8f95aef01904e49229827a68b Mon Sep 17 00:00:00 2001 From: George Lima Date: Sat, 12 Jan 2019 15:01:16 -0300 Subject: [PATCH 05/16] feature(redux): add settings container --- app/containers/settings.js | 12 ++++++++++++ app/router/router.js | 4 ++-- 2 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 app/containers/settings.js diff --git a/app/containers/settings.js b/app/containers/settings.js new file mode 100644 index 0000000..ffbf9e6 --- /dev/null +++ b/app/containers/settings.js @@ -0,0 +1,12 @@ +// @flow +import { connect } from 'react-redux'; + +import { SettingsView } from '../views/settings'; + +import type { AppState } from '../types/app-state'; + +const mapStateToProps = ({ walletSummary }: AppState) => ({ + addresses: walletSummary.addresses, +}); + +export const SettingsContainer = connect(mapStateToProps)(SettingsView); diff --git a/app/router/router.js b/app/router/router.js index 2d9369e..ea67cd5 100644 --- a/app/router/router.js +++ b/app/router/router.js @@ -10,7 +10,7 @@ import { DashboardContainer } from '../containers/dashboard'; import { TransactionsContainer } from '../containers/transactions'; import { SendContainer } from '../containers/send'; import { ReceiveContainer } from '../containers/receive'; -import { SettingsView } from '../views/settings'; +import { SettingsContainer } from '../containers/settings'; import { NotFoundView } from '../views/not-found'; import { ConsoleView } from '../views/console'; import { LayoutComponent } from '../components/layout'; @@ -59,7 +59,7 @@ export const RouterComponent = ({ location }: { location: Location }) => ( /> - + Date: Sat, 12 Jan 2019 15:02:34 -0300 Subject: [PATCH 06/16] feature(settings): add export view keys button --- app/views/settings.js | 132 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 130 insertions(+), 2 deletions(-) diff --git a/app/views/settings.js b/app/views/settings.js index 670e277..0aa0df0 100644 --- a/app/views/settings.js +++ b/app/views/settings.js @@ -1,5 +1,133 @@ // @flow +import React, { PureComponent } from 'react'; +import styled from 'styled-components'; -import React from 'react'; +import { Button } from '../components/button'; +import { ModalComponent } from '../components/modal'; +import { ConfirmDialogComponent } from '../components/confirm-dialog'; +import { TextComponent } from '../components/text'; +import { InputComponent } from '../components/input'; -export const SettingsView = () =>
settings
; +import rpc from '../../services/api'; + +const Wrapper = styled.div` + margin-top: ${props => props.theme.layoutContentPaddingTop}; +`; + +const ModalContent = styled.div` + padding: 20px; + width: 100%; + overflow-x: hidden; +`; + +type ViewKey = { + zAddress: string, + key: string, +}; + +type Props = { + addresses: string[], +}; +type State = { + viewKeys: ViewKey[], + isLoading: boolean, + successExportViewKeys: boolean, + message: string | null, +}; + +export class SettingsView extends PureComponent { + state = { + viewKeys: [], + isLoading: false, + successExportViewKeys: false, + message: null, + }; + + exportViewKeys = () => { + const { addresses } = this.props; + + const zAddresses = addresses.filter(addr => addr.startsWith('z')); + + Promise.all( + zAddresses.map(async (zAddr) => { + const viewKey = await rpc.z_exportviewingkey(zAddr); + return { zAddress: zAddr, key: viewKey }; + }), + ).then((viewKeys) => { + this.setState({ + viewKeys, + successExportViewKeys: true, + }); + }); + }; + + handleCloseModal = (fn: () => void) => () => { + this.setState( + { + message: null, + }, + fn, + ); + }; + + render = () => { + const { + viewKeys, isLoading, successExportViewKeys, message, + } = this.state; + + return ( + + ( + } >
Confirm content
From 3cf4d058f74a605109cdc8403bf683ac869ade37 Mon Sep 17 00:00:00 2001 From: George Lima Date: Sat, 12 Jan 2019 16:29:50 -0300 Subject: [PATCH 08/16] feature(clipboard): add Clipboard button component --- app/components/clipboard.js | 50 +++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 app/components/clipboard.js diff --git a/app/components/clipboard.js b/app/components/clipboard.js new file mode 100644 index 0000000..bda14ca --- /dev/null +++ b/app/components/clipboard.js @@ -0,0 +1,50 @@ +// @flow +import React, { PureComponent } from 'react'; + +import { Button } from './button'; + +type Props = { + text: string, + className?: string, +}; + +type State = { copied: boolean }; + +export class Clipboard extends PureComponent { + static defaultProps = { + className: '', + }; + + state = { + copied: false, + }; + + handleClick = () => { + const { text } = this.props; + + const el = document.createElement('textarea'); + el.value = text; + + if (document.body) document.body.appendChild(el); + + el.select(); + document.execCommand('copy'); + if (document.body) document.body.removeChild(el); + + this.setState({ copied: true }); + }; + + render() { + const { className } = this.props; + const { copied } = this.state; + + return ( +