Skip to content

Commit

Permalink
Merge pull request #332 from nossas/feature-analytics-events
Browse files Browse the repository at this point in the history
Improvements to send event to Google Analytics when key actions occurs
  • Loading branch information
lpirola authored Jan 30, 2017
2 parents 249858d + 4f70cb7 commit 17a4c4d
Show file tree
Hide file tree
Showing 12 changed files with 119 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { createAction } from './create-action'
import * as t from '../action-types'
import AnalyticsEvents from '../../../../../modules/widgets/utils/analytics-events'

const asyncDonationTransactionCreate = params => (dispatch, getState, axios) => {
const endpoint = `/mobilizations/${params.mobilization_id}/donations`
Expand All @@ -9,6 +10,9 @@ const asyncDonationTransactionCreate = params => (dispatch, getState, axios) =>
return axios.post(endpoint, body)
.then(response => {
dispatch({ type: t.ASYNC_DONATION_TRANSACTION_CREATE_SUCCESS })

AnalyticsEvents.donationFinishRequest()

return Promise.resolve()
})
.catch(failure => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import * as Paths from '../../../../../scripts/Paths'
// Parent module dependencies
import { WidgetOverlay, FinishMessageCustom } from '../../../../../modules/widgets/components'

import AnalyticsEvents from '../../../../../modules/widgets/utils/analytics-events'

// Current module dependencies
import { DonationTellAFriend } from '../components'
import * as DonationActions from '../action-creators'
Expand Down Expand Up @@ -94,6 +96,9 @@ class Donation extends React.Component {
uiColor: main_color,
paymentButtonText: widget.settings.button_text
}

AnalyticsEvents.donationSetValue()

checkout.open(params)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Parent module dependencies
import * as WidgetSelectors from '../../../../../modules/widgets/selectors'
import { actions as WidgetActions } from '../../../../../modules/widgets'
import AnalyticsEvents from '../../../../../modules/widgets/utils/analytics-events'

// Current module dependencies
import * as t from '../action-types'
Expand All @@ -19,6 +20,9 @@ const asyncFormEntryCreate = ({ mobilization, formEntry }) => (dispatch, getStat
dispatch(WidgetActions.setWidgetList(
updateWidgetList(state, response.data)
))

AnalyticsEvents.formSavedData()

return Promise.resolve()
})
.catch(failure => {
Expand Down
3 changes: 3 additions & 0 deletions app/modules/widgets/__plugins__/form/components/__form__.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { isValidEmail } from '../../../../../util/validation-helper'

// Parent module dependencies
import { WidgetOverlay, FinishMessageCustom } from '../../../../../modules/widgets/components'
import AnalyticsEvents from '../../../../../modules/widgets/utils/analytics-events'

// Current module dependencies
import { Button, Input, FormTellAFriend } from '../components'
Expand Down Expand Up @@ -107,6 +108,7 @@ class Form extends React.Component {
{...this.props}
key={field.uid}
uid={field.uid}
onBlur={(Number(index) === 0 ? AnalyticsEvents.formIsFilled.bind(AnalyticsEvents) : ()=>{})}
canMoveUp={index !== 0}
canMoveDown={index !== fields.length - 1}
initializeEditing={this.props.hasNewField && index === fields.length - 1}
Expand Down Expand Up @@ -229,6 +231,7 @@ class Form extends React.Component {
onClick={::this.handleOverlayOnClick}
text="Clique para configurar o formulário de inscrição"
>
<div onKeyDown={(e) => e.stopPropagation()} />
<div className={`widget ${headerFont}-header`}>
{success ? this.renderShareButtons() : this.renderForm()}
{this.renderCount()}
Expand Down
3 changes: 2 additions & 1 deletion app/modules/widgets/__plugins__/form/components/input.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class Input extends Component {
}

renderFieldKind() {
const { field, uid, editable, configurable } = this.props
const { field, uid, editable, configurable, onBlur } = this.props

if (field.kind === 'dropdown') {
return (<select
Expand Down Expand Up @@ -95,6 +95,7 @@ class Input extends Component {
borderRadius: '2px',
padding: '1rem',
}}
onBlur={onBlur}
placeholder={field.placeholder}
type='text'
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as t from '../action-types'
import { createAction } from './create-action'
import * as WidgetSelectors from '../../../../../modules/widgets/selectors'
import { actions as WidgetsActions } from '../../../../../modules/widgets'
import AnalyticsEvents from '../../../../../modules/widgets/utils/analytics-events'

//
// The name of this action needs to be refactored to make more sense.
Expand All @@ -22,6 +23,9 @@ const asyncFillWidget = ({ payload: fill, widget }) => (dispatch, getState, axio
dispatch(WidgetsActions.setWidgetList(
updateWidgetList(state, response.data)
))

AnalyticsEvents.pressureSavedData()

return Promise.resolve()
})
.catch(failure => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ export class Pressure extends Component {
)
) : (
<div className="pressure-widget">
<div onKeyDown={(e) => e.stopPropagation()} />
<h2
className="center py2 px3 m0 white rounded-top"
style={{ backgroundColor: main_color, fontFamily: headerFont }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import classnames from 'classnames'
import './pressure-form.scss'
import { isValidEmail } from '../../../../../util/validation-helper'

import AnalyticsEvents from '../../../../../modules/widgets/utils/analytics-events'

// TODO: Reusable Input
const controlClassname = 'px3 py1'
const inputReset = {
Expand Down Expand Up @@ -87,6 +89,7 @@ class PressureForm extends Component {
id="pressure-sender-email-id"
className="col-12"
style={inputReset}
onBlur={::AnalyticsEvents.pressureIsFilled}
type="email"
placeholder="Insira seu e-mail"
value={email}
Expand Down
52 changes: 52 additions & 0 deletions app/modules/widgets/utils/analytics-events.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import ReactGA from 'react-ga'

class AnalyticsEvents {
constructor () {
this.FORM_FILLED = { category: 'Formulário', action: 'Preenchimento Iniciado' }
this.FORM_SAVED = { category: 'Formulário', action: 'Dados Salvos com Sucesso' }

this.DONATION_STARTED = { category: 'Doação', action: 'Escolheu Valor' }
this.DONATION_FINISHED = { category: 'Doação', action: 'Servidor Recebeu Dados' }

this.PRESSURE_FILLED = { category: 'Pressão', action: 'Preenchimento Iniciado' }
this.PRESSURE_SAVED = { category: 'Pressão', action: 'Dados Salvos com Sucesso' }

this.SOCIAL_SHARED = { category: 'Redes Sociais', action: 'Compartilhou no ' }
}
sendEvent (event) {
return ReactGA.event(event)
}

formIsFilled () {
return this.sendEvent(this.FORM_FILLED)
}

formSavedData () {
return this.sendEvent(this.FORM_SAVED)
}

donationSetValue () {
return this.sendEvent(this.DONATION_STARTED)
}

donationFinishRequest (value) {
return this.sendEvent({...this.DONATION_FINISHED, label: value})
}

pressureIsFilled () {
return this.sendEvent(this.PRESSURE_FILLED)
}

pressureSavedData () {
return this.sendEvent(this.PRESSURE_SAVED)
}

socialShared (source, text) {
let evt = { ...this.SOCIAL_SHARED }
evt.action = evt.action + source
evt.label = text
return this.sendEvent(evt)
}
}

export default new AnalyticsEvents()
31 changes: 31 additions & 0 deletions app/modules/widgets/utils/analytics-events.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import sinon from 'sinon'
import { expect } from 'chai'

import AnalyticsEvents from '../../../modules/widgets/utils/analytics-events'

describe.skip('app/modules/widgets/utils/analytics-events', () => {
let sandbox

before(() => {
sandbox = sinon.sandbox.create()
sandbox.spy(AnalyticsEvents, 'sendEvent')
})

context('#formIsFilled', () => {
console.log(AnalyticsEvents)
it('should return true when form is filled', () => {
expect(AnalyticsEvents.formIsFilled()).to.be.true
})

expect(AnalyticsEvents.sendEvent).to.be.called
})

// formSavedData,
// formSocialShare,
// donationSetValue,
// donationFinishRequest,
// donationSocialShare,
// pressureIsFilled,
// pressureSavedData,
// pressureSocialShare
})
8 changes: 6 additions & 2 deletions app/scripts/components/FacebookShareButton.jsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import React, { PropTypes } from 'react'
import AnalyticsEvents from '../../modules/widgets/utils/analytics-events'

export default class FacebookShareButton extends React.Component {
static propTypes = {
href: PropTypes.string.isRequired
href: PropTypes.string.isRequired,
text: PropTypes.string.isRequired
}

handleClick() {
const { href } = this.props
const { text, href } = this.props

AnalyticsEvents.socialShared('Facebook', text)

window.open(
`http://www.facebook.com/sharer.php?u=${href}`,
Expand Down
4 changes: 4 additions & 0 deletions app/scripts/components/TwitterShareButton.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { PropTypes } from 'react'
import AnalyticsEvents from '../../modules/widgets/utils/analytics-events'

export default class TwitterShareButton extends React.Component {
static propTypes = {
Expand All @@ -13,6 +14,9 @@ export default class TwitterShareButton extends React.Component {
// hashtags: comma-separated list without #

const { href, text } = this.props

AnalyticsEvents.socialShared('Twitter', text)

window.open(
`https://twitter.com/intent/tweet?text=${encodeURIComponent(text)}&url=${href}`,
'Compartilhar no Twitter',
Expand Down

0 comments on commit 17a4c4d

Please sign in to comment.