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).
This commit is contained in:
@@ -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 -->
|
||||
|
||||
Reference in New Issue
Block a user