Commit 487bac51 by AlasdairSwan

Merge pull request #6364 from edx/alasdair/decoupled-verified

ECOM-811 design and layout changes
parents c28bed2b 8eb484c1
...@@ -992,7 +992,6 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase): ...@@ -992,7 +992,6 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase):
self._assert_requirements_displayed(response, [ self._assert_requirements_displayed(response, [
PayAndVerifyView.PHOTO_ID_REQ, PayAndVerifyView.PHOTO_ID_REQ,
PayAndVerifyView.WEBCAM_REQ, PayAndVerifyView.WEBCAM_REQ,
PayAndVerifyView.CREDIT_CARD_REQ,
]) ])
@ddt.data("expired", "denied") @ddt.data("expired", "denied")
...@@ -1033,9 +1032,7 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase): ...@@ -1033,9 +1032,7 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase):
PayAndVerifyView.MAKE_PAYMENT_STEP PayAndVerifyView.MAKE_PAYMENT_STEP
) )
self._assert_messaging(response, PayAndVerifyView.FIRST_TIME_VERIFY_MSG) self._assert_messaging(response, PayAndVerifyView.FIRST_TIME_VERIFY_MSG)
self._assert_requirements_displayed(response, [ self._assert_requirements_displayed(response, [])
PayAndVerifyView.CREDIT_CARD_REQ,
])
@ddt.data("verified", "professional") @ddt.data("verified", "professional")
def test_start_flow_already_paid(self, course_mode): def test_start_flow_already_paid(self, course_mode):
...@@ -1068,9 +1065,7 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase): ...@@ -1068,9 +1065,7 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase):
PayAndVerifyView.PAYMENT_STEPS, PayAndVerifyView.PAYMENT_STEPS,
PayAndVerifyView.MAKE_PAYMENT_STEP PayAndVerifyView.MAKE_PAYMENT_STEP
) )
self._assert_requirements_displayed(response, [ self._assert_requirements_displayed(response, [])
PayAndVerifyView.CREDIT_CARD_REQ,
])
def test_start_flow_unenrolled(self): def test_start_flow_unenrolled(self):
course = self._create_course("verified") course = self._create_course("verified")
...@@ -1086,9 +1081,7 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase): ...@@ -1086,9 +1081,7 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase):
PayAndVerifyView.PAYMENT_STEPS, PayAndVerifyView.PAYMENT_STEPS,
PayAndVerifyView.MAKE_PAYMENT_STEP PayAndVerifyView.MAKE_PAYMENT_STEP
) )
self._assert_requirements_displayed(response, [ self._assert_requirements_displayed(response, [])
PayAndVerifyView.CREDIT_CARD_REQ,
])
@ddt.data( @ddt.data(
("verified", "submitted"), ("verified", "submitted"),
...@@ -1128,7 +1121,6 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase): ...@@ -1128,7 +1121,6 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase):
self._assert_requirements_displayed(response, [ self._assert_requirements_displayed(response, [
PayAndVerifyView.PHOTO_ID_REQ, PayAndVerifyView.PHOTO_ID_REQ,
PayAndVerifyView.WEBCAM_REQ, PayAndVerifyView.WEBCAM_REQ,
PayAndVerifyView.CREDIT_CARD_REQ,
]) ])
def test_verify_now_already_verified(self): def test_verify_now_already_verified(self):
...@@ -1237,28 +1229,8 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase): ...@@ -1237,28 +1229,8 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase):
self._assert_requirements_displayed(response, [ self._assert_requirements_displayed(response, [
PayAndVerifyView.PHOTO_ID_REQ, PayAndVerifyView.PHOTO_ID_REQ,
PayAndVerifyView.WEBCAM_REQ, PayAndVerifyView.WEBCAM_REQ,
PayAndVerifyView.CREDIT_CARD_REQ,
]) ])
def test_payment_confirmation_skip_first_step(self):
course = self._create_course("verified")
self._enroll(course.id, "verified")
response = self._get_page(
'verify_student_payment_confirmation',
course.id,
skip_first_step=True
)
self._assert_messaging(response, PayAndVerifyView.PAYMENT_CONFIRMATION_MSG)
# Expect that *all* steps are displayed,
# but we start on the first verify step
self._assert_steps_displayed(
response,
PayAndVerifyView.PAYMENT_STEPS + PayAndVerifyView.VERIFICATION_STEPS,
PayAndVerifyView.FACE_PHOTO_STEP,
)
def test_payment_cannot_skip(self): def test_payment_cannot_skip(self):
""" """
Simple test to verify that certain steps cannot be skipped. This test sets up Simple test to verify that certain steps cannot be skipped. This test sets up
...@@ -1358,7 +1330,6 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase): ...@@ -1358,7 +1330,6 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase):
self._assert_requirements_displayed(response, [ self._assert_requirements_displayed(response, [
PayAndVerifyView.PHOTO_ID_REQ, PayAndVerifyView.PHOTO_ID_REQ,
PayAndVerifyView.WEBCAM_REQ, PayAndVerifyView.WEBCAM_REQ,
PayAndVerifyView.CREDIT_CARD_REQ,
]) ])
def test_upgrade_already_verified(self): def test_upgrade_already_verified(self):
...@@ -1373,9 +1344,7 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase): ...@@ -1373,9 +1344,7 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase):
PayAndVerifyView.MAKE_PAYMENT_STEP PayAndVerifyView.MAKE_PAYMENT_STEP
) )
self._assert_messaging(response, PayAndVerifyView.UPGRADE_MSG) self._assert_messaging(response, PayAndVerifyView.UPGRADE_MSG)
self._assert_requirements_displayed(response, [ self._assert_requirements_displayed(response, [])
PayAndVerifyView.CREDIT_CARD_REQ,
])
def test_upgrade_already_paid(self): def test_upgrade_already_paid(self):
course = self._create_course("verified") course = self._create_course("verified")
...@@ -1486,7 +1455,6 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase): ...@@ -1486,7 +1455,6 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase):
) )
self._assert_requirements_displayed(response, [ self._assert_requirements_displayed(response, [
PayAndVerifyView.ACCOUNT_ACTIVATION_REQ, PayAndVerifyView.ACCOUNT_ACTIVATION_REQ,
PayAndVerifyView.CREDIT_CARD_REQ,
PayAndVerifyView.PHOTO_ID_REQ, PayAndVerifyView.PHOTO_ID_REQ,
PayAndVerifyView.WEBCAM_REQ, PayAndVerifyView.WEBCAM_REQ,
]) ])
...@@ -1516,6 +1484,22 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase): ...@@ -1516,6 +1484,22 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase):
response = self._get_page("verify_student_start_flow", course.id) response = self._get_page("verify_student_start_flow", course.id)
self._assert_contribution_amount(response, "12.34") self._assert_contribution_amount(response, "12.34")
def test_verification_deadline(self):
# Set a deadline on the course mode
course = self._create_course("verified")
mode = CourseMode.objects.get(
course_id=course.id,
mode_slug="verified"
)
expiration = datetime(2999, 1, 2, tzinfo=pytz.UTC)
mode.expiration_datetime = expiration
mode.save()
# Expect that the expiration date is set
response = self._get_page("verify_student_start_flow", course.id)
data = self._get_page_data(response)
self.assertEqual(data['verification_deadline'], "Jan 02, 2999 at 00:00 UTC")
def _create_course(self, *course_modes, **kwargs): def _create_course(self, *course_modes, **kwargs):
"""Create a new course with the specified course modes. """ """Create a new course with the specified course modes. """
course = CourseFactory.create() course = CourseFactory.create()
...@@ -1648,7 +1632,8 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase): ...@@ -1648,7 +1632,8 @@ class TestPayAndVerifyView(UrlResetMixin, ModuleStoreTestCase):
'current_step': pay_and_verify_div['data-current-step'], 'current_step': pay_and_verify_div['data-current-step'],
'requirements': json.loads(pay_and_verify_div['data-requirements']), 'requirements': json.loads(pay_and_verify_div['data-requirements']),
'message_key': pay_and_verify_div['data-msg-key'], 'message_key': pay_and_verify_div['data-msg-key'],
'contribution_amount': pay_and_verify_div['data-contribution-amount'] 'contribution_amount': pay_and_verify_div['data-contribution-amount'],
'verification_deadline': pay_and_verify_div['data-verification-deadline']
} }
def _assert_redirects_to_dashboard(self, response): def _assert_redirects_to_dashboard(self, response):
......
...@@ -47,6 +47,7 @@ from xmodule.modulestore.django import modulestore ...@@ -47,6 +47,7 @@ from xmodule.modulestore.django import modulestore
from microsite_configuration import microsite from microsite_configuration import microsite
from util.json_request import JsonResponse from util.json_request import JsonResponse
from util.date_utils import get_default_time_display
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
...@@ -259,10 +260,9 @@ class PayAndVerifyView(View): ...@@ -259,10 +260,9 @@ class PayAndVerifyView(View):
ENROLLMENT_CONFIRMATION_STEP ENROLLMENT_CONFIRMATION_STEP
] ]
# These are steps that can be skipped, since there are no barring requirements. # These steps can be skipped using the ?skip-first-step GET param
SKIP_STEPS = [ SKIP_STEPS = [
INTRO_STEP, INTRO_STEP,
PAYMENT_CONFIRMATION_STEP
] ]
Step = namedtuple( Step = namedtuple(
...@@ -287,15 +287,15 @@ class PayAndVerifyView(View): ...@@ -287,15 +287,15 @@ class PayAndVerifyView(View):
template_name="payment_confirmation_step" template_name="payment_confirmation_step"
), ),
FACE_PHOTO_STEP: Step( FACE_PHOTO_STEP: Step(
title=ugettext_lazy("Take Face Photo"), title=ugettext_lazy("Take Photo"),
template_name="face_photo_step" template_name="face_photo_step"
), ),
ID_PHOTO_STEP: Step( ID_PHOTO_STEP: Step(
title=ugettext_lazy("ID Photo"), title=ugettext_lazy("Take a Photo of Your ID"),
template_name="id_photo_step" template_name="id_photo_step"
), ),
REVIEW_PHOTOS_STEP: Step( REVIEW_PHOTOS_STEP: Step(
title=ugettext_lazy("Review Photos"), title=ugettext_lazy("Review Your Info"),
template_name="review_photos_step" template_name="review_photos_step"
), ),
ENROLLMENT_CONFIRMATION_STEP: Step( ENROLLMENT_CONFIRMATION_STEP: Step(
...@@ -380,12 +380,10 @@ class PayAndVerifyView(View): ...@@ -380,12 +380,10 @@ class PayAndVerifyView(View):
ACCOUNT_ACTIVATION_REQ = "account-activation-required" ACCOUNT_ACTIVATION_REQ = "account-activation-required"
PHOTO_ID_REQ = "photo-id-required" PHOTO_ID_REQ = "photo-id-required"
WEBCAM_REQ = "webcam-required" WEBCAM_REQ = "webcam-required"
CREDIT_CARD_REQ = "credit-card-required"
STEP_REQUIREMENTS = { STEP_REQUIREMENTS = {
ID_PHOTO_STEP: [PHOTO_ID_REQ, WEBCAM_REQ], ID_PHOTO_STEP: [PHOTO_ID_REQ, WEBCAM_REQ],
FACE_PHOTO_STEP: [WEBCAM_REQ], FACE_PHOTO_STEP: [WEBCAM_REQ],
MAKE_PAYMENT_STEP: [CREDIT_CARD_REQ],
} }
@method_decorator(login_required) @method_decorator(login_required)
...@@ -507,6 +505,10 @@ class PayAndVerifyView(View): ...@@ -507,6 +505,10 @@ class PayAndVerifyView(View):
'course': course, 'course': course,
'course_key': unicode(course_key), 'course_key': unicode(course_key),
'course_mode': course_mode, 'course_mode': course_mode,
'verification_deadline': (
get_default_time_display(course_mode.expiration_datetime)
if course_mode.expiration_datetime else ""
),
'courseware_url': courseware_url, 'courseware_url': courseware_url,
'current_step': current_step, 'current_step': current_step,
'disable_courseware_js': True, 'disable_courseware_js': True,
...@@ -660,7 +662,6 @@ class PayAndVerifyView(View): ...@@ -660,7 +662,6 @@ class PayAndVerifyView(View):
self.ACCOUNT_ACTIVATION_REQ: not is_active, self.ACCOUNT_ACTIVATION_REQ: not is_active,
self.PHOTO_ID_REQ: False, self.PHOTO_ID_REQ: False,
self.WEBCAM_REQ: False, self.WEBCAM_REQ: False,
self.CREDIT_CARD_REQ: False
} }
display_steps = set(step['name'] for step in display_steps) display_steps = set(step['name'] for step in display_steps)
......
...@@ -1083,8 +1083,6 @@ verify_student_js = [ ...@@ -1083,8 +1083,6 @@ verify_student_js = [
'js/verify_student/models/verification_model.js', 'js/verify_student/models/verification_model.js',
'js/verify_student/views/error_view.js', 'js/verify_student/views/error_view.js',
'js/verify_student/views/webcam_photo_view.js', 'js/verify_student/views/webcam_photo_view.js',
'js/verify_student/views/progress_view.js',
'js/verify_student/views/requirements_view.js',
'js/verify_student/views/step_view.js', 'js/verify_student/views/step_view.js',
'js/verify_student/views/intro_step_view.js', 'js/verify_student/views/intro_step_view.js',
'js/verify_student/views/make_payment_step_view.js', 'js/verify_student/views/make_payment_step_view.js',
......
...@@ -397,14 +397,6 @@ ...@@ -397,14 +397,6 @@
exports: 'edx.verify_student.WebcamPhotoView', exports: 'edx.verify_student.WebcamPhotoView',
deps: [ 'jquery', 'underscore', 'backbone', 'gettext' ] deps: [ 'jquery', 'underscore', 'backbone', 'gettext' ]
}, },
'js/verify_student/views/progress_view': {
exports: 'edx.verify_student.ProgressView',
deps: [ 'jquery', 'underscore', 'backbone', 'gettext' ]
},
'js/verify_student/views/requirements_view': {
exports: 'edx.verify_student.RequirementsView',
deps: [ 'jquery', 'backbone', 'underscore', 'gettext' ]
},
'js/verify_student/views/step_view': { 'js/verify_student/views/step_view': {
exports: 'edx.verify_student.StepView', exports: 'edx.verify_student.StepView',
deps: [ 'jquery', 'underscore', 'underscore.string', 'backbone', 'gettext' ] deps: [ 'jquery', 'underscore', 'underscore.string', 'backbone', 'gettext' ]
...@@ -414,7 +406,6 @@ ...@@ -414,7 +406,6 @@
deps: [ deps: [
'jquery', 'jquery',
'js/verify_student/views/step_view', 'js/verify_student/views/step_view',
'js/verify_student/views/requirements_view'
] ]
}, },
'js/verify_student/views/make_payment_step_view': { 'js/verify_student/views/make_payment_step_view': {
...@@ -426,7 +417,6 @@ ...@@ -426,7 +417,6 @@
'jquery.cookie', 'jquery.cookie',
'jquery.url', 'jquery.url',
'js/verify_student/views/step_view', 'js/verify_student/views/step_view',
'js/verify_student/views/requirements_view'
] ]
}, },
'js/verify_student/views/payment_confirmation_step_view': { 'js/verify_student/views/payment_confirmation_step_view': {
...@@ -436,7 +426,6 @@ ...@@ -436,7 +426,6 @@
'underscore', 'underscore',
'gettext', 'gettext',
'js/verify_student/views/step_view', 'js/verify_student/views/step_view',
'js/verify_student/views/requirements_view'
] ]
}, },
'js/verify_student/views/face_photo_step_view': { 'js/verify_student/views/face_photo_step_view': {
...@@ -484,7 +473,6 @@ ...@@ -484,7 +473,6 @@
'backbone', 'backbone',
'gettext', 'gettext',
'js/verify_student/models/verification_model', 'js/verify_student/models/verification_model',
'js/verify_student/views/progress_view',
'js/verify_student/views/intro_step_view', 'js/verify_student/views/intro_step_view',
'js/verify_student/views/make_payment_step_view', 'js/verify_student/views/make_payment_step_view',
'js/verify_student/views/payment_confirmation_step_view', 'js/verify_student/views/payment_confirmation_step_view',
......
...@@ -69,27 +69,8 @@ define(['jquery', 'js/common_helpers/template_helpers', 'js/verify_student/views ...@@ -69,27 +69,8 @@ define(['jquery', 'js/common_helpers/template_helpers', 'js/verify_student/views
}; };
var expectStepRendered = function( stepName, stepNum, numSteps ) { var expectStepRendered = function( stepName, stepNum, numSteps ) {
var i, j, sel;
// Expect that the step container div rendered // Expect that the step container div rendered
expect( $( '.' + stepName ).length > 0 ).toBe( true ); expect( $( '.' + stepName ).length > 0 ).toBe( true );
// Expect that the progress indicator shows the correct step
expect( $( '#progress-step-' + stepNum ).hasClass( 'is-current' ) ).toBe( true );
// Expect that all steps before this step are completed
for ( i = 1; i < stepNum; i++ ) {
sel = $( '#progress-step-' + i );
expect( sel.hasClass('is-completed') ).toBe( true );
expect( sel.hasClass('is-current') ).toBe( false );
}
// Expect that all steps after this step are neither completed nor current
for ( j = stepNum + 1; j <= numSteps; j++ ) {
sel = $( '#progress-step-' + j );
expect( sel.hasClass('is-completed') ).toBe( false );
expect( sel.hasClass('is-current') ).toBe( false );
}
}; };
beforeEach(function() { beforeEach(function() {
......
...@@ -31,10 +31,6 @@ define([ ...@@ -31,10 +31,6 @@ define([
}).render(); }).render();
}; };
var confirmPhotos = function( isConfirmed ) {
$('#confirm_pics_good').trigger( 'click' );
};
var submitPhotos = function( requests, expectedParams, succeeds ) { var submitPhotos = function( requests, expectedParams, succeeds ) {
// Submit the photos // Submit the photos
$( '#next_step_button' ).click(); $( '#next_step_button' ).click();
...@@ -69,27 +65,11 @@ define([ ...@@ -69,27 +65,11 @@ define([
TemplateHelpers.installTemplate( 'templates/verify_student/review_photos_step' ); TemplateHelpers.installTemplate( 'templates/verify_student/review_photos_step' );
}); });
it( 'requires the user to confirm before submitting photos', function() {
createView();
// Initially disabled
expectSubmitEnabled( false );
// Confirm the photos, enabling submission
confirmPhotos( true );
expectSubmitEnabled( true );
// Unconfirm the photos, disabling submission
confirmPhotos( false );
expectSubmitEnabled( false );
});
it( 'allows the user to change her full name', function() { it( 'allows the user to change her full name', function() {
var requests = AjaxHelpers.requests( this ); var requests = AjaxHelpers.requests( this );
createView(); createView();
setFullName( FULL_NAME ); setFullName( FULL_NAME );
confirmPhotos( true );
submitPhotos( submitPhotos(
requests, requests,
{ {
...@@ -105,7 +85,6 @@ define([ ...@@ -105,7 +85,6 @@ define([
var requests = AjaxHelpers.requests( this ); var requests = AjaxHelpers.requests( this );
createView(); createView();
confirmPhotos( true );
submitPhotos( submitPhotos(
requests, requests,
{ {
...@@ -124,7 +103,6 @@ define([ ...@@ -124,7 +103,6 @@ define([
var view = createView(), var view = createView(),
requests = AjaxHelpers.requests( this ); requests = AjaxHelpers.requests( this );
confirmPhotos( true );
submitPhotos( submitPhotos(
requests, requests,
{ {
......
...@@ -46,6 +46,8 @@ var edx = edx || {}; ...@@ -46,6 +46,8 @@ var edx = edx || {};
isActive: el.data('is-active'), isActive: el.data('is-active'),
requirements: el.data('requirements'), requirements: el.data('requirements'),
courseKey: el.data('course-key'), courseKey: el.data('course-key'),
courseName: el.data('course-name'),
upgrade: el.data('data-msg-key') === 'upgrade',
minPrice: el.data('course-mode-min-price'), minPrice: el.data('course-mode-min-price'),
contributionAmount: el.data('contribution-amount'), contributionAmount: el.data('contribution-amount'),
suggestedPrices: _.filter( suggestedPrices: _.filter(
...@@ -53,12 +55,16 @@ var edx = edx || {}; ...@@ -53,12 +55,16 @@ var edx = edx || {};
function( price ) { return Boolean( price ); } function( price ) { return Boolean( price ); }
), ),
currency: el.data('course-mode-currency'), currency: el.data('course-mode-currency'),
purchaseEndpoint: el.data('purchase-endpoint') purchaseEndpoint: el.data('purchase-endpoint'),
verificationDeadline: el.data('verification-deadline')
}, },
'payment-confirmation-step': { 'payment-confirmation-step': {
courseKey: el.data('course-key'),
courseName: el.data('course-name'), courseName: el.data('course-name'),
courseStartDate: el.data('course-start-date'), courseStartDate: el.data('course-start-date'),
coursewareUrl: el.data('courseware-url') coursewareUrl: el.data('courseware-url'),
platformName: el.data('platform-name'),
requirements: el.data('requirements')
}, },
'review-photos-step': { 'review-photos-step': {
fullName: el.data('full-name'), fullName: el.data('full-name'),
...@@ -67,7 +73,14 @@ var edx = edx || {}; ...@@ -67,7 +73,14 @@ var edx = edx || {};
'enrollment-confirmation-step': { 'enrollment-confirmation-step': {
courseName: el.data('course-name'), courseName: el.data('course-name'),
courseStartDate: el.data('course-start-date'), courseStartDate: el.data('course-start-date'),
coursewareUrl: el.data('courseware-url') coursewareUrl: el.data('courseware-url'),
platformName: el.data('platform-name')
},
'face-photo-step': {
platformName: el.data('platform-name')
},
'id-photo-step': {
platformName: el.data('platform-name')
} }
} }
}).render(); }).render();
......
...@@ -21,7 +21,8 @@ var edx = edx || {}; ...@@ -21,7 +21,8 @@ var edx = edx || {};
return { return {
courseName: '', courseName: '',
courseStartDate: '', courseStartDate: '',
coursewareUrl: '' coursewareUrl: '',
platformName: ''
}; };
} }
}); });
......
...@@ -10,6 +10,12 @@ var edx = edx || {}; ...@@ -10,6 +10,12 @@ var edx = edx || {};
edx.verify_student.FacePhotoStepView = edx.verify_student.StepView.extend({ edx.verify_student.FacePhotoStepView = edx.verify_student.StepView.extend({
defaultContext: function() {
return {
platformName: ''
};
},
postRender: function() { postRender: function() {
var webcam = new edx.verify_student.WebcamPhotoView({ var webcam = new edx.verify_student.WebcamPhotoView({
el: $( '#facecam' ), el: $( '#facecam' ),
......
...@@ -10,6 +10,12 @@ var edx = edx || {}; ...@@ -10,6 +10,12 @@ var edx = edx || {};
edx.verify_student.IDPhotoStepView = edx.verify_student.StepView.extend({ edx.verify_student.IDPhotoStepView = edx.verify_student.StepView.extend({
defaultContext: function() {
return {
platformName: ''
};
},
postRender: function() { postRender: function() {
var webcam = new edx.verify_student.WebcamPhotoView({ var webcam = new edx.verify_student.WebcamPhotoView({
el: $( '#idcam' ), el: $( '#idcam' ),
......
...@@ -14,7 +14,9 @@ var edx = edx || {}; ...@@ -14,7 +14,9 @@ var edx = edx || {};
return { return {
introTitle: '', introTitle: '',
introMsg: '', introMsg: '',
isActive: false isActive: false,
platformName: '',
requirements: {}
}; };
}, },
...@@ -25,11 +27,6 @@ var edx = edx || {}; ...@@ -25,11 +27,6 @@ var edx = edx || {};
// and if they reload the page we want them to stay on the // and if they reload the page we want them to stay on the
// second step. // second step.
postRender: function() { postRender: function() {
new edx.verify_student.RequirementsView({
el: $( '.requirements-container', this.el ),
requirements: this.stepData.requirements
}).render();
// Track a virtual pageview, for easy funnel reconstruction. // Track a virtual pageview, for easy funnel reconstruction.
window.analytics.page( 'verification', this.templateName ); window.analytics.page( 'verification', this.templateName );
} }
......
...@@ -15,41 +15,62 @@ var edx = edx || {}; ...@@ -15,41 +15,62 @@ var edx = edx || {};
isActive: true, isActive: true,
suggestedPrices: [], suggestedPrices: [],
minPrice: 0, minPrice: 0,
currency: "usd" currency: 'usd',
upgrade: false,
verificationDeadline: '',
courseName: '',
requirements: {},
platformName: ''
}; };
}, },
postRender: function() { postRender: function() {
// Render requirements var templateContext = this.templateContext(),
new edx.verify_student.RequirementsView({ hasVisibleReqs = _.some(
el: $( '.requirements-container', this.el ), templateContext.requirements,
requirements: this.stepData.requirements function( isVisible ) { return isVisible; }
}).render(); );
// Track a virtual pageview, for easy funnel reconstruction. // Track a virtual pageview, for easy funnel reconstruction.
window.analytics.page( 'payment', this.templateName ); window.analytics.page( 'payment', this.templateName );
// Update the contribution amount with the amount the user // Update the contribution amount with the amount the user
// selected in a previous screen. // selected in a previous screen.
if ( this.stepData.contributionAmount ) { if ( templateContext.contributionAmount ) {
this.selectPaymentAmount( this.stepData.contributionAmount ); this.selectPaymentAmount( templateContext.contributionAmount );
} }
if ( this.templateContext().suggestedPrices.length > 0 ) { // The contribution section is hidden by default
// Display it if the user hasn't already selected an amount
// or is upgrading.
// In the short-term, we're also displaying this if there
// are no requirements (e.g. the user already verified).
// Otherwise, there's absolutely nothing to do on this page.
// In the future, we'll likely skip directly to payment
// from the track selection page if this happens.
if ( templateContext.upgrade || !templateContext.contributionAmount || !hasVisibleReqs ) {
$( '.wrapper-task' ).removeClass( 'hidden' ).removeAttr( 'aria-hidden' );
}
if ( templateContext.suggestedPrices.length > 0 ) {
// Enable the payment button once an amount is chosen // Enable the payment button once an amount is chosen
$( "input[name='contribution']" ).on( 'click', _.bind( this.enablePaymentButton, this ) ); $( 'input[name="contribution"]' ).on( 'click', _.bind( this.setPaymentEnabled, this ) );
} else { } else {
// If there is only one payment option, then the user isn't shown // If there is only one payment option, then the user isn't shown
// radio buttons, so we need to enable the radio button. // radio buttons, so we need to enable the radio button.
this.enablePaymentButton(); this.setPaymentEnabled( true );
} }
// Handle payment submission // Handle payment submission
$( "#pay_button" ).on( 'click', _.bind( this.createOrder, this ) ); $( '#pay_button' ).on( 'click', _.bind( this.createOrder, this ) );
}, },
enablePaymentButton: function() { setPaymentEnabled: function( isEnabled ) {
$("#pay_button").removeClass("is-disabled"); if ( _.isUndefined( isEnabled ) ) {
isEnabled = true;
}
$( '#pay_button' ).toggleClass( 'is-disabled', !isEnabled );
}, },
createOrder: function() { createOrder: function() {
...@@ -60,7 +81,7 @@ var edx = edx || {}; ...@@ -60,7 +81,7 @@ var edx = edx || {};
}; };
// Disable the payment button to prevent multiple submissions // Disable the payment button to prevent multiple submissions
$("#pay_button").addClass("is-disabled"); this.setPaymentEnabled( false );
// Create the order for the amount // Create the order for the amount
$.ajax({ $.ajax({
...@@ -84,16 +105,16 @@ var edx = edx || {}; ...@@ -84,16 +105,16 @@ var edx = edx || {};
// these parameters, then submit it to the payment processor. // these parameters, then submit it to the payment processor.
// This will send the user to a hosted order page, // This will send the user to a hosted order page,
// where she can enter credit card information. // where she can enter credit card information.
var form = $( "#payment-processor-form" ); var form = $( '#payment-processor-form' );
$( "input", form ).remove(); $( 'input', form ).remove();
form.attr( "action", this.stepData.purchaseEndpoint ); form.attr( 'action', this.stepData.purchaseEndpoint );
form.attr( "method", "POST" ); form.attr( 'method', 'POST' );
_.each( paymentParams, function( value, key ) { _.each( paymentParams, function( value, key ) {
$("<input>").attr({ $('<input>').attr({
type: "hidden", type: 'hidden',
name: key, name: key,
value: value value: value
}).appendTo(form); }).appendTo(form);
...@@ -121,15 +142,15 @@ var edx = edx || {}; ...@@ -121,15 +142,15 @@ var edx = edx || {};
}); });
// Re-enable the button so the user can re-try // Re-enable the button so the user can re-try
$( "#pay_button" ).removeClass("is-disabled"); $( '#pay_button' ).removeClass( 'is-disabled' );
}, },
getPaymentAmount: function() { getPaymentAmount: function() {
var contributionInput = $("input[name='contribution']:checked", this.el), var contributionInput = $( 'input[name="contribution"]:checked' , this.el),
amount = null; amount = null;
if ( contributionInput.attr('id') === 'contribution-other' ) { if ( contributionInput.attr('id') === 'contribution-other' ) {
amount = $( "input[name='contribution-other-amt']", this.el ).val(); amount = $( 'input[name="contribution-other-amt"]' , this.el ).val();
} else { } else {
amount = contributionInput.val(); amount = contributionInput.val();
} }
...@@ -167,7 +188,7 @@ var edx = edx || {}; ...@@ -167,7 +188,7 @@ var edx = edx || {};
} }
// In either case, enable the payment button // In either case, enable the payment button
this.enablePaymentButton(); this.setPaymentEnabled();
return amount; return amount;
}, },
......
/** /**
* Base view for the payment/verification flow. * Base view for the payment/verification flow.
* *
* This view is responsible for the "progress steps" * This view is responsible for keeping track of the
* at the top of the page, but it delegates * current step, but it delegates to
* to subviews to render individual steps. * to subviews to render individual steps.
* *
*/ */
...@@ -27,21 +27,11 @@ var edx = edx || {}; ...@@ -27,21 +27,11 @@ var edx = edx || {};
initialize: function( obj ) { initialize: function( obj ) {
this.errorModel = obj.errorModel || null; this.errorModel = obj.errorModel || null;
this.displaySteps = obj.displaySteps || []; this.displaySteps = obj.displaySteps || [];
this.progressView = new edx.verify_student.ProgressView({
el: this.el,
displaySteps: this.displaySteps,
// Determine which step we're starting on
// Depending on how the user enters the flow,
// this could be anywhere in the sequence of steps.
currentStepIndex: _.indexOf(
_.pluck( this.displaySteps, 'name' ),
obj.currentStep
)
});
this.initializeStepViews( obj.stepInfo || {} ); this.initializeStepViews( obj.stepInfo || {} );
this.currentStepIndex = _.indexOf(
_.pluck( this.displaySteps, 'name' ),
obj.currentStep
);
}, },
initializeStepViews: function( stepInfo ) { initializeStepViews: function( stepInfo ) {
...@@ -94,7 +84,6 @@ var edx = edx || {}; ...@@ -94,7 +84,6 @@ var edx = edx || {};
subviewConfig = { subviewConfig = {
errorModel: this.errorModel, errorModel: this.errorModel,
templateName: this.displaySteps[i].templateName, templateName: this.displaySteps[i].templateName,
nextStepNum: (i + 2), // Next index, starting from 1
nextStepTitle: nextStepTitle, nextStepTitle: nextStepTitle,
stepData: stepData stepData: stepData
}; };
...@@ -118,7 +107,6 @@ var edx = edx || {}; ...@@ -118,7 +107,6 @@ var edx = edx || {};
}, },
render: function() { render: function() {
this.progressView.render();
this.renderCurrentStep(); this.renderCurrentStep();
return this; return this;
}, },
...@@ -137,19 +125,30 @@ var edx = edx || {}; ...@@ -137,19 +125,30 @@ var edx = edx || {};
// underscore template. // underscore template.
// When the view is rendered, it will overwrite the existing // When the view is rendered, it will overwrite the existing
// step in the DOM. // step in the DOM.
stepName = this.displaySteps[ this.progressView.currentStepIndex ].name; stepName = this.displaySteps[ this.currentStepIndex ].name;
stepView = this.subviews[ stepName ]; stepView = this.subviews[ stepName ];
stepView.el = stepEl; stepView.el = stepEl;
stepView.render(); stepView.render();
}, },
nextStep: function() { nextStep: function() {
this.progressView.nextStep(); this.currentStepIndex = Math.min(
this.currentStepIndex + 1,
this.displaySteps.length - 1
);
this.render(); this.render();
}, },
goToStep: function( stepName ) { goToStep: function( stepName ) {
this.progressView.goToStep( stepName ); var stepIndex = _.indexOf(
_.pluck( this.displaySteps, 'name' ),
stepName
);
if ( stepIndex >= 0 ) {
this.currentStepIndex = stepIndex;
}
this.render(); this.render();
} }
}); });
......
...@@ -9,6 +9,18 @@ var edx = edx || {}; ...@@ -9,6 +9,18 @@ var edx = edx || {};
edx.verify_student = edx.verify_student || {}; edx.verify_student = edx.verify_student || {};
edx.verify_student.PaymentConfirmationStepView = edx.verify_student.StepView.extend({ edx.verify_student.PaymentConfirmationStepView = edx.verify_student.StepView.extend({
defaultContext: function() {
return {
courseKey: '',
courseName: '',
courseStartDate: '',
coursewareUrl: '',
platformName: '',
requirements: []
};
},
/** /**
* Retrieve receipt information from the shopping cart. * Retrieve receipt information from the shopping cart.
* *
...@@ -64,9 +76,7 @@ var edx = edx || {}; ...@@ -64,9 +76,7 @@ var edx = edx || {};
/** /**
* The "Verify Later" button goes directly to the dashboard, * The "Verify Later" button goes directly to the dashboard,
* The "Verify Now" button reloads this page with the "skip-first-step" * The "Verify Now" button sends the user to the verification flow.
* 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, except for * For this reason, we don't need any custom click handlers here, except for
* those used to track business intelligence events. * those used to track business intelligence events.
*/ */
......
/**
* Show progress steps in the payment/verification flow.
*/
var edx = edx || {};
(function( $, _, Backbone, gettext ) {
'use strict';
edx.verify_student = edx.verify_student || {};
edx.verify_student.ProgressView = Backbone.View.extend({
template: '#progress-tpl',
initialize: function( obj ) {
this.displaySteps = obj.displaySteps || {};
this.currentStepIndex = obj.currentStepIndex || 0;
},
nextStep: function() {
this.currentStepIndex = Math.min(
this.currentStepIndex + 1,
this.displaySteps.length - 1
);
},
goToStep: function( stepName ) {
var stepIndex = _.indexOf(
_.pluck( this.displaySteps, 'name' ),
stepName
);
if ( stepIndex >= 0 ) {
this.currentStepIndex = stepIndex;
}
},
render: function() {
var renderedHtml, context;
context = {
steps: this.steps()
};
renderedHtml = _.template( $(this.template).html(), context );
$(this.el).html(renderedHtml);
},
steps: function() {
var i,
stepDescription,
steps = [];
for ( i = 0; i < this.displaySteps.length; i++ ) {
stepDescription = {
title: this.displaySteps[i].title,
isCurrent: (i === this.currentStepIndex ),
isComplete: (i < this.currentStepIndex )
};
steps.push(stepDescription);
}
return steps;
}
});
})( $, _, Backbone, gettext );
/**
* View for the requirements (webcam, credit card, etc.)
*/
var edx = edx || {};
(function( $, Backbone, _, gettext ) {
'use strict';
edx.verify_student = edx.verify_student || {};
edx.verify_student.RequirementsView = Backbone.View.extend({
template: "#requirements-tpl",
initialize: function( obj ) {
this.requirements = obj.requirements || {};
},
render: function() {
var renderedHtml = _.template(
$( this.template ).html(),
{ requirements: this.requirements }
);
$( this.el ).html( renderedHtml );
}
});
})( jQuery, Backbone, _, gettext );
...@@ -12,8 +12,8 @@ var edx = edx || {}; ...@@ -12,8 +12,8 @@ var edx = edx || {};
defaultContext: function() { defaultContext: function() {
return { return {
platformName: "", platformName: '',
fullName: "", fullName: '',
}; };
}, },
...@@ -27,9 +27,6 @@ var edx = edx || {}; ...@@ -27,9 +27,6 @@ var edx = edx || {};
$( '.is-expandable' ).addClass('is-ready'); $( '.is-expandable' ).addClass('is-ready');
$( '.is-expandable .title-expand' ).on( 'click', this.expandCallback ); $( '.is-expandable .title-expand' ).on( 'click', this.expandCallback );
// Disable the submit button until user confirmation
$( '#confirm_pics_good' ).on( 'click', this.toggleSubmitEnabled );
// Go back to the first photo step if we need to retake photos // Go back to the first photo step if we need to retake photos
$( '#retake_photos_button' ).on( 'click', _.bind( this.retakePhotos, this ) ); $( '#retake_photos_button' ).on( 'click', _.bind( this.retakePhotos, this ) );
...@@ -40,10 +37,6 @@ var edx = edx || {}; ...@@ -40,10 +37,6 @@ var edx = edx || {};
window.analytics.page( 'verification', this.templateName ); window.analytics.page( 'verification', this.templateName );
}, },
toggleSubmitEnabled: function() {
$( '#next_step_button' ).toggleClass( 'is-disabled' );
},
retakePhotos: function() { retakePhotos: function() {
// Track the user's intent to retake their photos // Track the user's intent to retake their photos
window.analytics.track( 'edx.bi.user.images.retaken', { window.analytics.track( 'edx.bi.user.images.retaken', {
...@@ -73,11 +66,10 @@ var edx = edx || {}; ...@@ -73,11 +66,10 @@ var edx = edx || {};
}, },
handleSubmissionError: function( xhr ) { handleSubmissionError: function( xhr ) {
var isConfirmChecked = $( "#confirm_pics_good" ).prop('checked'), var errorMsg = gettext( 'An unexpected error occurred. Please try again later.' );
errorMsg = gettext( 'An unexpected error occurred. Please try again later.' );
// Re-enable the submit button to allow the user to retry // Re-enable the submit button to allow the user to retry
$( '#next_step_button' ).toggleClass( 'is-disabled', !isConfirmChecked ); $( '#next_step_button' ).removeClass( 'is-disabled' );
if ( xhr.status === 400 ) { if ( xhr.status === 400 ) {
errorMsg = xhr.responseText; errorMsg = xhr.responseText;
...@@ -91,11 +83,12 @@ var edx = edx || {}; ...@@ -91,11 +83,12 @@ var edx = edx || {};
}, },
expandCallback: function( event ) { expandCallback: function( event ) {
var title;
event.preventDefault(); event.preventDefault();
$(this).next('.expandable-area' ).slideToggle(); $(this).next('.expandable-area' ).slideToggle();
title = $( this ).parent();
var title = $( this ).parent();
title.toggleClass( 'is-expanded' ); title.toggleClass( 'is-expanded' );
title.attr( 'aria-expanded', !title.attr( 'aria-expanded' ) ); title.attr( 'aria-expanded', !title.attr( 'aria-expanded' ) );
} }
......
...@@ -43,19 +43,6 @@ ...@@ -43,19 +43,6 @@
return this; return this;
}, },
handleResponse: function( data ) {
var context = {
nextStepNum: this.nextStepNum,
nextStepTitle: this.nextStepTitle
};
// Include step-specific information
_.extend( context, this.stepData );
// Track a virtual pageview, for easy funnel reconstruction.
window.analytics.page( 'verification', this.templateName );
},
handleError: function( errorTitle, errorMsg ) { handleError: function( errorTitle, errorMsg ) {
this.errorModel.set({ this.errorModel.set({
errorTitle: errorTitle || gettext( "Error" ), errorTitle: errorTitle || gettext( "Error" ),
...@@ -66,7 +53,6 @@ ...@@ -66,7 +53,6 @@
templateContext: function() { templateContext: function() {
var context = { var context = {
nextStepNum: this.nextStepNum,
nextStepTitle: this.nextStepTitle nextStepTitle: this.nextStepTitle
}; };
return _.extend( context, this.defaultContext(), this.stepData ); return _.extend( context, this.defaultContext(), this.stepData );
......
...@@ -47,6 +47,7 @@ ...@@ -47,6 +47,7 @@
// base - specific views // base - specific views
@import 'views/login-register'; @import 'views/login-register';
@import 'views/verification'; @import 'views/verification';
@import 'views/decoupled-verification';
@import 'views/shoppingcart'; @import 'views/shoppingcart';
// applications // applications
......
// Updates for decoupled verification A/B test
.verification-process {
.pay-and-verify {
.review {
.title.center-col {
padding: 0 calc( ( 100% - 750px ) / 2 ) 10px;
}
}
.instruction {
&.center-col {
width: 750px;
margin-left: auto;
margin-right: auto;
}
}
.requirements-container {
.list-reqs {
width: 645px;
margin: 50px auto;
.req {
width: 300px;
height: 250px;
min-height: 250px;
margin-right: 45px;
&:last-of-type {
margin-right: 0;
}
}
&.account-not-activated {
width: 990px;
.req {
height: 290px;
min-height: 290px;
}
}
}
}
.no-content {
margin-bottom: 50px;
}
.nav-wizard {
&.center {
text-align: center;
}
.right {
float: right;
padding: 15px 50px;
}
.nav-link {
line-height: 45px;
}
.prompt-verify .title {
width: 600px;
position: relative;
display: inline;
float: left;
line-height: 45px;
}
.wizard-steps {
width: auto;
}
}
.retake-photos {
color: $blue;
&:hover {
cursor: pointer;
}
}
.tip {
.is-expandable {
.title-expand {
color: $blue !important;
}
}
.expandable-area {
margin-top: 5px;
}
}
.help-tips {
margin-left: 0 !important;
}
.wrapper-task {
.msg-retake {
margin-top: 0;
}
.wrapper-photos {
margin-bottom: 0 !important;
}
}
.report-course {
.course-actions {
td:last-of-type {
width: 300px;
}
}
}
.enrollment-status-footer {
margin: 50px 0;
h4 {
font-weight: 600;
}
.verify-pending-msg {
margin: 20px 0;
}
}
}
.tooltip {
@include transition(opacity $tmg-f3 ease-out 0s);
@include font-size(12);
position: absolute;
width: 350px;
top: 0;
left: 0;
padding: 10px 20px;
border-radius: 3px;
background: rgba(0, 0, 0, 0.85);
line-height: 26px;
color: $white;
pointer-events: none;
opacity: 0.0;
&:after {
@include font-size(20);
content: '▾';
display: block;
position: absolute;
bottom: -14px;
left: 50%;
margin-left: -7px;
color: rgba(0, 0, 0, 0.85);
}
}
}
<div class="wrapper-content-main enrollment-confirmation-step"> <div class="wrapper-content-main enrollment-confirmation-step">
<article class="content-main"> <article class="content-main">
<h3 class="title"><%- gettext( "Congratulations! You are now enrolled in the verified track." ) %></h3> <h3 class="title"><%- _.sprintf( gettext( "Congratulations! You are now verified on %(platformName)s!" ), { platformName: platformName } ) %></h3>
<div class="instruction"> <div class="instruction">
<p><%- gettext( "You are now enrolled as a verified student! Your enrollment details are below.") %></p> <p><%- gettext( "You are now enrolled as an ID verified student for:" ) %></p>
</div> </div>
<ul class="list-info"> <ul class="list-info">
<li class="info-item course-info"> <li class="info-item course-info">
<h4 class="title">
<%- gettext( "You are enrolled in " ) %> :
</h4>
<div class="wrapper-report"> <div class="wrapper-report">
<table class="report report-course"> <table class="report report-course">
<caption class="sr"><%- gettext( "A list of courses you have just enrolled in as a verified student" ) %></caption> <caption class="sr"><%- gettext( "A list of courses you have just enrolled in as a verified student" ) %></caption>
...@@ -17,7 +14,6 @@ ...@@ -17,7 +14,6 @@
<tr> <tr>
<th scope="col" ><%- gettext( "Course" ) %></th> <th scope="col" ><%- gettext( "Course" ) %></th>
<th scope="col" ><%- gettext( "Status" ) %></th> <th scope="col" ><%- gettext( "Status" ) %></th>
<th scope="col" ><span class="sr"><%- gettext( "Options" ) %></span></th>
</tr> </tr>
</thead> </thead>
...@@ -27,17 +23,18 @@ ...@@ -27,17 +23,18 @@
<td> <td>
<%- _.sprintf( gettext( "Starts: %(start)s" ), { start: courseStartDate } ) %> <%- _.sprintf( gettext( "Starts: %(start)s" ), { start: courseStartDate } ) %>
</td> </td>
<td class="options">
<% if ( coursewareUrl ) { %>
<a class="action action-course" href="<%- coursewareUrl %>"><%- gettext( "Go to Course" ) %></a>
<% } %>
</td>
</tr> </tr>
</tbody> </tbody>
<tfoot> <tfoot>
<tr class="course-actions"> <tr class="course-actions">
<td colspan="3"> <td>
<a class="action action-dashboard" href="/dashboard"><%- gettext("Go to your dashboard") %></a> <% if ( coursewareUrl ) { %>
<a class="action action-course" href="<%- coursewareUrl %>"><%- gettext( "Explore your course!" ) %></a>
<% } %>
</td>
<td>
<a class="action action-primary" href="/dashboard"><%- gettext("Go to your dashboard") %></a>
</td> </td>
</tr> </tr>
</tfoot> </tfoot>
...@@ -46,5 +43,11 @@ ...@@ -46,5 +43,11 @@
</li> </li>
</ul> </ul>
<div class="enrollment-status-footer">
<h4 class="title"><%- gettext( "Verified Status" ) %></h4>
<p class="verify-pending-msg">
<%- gettext( "Thank you for submitting your identification photos, we will review them soon. If there is a problem with any of the items, we will contact you to resubmit. You can now enroll in any of the verified certificate courses for one year without having to re-verify." ) %></p>
</div>
</article> </article>
</div> </div>
...@@ -16,21 +16,27 @@ ...@@ -16,21 +16,27 @@
<ul class="list-help"> <ul class="list-help">
<li class="help-item"><%- gettext( "Make sure your face is well-lit" ) %></li> <li class="help-item"><%- gettext( "Make sure your face is well-lit" ) %></li>
<li class="help-item"><%- gettext( "Be sure your entire face is inside the frame" ) %></li> <li class="help-item"><%- gettext( "Be sure your entire face is inside the frame" ) %></li>
<li class="help-item">
<%= _.sprintf( gettext( "Once in position, use the camera button %(icon)s to capture your face" ), { icon: '<span class="example">(<i class="icon-camera"></i>)</span>' } ) %>
</li>
<li class="help-item"><%- gettext( "Can we match the photo you took with the one on your ID?" ) %></li> <li class="help-item"><%- gettext( "Can we match the photo you took with the one on your ID?" ) %></li>
<li class="help-item"><%- gettext( "Once in position, use the camera button" ) %> <span class="example">(<i class="icon-camera"></i>)</span> <%- gettext( "to capture your picture" ) %></li> <li class="help-item"><%- gettext( "Use the retake photo button if you are not pleased with your photo" ) %></li>
</ul> </ul>
</div> </div>
</div> </div>
<div class="help help-faq facefaq"> <div class="help help-faq facefaq">
<h4 class="sr title"><%- gettext( "Common Questions" ) %></h4> <h4 class="sr title"><%- gettext( "Common Questions" ) %></h4>
<div class="copy"> <div class="copy">
<dl class="list-faq"> <dl class="list-faq">
<dt class="faq-question"><%- gettext( "Why do you need my photo?" ) %></dt> <dt class="faq-question">
<dd class="faq-answer"><%- gettext( "As part of the verification process, we need your photo to confirm that you are you." ) %></dd> <%- _.sprintf( gettext( "Why does %(platformName)s need my photo?" ), { platformName: platformName } ) %>
<dt class="faq-question"><%- gettext( "What do you do with this picture?" ) %></dt> </dt>
<dd class="faq-answer"><%- gettext( "We only use it to verify your identity. It is not displayed anywhere." ) %></dd> <dd class="faq-answer"><%- gettext( "As part of the verification process, we need your photo to confirm your identity." ) %></dd>
<dt class="faq-question">
<%- _.sprintf( gettext( "What does %(platformName)s do with this picture?" ), { platformName: platformName } ) %>
</dt>
<dd class="faq-answer"><%- gettext( "We encrypt it and send it to our secure authorization service for review. We use the highest levels of security and do not save the photo or information anywhere once the match has been completed." ) %></dd>
</dl> </dl>
</div> </div>
</div> </div>
...@@ -39,18 +45,11 @@ ...@@ -39,18 +45,11 @@
<% if ( nextStepTitle ) { %> <% if ( nextStepTitle ) { %>
<nav class="nav-wizard" id="face_next_button_nav"> <nav class="nav-wizard" id="face_next_button_nav">
<span class="help help-inline"> <a id="next_step_button" class="next action-primary is-disabled right" aria-hidden="true" title="Next">
<%- _.sprintf( gettext( "Once you verify your photo looks good, you can move on to step %s." ), nextStepNum ) %> <%- nextStepTitle %>
</span> </a>
<ol class="wizard-steps">
<li class="wizard-step">
<a id="next_step_button" class="next action-primary is-disabled" aria-hidden="true" title="Next">
<%- _.sprintf( gettext( "Go to Step %s" ), nextStepNum ) %>: <%- nextStepTitle %>
</a>
</li>
</ol>
</nav> </nav>
<% } %> <% } %>
</div> </div>
......
<div id="wrapper-idphoto" class="wrapper-view block-photo id-photo-step"> <div id="wrapper-idphoto" class="wrapper-view block-photo id-photo-step">
<div class="idphoto view"> <div class="idphoto view">
<h3 class="title"><%- gettext( "Show Us Your ID" ) %></h3> <h3 class="title"><%- gettext( "Take a Photo of Your ID" ) %></h3>
<div class="instruction"> <div class="instruction">
<p><%- gettext("Use your webcam to take a picture of your ID so we can match it with your photo and the name on your account.") %></p> <p><%- gettext("Use your webcam to take a picture of your ID so we can match it with your photo and the name on your account.") %></p>
</div> </div>
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
<div id="idcam" class="task cam"></div> <div id="idcam" class="task cam"></div>
<div class="wrapper-help"> <div class="wrapper-help">
<div class="help help-task photo-tips idtips"> <div class="help help-task photo-tips idtips">
<h4 class="title"><%- gettext( "Tips on taking a successful photo" ) %></h4> <h4 class="title"><%- gettext( "Tips on taking a successful photo" ) %></h4>
<div class="copy"> <div class="copy">
...@@ -18,8 +18,10 @@ ...@@ -18,8 +18,10 @@
<li class="help-item"><%- gettext( "Check that there isn't any glare" ) %></li> <li class="help-item"><%- gettext( "Check that there isn't any glare" ) %></li>
<li class="help-item"><%- gettext( "Ensure that you can see your photo and read your name" ) %></li> <li class="help-item"><%- gettext( "Ensure that you can see your photo and read your name" ) %></li>
<li class="help-item"><%- gettext( "Try to keep your fingers at the edge to avoid covering important information" ) %></li> <li class="help-item"><%- gettext( "Try to keep your fingers at the edge to avoid covering important information" ) %></li>
<li class="help-item"><%- gettext( "Acceptable IDs include drivers licenses, passports, or other goverment-issued IDs that include your name and photo" ) %></li> <li class="help-item"><%- gettext( "Acceptable IDs include driver's licenses, passports, or other government-issued IDs that include your name and photo" ) %></li>
<li class="help-item"><%- gettext( "Once in position, use the camera button ") %> <span class="example">(<i class="icon-camera"></i>)</span> <%- gettext( "to capture your ID" ) %></li> <li class="help-item">
<%= _.sprintf( gettext( "Once in position, use the camera button %(icon)s to capture your ID" ), { icon: '<span class="example">(<i class="icon-camera"></i>)</span>' } ) %>
</li>
</ul> </ul>
</div> </div>
</div> </div>
...@@ -42,17 +44,9 @@ ...@@ -42,17 +44,9 @@
<% if ( nextStepTitle ) { %> <% if ( nextStepTitle ) { %>
<nav class="nav-wizard" id="face_next_button_nav"> <nav class="nav-wizard" id="face_next_button_nav">
<span class="help help-inline"> <a id="next_step_button" class="next action-primary is-disabled right" aria-hidden="true" title="Next">
<%- _.sprintf( gettext( "Once you verify your photo looks good, you can move on to step %s." ), nextStepNum ) %> <%- nextStepTitle %>
</span> </a>
<ol class="wizard-steps">
<li class="wizard-step">
<a id="next_step_button" class="next action-primary is-disabled" aria-hidden="true" title="Next">
<%- _.sprintf( gettext( "Go to Step %s" ), nextStepNum ) %>: <%- nextStepTitle %>
</a>
</li>
</ol>
</nav> </nav>
<% } %> <% } %>
</div> </div>
......
<div class="wrapper-content-main intro-step"> <div class="wrapper-content-main intro-step">
<article class="content-main"> <article class="content-main">
<h3 class="title"><%- introTitle %></h3> <h3 class="title"><%- introTitle %></h3>
<div class="instruction"><p><%- introMsg %></p></div> <% if ( introMsg ) { %>
<div class="instruction"><p><%- introMsg %></p></div>
<% } %>
<div class="requirements-container">
<ul class="list-reqs <% if ( requirements['account-activation-required'] ) { %>account-not-activated<% } %>">
<% if ( requirements['account-activation-required'] ) { %>
<li class="req req-0 req-activate">
<h4 class="title"><%- gettext( "Activate Your Account" ) %></h4>
<div class="placeholder-art">
<i class="icon-envelope-alt"></i>
</div>
<div class="copy">
<p>
<span class="copy-super"><%- gettext( "Check your email" ) %></span>
<span class="copy-sub"><%-
gettext( "You need to activate your account before you can register for courses. Check your inbox for an activation email." )
%>
</span>
</p>
</div>
</li>
<% } %>
<% if ( requirements['photo-id-required'] ) { %>
<li class="req req-1 req-id">
<h4 class="title"><%- gettext( "Photo ID" ) %></h4>
<div class="placeholder-art">
<i class="icon-list-alt icon-under"></i>
<i class="icon-user icon-over"></i>
</div>
<div class="requirements-container"></div> <div class="copy">
<p>
<span class="copy-sub"><%- gettext( "A driver's license, passport, or government-issued ID with your name and picture" ) %></span>
</p>
</div>
</li>
<% } %>
<% if ( requirements['webcam-required'] ) { %>
<li class="req req-2 req-webcam">
<h4 class="title"><%- gettext( "Webcam" ) %></h4>
<div class="placeholder-art">
<i class="icon-facetime-video"></i>
</div>
<div class="copy"></div>
</li>
<% } %>
</ul>
</div>
<% if ( nextStepTitle ) { %> <% if ( nextStepTitle ) { %>
<nav class="nav-wizard is-ready"> <nav class="nav-wizard is-ready">
...@@ -13,7 +63,7 @@ ...@@ -13,7 +63,7 @@
<% if ( !isActive ) { %> <% if ( !isActive ) { %>
<%- gettext( "Activate Your Account" ) %> <%- gettext( "Activate Your Account" ) %>
<% } else { %> <% } else { %>
<%- _.sprintf( gettext( "Go to Step %(stepNumber)s" ), { stepNumber: nextStepNum } ) %>: <%- nextStepTitle %> <%- nextStepTitle %>
<% } %> <% } %>
</a> </a>
</li> </li>
......
<div id="wrapper-review" class="wrapper-view make-payment-step"> <div id="wrapper-review" class="wrapper-view make-payment-step">
<div class="review view"> <div class="review view">
<h3 class="title"><%- gettext( "Make Payment" ) %></h3> <h3 class="title <% if ( !upgrade ) { %>center-col<% } %>">
<div class="instruction"> <%- gettext( "You are enrolling in: " ) %>
<p><%- gettext( "Make payment. TODO: actual copy here." ) %></p> <span class="course-title"><%= courseName %></span>
</div> </h3>
<div class="requirements-container"></div>
<% if ( isActive ) { %> <% if ( isActive ) { %>
<div class="wrapper-task"> <div class="wrapper-task hidden" aria-hidden="true">
<ol class="review-tasks"> <ol class="review-tasks">
<% if ( suggestedPrices.length > 0 ) { %> <% if ( suggestedPrices.length > 0 ) { %>
<li class="review-task review-task-contribution"> <li class="review-task review-task-contribution">
...@@ -60,7 +58,7 @@ ...@@ -60,7 +58,7 @@
<li class="review-task review-task-contribution"> <li class="review-task review-task-contribution">
<h4 class="title"><%- gettext( "Your Course Total" ) %></h4> <h4 class="title"><%- gettext( "Your Course Total" ) %></h4>
<div class="copy"> <div class="copy">
<p><%- gettext( "To complete your registration, you will need to pay:" ) %></p> <p><%- gettext( "To complete your enrollment, you will need to pay:" ) %></p>
</div> </div>
<ul class="list-fields contribution-options"> <ul class="list-fields contribution-options">
<li class="field contribution-option"> <li class="field contribution-option">
...@@ -74,12 +72,71 @@ ...@@ -74,12 +72,71 @@
</ol> </ol>
</div> </div>
</div> </div>
<% } %> <% } %>
<div class="instruction <% if ( !upgrade ) { %>center-col<% } %>">
<% if ( _.some( requirements, function( isVisible ) { return isVisible; } ) ) { %>
<p>
<% if ( verificationDeadline ) { %>
<%- _.sprintf(
gettext( "You can pay now even if you don't have the following items available, but you will need to have these by %(date)s to qualify to earn a Verified Certificate." ),
{ date: verificationDeadline }
) %>
<% } else { %>
<%- gettext( "You can pay now even if you don't have the following items available, but you will need to have these to qualify to earn a Verified Certificate." ) %>
<% } %>
</p>
<% } %>
</div>
<div class="requirements-container">
<ul class="list-reqs <% if ( requirements['account-activation-required'] ) { %>account-not-activated<% } %>">
<% if ( requirements['account-activation-required'] ) { %>
<li class="req req-0 req-activate">
<h4 class="title"><%- gettext( "Activate Your Account" ) %></h4>
<div class="placeholder-art">
<i class="icon-envelope-alt"></i>
</div>
<div class="copy">
<p>
<span class="copy-super"><%- gettext( "Check your email" ) %></span>
<span class="copy-sub"><%-
gettext( "You need to activate your account before you can enroll in courses. Check your inbox for an activation email." )
%>
</span>
</p>
</div>
</li>
<% } %>
<% if ( requirements['photo-id-required'] ) { %>
<li class="req req-1 req-id">
<h4 class="title"><%- gettext( "Government-Issued Photo ID" ) %></h4>
<div class="placeholder-art">
<i class="icon-list-alt icon-under"></i>
<i class="icon-user icon-over"></i>
</div>
<div class="copy"></div>
</li>
<% } %>
<% if ( requirements['webcam-required'] ) { %>
<li class="req req-2 req-webcam">
<h4 class="title"><%- gettext( "Webcam" ) %></h4>
<div class="placeholder-art">
<i class="icon-facetime-video"></i>
</div>
<div class="copy"></div>
</li>
<% } %>
</ul>
</div>
<nav class="nav-wizard is-ready"> <nav class="nav-wizard is-ready center">
<ol class="wizard-steps"> <% if ( isActive ) { %>
<li class="wizard-step">
<% if ( isActive ) { %>
<a class="next action-primary is-disabled" id="pay_button"> <a class="next action-primary is-disabled" id="pay_button">
<%- gettext( "Go to payment" ) %> <%- gettext( "Go to payment" ) %>
</a> </a>
...@@ -88,10 +145,7 @@ ...@@ -88,10 +145,7 @@
<%- gettext( "Activate Your Account" ) %> <%- gettext( "Activate Your Account" ) %>
</a> </a>
<% } %> <% } %>
</li>
</ol>
</nav> </nav>
<form id="payment-processor-form"></form> <form id="payment-processor-form"></form>
</div> </div>
...@@ -11,7 +11,7 @@ from verify_student.views import PayAndVerifyView ...@@ -11,7 +11,7 @@ from verify_student.views import PayAndVerifyView
<%block name="header_extras"> <%block name="header_extras">
<% <%
template_names = ( template_names = (
["progress", "requirements", "webcam_photo", "error"] + ["webcam_photo", "error"] +
[step['templateName'] for step in display_steps] [step['templateName'] for step in display_steps]
) )
%> %>
...@@ -26,6 +26,7 @@ from verify_student.views import PayAndVerifyView ...@@ -26,6 +26,7 @@ from verify_student.views import PayAndVerifyView
<script src="${static.url('js/vendor/underscore-min.js')}"></script> <script src="${static.url('js/vendor/underscore-min.js')}"></script>
<script src="${static.url('js/vendor/underscore.string.min.js')}"></script> <script src="${static.url('js/vendor/underscore.string.min.js')}"></script>
<script src="${static.url('js/vendor/backbone-min.js')}"></script> <script src="${static.url('js/vendor/backbone-min.js')}"></script>
<script src="${static.url('js/src/tooltip_manager.js')}"></script>
<%static:js group='verify_student'/> <%static:js group='verify_student'/>
</%block> </%block>
...@@ -36,24 +37,12 @@ from verify_student.views import PayAndVerifyView ...@@ -36,24 +37,12 @@ from verify_student.views import PayAndVerifyView
<div class="container"> <div class="container">
<section class="wrapper carousel"> <section class="wrapper carousel">
## Verification status header
<header class="page-header">
<h2 class="title">
<span class="wrapper-sts">
<span class="sts-label">${messages.top_level_msg}</span>
</span>
<span class="sts-track ${"professional-ed" if course_mode.slug == "professional" else ""}">
<span class="sts-track-value"><span class="context">${messages.status_msg}</span>: ${course_mode.name}<span>
</span>
</h2>
</header>
## Payment / Verification flow ## Payment / Verification flow
## Most of these data attributes are used to dynamically render ## Most of these data attributes are used to dynamically render
## the steps, but some are just useful for A/B test setup. ## the steps, but some are just useful for A/B test setup.
<div <div
id="pay-and-verify-container" id="pay-and-verify-container"
class="pay-and-verify"
data-full-name='${user_full_name}' data-full-name='${user_full_name}'
data-platform-name='${platform_name}' data-platform-name='${platform_name}'
data-course-key='${course_key}' data-course-key='${course_key}'
...@@ -67,6 +56,7 @@ from verify_student.views import PayAndVerifyView ...@@ -67,6 +56,7 @@ from verify_student.views import PayAndVerifyView
data-course-mode-currency='${course_mode.currency}' data-course-mode-currency='${course_mode.currency}'
data-contribution-amount='${contribution_amount}' data-contribution-amount='${contribution_amount}'
data-purchase-endpoint='${purchase_endpoint}' data-purchase-endpoint='${purchase_endpoint}'
data-verification-deadline='${verification_deadline}'
data-display-steps='${json.dumps(display_steps)}' data-display-steps='${json.dumps(display_steps)}'
data-current-step='${current_step}' data-current-step='${current_step}'
data-requirements='${json.dumps(requirements)}' data-requirements='${json.dumps(requirements)}'
......
<div class="wrapper-content-main payment-confirmation-step"> <div class="wrapper-content-main payment-confirmation-step">
<article class="content-main"> <article class="content-main">
<h3 class="title"><%- gettext( "Congratulations! You are now enrolled in the verified track." ) %></h3> <h3 class="title">
<div class="instruction"> <%- _.sprintf( gettext( "Thank you! We have received your payment for %(courseName)s" ), { courseName: courseName } ) %>
<p><%- gettext( "You are now enrolled as a verified student! Your enrollment details are below.") %></p> </h3>
</div>
<% if ( receipt ) { %> <% if ( receipt ) { %>
<ul class="list-info"> <ul class="list-info">
<li class="info-item payment-info"> <li class="info-item payment-info">
<h4 class="title"><%- gettext( "Payment Details" ) %></h4>
<div class="copy"> <div class="copy">
<p><%- gettext( "Please print this page for your records; it serves as your receipt. You will also receive an email with the same information." ) %></p> <p><%- gettext( "Please print this page for your records; it serves as your receipt. You will also receive an email with the same information." ) %></p>
</div> </div>
...@@ -77,23 +74,73 @@ ...@@ -77,23 +74,73 @@
</li> </li>
</ul> </ul>
<% } else { %> <% } else { %>
<p><%- gettext( "No receipt available." ) %></p> <p class="no-content"><%- gettext( "No receipt available." ) %></p>
<% } %> <% } %>
<% if ( nextStepTitle ) { %> <% if ( nextStepTitle ) { %>
<nav class="nav-wizard is-ready"> <h3 class="title"><%- gettext( "Next Step: Confirm Your Identity" ) %></h3>
<ol class="wizard-steps">
<li class="wizard-step"> <div class="requirements-container">
<a class="next action-primary" id="verify_now_button" href="?skip-first-step=1"> <ul class="list-reqs <% if ( requirements['account-activation-required'] ) { %>account-not-activated<% } %>">
<%- gettext( "Verify Now" ) %> <% if ( requirements['account-activation-required'] ) { %>
</a> <li class="req req-0 req-activate">
<h4 class="title"><%- gettext( "Activate Your Account" ) %></h4>
<div class="placeholder-art">
<i class="icon-envelope-alt"></i>
</div>
<div class="copy">
<p>
<span class="copy-super"><%- gettext( "Check your email." ) %></span>
<span class="copy-sub"><%-
gettext( "You need to activate your account before you can enroll in courses. Check your inbox for an activation email." )
%>
</span>
</p>
</div>
</li> </li>
<li class="wizard-step"> <% } %>
<a class="next action-secondary" id="verify_later_button" href="/dashboard">
<%- gettext( "Verify Later" ) %> <% if ( requirements['photo-id-required'] ) { %>
</a> <li class="req req-1 req-id">
<h4 class="title"><%- gettext( "Photo ID" ) %></h4>
<div class="placeholder-art">
<i class="icon-list-alt icon-under"></i>
<i class="icon-user icon-over"></i>
</div>
<div class="copy">
<p>
<span class="copy-sub"><%- gettext( "A driver's license, passport, or government-issued ID with your name and picture." ) %></span>
</p>
</div>
</li>
<% } %>
<% if ( requirements['webcam-required'] ) { %>
<li class="req req-2 req-webcam">
<h4 class="title"><%- gettext( "Webcam" ) %></h4>
<div class="placeholder-art">
<i class="icon-facetime-video"></i>
</div>
<div class="copy"></div>
</li> </li>
</ol> <% } %>
</ul>
</div>
<nav class="nav-wizard is-ready">
<a id="verify_now_button"
class="next action-primary right"
href="<%- _.sprintf( '/verify_student/verify-now/%(courseKey)s', { courseKey: courseKey } ) %>"
>
<%- nextStepTitle %>
</a>
<a id="verify_later_button" class="next action-secondary verify-later nav-link" href="/dashboard" data-tooltip="<%- _.sprintf( gettext( "If you don't confirm your identity now, you can go to the dashboard to explore your course and %(platformName)s will remind you later." ), { platformName: platformName } ) %>">
<%- gettext( "Want to confirm your identity later?" ) %>
</a>
</nav> </nav>
<% } %> <% } %>
</article> </article>
......
<div class="wrapper-progress progress">
<section class="progress">
<h3 class="sr title"><%- gettext("Your Progress") %></h3>
<ol class="progress-steps">
<% for ( var stepNum = 0; stepNum < steps.length; stepNum++ ) { %>
<li
class="progress-step
<% if ( steps[stepNum].isCurrent ) { %> is-current <% } %>
<% if ( steps[stepNum].isComplete ) { %> is-completed <% } %>"
id="progress-step-<%- stepNum + 1 %>"
>
<span class="wrapper-step-number"><span class="step-number"><%- stepNum + 1 %></span></span>
<span class="step-name"><span class="sr"><%- gettext("Current Step") %>: </span><%- steps[stepNum].title %></span>
</li>
<% } %>
<span class="progress-sts">
<span class="progress-sts-value"></span>
</span>
</section>
</div>
<ul class="list-reqs <% if ( requirements['account-activation-required'] ) { %>account-not-activated<% } %>">
<% if ( requirements['account-activation-required'] ) { %>
<li class="req req-0 req-activate">
<h4 class="title"><%- gettext( "Activate Your Account" ) %></h4>
<div class="placeholder-art">
<i class="icon-envelope-alt"></i>
</div>
<div class="copy">
<p>
<span class="copy-super"><%- gettext( "Check your email." ) %></span>
<span class="copy-sub"><%-
gettext( "You need to activate your account before you can register for courses. Check your inbox for an activation email." )
%>
</span>
</p>
</div>
</li>
<% } %>
<% if ( requirements['photo-id-required'] ) { %>
<li class="req req-1 req-id">
<h4 class="title"><%- gettext( "Identification" ) %></h4>
<div class="placeholder-art">
<i class="icon-list-alt icon-under"></i>
<i class="icon-user icon-over"></i>
</div>
<div class="copy">
<p>
<span class="copy-super"><%- gettext( "A photo identification document" ) %></span>
<span class="copy-sub"><%- gettext( "A driver's license, passport, or other government or school-issued ID with your name and picture on it." ) %></span>
</p>
</div>
</li>
<% } %>
<% if ( requirements['webcam-required'] ) { %>
<li class="req req-2 req-webcam">
<h4 class="title"><%- gettext( "Webcam" ) %></h4>
<div class="placeholder-art">
<i class="icon-facetime-video"></i>
</div>
<div class="copy">
<p>
<span class="copy-super"><%- gettext( "A webcam and a modern browser" ) %></span>
<span class="copy-sub"><strong>
<a rel="external" href="https://www.mozilla.org/en-US/firefox/new/">Firefox</a>,
<a rel="external" href="https://www.google.com/intl/en/chrome/browser/">Chrome</a>,
<a rel="external" href="http://www.apple.com/safari/">Safari</a>,
<a rel="external" href="http://windows.microsoft.com/en-us/internet-explorer/download-ie"><%- gettext("Internet Explorer 9 or later" ) %></a></strong>.
<%- gettext( "Please make sure your browser is updated to the most recent version possible." ) %>
</span>
</p>
</div>
</li>
<% } %>
<% if ( requirements['credit-card-required'] ) { %>
<li class="req req-3 req-payment">
<h4 class="title"><%- gettext( "Credit or Debit Card" ) %></h4>
<div class="placeholder-art">
<i class="icon-credit-card"></i>
</div>
<div class="copy">
<p>
<span class="copy-super"><%- gettext( "A major credit or debit card" ) %></span>
<span class="copy-sub"><%- gettext( "Visa, MasterCard, American Express, Discover, Diners Club, or JCB with the Discover logo." ) %></span>
</p>
</div>
</li>
<% } %>
</ul>
<div id="wrapper-review" class="wrapper-view review-photos-step"> <div id="wrapper-review" class="wrapper-view review-photos-step">
<div class="review view"> <div class="review view">
<h3 class="title"><%- gettext( "Verify Your Submission" ) %></h3> <h3 class="title"><%- gettext( "Review Your Photos" ) %></h3>
<div class="instruction"> <div class="instruction">
<p><%- gettext( "Make sure we can verify your identity with the photos and information below." ) %></p> <p><%- gettext( "Make sure we can verify your identity from the photos below." ) %></p>
</div> </div>
<div class="wrapper-task"> <div class="wrapper-task">
<ol class="review-tasks"> <div class="review-task review-task-photos">
<div class="wrapper-photos">
<li class="review-task review-task-photos"> <div class="wrapper-photo">
<h4 class="title"><%- gettext( "Review the Photos You've Taken" ) %></h4> <div class="placeholder-photo">
<img id="face_image" src=""/>
<div class="copy"> </div>
<p><%- gettext( "Please review the photos and verify that they meet the requirements listed below." ) %></p>
</div> </div>
<div class="wrapper-photo">
<ol class="wrapper-photos"> <div class="placeholder-photo">
<li class="wrapper-photo"> <img id="photo_id_image" src=""/>
<div class="placeholder-photo">
<img id="face_image" src=""/>
</div>
<div class="help-tips">
<h5 class="title"><%- gettext( "The photo above needs to meet the following requirements:" ) %></h5>
<ul class="list-help list-tips copy">
<li class="tip"><%- gettext( "Be well lit" ) %></li>
<li class="tip"><%- gettext( "Show your whole face" ) %></li>
<li class="tip"><%- gettext( "The photo on your ID must match the photo of your face" ) %></li>
</ul>
</div>
</li>
<li class="wrapper-photo">
<div class="placeholder-photo">
<img id="photo_id_image" src=""/>
</div>
<div class="help-tips">
<h5 class="title"><%- gettext( "The photo above needs to meet the following requirements:" ) %></h5>
<ul class="list-help list-tips copy">
<li class="tip"><%- gettext( "Be readable (not too far away, no glare)" ) %></li>
<li class="tip"><%- gettext( "The photo on your ID must match the photo of your face" ) %></li>
<li class="tip"><%- gettext( "The name on your ID must match the name on your account below" ) %></li>
</ul>
</div>
</li>
</ol>
<div class="msg msg-retake msg-followup">
<div class="copy">
<p><%- gettext( "Photos don't meet the requirements?" ) %></p>
</div> </div>
</div>
<ul class="list-actions"> </div>
<li class="action action-retakephotos">
<a id="retake_photos_button" class="retake-photos"> <div class="wrapper-photos">
<%- gettext( "Retake Your Photos" ) %> <div class="help-tips">
</a> <h5 class="title"><%- gettext( "Photo requirements:" ) %></h5>
<ul class="list-help list-tips copy">
<li class="tip"><%- gettext( "Does the photo of you show your whole face?" ) %></li>
<li class="tip"><%- gettext( "Does the photo of you match your ID photo?" ) %></li>
<li class="tip"><%- gettext( "Is your name on your ID readable?" ) %></li>
<li class="tip"><%- _.sprintf( gettext( "Does the name on your ID match your account name: %(fullName)s?" ), { fullName: fullName } ) %>
<div class="help-tip is-expandable">
<a href="#" class="title title-expand" aria-expanded="false" role="link">
<%- gettext( "Edit Your Name" ) %>
</a>
<div class="copy expandable-area">
<p><%- gettext( "You should change the name on your account to match your ID." ) %></p>
<input type="text" name="new-name" id="new-name" placeholder=<%= fullName %>>
</div>
</div>
</li> </li>
</ul> </ul>
</div> </div>
</li> </div>
<li class="review-task review-task-name">
<h4 class="title"><%- gettext( "Check Your Name" ) %></h4>
<div class="msg msg-retake msg-followup">
<div class="copy"> <div class="copy">
<p><%- _.sprintf( gettext( "Make sure the full name on your %(platformName)s account (%(fullName)s) matches your ID. We will use this as the name on your certificate." ), { platformName: platformName, fullName: fullName } ) %></p> <p>
</div> <%- gettext( "Photos don't meet the requirements?" ) %>
<a id="retake_photos_button" class="retake-photos">
<div class="msg msg-followup"> <%- gettext( "Retake Your Photos" ) %>
<div class="help-tip is-expandable"> </a>
<h5 class="title title-expand" aria-expanded="false" role="link"> </p>
<i class="icon-caret-down expandable-icon"></i>
<%- gettext( "What if the name on my account doesn't match the name on my ID?" ) %>
</h5>
<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 %>>
</div>
</div>
</div> </div>
</div>
</ol> </div>
</div> </div>
<nav class="nav-wizard"> <nav class="nav-wizard">
<div class="prompt-verify"> <div class="prompt-verify">
<h3 class="title"><%- gettext( "Before proceeding, please confirm that your details match" ) %></h3> <h3 class="title"><%- gettext( "Before proceeding, please confirm that your photos match." ) %></h3>
<p class="copy">
<%- _.sprintf( gettext( "Once you verify your details match the requirements, you can move on to step %(stepNum)s, %(stepTitle)s." ), { stepNum: nextStepNum, stepTitle: nextStepTitle } ) %>
</p>
<ul class="list-actions">
<li class="action action-verify">
<input type="checkbox" name="match" id="confirm_pics_good" />
<label for="confirm_pics_good"><%- gettext( "Yes! My details all match." ) %></label>
</li>
</ul>
</div> </div>
<ol class="wizard-steps"> <ol class="wizard-steps">
<li class="wizard-step step-proceed"> <li class="wizard-step step-proceed">
<a id="next_step_button" class="next action-primary is-disabled" aria-hidden="true" title="Next"> <a id="next_step_button" class="next action-primary right" aria-hidden="true" title="Confirmation">
<%- _.sprintf( gettext( "Go to Step %s" ), nextStepNum ) %>: <%- nextStepTitle %> <%- gettext( "Confirmation" ) %>
</a> </a>
</li> </li>
</ol> </ol>
......
...@@ -10,11 +10,8 @@ ...@@ -10,11 +10,8 @@
<div class="controls photo-controls"> <div class="controls photo-controls">
<ul class="list-controls"> <ul class="list-controls">
<li class="control control-retake is-hidden" id="webcam_reset_button"> <li class="control control-retake is-hidden" id="webcam_reset_button">
<a class="action action-redo"> <a class="action action-redo"><%- gettext( "Retake Photo" ) %></a>
<i class="icon-undo"></i> <span class="sr"><%- gettext( "Retake" ) %></span>
</a>
</li> </li>
<li class="control control-do is-hidden" id="webcam_capture_button"> <li class="control control-do is-hidden" id="webcam_capture_button">
<a class="action action-do"> <a class="action action-do">
<i class="icon-camera"></i> <span class="sr"><%- gettext( "Take photo" ) %></span> <i class="icon-camera"></i> <span class="sr"><%- gettext( "Take photo" ) %></span>
......
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