diff --git a/src/components/SettingsPage/DisablePasswordModal.js b/src/components/SettingsPage/DisablePasswordModal.js new file mode 100644 index 00000000..05753000 --- /dev/null +++ b/src/components/SettingsPage/DisablePasswordModal.js @@ -0,0 +1,121 @@ +// @flow + +import React, { PureComponent } from 'react' +import bcrypt from 'bcryptjs' + +import Box from 'components/base/Box' +import Button from 'components/base/Button' +import InputPassword from 'components/base/InputPassword' +import { ErrorMessageInput } from 'components/base/Input' +import { Modal, ModalContent, ModalBody, ModalTitle, ModalFooter } from 'components/base/Modal' + +import type { T } from 'types/common' + +type Props = { + t: T, + onClose: Function, + isPasswordEnabled: boolean, + currentPasswordHash: string, + onChangePassword: Function, +} + +type State = { + currentPassword: string, + incorrectPassword: boolean, +} + +const INITIAL_STATE = { + currentPassword: '', + incorrectPassword: false, +} + +class DisablePasswordModal extends PureComponent { + state = INITIAL_STATE + + disablePassword = (e: SyntheticEvent) => { + if (e) { + e.preventDefault() + } + + const { currentPassword } = this.state + const { isPasswordEnabled, currentPasswordHash, onChangePassword } = this.props + if (isPasswordEnabled) { + if (!bcrypt.compareSync(currentPassword, currentPasswordHash)) { + this.setState({ incorrectPassword: true }) + return + } + onChangePassword('') + } else { + onChangePassword('') + } + } + + handleInputChange = (key: string) => (value: string) => { + if (this.state.incorrectPassword) { + this.setState({ incorrectPassword: false }) + } + this.setState({ [key]: value }) + } + + handleReset = () => this.setState(INITIAL_STATE) + + render() { + const { t, isPasswordEnabled, onClose, ...props } = this.props + const { currentPassword, incorrectPassword } = this.state + return ( + ( +
+ + {t('settings:profile.disablePasswordModalTitle')} + + + {t('settings:profile.disablePasswordModalSubtitle')} + + + {t('settings:profile.disablePasswordModalDesc')} + + {isPasswordEnabled && ( + + + {incorrectPassword && ( + + {t('password:errorMessageIncorrectPassword')} + + )} + + )} + + + + + + + + +
+ )} + /> + ) + } +} + +export default DisablePasswordModal diff --git a/src/components/SettingsPage/PasswordModal.js b/src/components/SettingsPage/PasswordModal.js index 85119688..4ee151a0 100644 --- a/src/components/SettingsPage/PasswordModal.js +++ b/src/components/SettingsPage/PasswordModal.js @@ -11,6 +11,7 @@ import Button from 'components/base/Button' import InputPassword from 'components/base/InputPassword' import Label from 'components/base/Label' import { Modal, ModalContent, ModalBody, ModalTitle, ModalFooter } from 'components/base/Modal' +import { ErrorMessageInput } from 'components/base/Input' import type { T } from 'types/common' @@ -30,11 +31,13 @@ type Props = { type State = { currentPassword: string, newPassword: string, + incorrectPassword: boolean, } const INITIAL_STATE = { currentPassword: '', newPassword: '', + incorrectPassword: false, } class PasswordModal extends PureComponent { @@ -51,6 +54,7 @@ class PasswordModal extends PureComponent { const { isPasswordEnabled, currentPasswordHash, onChangePassword } = this.props if (isPasswordEnabled) { if (!bcrypt.compareSync(currentPassword, currentPasswordHash)) { + this.setState({ incorrectPassword: true }) return } onChangePassword(newPassword) @@ -59,7 +63,12 @@ class PasswordModal extends PureComponent { } } - handleInputChange = key => value => this.setState({ [key]: value }) + handleInputChange = (key: string) => (value: string) => { + if (this.state.incorrectPassword) { + this.setState({ incorrectPassword: false }) + } + this.setState({ [key]: value }) + } handleReset = () => this.setState(INITIAL_STATE) @@ -70,7 +79,7 @@ class PasswordModal extends PureComponent { render() { const { t, isPasswordEnabled, onClose, ...props } = this.props - const { currentPassword, newPassword } = this.state + const { currentPassword, newPassword, incorrectPassword } = this.state const isValid = this.isValid() return ( { onChange={this.handleInputChange('currentPassword')} value={currentPassword} /> + {incorrectPassword && ( + + {t('password:errorMessageIncorrectPassword')} + + )} )} @@ -122,7 +136,9 @@ class PasswordModal extends PureComponent { - + diff --git a/src/components/SettingsPage/sections/About.js b/src/components/SettingsPage/sections/About.js index e8fba224..54674256 100644 --- a/src/components/SettingsPage/sections/About.js +++ b/src/components/SettingsPage/sections/About.js @@ -6,7 +6,7 @@ import { shell } from 'electron' import type { T } from 'types/common' import IconHelp from 'icons/Help' -import IconChevronRight from 'icons/ChevronRight' +import IconExternalLink from 'icons/ExternalLink' import { SettingsSection as Section, @@ -33,25 +33,25 @@ class SectionAbout extends PureComponent { /> - + - + - + diff --git a/src/components/SettingsPage/sections/Display.js b/src/components/SettingsPage/sections/Display.js index 0fe220b2..c1cc662c 100644 --- a/src/components/SettingsPage/sections/Display.js +++ b/src/components/SettingsPage/sections/Display.js @@ -24,6 +24,20 @@ const fiats = listFiats().map(fiat => ({ name: `${fiat.name} - ${fiat.code}${fiat.symbol ? ` (${fiat.symbol})` : ''}`, })) +/* temporary subset of countries */ +const COUNTRIES = [ + { name: 'China', key: 'CN' }, + { name: 'France', key: 'FR' }, + { name: 'India', key: 'IN' }, + { name: 'Italy', key: 'IT' }, + { name: 'Japan', key: 'JP' }, + { name: 'Russian Federation', key: 'RU' }, + { name: 'Singapore', key: 'SG' }, + { name: 'Switzerland', key: 'CH' }, + { name: 'United Kingdom', key: 'GB' }, + { name: 'United States', key: 'US' }, +] + type Props = { t: T, settings: Settings, @@ -35,6 +49,7 @@ type State = { cachedMarketIndicator: string, cachedLanguageKey: string, cachedCounterValue: ?Object, + cachedRegion: Object, } class TabProfile extends PureComponent { @@ -42,6 +57,7 @@ class TabProfile extends PureComponent { cachedMarketIndicator: this.props.settings.marketIndicator, cachedLanguageKey: this.props.settings.language, cachedCounterValue: fiats.find(fiat => fiat.fiat.code === this.props.settings.counterValue), + cachedRegion: this.props.settings.region, } getDatas() { @@ -83,6 +99,14 @@ class TabProfile extends PureComponent { }) } + handleChangeRegion = (region: Object) => { + const { saveSettings } = this.props + this.setState({ cachedRegion: region }) + window.requestIdleCallback(() => { + saveSettings({ region }) + }) + } + handleChangeMarketIndicator = (item: Object) => { const { saveSettings } = this.props const marketIndicator = item.key @@ -96,9 +120,15 @@ class TabProfile extends PureComponent { render() { const { t } = this.props - const { cachedMarketIndicator, cachedLanguageKey, cachedCounterValue } = this.state + const { + cachedMarketIndicator, + cachedLanguageKey, + cachedCounterValue, + cachedRegion, + } = this.state const { languages } = this.getDatas() const currentLanguage = languages.find(l => l.key === cachedLanguageKey) + const currentRegion = COUNTRIES.find(r => r.key === cachedRegion.key) return (
@@ -135,7 +165,16 @@ class TabProfile extends PureComponent { /> - {'-'} +