Merge branch 'ormsbee/verifyuser' into ormsbee/verifyuser_func

Conflicts:
	lms/djangoapps/verify_student/models.py
	lms/djangoapps/verify_student/tests/test_models.py
	lms/djangoapps/verify_student/tests/test_views.py
	lms/djangoapps/verify_student/urls.py
	lms/djangoapps/verify_student/views.py
	lms/envs/dev.py
	lms/templates/verify_student/face_upload.html
	lms/templates/verify_student/photo_id_upload.html
	lms/urls.py
This commit is contained in:
David Ormsbee
2013-08-22 14:07:08 -04:00
14 changed files with 963 additions and 9 deletions

View File

@@ -0,0 +1,23 @@
<%! from django.utils.translation import ugettext as _ %>
<%! from django.core.urlresolvers import reverse %>
<%inherit file="../main.html" />
<%block name="content">
<form method="post" name="enrollment_mode_form" id="enrollment_mode_form">
% if "audit" in modes:
<div>
<input type="submit" name="mode" value="Select Audit" />
</div>
<br/>
% endif
% if "verified" in modes:
<div>
<input type="submit" name="mode" value="Select Certificate" />
</div>
% endif
<input type="hidden" name="csrfmiddlewaretoken" value="${ csrf_token }">
</form>
</%block>

View File

