Commit f2e83bf5 by Renzo Lucioni

Split payment/verification business intelligence analytics

Track verify now and verify later choices, image captures, image retake, and name changes, as well as virtual pageviews for every step in the new flow(s).
parent cb7f725d
......@@ -22,16 +22,21 @@
},
sync: function( method, model ) {
var headers = { 'X-CSRFToken': $.cookie('csrftoken') },
var headers = { 'X-CSRFToken': $.cookie( 'csrftoken' ) },
data = {
face_image: model.get('faceImage'),
photo_id_image: model.get('identificationImage')
face_image: model.get( 'faceImage' ),
photo_id_image: model.get( 'identificationImage' )
};
// Full name is an optional parameter; if not provided,
// it won't be changed.
if ( !_.isNull( model.get('fullName') ) ) {
data.full_name = model.get('fullName');
if ( !_.isEmpty( model.get( 'fullName' ) ) ) {
data.full_name = model.get( 'fullName' );
// Track the user's decision to change the name on their account
window.analytics.track( 'edx.bi.user.full_name.changed', {
category: 'verification'
});
}
// Submit the request to the server,
......
......@@ -11,15 +11,22 @@ var edx = edx || {};
edx.verify_student.FacePhotoStepView = edx.verify_student.StepView.extend({
postRender: function() {
new edx.verify_student.WebcamPhotoView({
el: $("#facecam"),
var webcam = new edx.verify_student.WebcamPhotoView({
el: $( '#facecam' ),
model: this.model,
modelAttribute: 'faceImage',
submitButton: '#next_step_button',
errorModel: this.errorModel
}).render();
$('#next_step_button').on( 'click', _.bind( this.nextStep, this ) );
this.listenTo( webcam, 'imageCaptured', function() {
// Track the user's successful image capture
window.analytics.track( 'edx.bi.user.face_image.captured', {
category: 'verification'
});
});
$( '#next_step_button' ).on( 'click', _.bind( this.nextStep, this ) );
},
});
......
......@@ -11,16 +11,23 @@ var edx = edx || {};
edx.verify_student.IDPhotoStepView = edx.verify_student.StepView.extend({
postRender: function() {
new edx.verify_student.WebcamPhotoView({
el: $("#idcam"),
var webcam = new edx.verify_student.WebcamPhotoView({
el: $( '#idcam' ),
model: this.model,
modelAttribute: 'identificationImage',
submitButton: '#next_step_button',
errorModel: this.errorModel
}).render();
$('#next_step_button').on( 'click', _.bind( this.nextStep, this ) );
},
this.listenTo( webcam, 'imageCaptured', function() {
// Track the user's successful image capture
window.analytics.track( 'edx.bi.user.identification_image.captured', {
category: 'verification'
});
});
$( '#next_step_button' ).on( 'click', _.bind( this.nextStep, this ) );
}
});
})( jQuery );
......@@ -75,6 +75,11 @@ var edx = edx || {};
}).appendTo(form);
});
// Marketing needs a way to tell the difference between users
// leaving for the payment processor and users dropping off on
// this page. A virtual pageview can be used to do this.
window.analytics.page( 'verification', 'payment_processor_step' );
form.submit();
},
......
......@@ -9,7 +9,6 @@ var edx = edx || {};
edx.verify_student = edx.verify_student || {};
edx.verify_student.PaymentConfirmationStepView = edx.verify_student.StepView.extend({
/**
* Retrieve receipt information from the shopping cart.
*
......@@ -68,9 +67,24 @@ var edx = edx || {};
* The "Verify Now" button reloads this page with the "skip-first-step"
* flag set. This allows the user to navigate back to the confirmation
* if he/she wants to.
* For this reason, we don't need any custom click handlers here.
* For this reason, we don't need any custom click handlers here, except for
* those used to track business intelligence events.
*/
postRender: function() {},
postRender: function() {
// Track the user's decision to verify immediately
$( '#verify_now_button' ).on( 'click', function() {
window.analytics.track( 'edx.bi.user.verification.immediate', {
category: 'verification'
});
});
// Track the user's decision to defer their verification
$( '#verify_later_button' ).on( 'click', function() {
window.analytics.track( 'edx.bi.user.verification.deferred', {
category: 'verification'
});
});
},
/**
* Retrieve receipt data from the shoppingcart.
......
......@@ -14,8 +14,8 @@ var edx = edx || {};
var model = this.model;
// Load the photos from the previous steps
$( "#face_image")[0].src = this.model.get('faceImage');
$( "#photo_id_image")[0].src = this.model.get('identificationImage');
$( '#face_image' )[0].src = this.model.get('faceImage');
$( '#photo_id_image' )[0].src = this.model.get('identificationImage');
// Prep the name change dropdown
$( '.expandable-area' ).slideUp();
......@@ -37,12 +37,17 @@ var edx = edx || {};
},
retakePhotos: function() {
// Track the user's intent to retake their photos
window.analytics.track( 'edx.bi.user.verification_images.retaken', {
category: 'verification'
});
this.goToStep( 'face-photo-step' );
},
submitPhotos: function() {
// Disable the submit button to prevent duplicate submissions
$( "#next_step_button" ).addClass( "is-disabled" );
$( '#next_step_button' ).addClass( 'is-disabled' );
// On success, move on to the next step
this.listenToOnce( this.model, 'sync', _.bind( this.nextStep, this ) );
......@@ -57,8 +62,8 @@ var edx = edx || {};
handleSubmissionError: function( xhr ) {
// Re-enable the submit button to allow the user to retry
var isConfirmChecked = $( "#confirm_pics_good" ).prop('checked');
$( "#next_step_button" ).toggleClass( "is-disabled", !isConfirmChecked );
var isConfirmChecked = $( '#confirm_pics_good' ).prop( 'checked' );
$( '#next_step_button' ).toggleClass( 'is-disabled', !isConfirmChecked );
// Display the error
if ( xhr.status === 400 ) {
......@@ -77,14 +82,14 @@ var edx = edx || {};
}
},
expandCallback: function(event) {
expandCallback: function( event ) {
event.preventDefault();
$(this).next('.expandable-area' ).slideToggle();
var title = $( this ).parent();
title.toggleClass( 'is-expanded' );
title.attr( 'aria-expanded', !title.attr('aria-expanded') );
title.attr( 'aria-expanded', !title.attr( 'aria-expanded' ) );
}
});
......
......@@ -47,6 +47,9 @@
this.postRender();
}
).fail( _.bind( this.handleError, this ) );
// Track a virtual pageview, for easy funnel reconstruction.
window.analytics.page( 'verification', this.templateName );
},
handleResponse: function( data ) {
......
......@@ -262,6 +262,10 @@
var success = this.backend.snapshot();
if ( success ) {
// Trigger an event which parent views can use to fire a
// business intelligence event
this.trigger( 'imageCaptured' );
// Hide the capture button, and show the reset button
$( "#webcam_capture_button", this.el ).hide();
$( "#webcam_reset_button", this.el ).show();
......
......@@ -78,7 +78,7 @@
<div class="copy expandable-area">
<p><%- gettext( "You should change the name on your account to match." ) %></p>
<input type="text" name="new-name" id="new-name" placeholder=<%- fullName %>>
<input type="text" name="new-name" id="new-name" placeholder=<%= fullName %>>
</div>
</div>
</div>
......
......@@ -19,7 +19,8 @@
<script type="text/javascript">
var analytics = {
track: function() { return; },
pageview: function() { return; }
pageview: function() { return; },
page: function() { return; }
};
</script>
<!-- end dummy segment.io -->
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment