зеркало из https://github.com/mozilla/CSOL-site.git
Change /backpack/badges to /mybadges
Remove /backpack Require login for /mybadges Add openbadger method to fetch user badges Add session to query object passed to api methods Basic /mybadges display (doesn't really work until openbadger changes are made)
This commit is contained in:
Родитель
a5a92918c2
Коммит
9d7b65d500
3
api.js
3
api.js
|
@ -27,7 +27,8 @@ function middleware (method, default_query) {
|
|||
default_query || {},
|
||||
req.query || {},
|
||||
req.body || {},
|
||||
req.params || {}
|
||||
req.params || {},
|
||||
{ session: req.session || {} } // TODO: move session to separate arg
|
||||
);
|
||||
|
||||
method(query, function(err, data) {
|
||||
|
|
|
@ -67,7 +67,7 @@ function extractUserData (user) {
|
|||
if ('home' in user) return user;
|
||||
|
||||
var userType = user.daoFactoryName.toLowerCase();
|
||||
var userHome = (userType === 'learner') ? '/backpack' : '/dashboard';
|
||||
var userHome = (userType === 'learner') ? '/mybadges' : '/dashboard';
|
||||
|
||||
return {
|
||||
id: user.id,
|
||||
|
|
|
@ -1,18 +1,14 @@
|
|||
const openbadger = require('../openbadger');
|
||||
const db = require('../db');
|
||||
const claim = db.model('Claim');
|
||||
const loggedIn = require('../middleware').loggedIn;
|
||||
|
||||
module.exports = function (app) {
|
||||
|
||||
app.get('/claim', function (req, res, next) {
|
||||
app.get('/claim', [loggedIn], function (req, res, next) {
|
||||
var claimCode = req.query.code;
|
||||
var user = res.locals.user;
|
||||
|
||||
if (!user) {
|
||||
req.session.afterLogin = req.originalUrl;
|
||||
return res.redirect('/login');
|
||||
}
|
||||
|
||||
if (!claimCode)
|
||||
return res.render('claim.html');
|
||||
claimCode = claimCode.trim();
|
||||
|
@ -42,39 +38,10 @@ module.exports = function (app) {
|
|||
|
||||
});
|
||||
|
||||
app.post('/claim', function (req, res, next) {
|
||||
app.post('/claim', [loggedIn], function (req, res, next) {
|
||||
var claimCode = req.query.code;
|
||||
var user = res.locals.user;
|
||||
|
||||
if (!user) {
|
||||
return res.redirect('/login');
|
||||
}
|
||||
|
||||
openbadger.claim({
|
||||
code: claimCode,
|
||||
email: user.email
|
||||
}, function(err, data) {
|
||||
console.log(err, data);
|
||||
if (err)
|
||||
if (err.code === 409)
|
||||
req.flash('warn', "You already have that badge.");
|
||||
else
|
||||
req.flash('error', "There has been an error claiming your badge.");
|
||||
else
|
||||
req.flash('success', "You've claimed a new badge!");
|
||||
return res.redirect('/backpack');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
app.post('/claim', function (req, res, next) {
|
||||
var claimCode = req.query.code;
|
||||
var user = res.locals.user;
|
||||
|
||||
if (!user) {
|
||||
return res.redirect('/login');
|
||||
}
|
||||
|
||||
claim.findOrCreate({
|
||||
code: claimCode,
|
||||
LearnerId: user.id
|
||||
|
@ -96,25 +63,17 @@ module.exports = function (app) {
|
|||
else
|
||||
req.flash('success', "You've claimed a new badge!");
|
||||
}
|
||||
return res.redirect('/backpack');
|
||||
return res.redirect('/mybadges');
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
app.get('/backpack', function (req, res, next) {
|
||||
var badges = [];
|
||||
|
||||
for (var i = 0; i < 7; ++i) {
|
||||
badges.push({
|
||||
thumbnail: '/media/images/badge.png',
|
||||
description: 'Badge blah in voluptate velit...',
|
||||
url: '/badges/ae784f'
|
||||
});
|
||||
}
|
||||
app.get('/mybadges', [loggedIn], openbadger.middleware('getUserBadges'), function (req, res, next) {
|
||||
var data = req.remote;
|
||||
|
||||
res.render('user/backpack.html', {
|
||||
items: badges
|
||||
items: data.badges
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -25,3 +25,12 @@ exports.session = function session (config) {
|
|||
})
|
||||
});
|
||||
};
|
||||
|
||||
exports.loggedIn = function loggedIn(req, res, next) {
|
||||
var user = req.session.user;
|
||||
if (!user) {
|
||||
req.session.afterLogin = req.originalUrl;
|
||||
return res.redirect('/login');
|
||||
}
|
||||
return next();
|
||||
}
|
||||
|
|
|
@ -146,6 +146,27 @@ var openbadger = new Api(ENDPOINT, {
|
|||
});
|
||||
},
|
||||
|
||||
getUserBadges: {
|
||||
func: function getUserBadges (query, callback) {
|
||||
var email = query.session.user.email;
|
||||
var code = query.code;
|
||||
var params = {
|
||||
auth: getJWTToken(email),
|
||||
email: email
|
||||
};
|
||||
this.get('/user', { qs: params }, function(err, data) {
|
||||
if (err)
|
||||
return callback(err, data);
|
||||
|
||||
return callback(null, {
|
||||
badges: _.map(data.badges, normalizeBadge)
|
||||
});
|
||||
});
|
||||
},
|
||||
paginate: true,
|
||||
key: 'badges'
|
||||
},
|
||||
|
||||
getBadgeFromCode: function getBadgeFromCode (query, callback) {
|
||||
var email = query.email;
|
||||
var code = query.code;
|
||||
|
@ -170,7 +191,7 @@ var openbadger = new Api(ENDPOINT, {
|
|||
this.post('/claim', { json: params }, function(err, data) {
|
||||
return callback(err, data);
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = openbadger;
|
||||
|
|
|
@ -28,8 +28,11 @@ function fakeRequest(func, config, callback) {
|
|||
|
||||
// TODO: translating config object to req data is sloppy
|
||||
var req = _.extend(
|
||||
{ __proto__: express.request,
|
||||
headers: {} },
|
||||
{
|
||||
__proto__: express.request,
|
||||
headers: {} ,
|
||||
session: config.session || {}
|
||||
},
|
||||
config
|
||||
);
|
||||
req.headers = {'x-requested-with': config.xhr ? 'XmlHttpRequest' : 'Whatever'};
|
||||
|
@ -194,6 +197,25 @@ test('api.middleware(method)', function(t) {
|
|||
);
|
||||
});
|
||||
|
||||
t.test('query object contains session', function(t) {
|
||||
var method = sinon.stub();
|
||||
var api = new Api(ORIGIN, {
|
||||
method: method
|
||||
});
|
||||
fakeRequest(
|
||||
api.middleware('method'),
|
||||
{
|
||||
session: { some: 'sessionstuff' }
|
||||
},
|
||||
function(req, res, next) {
|
||||
t.ok(method.calledWith(
|
||||
sinon.match({ session: { some: 'sessionstuff' }})
|
||||
), 'session in query obj');
|
||||
t.end();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
t.test('query object contains default params', function(t) {
|
||||
var method = sinon.stub();
|
||||
var api = new Api(ORIGIN, {
|
||||
|
@ -216,7 +238,6 @@ test('api.middleware(method)', function(t) {
|
|||
fakeRequest(
|
||||
api.middleware('method'),
|
||||
function(req, res, next) {
|
||||
console.log(req);
|
||||
t.same(req.remote, { result: 1 }, 'req.remote');
|
||||
t.ok(next.calledOnce, 'next');
|
||||
t.end();
|
||||
|
@ -342,7 +363,6 @@ test('api.get', function(t) {
|
|||
|
||||
api.get('/foo', { some: 'params' }, function(){});
|
||||
t.ok(get.calledOnce, 'called');
|
||||
console.log(get.args);
|
||||
t.ok(get.calledWith(
|
||||
sinon.match(ORIGIN + '/foo'),
|
||||
sinon.match({ some: 'params' })
|
||||
|
|
|
@ -33,16 +33,13 @@
|
|||
{% if user %}
|
||||
{% if user.type == 'learner' %}
|
||||
<li class="dropdown backpack{% if navItem == 'backpack' %} active{% endif %}">
|
||||
<a href="/backpack" class="dropdown-toggle" role="button" data-toggle="dropdown" id="backpack-menu-toggle">My Backpack <i class="caret"></i></a>
|
||||
<a class="dropdown-toggle" role="button" data-toggle="dropdown" id="backpack-menu-toggle">My Backpack <i class="caret"></i></a>
|
||||
<ul class="dropdown-menu" role="menu" id="backpack-menu" aria-labelledby="backpack-menu-toggle">
|
||||
<li role="presentation"{% if subNavItem == 'badges' %} class="active"{% endif %}>
|
||||
<a role="menuitem" tabindex="-1" href="/backpack/badges">My Badges</a>
|
||||
<a role="menuitem" tabindex="-1" href="/mybadges">My Badges</a>
|
||||
</li>
|
||||
<li role="presentation"{% if subNavItem == 'badges' %} class="active"{% endif %}>
|
||||
<a role="menuitem" tabindex="-1" href="/backpack/favorites">My Favorites</a>
|
||||
</li>
|
||||
<li role="presentation"{% if subNavItem == 'badges' %} class="active"{% endif %}>
|
||||
<a role="menuitem" tabindex="-1" href="/backpack/applications">My Applications</a>
|
||||
<a role="menuitem" tabindex="-1" href="/myapplications">My Applications</a>
|
||||
</li>
|
||||
<li class="divider" role="presentation" aria-hidden="true"></li>
|
||||
<li role="presentation">
|
||||
|
|
|
@ -3,116 +3,26 @@
|
|||
{% set navItem = 'backpack' %}
|
||||
|
||||
{% block list %}
|
||||
<li class="span3">
|
||||
<figure class="thumbnail">
|
||||
<div class="status awarded">
|
||||
<img src="/media/images/icon_status_awarded.png" alt="Awarded"/>Awarded
|
||||
</div><!-- .status -->
|
||||
|
||||
<a href="/badges/ae784f">
|
||||
<img src="http://placehold.it/180x180">
|
||||
<span class="new">New</span>
|
||||
</a>
|
||||
<figcaption class="caption clearfix">
|
||||
<p>Pulvinar? Phasellus eu sagittis adipiscing tristique massa.</p>
|
||||
|
||||
<p class="pull-left">
|
||||
<a href="#trashModal" data-toggle="modal" class="btn show-tooltip" title="Trash"><i class="icon-trash"></i></a>
|
||||
</p>
|
||||
<p class="pull-right">
|
||||
<a href="#shareModal" data-toggle="modal" class="btn show-tooltip" title="Share"><i class="icon-share-alt"></i></a>
|
||||
<a href="/badges/ae784f" class="btn">Details</a>
|
||||
</p>
|
||||
</figcaption>
|
||||
</figure>
|
||||
</li>
|
||||
|
||||
<li class="span3">
|
||||
<figure class="thumbnail">
|
||||
<div class="status queued">
|
||||
<img src="/media/images/icon_status_queue.png" alt="In Queue"/>In Queue
|
||||
</div><!-- .status -->
|
||||
|
||||
<a href="/badges/ae784f">
|
||||
<img src="http://placehold.it/180x180">
|
||||
<span class="new">New</span>
|
||||
</a>
|
||||
<figcaption class="caption clearfix">
|
||||
<p>Pulvinar? Phasellus eu sagittis adipiscing tristique massa.</p>
|
||||
|
||||
<p class="pull-left">
|
||||
<a href="#trashModal" data-toggle="modal" class="btn show-tooltip" title="Trash"><i class="icon-trash"></i></a>
|
||||
</p>
|
||||
<p class="pull-right">
|
||||
<a href="#shareModal" data-toggle="modal" class="btn show-tooltip" title="Share"><i class="icon-share-alt"></i></a>
|
||||
<a href="/badges/ae784f" class="btn">Details</a>
|
||||
</p>
|
||||
</figcaption>
|
||||
</figure>
|
||||
</li>
|
||||
|
||||
<li class="span3">
|
||||
<figure class="thumbnail">
|
||||
<div class="status reviewed">
|
||||
<img src="/media/images/icon_status_reviewed.png" alt="Reviewed"/>Reviewed
|
||||
<div class="favorite"></div>
|
||||
</div><!-- .status -->
|
||||
|
||||
<a href="/badges/ae784f">
|
||||
<img src="http://placehold.it/180x180">
|
||||
<span class="new">New</span>
|
||||
</a>
|
||||
<figcaption class="caption clearfix">
|
||||
<p>Pulvinar? Phasellus eu sagittis adipiscing tristique massa.</p>
|
||||
|
||||
<p class="pull-left">
|
||||
<a href="#trashModal" data-toggle="modal" class="btn show-tooltip" title="Trash"><i class="icon-trash"></i></a>
|
||||
</p>
|
||||
<p class="pull-right">
|
||||
<a href="#shareModal" data-toggle="modal" class="btn show-tooltip" title="Share"><i class="icon-share-alt"></i></a>
|
||||
<a href="/badges/ae784f" class="btn">Details</a>
|
||||
</p>
|
||||
</figcaption>
|
||||
</figure>
|
||||
</li>
|
||||
|
||||
<li class="span3">
|
||||
<figure class="thumbnail">
|
||||
<div class="status favorite">
|
||||
<img src="/media/images/icon_status_favorite.png" alt="Favorite"/>Favorite
|
||||
</div><!-- .status -->
|
||||
|
||||
<a href="/badges/ae784f">
|
||||
<img src="http://placehold.it/180x180">
|
||||
<span class="new">New</span>
|
||||
</a>
|
||||
<figcaption class="caption clearfix">
|
||||
<p>Pulvinar? Phasellus eu sagittis adipiscing tristique massa.</p>
|
||||
|
||||
<p class="pull-left">
|
||||
<a href="#trashModal" data-toggle="modal" class="btn show-tooltip" title="Trash"><i class="icon-trash"></i></a>
|
||||
</p>
|
||||
<p class="pull-right">
|
||||
<a href="#shareModal" data-toggle="modal" class="btn show-tooltip" title="Share"><i class="icon-share-alt"></i></a>
|
||||
<a href="/badges/ae784f" class="btn">Details</a>
|
||||
</p>
|
||||
</figcaption>
|
||||
</figure>
|
||||
</li>
|
||||
|
||||
<li class="span3">
|
||||
<figure class="thumbnail">
|
||||
<a href="/claim"><img src="/media/images/add-badge.png"></a>
|
||||
<figcaption class="caption">
|
||||
<p>Claim another badge!</p>
|
||||
<p class="text-right"><a href="/claim" class="btn">+1</a></p>
|
||||
</figcaption>
|
||||
</figure>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
{{ super() }}
|
||||
<li class="span3">
|
||||
<figure class="thumbnail">
|
||||
<a href="/claim"><img src="/media/images/add-badge.png"></a>
|
||||
<figcaption class="caption">
|
||||
<p>Claim another badge!</p>
|
||||
<p class="text-right"><a href="/claim" class="btn">+1</a></p>
|
||||
</figcaption>
|
||||
</figure>
|
||||
</li>
|
||||
{% endblock %}
|
||||
|
||||
{% block item_actions %}
|
||||
{#
|
||||
{{ super() }}
|
||||
<a class="btn show-tooltip" title="Add to your favorites" href="{{ item.url }}/favorite"><i class="icon-heart"></i></a>
|
||||
#}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block modal %}
|
||||
|
||||
<!-- Modal -->
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
{% extends 'layout.html' %}
|
||||
{% set navitem = 'backpack' %}
|
||||
{% set pageTitle = badge.name %}
|
||||
|
||||
{% block content %}
|
||||
hooray
|
||||
{% endblock %}
|
Загрузка…
Ссылка в новой задаче