@@ -0,0 +1,96 @@
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding model 'SoftwareSecurePhotoVerification'
db.create_table('verify_student_softwaresecurephotoverification', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('status', self.gf('model_utils.fields.StatusField')(default='created', max_length=100, no_check_for_status=True)),
('status_changed', self.gf('model_utils.fields.MonitorField')(default=datetime.datetime.now, monitor=u'status')),
('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])),
('name', self.gf('django.db.models.fields.CharField')(max_length=255, blank=True)),
('face_image_url', self.gf('django.db.models.fields.URLField')(max_length=255, blank=True)),
('photo_id_image_url', self.gf('django.db.models.fields.URLField')(max_length=255, blank=True)),
('receipt_id', self.gf('django.db.models.fields.CharField')(max_length=255, db_index=True)),
('created_at', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, db_index=True, blank=True)),
('updated_at', self.gf('django.db.models.fields.DateTimeField')(auto_now=True, db_index=True, blank=True)),
('submitted_at', self.gf('django.db.models.fields.DateTimeField')(null=True, db_index=True)),
('reviewing_user', self.gf('django.db.models.fields.related.ForeignKey')(default=None, related_name='photo_verifications_reviewed', null=True, to=orm['auth.User'])),
('reviewing_service', self.gf('django.db.models.fields.CharField')(max_length=255, blank=True)),
('error_msg', self.gf('django.db.models.fields.TextField')(blank=True)),
('error_code', self.gf('django.db.models.fields.CharField')(max_length=50, blank=True)),
('photo_id_key', self.gf('django.db.models.fields.TextField')(max_length=1024)),
))
db.send_create_signal('verify_student', ['SoftwareSecurePhotoVerification'])
def backwards(self, orm):
# Deleting model 'SoftwareSecurePhotoVerification'
db.delete_table('verify_student_softwaresecurephotoverification')
models = {
'auth.group': {
'Meta': {'object_name': 'Group'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
'auth.permission': {
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'verify_student.softwaresecurephotoverification': {
'Meta': {'ordering': "['-created_at']", 'object_name': 'SoftwareSecurePhotoVerification'},
'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'db_index': 'True', 'blank': 'True'}),
'error_code': ('django.db.models.fields.CharField', [], {'max_length': '50', 'blank': 'True'}),
'error_msg': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'face_image_url': ('django.db.models.fields.URLField', [], {'max_length': '255', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'photo_id_image_url': ('django.db.models.fields.URLField', [], {'max_length': '255', 'blank': 'True'}),
'photo_id_key': ('django.db.models.fields.TextField', [], {'max_length': '1024'}),
'receipt_id': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
'reviewing_service': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
'reviewing_user': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'photo_verifications_reviewed'", 'null': 'True', 'to': "orm['auth.User']"}),
'status': ('model_utils.fields.StatusField', [], {'default': "'created'", 'max_length': '100', u'no_check_for_status': 'True'}),
'status_changed': ('model_utils.fields.MonitorField', [], {'default': 'datetime.datetime.now', u'monitor': "u'status'"}),
'submitted_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'db_index': 'True'}),
'updated_at': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'db_index': 'True', 'blank': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
}
}
complete_apps = ['verify_student']

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,38 @@
/*
* responsive-carousel keyboard extension
* https://github.com/filamentgroup/responsive-carousel
*
* Copyright (c) 2012 Filament Group, Inc.
* Licensed under the MIT, GPL licenses.
*/
(function($) {
var pluginName = "carousel",
initSelector = "." + pluginName,
navSelector = "." + pluginName + "-nav a",
buffer,
keyNav = function( e ) {
clearTimeout( buffer );
buffer = setTimeout(function() {
var $carousel = $( e.target ).closest( initSelector );
if( e.keyCode === 39 || e.keyCode === 40 ){
$carousel[ pluginName ]( "next" );
}
else if( e.keyCode === 37 || e.keyCode === 38 ){
$carousel[ pluginName ]( "prev" );
}
}, 200 );
if( 37 <= e.keyCode <= 40 ) {
e.preventDefault();
}
};
// Touch handling
$( document )
.on( "click", navSelector, function( e ) {
$( e.target )[ 0 ].focus();
})
.on( "keydown", navSelector, keyNav );
}(jQuery));

View File

@@ -9,7 +9,8 @@
@import 'base/reset';
@import 'vendor/font-awesome';
@import 'vendor/responsive-carousel/responsive-carousel';
@import 'vendor/responsive-carousel/responsive-carousel.slide';
// BASE *default edX offerings*
// ====================
@@ -36,12 +37,18 @@
// base - assets
@import 'base/font_face';
@import 'base/extends';
@import 'base/animations';
@import 'base/animations';
// base - starter
@import 'base/base';
// shared - course
// base - elements
@import 'elements/typography';
// base - specific views
@import 'views/verification';
// shared - course
@import 'shared/forms';
@import 'shared/footer';
@import 'shared/header';
@@ -67,7 +74,7 @@
@import 'multicourse/help';
@import 'multicourse/edge';
// applications
// applications
@import 'discussion';
@import 'news';

View File

@@ -1,3 +1,6 @@
// lms - utilities - mixins and extends
// ====================
// mixins - font sizing
@mixin font-size($sizeValue: 16){
font-size: $sizeValue + px;
@@ -44,6 +47,9 @@
}
//-----------------
// Theme Mixin Styles
//-----------------

View File

@@ -9,6 +9,7 @@ $fg-max-columns: 12;
$fg-max-width: 1400px;
$fg-min-width: 810px;
// fonts
$sans-serif: 'Open Sans', $verdana;
$monospace: Monaco, 'Bitstream Vera Sans Mono', 'Lucida Console', monospace;
$body-font-family: $sans-serif;
@@ -197,4 +198,14 @@ $homepage-bg-image: '../images/homepage-bg.jpg';
$login-banner-image: url(../images/bg-banner-login.png);
$register-banner-image: url(../images/bg-banner-register.png);
$video-thumb-url: '../images/courses/video-thumb.jpg';
$video-thumb-url: '../images/courses/video-thumb.jpg';
//-----------------
// Newer variables ported from Studio
//-----------------
// fonts
$f-serif: 'Bree Serif', Georgia, Cambria, 'Times New Roman', Times, serif;
$f-sans-serif: 'Open Sans','Helvetica Neue', Helvetica, Arial, sans-serif;
$f-monospace: 'Bitstream Vera Sans Mono', Consolas, Courier, monospace;

View File

@@ -0,0 +1,178 @@
// lms - elements - typography
// ====================
// Scale - (6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 21, 24, 36, 48, 60, 72)
// headings/titles
.t-title {
font-family: $f-sans-serif;
}
.t-title1 {
@extend .t-title;
@include font-size(60);
@include line-height(60);
}
.t-title2 {
@extend .t-title;
@include font-size(48);
@include line-height(48);
}
.t-title3 {
@include font-size(36);
@include line-height(36);
}
.t-title4 {
@extend .t-title;
@include font-size(24);
@include line-height(24);
}
.t-title5 {
@extend .t-title;
@include font-size(18);
@include line-height(18);
}
.t-title6 {
@extend .t-title;
@include font-size(16);
@include line-height(16);
}
.t-title7 {
@extend .t-title;
@include font-size(14);
@include line-height(14);
}
.t-title8 {
@extend .t-title;
@include font-size(12);
@include line-height(12);
}
.t-title9 {
@extend .t-title;
@include font-size(11);
@include line-height(11);
}
// ====================
// copy
.t-copy {
font-family: $f-sans-serif;
}
.t-copy-base {
@extend .t-copy;
@include font-size(16);
@include line-height(16);
}
.t-copy-lead1 {
@extend .t-copy;
@include font-size(18);
@include line-height(18);
}
.t-copy-lead2 {
@extend .t-copy;
@include font-size(24);
@include line-height(24);
}
.t-copy-sub1 {
@extend .t-copy;
@include font-size(14);
@include line-height(14);
}
.t-copy-sub2 {
@extend .t-copy;
@include font-size(12);
@include line-height(12);
}
// ====================
// actions/labels
.t-action1 {
@include font-size(18);
@include line-height(18);
}
.t-action2 {
@include font-size(16);
@include line-height(16);
}
.t-action3 {
@include font-size(14);
@include line-height(14);
}
.t-action4 {
@include font-size(12);
@include line-height(12);
}
// ====================
// code
.t-code {
font-family: $f-monospace;
}
// ====================
// icons
.t-icon1 {
@include font-size(48);
@include line-height(48);
}
.t-icon2 {
@include font-size(36);
@include line-height(36);
}
.t-icon3 {
@include font-size(24);
@include line-height(24);
}
.t-icon4 {
@include font-size(18);
@include line-height(18);
}
.t-icon5 {
@include font-size(16);
@include line-height(16);
}
.t-icon6 {
@include font-size(14);
@include line-height(14);
}
.t-icon7 {
@include font-size(12);
@include line-height(12);
}
.t-icon8 {
@include font-size(11);
@include line-height(11);
}
.t-icon9 {
@include font-size(10);
@include line-height(10);
}

View File

@@ -0,0 +1,20 @@
/*
* responsive-carousel
* https://github.com/filamentgroup/responsive-carousel
*
* Copyright (c) 2012 Filament Group, Inc.
* Licensed under the MIT, GPL licenses.
*/
.carousel {
width: 100%;
position: relative;
}
.carousel .carousel-item {
display: none;
}
.carousel .carousel-active {
display: block;
}
.carousel .carousel-nav:nth-child(2) {
display: none;
}

View File

@@ -0,0 +1,61 @@
/*
* responsive-carousel
* https://github.com/filamentgroup/responsive-carousel
*
* Copyright (c) 2012 Filament Group, Inc.
* Licensed under the MIT, GPL licenses.
*/
.carousel-slide {
position: relative;
overflow: hidden;
-webkit-transform: translate3d(0, 0, 0);
-moz-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
-o-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
}
.carousel-slide .carousel-item {
position: absolute;
left: 100%;
top: 0;
width: 100%; /* necessary for non-active slides */
display: block; /* overrides basic carousel styles */
z-index: 1;
-webkit-transition: left .2s ease;
-moz-transition: left .2s ease;
-ms-transition: left .2s ease;
-o-transition: left .2s ease;
transition: left .2s ease;
}
.carousel-no-transition .carousel-item {
-webkit-transition: none;
-moz-transition: none;
-ms-transition: none;
-o-transition: none;
transition: none;
}
.carousel-slide .carousel-active {
left: 0;
position: relative;
z-index: 2;
}
.carousel-slide .carousel-in {
left: 0;
}
.carousel-slide-reverse .carousel-out {
left: 100%;
}
.carousel-slide .carousel-out,
.carousel-slide-reverse .carousel-in {
left: -100%;
}
.carousel-slide-reverse .carousel-item {
-webkit-transition: left .1s ease;
-moz-transition: left .1s ease;
-ms-transition: left .1s ease;
-o-transition: left .1s ease;
transition: left .1s ease;
}
.carousel-slide-reverse .carousel-active {
left: 0;
}

View File

@@ -0,0 +1,166 @@
// lms - views - verification flow
// ====================
body.register.verification {
font-family: 'Open Sans', sans-serif;
h1, h2, h3, h4, h5, h6, p {
font-family: 'Open Sans', sans-serif;
}
.page-header {
.title {
@extend .t-title5;
margin-bottom: $baseline;
font-weight: bold;
}
}
.title {
@extend .t-title9;
margin-bottom: ($baseline/2);
font-weight: bold;
}
.select {
@include clearfix();
.block {
float: left;
margin: 0 $baseline $baseline 0;
background-color: #eee;
padding: $baseline;
width: 60%;
.title {
@extend .t-title7;
}
}
.tips {
float: right;
width: 32%;
}
}
.progress {
.progress-step {
border: 1px solid #eee;
display: inline-block;
padding: ($baseline/2) $baseline;
}
}
// for dev placement only
.placeholder-cam,
.placeholder-photo {
height: 300px;
background-color: #eee;
position: relative;
p {
position: absolute;
top: 40%;
left: 40%;
color: #ccc;
}
}
.block-photo {
@include clearfix();
background-color: $white;
.title {
font-weight: bold;
}
.wrapper-up,
.wrapper-down {
@include clearfix();
}
.cam {
width: 45%;
float: left;
padding-right: $baseline;
}
.photo-controls {
background-color: #ddd;
.controls-list {
margin: 0;
padding: ($baseline*.25) ($baseline*.75);
list-style-type: none;
.control {
display: inline-block;
.action {
@extend .button-primary;
display: block;
background-color: $blue;
color: $white;
padding: ($baseline*.25) ($baseline*.5);
border: none;
&:hover {
}
}
}
}
}
.faq {
width: 45%;
float: left;
padding-right: $baseline;
dt {
font-weight: bold;
padding: 0 0 ($baseline/2) 0;
}
dd {
margin: 0;
padding: 0 0 $baseline 0;
}
}
}
.photo-tips {
width: 45%;
float: left;
}
.actions {
width: 45%;
float: right;
}
.review-photo {
width: 45%;
float: left;
}
#review-facephoto {
margin-right: $baseline;
}
}

View File

@@ -92,6 +92,9 @@
<%static:js group='application'/>
<%static:js group='module-js'/>
<script src="${static.url('js/vendor/responsive-carousel/responsive-carousel.js')}"></script>
<script src="${static.url('js/vendor/responsive-carousel/responsive-carousel.keybd.js')}"></script>
<%block name="js_extra"/>
</body>
</html>

View File

@@ -2,10 +2,277 @@
<%! from django.core.urlresolvers import reverse %>
<%inherit file="../main.html" />
<%block name="bodyclass">register verification photos</%block>
<%block name="js_extra">
<!-- please move link to js/vendor/responsive-carousel/responsive-carousel.js from main.html to here -->
<script type="text/javascript">
$(document).ready(function() {
$( ".carousel-nav" ).addClass('sr');
});
</script>
</%block>
<%block name="content">
<div class="container">
<h1>Face Upload!</h1>
<header class="page-header">
<h2 class="title">You are registering for [coursename] (ID Verified)</h2>
</header>
<section class="progress">
<h3 class="sr">Your Progress</h3>
<ol>
<li class="progress-step current" id="progress-step1"><span class="sr">Current: </span>Step 1 Take Your Photo</li>
<li class="progress-step" id="progress-step2">Step 2 ID Photo</li>
<li class="progress-step" id="progress-step3">Step 3 Review</li>
<li class="progress-step" id="progress-step4">Step 4 Payment</li>
<li class="progress-step" id="progress-step5">Finished Confirmation</li>
</ol>
</section>
<section class="wrapper carousel" data-transition="slide">
<div id="wrapper-facephoto" class="block-photo">
<h3 class="title">Take Your Photo</h3>
<p>Use your webcam to take a picture of your face so we can match it with the picture on your ID.</p>
<div class="wrapper-up">
<div id="facecam" class="cam">
<div class="placeholder-cam">
<!-- cam image -->
<p>cam image</p>
</div>
<div class="controls photo-controls">
<ul class="controls-list">
<li class="control control-do">
<a class="action action-do" href=""><i class="icon-camera"></i> <span class="sr">Take photo</span></a>
</li>
<li class="control control-redo">
<a class="action action-redo" href=""><i class="icon-undo"></i> <span class="sr">Retake</span></a>
</li>
<li class="control control-approve">
<a class="action action-approve" href=""><i class="icon-ok"></i> <span class="sr">Looks good</span></a>
</li>
</ul>
</div>
</div>
<div class="photo-tips facetips">
<h4>Tips on taking a successful photo</h4>
<ul>
<li>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.</li>
<li>Maecenas faucibus mollis interdum.</li>
<li>Nullam id dolor id nibh ultricies vehicula ut id elit.</li>
<li>Cras mattis consectetur purus sit amet fermentum.</li>
</ul>
</div>
</div>
<div class="wrapper-down">
<div class="faq facefaq">
<h4 class="sr">Common Questions</h4>
<dl>
<dt>Cras justo odio, dapibus ac facilisis in, egestas eget quam.</dt>
<dd>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</dd>
<dt>Vestibulum id ligula porta felis euismod semper.</dt>
<dt>Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit.</dt>
<dd>Aenean eu leo quam.</dd>
<dt>Pellentesque ornare sem lacinia quam venenatis vestibulum.</dt>
<dd>Maecenas faucibus mollis interdum.</dd>
</dl>
</div>
<div class="actions">
<ul>
<li class="action action-next">
<a class="next" href="#next" aria-hidden="true" title="Next">Go to Step 2: Take ID Photo</a>
<p class="tips">Once you verify your photo looks good, you can move on to step 2.</p>
</li>
</ul>
</div>
</div>
</div>
<div id="wrapper-idphoto" class="block-photo">
<h3 class="title">Take Your Photo</h3>
<p>Use your webcam to take a picture of your face so we can match it with the picture on your ID.</p>
<div class="wrapper-up">
<div id="idcam" class="cam">
<div class="placeholder-cam">
<!-- cam image -->
<p>cam image</p>
</div>
<div class="controls photo-controls">
<ul class="controls-list">
<li class="control control-do">
<a class="action action-do" href=""><i class="icon-camera"></i> <span class="sr">Take photo</span></a>
</li>
<li class="control control-redo">
<a class="action action-redo" href=""><i class="icon-undo"></i> <span class="sr">Retake</span></a>
</li>
<li class="control control-approve">
<a class="action action-approve" href=""><i class="icon-ok"></i> <span class="sr">Looks good</span></a>
</li>
</ul>
</div>
</div>
<div class="photo-tips idtips">
<h4>Tips on taking a successful photo</h4>
<ul>
<li>Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor auctor.</li>
<li>Maecenas faucibus mollis interdum.</li>
<li>Nullam id dolor id nibh ultricies vehicula ut id elit.</li>
<li>Cras mattis consectetur purus sit amet fermentum.</li>
</ul>
</div>
</div>
<div class="wrapper-down">
<div class="faq idfaq">
<h4 class="sr">Common Questions</h4>
<dl>
<dt>Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit.</dt>
<dd>Aenean eu leo quam.</dd>
<dt>Pellentesque ornare sem lacinia quam venenatis vestibulum.</dt>
<dd>Maecenas faucibus mollis interdum.</dd>
<dt>Cras justo odio, dapibus ac facilisis in, egestas eget quam.</dt>
<dd>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</dd>
<dt>Vestibulum id ligula porta felis euismod semper.</dt>
</dl>
</div>
<div class="actions">
<ul>
<li class="action action-next">
<a class="next" href="#next" aria-hidden="true" title="Next">Go to Step 3: Review Your Info</a>
<p class="tips">Once you verify your ID photo looks good, you can move on to step 3.</p>
</li>
</ul>
</div>
</div>
</div>
<div id="wrapper-review" class="block-photo">
<h3 class="title">Verify Your Submission</h3>
<p>Make sure we can verify your identity with the photos and information below.</p>
<div class="review-name">
<h3>Check Your Name</h3>
<p>Make sure your full name on your edX account, [User Name], matches your ID. We will also use this as the name on your certificate.</p>
<p><a href="#">Edit my name</a></p>
</div>
<div class="wrapper-up">
<div id="review-facephoto" class="review-photo">
<div class="placeholder-photo">
<!-- photo image -->
</div>
<h4>The photo above needs to meet the following requirements:</h4>
<ul>
<li>Be well lit</li>
<li>Show your whole face</li>
<li>Match your ID</li>
</ul>
</div>
<div id="review-idphoto" class="review-photo">
<div class="placeholder-photo">
<!-- photo image -->
</div>
<h4>The photo above needs to meet the following requirements:</h4>
<ul>
<li>Be readable (not too far away, no glare)</li>
<li>Show your name</li>
<li>Match the photo of your face and your name above</li>
</ul>
</div>
</div>
<div class="next">
<p>Photos don't meet the requirements? <a href="">Retake the photos</a>.</p>
<input type="checkbox" name="match" /> <label for="match">Yes! My details all match.</label>
<div class="actions">
<ul>
<li class="action action-next">
<a href="#">Go to Step 4: Secure Payment</a>
<p class="tips">Once you verify your details match the requirements, you can move on to step 4, payment on our secure server.</p>
</li>
</ul>
</div>
</div>
</section>
<section class="support">
<p>More questions? <a rel="external" href="">Check out our FAQs.</a></p>
<p>Change your mind? <a href="">You can always Audit the course for free without verifying.</a></p>
</section>
</div>
<section id="edit-name" class="modal">
<header>
<h4>${_("Edit Your Full Name")}</h4>
</header>
<form id="course-checklists" class="course-checklists" method="post" action="">
<div role="alert" class="status message submission-error" tabindex="-1">
<p class="message-title">${_("The following error occured while editing your name:")}
<span class="message-copy"> </span>
</p>
</div>
<p>
<label for="name">${_('Full Name')}</label>
<input id="name" type="text" name="name" value="" placeholder="${_('example: Jane Doe')}" required aria-required="true" />
</p>
<div class="actions">
<button class="action action-primary" type="submit">${_("Save")}</button>
<button class="action action-secondary action-cancel">${_("Cancel")}</button>
</div>
</form>
<a href="#" data-dismiss="modal" rel="view" class="action action-close action-editname-close">
<i class="icon-remove-sign"></i>
<span class="label">close</span>
</a>
</section>
<a href="${reverse('verify_student/photo_id_upload')}">Upload Photo ID</a>
</%block>

View File

@@ -2,10 +2,84 @@
<%! from django.core.urlresolvers import reverse %>
<%inherit file="../main.html" />
<%block name="bodyclass">register verification select</%block>
<%block name="content">
<div class="container">
<section class="wrapper">
<h1>Photo ID Upload!</h1>
<header class="page-header">
<h2 class="title">You are registering for [coursename] (ID Verified)</h2>
</header>
<a href="${reverse('verify_student/final_verification')}">Final Verification</a>
<h3 class="title">Select your track:</h3>
<div class="select">
<div class="block block-audit">
<h4 class="title">Audit</h4>
<p>Sign up to audit this course for free and track your own progress.</p>
<p class="btn">
<a href="">Select Audit</a>
</p>
</div>
<div class="select">
<div class="block block-cert">
<h4 class="title">Certificate of Achievement</h4>
<p>Sign up as a verified student and work toward a Certificate of Achievement.</p>
<dl>
<dt>
Select your contribution for this course (in USD):
</dt>
<dd>
<ul>
<li>
<input type="radio" name="contribution-25" id="contribution"> <label for="contribution-25">$25</label>
</li>
<li>
<input type="radio" name="contribution-50" id="contribution"> <label for="contribution-50">$50</label>
</li>
<li>
<input type="radio" name="contribution-100" id="contribution"> <label for="contribution-100">$100</label>
</li>
<li>
<input type="radio" name="contribution-other" id="contribution"> <label for="contribution-other">Other</label>
</li>
<li>
<label for="contribution-other-amt">Other Amount</label> <input type="text" name="contribution-other" id="contribution-other-amt">
</li>
</ul>
</dd>
</dl>
<a href="">Why do I have to pay? What if I don't meet all the requirements?</a>
<img src="" />
<p>
<a href="">What is an ID Verified Certificate?</a>
</p>
<p class="btn">
<a href="${reverse('verify_student/show_requirements')}">Select Certificate</a>
</p>
</div>
<div class="tips">
<p>
To register for a Verified Certificate of Achievement option, you will need a webcam, a credit or debit card, and an ID. <a href="">View requirements</a>
</p>
</div>
</div>
<p><i class="icon-question-sign"></i> Have questions? <a href="">Check out our FAQs.</a></p>
<p>Not the course you wanted? <a href="">Return to our course listings</a>.</p>
</section>
</div>
</%block>