diff --git a/src/components/Onboarding/index.js b/src/components/Onboarding/index.js index 19d5790a..7efec2ae 100644 --- a/src/components/Onboarding/index.js +++ b/src/components/Onboarding/index.js @@ -96,6 +96,7 @@ export type StepProps = { savePassword: Function, getDeviceInfo: Function, updateGenuineCheck: Function, + openModal: Function, isLedgerNano: Function, flowType: Function, } @@ -145,6 +146,7 @@ class Onboarding extends PureComponent { onboarding, settings, updateGenuineCheck, + openModal, isLedgerNano, flowType, prevStep, diff --git a/src/components/Onboarding/steps/Analytics.js b/src/components/Onboarding/steps/Analytics.js index 72705880..84d95aea 100644 --- a/src/components/Onboarding/steps/Analytics.js +++ b/src/components/Onboarding/steps/Analytics.js @@ -8,12 +8,17 @@ import Box from 'components/base/Box' import Switch from 'components/base/Switch' import TrackPage from 'analytics/TrackPage' import Track from 'analytics/Track' +import { openModal } from 'reducers/modals' +import { MODAL_SHARE_ANALYTICS, MODAL_TECHNICAL_DATA } from 'config/constants' +import ShareAnalytics from '../../modals/ShareAnalytics' +import TechnicalData from '../../modals/TechnicalData' +import FakeLink from '../../base/FakeLink' import { Title, Description, FixedTopContainer, StepContainerInner } from '../helperComponents' import OnboardingFooter from '../OnboardingFooter' import type { StepProps } from '..' -const mapDispatchToProps = { saveSettings } +const mapDispatchToProps = { saveSettings, openModal } type State = { analyticsToggle: boolean, @@ -46,7 +51,12 @@ class Analytics extends PureComponent { savePassword(undefined) prevStep() } - + handleShareAnalyticsModal = () => { + this.props.openModal(MODAL_SHARE_ANALYTICS) + } + handleTechnicalDataModal = () => { + this.props.openModal(MODAL_TECHNICAL_DATA) + } render() { const { nextStep, t, onboarding } = this.props const { analyticsToggle, sentryLogsToggle } = this.state @@ -65,7 +75,9 @@ class Analytics extends PureComponent { - {t('onboarding:analytics.sentryLogs.title')} + + {t('onboarding:analytics.sentryLogs.title')} + {t('onboarding:analytics.sentryLogs.desc')} @@ -82,7 +94,19 @@ class Analytics extends PureComponent { - {t('onboarding:analytics.shareAnalytics.title')} + + {t('onboarding:analytics.shareAnalytics.title')} + + {t('app:common.learnMore')} + + + {t('onboarding:analytics.shareAnalytics.desc')} @@ -97,6 +121,30 @@ class Analytics extends PureComponent { + + + + {t('onboarding:analytics.technicalData.title')} + + {t('app:common.learnMore')} + + + + {t('onboarding:analytics.technicalData.desc')} + + {t('onboarding:analytics.technicalData.mandatoryText')} + + + + + + (p.disabled ? 0.3 : 1)}; transition: 250ms linear background-color; - cursor: pointer; + cursor: ${p => (p.disabled ? 'cursor' : 'pointer')}; &:focus { outline: none; } diff --git a/src/components/modals/ShareAnalytics.js b/src/components/modals/ShareAnalytics.js new file mode 100644 index 00000000..4365ac97 --- /dev/null +++ b/src/components/modals/ShareAnalytics.js @@ -0,0 +1,99 @@ +// @flow +import React, { PureComponent } from 'react' +import { translate } from 'react-i18next' +import styled from 'styled-components' + +import { MODAL_SHARE_ANALYTICS } from 'config/constants' +import Modal, { ModalBody, ModalTitle, ModalContent, ModalFooter } from 'components/base/Modal' + +import Button from 'components/base/Button' +import Box from 'components/base/Box' + +import type { T } from 'types/common' + +type Props = { + t: T, +} +class ShareAnalytics extends PureComponent { + render() { + const { t } = this.props + const items = [ + { + key: 'item1', + desc: t('onboarding:analytics.shareAnalytics.mandatoryContextual.item1'), + }, + { + key: 'item2', + desc: t('onboarding:analytics.shareAnalytics.mandatoryContextual.item2'), + }, + { + key: 'item3', + desc: t('onboarding:analytics.shareAnalytics.mandatoryContextual.item3'), + }, + { + key: 'item4', + desc: t('onboarding:analytics.shareAnalytics.mandatoryContextual.item4'), + }, + { + key: 'item5', + desc: t('onboarding:analytics.shareAnalytics.mandatoryContextual.item5'), + }, + { + key: 'item6', + desc: t('onboarding:analytics.shareAnalytics.mandatoryContextual.item6'), + }, + { + key: 'item7', + desc: t('onboarding:analytics.shareAnalytics.mandatoryContextual.item7'), + }, + { + key: 'item8', + desc: t('onboarding:analytics.shareAnalytics.mandatoryContextual.item8'), + }, + { + key: 'item9', + desc: t('onboarding:analytics.shareAnalytics.mandatoryContextual.item9'), + }, + { + key: 'item10', + desc: t('onboarding:analytics.shareAnalytics.mandatoryContextual.item10'), + }, + ] + return ( + ( + + {t('onboarding:analytics.shareAnalytics.title')} + {t('onboarding:analytics.shareAnalytics.desc')} + +
    {items.map(item =>
  • {item.desc}
  • )}
+
+ + + +
+ )} + /> + ) + } +} + +export default translate()(ShareAnalytics) + +export const Ul = styled.ul.attrs({ + ff: 'Open Sans|Regular', +})` + margin-top: 15px; + font-size: 13px; + color: ${p => p.theme.colors.graphite}; + line-height: 1.69; +` +export const InlineDesc = styled(Box).attrs({ + ff: 'Open Sans|SemiBold', + fontSize: 4, + color: 'dark', + mx: '45px', +})`` diff --git a/src/components/modals/TechnicalData.js b/src/components/modals/TechnicalData.js new file mode 100644 index 00000000..43e4ed04 --- /dev/null +++ b/src/components/modals/TechnicalData.js @@ -0,0 +1,71 @@ +// @flow +import React, { PureComponent } from 'react' +import { translate } from 'react-i18next' + +import { MODAL_TECHNICAL_DATA } from 'config/constants' +import Modal, { ModalBody, ModalTitle, ModalContent, ModalFooter } from 'components/base/Modal' +import Button from 'components/base/Button' + +import type { T } from 'types/common' +import { Ul, InlineDesc } from './ShareAnalytics' + +type Props = { + t: T, +} + +class TechnicalData extends PureComponent { + render() { + const { t } = this.props + + const items = [ + { + key: 'item1', + desc: t('onboarding:analytics.technicalData.mandatoryContextual.item1'), + }, + { + key: 'item2', + desc: t('onboarding:analytics.technicalData.mandatoryContextual.item2'), + }, + { + key: 'item3', + desc: t('onboarding:analytics.technicalData.mandatoryContextual.item3'), + }, + { + key: 'item4', + desc: t('onboarding:analytics.technicalData.mandatoryContextual.item4'), + }, + { + key: 'item5', + desc: t('onboarding:analytics.technicalData.mandatoryContextual.item5'), + }, + { + key: 'item6', + desc: t('onboarding:analytics.technicalData.mandatoryContextual.item6'), + }, + ] + + return ( + ( + + + {t('onboarding:analytics.technicalData.mandatoryContextual.title')} + + {t('onboarding:analytics.technicalData.desc')} + +
    {items.map(item =>
  • {item.desc}
  • )}
