Commit 1a6394b7 by Jonathan Piacenti

Add share modal to badge listing.

parent ccb5b6c7
"""
Serializers for badging
Serializers for Badges
"""
from rest_framework import serializers
......
......@@ -7,6 +7,7 @@ from django.core.urlresolvers import reverse
from django.http import Http404
from django.views.decorators.http import require_http_methods
from django_countries import countries
from django.contrib.staticfiles.storage import staticfiles_storage
from edxmako.shortcuts import render_to_response, marketing_link
from microsite_configuration import microsite
......@@ -87,6 +88,9 @@ def learner_profile_context(request, profile_username, user_is_staff):
'country_options': list(countries),
'find_courses_url': marketing_link('COURSES'),
'language_options': settings.ALL_LANGUAGES,
'badges_logo': staticfiles_storage.url('certificates/images/backpack-logo.png'),
'badges_icon': staticfiles_storage.url('certificates/images/ico-mozillaopenbadges.png'),
'backpack_ui_img': staticfiles_storage.url('certificates/images/backpack-ui.png'),
'platform_name': microsite.get_value('platform_name', settings.PLATFORM_NAME),
},
'disable_courseware_js': True,
......
......@@ -9,6 +9,8 @@
initialize: function (options) {
BadgeListContainer.__super__.initialize.call(this, options);
this.listView.find_courses_url = options.find_courses_url;
this.listView.badgeMeta = options.badgeMeta;
this.listView.ownProfile = options.ownProfile;
},
type: 'badge',
itemViewClass: BadgeView,
......
......@@ -17,7 +17,11 @@
row = $('<div class="row">');
this.$el.append(row);
}
var item = new BadgeView({model: badge}).render().el;
var item = new BadgeView({
model: badge,
badgeMeta: this.badgeMeta,
ownProfile: this.ownProfile
}).render().el;
row.append(item);
this.itemViews.push(item);
}, this);
......
;(function (define, undefined) {
'use strict';
define([
'gettext', 'jquery', 'underscore', 'backbone', 'moment', 'text!templates/student_profile/badge.underscore'],
function (gettext, $, _, Backbone, Moment, badgeTemplate) {
define(['gettext', 'jquery', 'underscore', 'backbone', 'moment',
'text!templates/student_profile/badge.underscore',
'js/student_profile/views/share_modal_view'],
function (gettext, $, _, Backbone, Moment, badgeTemplate, ShareModalView) {
var BadgeView = Backbone.View.extend({
initialize: function(options) {
this.context = _.extend(this.options.model.toJSON(), {
'created': new Moment(this.options.model.toJSON().created),
'ownProfile': options.ownProfile,
'badgeMeta': options.badgeMeta
});
},
attributes: {
'class': 'badge-display'
},
template: _.template(badgeTemplate),
render: function () {
var context = _.extend(this.options.model.toJSON(), {
'created': new Moment(this.options.model.toJSON().created)
events: {
'click .share-button': 'createModal'
},
createModal: function() {
var modal = new ShareModalView({
model: new Backbone.Model(this.context),
shareButton: this.shareButton
});
this.$el.html(this.template(context));
modal.$el.hide();
modal.render();
$('body').append(modal.$el);
modal.$el.fadeIn('short', 'swing', _.bind(modal.ready, modal));
},
render: function () {
this.$el.html(this.template(this.context));
this.shareButton = this.$el.find('.share-button');
return this;
}
});
......
......@@ -131,7 +131,13 @@
var badgeListContainer = new BadgeListContainer({
'attributes': {'class': 'badge-set-display'},
'collection': badgeCollection,
'find_courses_url': options.find_courses_url
'find_courses_url': options.find_courses_url,
'ownProfile': options.own_profile,
'badgeMeta': {
'badges_logo': options.badges_logo,
'backpack_ui_img': options.backpack_ui_img,
'badges_icon': options.badges_icon
}
});
var learnerProfileView = new LearnerProfileView({
......
;(function (define, undefined) {
'use strict';
define(['gettext', 'jquery', 'underscore', 'backbone', 'moment',
'text!templates/student_profile/share_modal.underscore'],
function (gettext, $, _, Backbone, Moment, badgeModalTemplate) {
var ShareModalView = Backbone.View.extend({
attributes: {
'class': 'badges-overlay'
},
events: {
'click .badges-modal': function (event) {event.stopPropagation();},
'click .badges-modal .close': 'close',
'click .badges-overlay': 'close',
'keydown': 'keyAction',
'focus .focusguard-start': 'focusGuardStart',
'focus .focusguard-end': 'focusGuardEnd'
},
focusGuardStart: function () {
// Should only be selected directly if shift-tabbing from the start, so grab last item.
this.$el.find("a").last().focus();
},
focusGuardEnd: function() {
this.$el.find(".badges-modal").focus();
},
close: function () {
this.$el.fadeOut('short', 'swing', _.bind(this.remove, this));
this.options.shareButton.focus();
},
keyAction: function (event) {
if (event.keyCode === $.ui.keyCode.ESCAPE) {
this.close();
}
},
ready: function() {
// Focusing on the modal background directly doesn't work, probably due
// to its positioning.
this.$el.find('.badges-modal').focus();
},
render: function () {
this.$el.html(_.template(badgeModalTemplate, this.model.toJSON()));
return this;
}
});
return ShareModalView;
});
}).call(this, define || RequireJS.define);
......@@ -365,6 +365,37 @@
font-weight: bold;
color: $blue-s3;
}
.share-button {
@extend %t-action3;
@extend %button-reset;
background: $gray-l6;
color: $gray-d1;
padding: ($baseline / 4) ($baseline / 2);
margin-bottom: ($baseline / 2);
display: inline-block;
border-radius: 5px;
border: 2px solid $gray-d1;
cursor: pointer;
transition: background .5s;
.share-prefix {
display: inline-block;
vertical-align: middle;
}
.share-icon-container {
display: inline-block;
img.icon-mozillaopenbadges {
max-width: 1.5em;
margin-right: .25em;
}
}
&:hover {
background: $gray-l4;
}
&:active {
box-shadow: inset 0 4px 15px 0 $black-t2;
transition: none;
}
}
}
}
.badge-placeholder {
......@@ -372,4 +403,90 @@
box-shadow: inset 0 0 4px 0 $gray-l4;
}
}
// ------------------------------
// #BADGES MODAL
// ------------------------------
.badges-overlay {
@extend %ui-depth1;
position: fixed;
top: 0;
left: 0;
background-color: $dark-trans-bg; /* dim the background */
width: 100%;
height: 100%;
vertical-align: middle;
.badges-modal {
@extend %t-copy-lead1;
@extend %ui-depth2;
color: $lighter-base-font-color;
box-sizing: content-box;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 80%;
max-width: 700px;
max-height: calc(100% - 100px);
margin-right: auto;
margin-left: auto;
border-top: rem(10) solid $blue-l2;
background: $light-gray3;
padding-right: ($baseline * 2);
padding-left: ($baseline * 2);
padding-bottom: ($baseline);
overflow-x: hidden;
.modal-header {
margin-top: ($baseline / 2);
margin-bottom: ($baseline / 2);
}
.close {
@extend %button-reset;
@extend %t-strong;
color: $lighter-base-font-color;
position: absolute;
right: ($baseline);
top: $baseline;
cursor: pointer;
padding: ($baseline / 4) ($baseline / 2);
@include transition(all $tmg-f2 ease-in-out 0s);
&:focus, &:hover {
background-color: $blue-d2;
border-radius: 3px;
color: $white;
}
}
.badges-steps {
display: table;
}
.image-container{
// Lines the image up with the content of the above list.
@include ltr {
@include padding-left(2em);
}
@include rtl {
@include padding-right(1em);
float: right;
}
}
.backpack-logo {
@include float(right);
@include margin-left($baseline);
}
}
}
.modal-hr {
display: block;
border: none;
background-color: $light-gray;
height: rem(2);
width: 100%;
}
}
......@@ -4,6 +4,20 @@
<div class="badge-details">
<div class="badge-name"><%- badge_class.display_name %></div>
<p class="badge-description"><%- badge_class.description %></p>
<% if (ownProfile) { %>
<button class="share-button">
<div class="share-icon-container">
<img class="icon icon-mozillaopenbadges" src="<%- badgeMeta.badges_icon %>" alt="<%-
interpolate(
// Translators: display_name is the name of an OpenBadges award.
gettext('Share your "%(display_name)s" award'),
{'display_name': badge_class.display_name},
true
)%>">
</div>
<div class="share-prefix" aria-hidden="true"><%- gettext("Share") %></div>
</div>
<% } %>
<div class="badge-date-stamp">
<%-
interpolate(
......
<div class="focusguard focusguard-start" tabindex="0"></div>
<div class="badges-modal" tabindex="0">
<button class="close"><i class="fa fa-close" aria-hidden="true"></i><span class="sr"><%- gettext("Close") %></span></button>
<h1 class="modal-header"><%- gettext("Share on Mozilla Backpack") %></h1>
<p class="explanation"><%- gettext("To share your certificate on Mozilla Backpack, you must first have a Backpack account. Complete the following steps to add your certificate to Backpack.") %>
</p>
<hr class="modal-hr"/>
<img class="backpack-logo" src="<%- badgeMeta.badges_logo %>" alt="">
<ol class="badges-steps">
<li class="step"><%=
interpolate(
gettext("Create a %(link_start)sMozilla Backpack%(link_end)s account, or log in to your existing account"),
{link_start: '<a href="https://backpack.openbadges.org/" target="_blank">', link_end: '</a>'},
true
)%>
</li>
<li class="step"><%=
interpolate(
gettext("%(download_link_start)sDownload this image (right-click or option-click, save as)%(link_end)s and then %(upload_link_start)supload%(link_end)s it to your backpack.</li>"), {
download_link_start: '<a class="badge-link" href="' + image_url + '" target="_blank">',
link_end: '</a>', upload_link_start: '<a href="https://backpack.openbadges.org/backpack/add" target="_blank">'
},
true
)%>
</ol>
<div class="image-container">
<img class="badges-backpack-example" src="<%- badgeMeta.backpack_ui_img %>" alt="">
</div>
</div>
<div class="focusguard focusguard-end" tabindex="0"></div>
\ No newline at end of file
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