Browse Source

analytics page onboarding 2 modals for additional reqs

master
Anastasia Poupeney 7 years ago
parent
commit
1cc9a4a62f
  1. 2
      src/components/Onboarding/index.js
  2. 57
      src/components/Onboarding/steps/Analytics.js
  3. 3
      src/components/base/Switch/index.js
  4. 45
      src/components/modals/ShareAnalytics.js
  5. 43
      src/components/modals/TechnicalData.js
  6. 2
      src/config/constants.js
  7. 2
      src/reducers/onboarding.js
  8. 12
      static/i18n/en/onboarding.yml

2
src/components/Onboarding/index.js

@ -96,7 +96,7 @@ export type StepProps = {
savePassword: Function, savePassword: Function,
getDeviceInfo: Function, getDeviceInfo: Function,
updateGenuineCheck: Function, updateGenuineCheck: Function,
openModal: string => void, openModal: Function,
isLedgerNano: Function, isLedgerNano: Function,
flowType: Function, flowType: Function,
} }

57
src/components/Onboarding/steps/Analytics.js

@ -9,8 +9,8 @@ import Switch from 'components/base/Switch'
import TrackPage from 'analytics/TrackPage' import TrackPage from 'analytics/TrackPage'
import Track from 'analytics/Track' import Track from 'analytics/Track'
import { openModal } from 'reducers/modals' import { openModal } from 'reducers/modals'
import { MODAL_REPORT_BUGS, MODAL_TECHNICAL_DATA } from 'config/constants' import { MODAL_SHARE_ANALYTICS, MODAL_TECHNICAL_DATA } from 'config/constants'
import ReportBugs from '../../modals/ReportBugs' import ShareAnalytics from '../../modals/ShareAnalytics'
import TechnicalData from '../../modals/TechnicalData' import TechnicalData from '../../modals/TechnicalData'
import FakeLink from '../../base/FakeLink' import FakeLink from '../../base/FakeLink'
import { Title, Description, FixedTopContainer, StepContainerInner } from '../helperComponents' import { Title, Description, FixedTopContainer, StepContainerInner } from '../helperComponents'
@ -51,8 +51,8 @@ class Analytics extends PureComponent<StepProps, State> {
savePassword(undefined) savePassword(undefined)
prevStep() prevStep()
} }
handleBugsModal = () => { handleShareAnalyticsModal = () => {
this.props.openModal(MODAL_REPORT_BUGS) this.props.openModal(MODAL_SHARE_ANALYTICS)
} }
handleTechnicalDataModal = () => { handleTechnicalDataModal = () => {
this.props.openModal(MODAL_TECHNICAL_DATA) this.props.openModal(MODAL_TECHNICAL_DATA)
@ -75,18 +75,8 @@ class Analytics extends PureComponent<StepProps, State> {
<Box mt={5}> <Box mt={5}>
<Container> <Container>
<Box> <Box>
<Box horizontal mb={2}> <Box mb={1}>
<AnalyticsTitle>{t('onboarding:analytics.sentryLogs.title')}</AnalyticsTitle> <AnalyticsTitle>{t('onboarding:analytics.sentryLogs.title')}</AnalyticsTitle>
<FakeLink
style={{ textDecoration: 'underline' }}
fontSize={3}
color="smoke"
ml={2}
onClick={this.handleBugsModal}
>
{t('app:common.learnMore')}
</FakeLink>
<ReportBugs />
</Box> </Box>
<AnalyticsText>{t('onboarding:analytics.sentryLogs.desc')}</AnalyticsText> <AnalyticsText>{t('onboarding:analytics.sentryLogs.desc')}</AnalyticsText>
</Box> </Box>
@ -104,19 +94,19 @@ class Analytics extends PureComponent<StepProps, State> {
</Container> </Container>
<Container> <Container>
<Box> <Box>
<Box horizontal mb={2}> <Box horizontal mb={1}>
<AnalyticsTitle>{t('onboarding:analytics.shareAnalytics.title')}</AnalyticsTitle> <AnalyticsTitle>{t('onboarding:analytics.shareAnalytics.title')}</AnalyticsTitle>
<FakeLink <FakeLink
style={{ textDecoration: 'underline' }} style={{ textDecoration: 'underline' }}
fontSize={3} fontSize={3}
color="smoke" color="smoke"
ml={2} ml={2}
onClick={this.handleTechnicalDataModal} onClick={this.handleShareAnalyticsModal}
> >
{t('app:common.learnMore')} {t('app:common.learnMore')}
</FakeLink> </FakeLink>
<ShareAnalytics />
</Box> </Box>
<TechnicalData />
<AnalyticsText>{t('onboarding:analytics.shareAnalytics.desc')}</AnalyticsText> <AnalyticsText>{t('onboarding:analytics.shareAnalytics.desc')}</AnalyticsText>
</Box> </Box>
<Box justifyContent="center"> <Box justifyContent="center">
@ -131,6 +121,30 @@ class Analytics extends PureComponent<StepProps, State> {
<Switch isChecked={analyticsToggle} onChange={this.handleAnalyticsToggle} /> <Switch isChecked={analyticsToggle} onChange={this.handleAnalyticsToggle} />
</Box> </Box>
</Container> </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> </Box>
</StepContainerInner> </StepContainerInner>
<OnboardingFooter <OnboardingFooter
@ -151,6 +165,13 @@ export default connect(
mapDispatchToProps, mapDispatchToProps,
)(Analytics) )(Analytics)
const MandatoryText = styled(Box).attrs({
ff: 'Open Sans|Regular',
fontSize: 2,
textAlign: 'left',
color: 'grey',
mt: 1,
})``
export const AnalyticsText = styled(Box).attrs({ export const AnalyticsText = styled(Box).attrs({
ff: 'Open Sans|Regular', ff: 'Open Sans|Regular',
fontSize: 3, fontSize: 3,

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

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

45
src/components/modals/ReportBugs.js → src/components/modals/ShareAnalytics.js

@ -3,82 +3,75 @@ import React, { PureComponent } from 'react'
import { translate } from 'react-i18next' import { translate } from 'react-i18next'
import styled from 'styled-components' import styled from 'styled-components'
import { MODAL_REPORT_BUGS } from 'config/constants' import { MODAL_SHARE_ANALYTICS } from 'config/constants'
import Modal, { ModalBody, ModalTitle, ModalContent, ModalFooter } from 'components/base/Modal' import Modal, { ModalBody, ModalTitle, ModalContent, ModalFooter } from 'components/base/Modal'
import Button from 'components/base/Button' import Button from 'components/base/Button'
import Box from 'components/base/Box' import Box from 'components/base/Box'
import Text from 'components/base/Text'
import type { T } from 'types/common' import type { T } from 'types/common'
const Title = styled(Text).attrs({
ff: 'Museo Sans',
fontSize: 5,
color: 'dark',
})``
type Props = { type Props = {
t: T, t: T,
} }
class ReportBugs extends PureComponent<Props, *> { class ShareAnalytics extends PureComponent<Props, *> {
render() { render() {
const { t } = this.props const { t } = this.props
const steps = [ const items = [
{ {
key: 'item1', key: 'item1',
desc: t('onboarding:analytics.sentryLogs.mandatoryContextual.item1'), desc: t('onboarding:analytics.shareAnalytics.mandatoryContextual.item1'),
}, },
{ {
key: 'item2', key: 'item2',
desc: t('onboarding:analytics.sentryLogs.mandatoryContextual.item2'), desc: t('onboarding:analytics.shareAnalytics.mandatoryContextual.item2'),
}, },
{ {
key: 'item3', key: 'item3',
desc: t('onboarding:analytics.sentryLogs.mandatoryContextual.item3'), desc: t('onboarding:analytics.shareAnalytics.mandatoryContextual.item3'),
}, },
{ {
key: 'item4', key: 'item4',
desc: t('onboarding:analytics.sentryLogs.mandatoryContextual.item4'), desc: t('onboarding:analytics.shareAnalytics.mandatoryContextual.item4'),
}, },
{ {
key: 'item5', key: 'item5',
desc: t('onboarding:analytics.sentryLogs.mandatoryContextual.item5'), desc: t('onboarding:analytics.shareAnalytics.mandatoryContextual.item5'),
}, },
{ {
key: 'item6', key: 'item6',
desc: t('onboarding:analytics.sentryLogs.mandatoryContextual.item6'), desc: t('onboarding:analytics.shareAnalytics.mandatoryContextual.item6'),
}, },
{ {
key: 'item7', key: 'item7',
desc: t('onboarding:analytics.sentryLogs.mandatoryContextual.item7'), desc: t('onboarding:analytics.shareAnalytics.mandatoryContextual.item7'),
}, },
{ {
key: 'item8', key: 'item8',
desc: t('onboarding:analytics.sentryLogs.mandatoryContextual.item8'), desc: t('onboarding:analytics.shareAnalytics.mandatoryContextual.item8'),
}, },
{ {
key: 'item9', key: 'item9',
desc: t('onboarding:analytics.sentryLogs.mandatoryContextual.item9'), desc: t('onboarding:analytics.shareAnalytics.mandatoryContextual.item9'),
}, },
{ {
key: 'item10', key: 'item10',
desc: t('onboarding:analytics.sentryLogs.mandatoryContextual.item10'), desc: t('onboarding:analytics.shareAnalytics.mandatoryContextual.item10'),
}, },
] ]
return ( return (
<Modal <Modal
name={MODAL_REPORT_BUGS} name={MODAL_SHARE_ANALYTICS}
render={({ onClose }) => ( render={({ onClose }) => (
<ModalBody onClose={onClose}> <ModalBody onClose={onClose}>
<ModalTitle>{t('onboarding:analytics.sentryLogs.title')}</ModalTitle> <ModalTitle>{t('onboarding:analytics.shareAnalytics.title')}</ModalTitle>
<InlineDesc>{t('onboarding:analytics.sentryLogs.desc')}</InlineDesc> <InlineDesc>{t('onboarding:analytics.shareAnalytics.desc')}</InlineDesc>
<ModalContent mx={5}> <ModalContent mx={5}>
<Ul>{steps.map(step => <li key={step.key}>{step.desc}</li>)}</Ul> <Ul>{items.map(item => <li key={item.key}>{item.desc}</li>)}</Ul>
</ModalContent> </ModalContent>
<ModalFooter horizontal justifyContent="flex-end"> <ModalFooter horizontal justifyContent="flex-end">
<Button onClick={onClose} primary> <Button onClick={onClose} primary>
Close {t('app:common.close')}
</Button> </Button>
</ModalFooter> </ModalFooter>
</ModalBody> </ModalBody>
@ -88,7 +81,7 @@ class ReportBugs extends PureComponent<Props, *> {
} }
} }
export default translate()(ReportBugs) export default translate()(ShareAnalytics)
export const Ul = styled.ul.attrs({ export const Ul = styled.ul.attrs({
ff: 'Open Sans|Regular', ff: 'Open Sans|Regular',

43
src/components/modals/TechnicalData.js

@ -1,29 +1,13 @@
// @flow // @flow
import React, { PureComponent } from 'react' import React, { PureComponent } from 'react'
import { translate } from 'react-i18next' import { translate } from 'react-i18next'
import ReactMarkdown from 'react-markdown'
import styled from 'styled-components'
import network from 'api/network'
import { MODAL_TECHNICAL_DATA } from 'config/constants' import { MODAL_TECHNICAL_DATA } from 'config/constants'
import Modal, { ModalBody, ModalTitle, ModalContent, ModalFooter } from 'components/base/Modal' import Modal, { ModalBody, ModalTitle, ModalContent, ModalFooter } from 'components/base/Modal'
import Button from 'components/base/Button' import Button from 'components/base/Button'
import Box from 'components/base/Box'
import GrowScroll from 'components/base/GrowScroll'
import Text from 'components/base/Text'
import Spinner from 'components/base/Spinner'
import GradientBox from 'components/GradientBox'
import IconChevronRight from 'icons/ChevronRight'
import { OptionRow } from 'components/Onboarding/helperComponents'
import type { T } from 'types/common' import type { T } from 'types/common'
import { Ul, InlineDesc } from './ShareAnalytics'
const Title = styled(Text).attrs({
ff: 'Museo Sans',
fontSize: 5,
color: 'dark',
})``
type Props = { type Props = {
t: T, t: T,
@ -33,7 +17,7 @@ class TechnicalData extends PureComponent<Props, *> {
render() { render() {
const { t } = this.props const { t } = this.props
const steps = [ const items = [
{ {
key: 'item1', key: 'item1',
desc: t('onboarding:analytics.technicalData.mandatoryContextual.item1'), desc: t('onboarding:analytics.technicalData.mandatoryContextual.item1'),
@ -65,14 +49,16 @@ class TechnicalData extends PureComponent<Props, *> {
name={MODAL_TECHNICAL_DATA} name={MODAL_TECHNICAL_DATA}
render={({ onClose }) => ( render={({ onClose }) => (
<ModalBody onClose={onClose}> <ModalBody onClose={onClose}>
<ModalTitle>{t('onboarding:analytics.technicalData.title')}</ModalTitle> <ModalTitle>
{t('onboarding:analytics.technicalData.mandatoryContextual.title')}
</ModalTitle>
<InlineDesc>{t('onboarding:analytics.technicalData.desc')}</InlineDesc> <InlineDesc>{t('onboarding:analytics.technicalData.desc')}</InlineDesc>
<ModalContent mx={5}> <ModalContent mx={5}>
<Ul>{steps.map(step => <li key={step.key}>{step.desc}</li>)}</Ul> <Ul>{items.map(item => <li key={item.key}>{item.desc}</li>)}</Ul>
</ModalContent> </ModalContent>
<ModalFooter horizontal justifyContent="flex-end"> <ModalFooter horizontal justifyContent="flex-end">
<Button onClick={onClose} primary> <Button onClick={onClose} primary>
Close {t('app:common.close')}
</Button> </Button>
</ModalFooter> </ModalFooter>
</ModalBody> </ModalBody>
@ -83,18 +69,3 @@ class TechnicalData extends PureComponent<Props, *> {
} }
export default translate()(TechnicalData) export default translate()(TechnicalData)
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',
})``

2
src/config/constants.js

@ -96,7 +96,7 @@ export const MODAL_RECEIVE = 'MODAL_RECEIVE'
export const MODAL_SEND = 'MODAL_SEND' export const MODAL_SEND = 'MODAL_SEND'
export const MODAL_SETTINGS_ACCOUNT = 'MODAL_SETTINGS_ACCOUNT' export const MODAL_SETTINGS_ACCOUNT = 'MODAL_SETTINGS_ACCOUNT'
export const MODAL_RELEASES_NOTES = 'MODAL_RELEASES_NOTES' export const MODAL_RELEASES_NOTES = 'MODAL_RELEASES_NOTES'
export const MODAL_REPORT_BUGS = 'MODAL_REPORT_BUGS' export const MODAL_SHARE_ANALYTICS = 'MODAL_SHARE_ANALYTICS'
export const MODAL_TECHNICAL_DATA = 'MODAL_TECHNICAL_DATA' export const MODAL_TECHNICAL_DATA = 'MODAL_TECHNICAL_DATA'
export const MODAL_DISCLAIMER = 'MODAL_DISCLAIMER' export const MODAL_DISCLAIMER = 'MODAL_DISCLAIMER'

2
src/reducers/onboarding.js

@ -32,7 +32,7 @@ export type OnboardingState = {
const state: OnboardingState = { const state: OnboardingState = {
stepIndex: 0, // FIXME is this used at all? dup with stepName? stepIndex: 0, // FIXME is this used at all? dup with stepName?
stepName: 'analytics', stepName: SKIP_ONBOARDING ? 'analytics' : 'start',
genuine: { genuine: {
pinStepPass: false, pinStepPass: false,
recoveryStepPass: false, recoveryStepPass: false,

12
static/i18n/en/onboarding.yml

@ -131,9 +131,6 @@ analytics:
shareAnalytics: shareAnalytics:
title: Share usage data 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. 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.
sentryLogs:
title: Report bugs
desc: Automatically send reports to help Ledger fix bugs
mandatoryContextual: mandatoryContextual:
item1: Page visits item1: Page visits
item2: Actions (send, receive, logout) item2: Actions (send, receive, logout)
@ -145,10 +142,15 @@ analytics:
item8: Overall and page session duration item8: Overall and page session duration
item9: Device product ID item9: Device product ID
item10: Device firmware and app versions item10: Device firmware and app versions
sentryLogs:
title: Report bugs
desc: Automatically send reports to help Ledger fix bugs
technicalData: technicalData:
title: Report bugs title: Technical data *
desc: Automatically send reports to help Ledger fix bugs desc: Ledger will automatically collect technical information to help improve user experience. This information is fully anonymized.
mandatoryText: '* mandatory'
mandatoryContextual: mandatoryContextual:
title: Technical data
item1: Active unique users item1: Active unique users
item2: OS name item2: OS name
item3: OS versions item3: OS versions

Loading…
Cancel
Save