+
+ + + +
+ )} + /> + ) + } +} + +export default translate()(TechnicalData) diff --git a/src/config/constants.js b/src/config/constants.js index b9a4b4ce..7396c0f5 100644 --- a/src/config/constants.js +++ b/src/config/constants.js @@ -96,6 +96,8 @@ export const MODAL_RECEIVE = 'MODAL_RECEIVE' export const MODAL_SEND = 'MODAL_SEND' export const MODAL_SETTINGS_ACCOUNT = 'MODAL_SETTINGS_ACCOUNT' export const MODAL_RELEASES_NOTES = 'MODAL_RELEASES_NOTES' +export const MODAL_SHARE_ANALYTICS = 'MODAL_SHARE_ANALYTICS' +export const MODAL_TECHNICAL_DATA = 'MODAL_TECHNICAL_DATA' export const MODAL_DISCLAIMER = 'MODAL_DISCLAIMER' export const MODAL_DISCLAIMER_DELAY = 1 * 1000 diff --git a/static/i18n/en/app.yml b/static/i18n/en/app.yml index 98ece127..ac2bf5c0 100644 --- a/static/i18n/en/app.yml +++ b/static/i18n/en/app.yml @@ -7,6 +7,7 @@ common: cancel: Cancel delete: Delete continue: Continue + learnMore: Learn More skipThisStep: Skip this step chooseWalletPlaceholder: Choose a wallet... currency: Currency diff --git a/static/i18n/en/onboarding.yml b/static/i18n/en/onboarding.yml index 357b8f5d..58724913 100644 --- a/static/i18n/en/onboarding.yml +++ b/static/i18n/en/onboarding.yml @@ -131,12 +131,32 @@ analytics: shareAnalytics: title: Share usage data desc: Enable analytics of anonymous data to help Ledger improve the user experience. This includes the operating system, language, firmware versions and the number of added accounts. + mandatoryContextual: + item1: Page visits + item2: Actions (send, receive, logout) + item3: Clicks + item4: Redirections to webpages + item5: Scrolled to end of page + item6: Install/Uninstall + item7: Number of accounts, currencies and operations + item8: Overall and page session duration + item9: Device product ID + item10: Device firmware and app versions sentryLogs: title: Report bugs desc: Automatically send reports to help Ledger fix bugs - # mandatoryContextual: - # title: Technical data - # desc: Ledger will automatically collect technical information to help improve user experience. This information is fully anonymized. + technicalData: + title: Technical data * + desc: Ledger will automatically collect technical information to help improve user experience. This information is fully anonymized. + mandatoryText: '* mandatory' + mandatoryContextual: + title: Technical data + item1: Active unique users + item2: OS name + item3: OS versions + item4: Ledger Live application version + item5: App Language/Region + item6: OS Language/Region finish: title: Your device is ready! desc: Proceed to your portfolio and start adding your accounts...