Browse Source

Merge pull request #836 from NastiaS/analytics-addition-onboarding

Analytics addition onboarding
master
NastiaS 7 years ago
committed by GitHub
parent
commit
bb7438f9de
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      src/components/Onboarding/index.js
  2. 67
      src/components/Onboarding/steps/Analytics.js
  3. 3
      src/components/base/Switch/index.js
  4. 99
      src/components/modals/ShareAnalytics.js
  5. 71
      src/components/modals/TechnicalData.js
  6. 2
      src/config/constants.js
  7. 1
      static/i18n/en/app.yml
  8. 26
      static/i18n/en/onboarding.yml

2
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<Props> {
onboarding,
settings,
updateGenuineCheck,
openModal,
isLedgerNano,
flowType,
prevStep,

67
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<StepProps, State> {
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<StepProps, State> {
<Box mt={5}>
<Container>
<Box>
<AnalyticsTitle>{t('onboarding:analytics.sentryLogs.title')}</AnalyticsTitle>
<Box mb={1}>
<AnalyticsTitle>{t('onboarding:analytics.sentryLogs.title')}</AnalyticsTitle>
</Box>
<AnalyticsText>{t('onboarding:analytics.sentryLogs.desc')}</AnalyticsText>
</Box>
<Box justifyContent="center">
@ -82,7 +94,19 @@ class Analytics extends PureComponent<StepProps, State> {
</Container>
<Container>
<Box>
<AnalyticsTitle>{t('onboarding:analytics.shareAnalytics.title')}</AnalyticsTitle>
<Box horizontal mb={1}>
<AnalyticsTitle>{t('onboarding:analytics.shareAnalytics.title')}</AnalyticsTitle>
<FakeLink
style={{ textDecoration: 'underline' }}
fontSize={3}
color="smoke"
ml={2}
onClick={this.handleShareAnalyticsModal}
>
{t('app:common.learnMore')}
</FakeLink>
<ShareAnalytics />
</Box>
<AnalyticsText>{t('onboarding:analytics.shareAnalytics.desc')}</AnalyticsText>
</Box>
<Box justifyContent="center">
@ -97,6 +121,30 @@ class Analytics extends PureComponent<StepProps, State> {
<Switch isChecked={analyticsToggle} onChange={this.handleAnalyticsToggle} />
</Box>
</Container>
<Container>
<Box>
<Box horizontal mb={1}>
<AnalyticsTitle>{t('onboarding:analytics.technicalData.title')}</AnalyticsTitle>
<FakeLink
underline
fontSize={3}
color="smoke"
ml={2}
onClick={this.handleTechnicalDataModal}
>
{t('app:common.learnMore')}
</FakeLink>
</Box>
<TechnicalData />
<AnalyticsText>{t('onboarding:analytics.technicalData.desc')}</AnalyticsText>
<MandatoryText>
{t('onboarding:analytics.technicalData.mandatoryText')}
</MandatoryText>
</Box>
<Box justifyContent="center">
<Switch disabled isChecked />
</Box>
</Container>
</Box>
</StepContainerInner>
<OnboardingFooter
@ -117,6 +165,13 @@ export default connect(
mapDispatchToProps,
)(Analytics)
const MandatoryText = styled(Box).attrs({
ff: 'Open Sans|Regular',
fontSize: 2,
textAlign: 'left',
color: 'grey',
mt: 1,
})``
export const AnalyticsText = styled(Box).attrs({
ff: 'Open Sans|Regular',
fontSize: 3,
@ -129,9 +184,7 @@ export const AnalyticsTitle = styled(Box).attrs({
ff: 'Open Sans|SemiBold',
fontSize: 4,
textAlign: 'left',
})`
margin-bottom: 5px;
`
})``
const Container = styled(Box).attrs({
horizontal: true,
p: 3,

3
src/components/base/Switch/index.js

@ -15,8 +15,9 @@ const Base = styled(Tabbable).attrs({
width: 50px;
height: 26px;
border-radius: 13px;
opacity: ${p => (p.disabled ? 0.3 : 1)};
transition: 250ms linear background-color;
cursor: pointer;
cursor: ${p => (p.disabled ? 'cursor' : 'pointer')};
&:focus {
outline: none;
}

99
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<Props, *> {
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 (
<Modal
name={MODAL_SHARE_ANALYTICS}
render={({ onClose }) => (
<ModalBody onClose={onClose}>
<ModalTitle>{t('onboarding:analytics.shareAnalytics.title')}</ModalTitle>
<InlineDesc>{t('onboarding:analytics.shareAnalytics.desc')}</InlineDesc>
<ModalContent mx={5}>
<Ul>{items.map(item => <li key={item.key}>{item.desc}</li>)}</Ul>
</ModalContent>
<ModalFooter horizontal justifyContent="flex-end">
<Button onClick={onClose} primary>
{t('app:common.close')}
</Button>
</ModalFooter>
</ModalBody>
)}
/>
)
}
}
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',
})``

71
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<Props, *> {
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 (
<Modal
name={MODAL_TECHNICAL_DATA}
render={({ onClose }) => (
<ModalBody onClose={onClose}>
<ModalTitle>
{t('onboarding:analytics.technicalData.mandatoryContextual.title')}
</ModalTitle>
<InlineDesc>{t('onboarding:analytics.technicalData.desc')}</InlineDesc>
<ModalContent mx={5}>
<Ul>{items.map(item => <li key={item.key}>{item.desc}</li>)}</Ul>
</ModalContent>
<ModalFooter horizontal justifyContent="flex-end">
<Button onClick={onClose} primary>
{t('app:common.close')}
</Button>
</ModalFooter>
</ModalBody>
)}
/>
)
}
}
export default translate()(TechnicalData)

2
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

1
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

26
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...

Loading…
Cancel
Save