refactor challenge and challengeMap

This commit is contained in:
Berkeley Martinez
2015-06-02 19:02:54 -07:00
parent 956a2b915e
commit e7d01424e9
4 changed files with 441 additions and 452 deletions

View File

@ -57,6 +57,9 @@
"less": "~1.7.5", "less": "~1.7.5",
"less-middleware": "~2.0.1", "less-middleware": "~2.0.1",
"lodash": "~2.4.1", "lodash": "~2.4.1",
"loopback": "^2.18.0",
"loopback-boot": "^2.8.0",
"loopback-connector-mongodb": "^1.10.0",
"lusca": "~1.0.2", "lusca": "~1.0.2",
"method-override": "~2.3.0", "method-override": "~2.3.0",
"moment": "~2.10.2", "moment": "~2.10.2",

View File

@ -31,33 +31,13 @@
*/ */
var R = require('ramda'), var R = require('ramda'),
express = require('express'),
Challenge = require('../../common/models/Challenge'),
User = require('../../common/models/User'),
resources = require('../resources/resources'), resources = require('../resources/resources'),
userMigration = require('../resources/middleware').userMigration, userMigration = require('../resources/middleware').userMigration,
MDNlinks = require('../../seed_data/bonfireMDNlinks'); MDNlinks = require('../../seed_data/bonfireMDNlinks');
var router = express.Router();
var challengeMapWithNames = resources.getChallengeMapWithNames(); var challengeMapWithNames = resources.getChallengeMapWithNames();
var challengeMapWithIds = resources.getChallengeMapWithIds(); var challengeMapWithIds = resources.getChallengeMapWithIds();
router.get(
'/challenges/next-challenge',
userMigration,
returnNextChallenge
);
router.get(
'/challenges/:challengeName',
userMigration,
returnIndividualChallenge
);
router.get('/challenges/', userMigration, returnCurrentChallenge);
router.post('/completed-challenge/', completedChallenge);
router.post('/completed-zipline-or-basejump', completedZiplineOrBasejump);
router.post('/completed-bonfire', completedBonfire);
function getMDNlinks(links) { function getMDNlinks(links) {
// takes in an array of links, which are strings // takes in an array of links, which are strings
@ -73,278 +53,300 @@ function getMDNlinks(links) {
return populatedLinks; return populatedLinks;
} }
function returnNextChallenge(req, res, next) { module.exports = function(app) {
if (!req.user) { var router = app.Router();
return res.redirect('../challenges/learn-how-free-code-camp-works'); var Challenge = app.models.Challenge;
} var User = app.models.User;
var completed = req.user.completedChallenges.map(function (elem) {
return elem._id;
});
req.user.uncompletedChallenges = resources.allChallengeIds() router.get(
.filter(function (elem) { '/challenges/next-challenge',
if (completed.indexOf(elem) === -1) { userMigration,
return elem; returnNextChallenge
} );
});
// find the user's current challenge and block router.get(
// look in that block and find the index of their current challenge '/challenges/:challengeName',
// if index + 1 < block.challenges.length userMigration,
// serve index + 1 challenge returnIndividualChallenge
// otherwise increment block key and serve the first challenge in that block );
// unless the next block is undefined, which means no next block
var nextChallengeName;
var challengeId = String(req.user.currentChallenge.challengeId); router.get('/challenges/', userMigration, returnCurrentChallenge);
var challengeBlock = req.user.currentChallenge.challengeBlock; router.post('/completed-challenge/', completedChallenge);
var indexOfChallenge = challengeMapWithIds[challengeBlock] router.post('/completed-zipline-or-basejump', completedZiplineOrBasejump);
.indexOf(challengeId); router.post('/completed-bonfire', completedBonfire);
if (indexOfChallenge + 1 function returnNextChallenge(req, res, next) {
< challengeMapWithIds[challengeBlock].length) { if (!req.user) {
nextChallengeName = return res.redirect('../challenges/learn-how-free-code-camp-works');
challengeMapWithNames[challengeBlock][++indexOfChallenge];
} else if (typeof challengeMapWithIds[++challengeBlock] !== 'undefined') {
nextChallengeName = R.head(challengeMapWithNames[challengeBlock]);
} else {
req.flash('errors', {
msg: 'It looks like you have finished all of our challenges.' +
' Great job! Now on to helping nonprofits!'
});
nextChallengeName = R.head(challengeMapWithNames[0].challenges);
}
var nameString = nextChallengeName.trim()
.toLowerCase()
.replace(/\s/g, '-');
req.user.save(function(err) {
if (err) {
return next(err);
} }
return res.redirect('../challenges/' + nameString); var completed = req.user.completedChallenges.map(function (elem) {
}); return elem._id;
}
function returnCurrentChallenge(req, res, next) {
if (!req.user) {
return res.redirect('../challenges/learn-how-free-code-camp-works');
}
var completed = req.user.completedChallenges.map(function (elem) {
return elem._id;
});
req.user.uncompletedChallenges = resources.allChallengeIds()
.filter(function (elem) {
if (completed.indexOf(elem) === -1) {
return elem;
}
}); });
if (!req.user.currentChallenge) {
req.user.currentChallenge = {}; req.user.uncompletedChallenges = resources.allChallengeIds()
req.user.currentChallenge.challengeId = challengeMapWithIds['0'][0]; .filter(function (elem) {
req.user.currentChallenge.challengeName = challengeMapWithNames['0'][0]; if (completed.indexOf(elem) === -1) {
req.user.currentChallenge.challengeBlock = '0'; return elem;
}
});
// find the user's current challenge and block
// look in that block and find the index of their current challenge
// if index + 1 < block.challenges.length
// serve index + 1 challenge
// otherwise increment block key and serve the first challenge in that block
// unless the next block is undefined, which means no next block
var nextChallengeName;
var challengeId = String(req.user.currentChallenge.challengeId);
var challengeBlock = req.user.currentChallenge.challengeBlock;
var indexOfChallenge = challengeMapWithIds[challengeBlock]
.indexOf(challengeId);
if (indexOfChallenge + 1
< challengeMapWithIds[challengeBlock].length) {
nextChallengeName =
challengeMapWithNames[challengeBlock][++indexOfChallenge];
} else if (typeof challengeMapWithIds[++challengeBlock] !== 'undefined') {
nextChallengeName = R.head(challengeMapWithNames[challengeBlock]);
} else {
req.flash('errors', {
msg: 'It looks like you have finished all of our challenges.' +
' Great job! Now on to helping nonprofits!'
});
nextChallengeName = R.head(challengeMapWithNames[0].challenges);
}
var nameString = nextChallengeName.trim()
.toLowerCase()
.replace(/\s/g, '-');
req.user.save(function(err) { req.user.save(function(err) {
if (err) { if (err) {
return next(err); return next(err);
} }
return res.redirect('../challenges/' + nameString);
}); });
} }
var nameString = req.user.currentChallenge.challengeName.trim()
.toLowerCase() function returnCurrentChallenge(req, res, next) {
.replace(/\s/g, '-') if (!req.user) {
.replace(/[^a-z0-9\-\/.]/gi, ''); return res.redirect('../challenges/learn-how-free-code-camp-works');
req.user.save(function(err) {
if (err) {
return next(err);
} }
return res.redirect('../challenges/' + nameString); var completed = req.user.completedChallenges.map(function (elem) {
}); return elem._id;
}
function returnIndividualChallenge(req, res, next) {
var dashedName = req.params.challengeName;
var challengeName =
(/^(bonfire|waypoint|zipline|basejump)/i).test(dashedName) ?
dashedName
.replace(/\-/g, ' ')
.split(' ')
.slice(1)
.join(' ') :
dashedName.replace(/\-/g, ' ');
Challenge.find({'name': new RegExp(challengeName, 'i')},
function(err, challengeFromMongo) {
if (err) {
return next(err);
}
// Handle not found
if (challengeFromMongo.length < 1) {
req.flash('errors', {
msg: '404: We couldn\'t find a challenge with that name. ' +
'Please double check the name.'
});
return res.redirect('/challenges');
}
var challenge = challengeFromMongo.pop();
// Redirect to full name if the user only entered a partial
var dashedNameFull = challenge.name
.toLowerCase()
.replace(/\s/g, '-')
.replace(/[^a-z0-9\-\.]/gi, '');
if (dashedNameFull !== dashedName) {
return res.redirect('../challenges/' + dashedNameFull);
} else if (req.user) {
req.user.currentChallenge = {
challengeId: challenge._id,
challengeName: challenge.name,
challengeBlock: R.head(R.flatten(Object.keys(challengeMapWithIds).
map(function (key) {
return challengeMapWithIds[key]
.filter(function (elem) {
return String(elem) === String(challenge._id);
}).map(function () {
return key;
});
})
))
};
}
var challengeType = {
0: function() {
res.render('coursewares/showHTML', {
title: challenge.name,
dashedName: dashedName,
name: challenge.name,
brief: challenge.description[0],
details: challenge.description.slice(1),
tests: challenge.tests,
challengeSeed: challenge.challengeSeed,
verb: resources.randomVerb(),
phrase: resources.randomPhrase(),
compliment: resources.randomCompliment(),
challengeId: challenge._id,
environment: resources.whichEnvironment(),
challengeType: challenge.challengeType
});
},
1: function() {
res.render('coursewares/showJS', {
title: challenge.name,
dashedName: dashedName,
name: challenge.name,
brief: challenge.description[0],
details: challenge.description.slice(1),
tests: challenge.tests,
challengeSeed: challenge.challengeSeed,
verb: resources.randomVerb(),
phrase: resources.randomPhrase(),
compliment: resources.randomCompliment(),
challengeId: challenge._id,
challengeType: challenge.challengeType
});
},
2: function() {
res.render('coursewares/showVideo', {
title: challenge.name,
dashedName: dashedName,
name: challenge.name,
details: challenge.description,
tests: challenge.tests,
video: challenge.challengeSeed[0],
verb: resources.randomVerb(),
phrase: resources.randomPhrase(),
compliment: resources.randomCompliment(),
challengeId: challenge._id,
challengeType: challenge.challengeType
});
},
3: function() {
res.render('coursewares/showZiplineOrBasejump', {
title: challenge.name,
dashedName: dashedName,
name: challenge.name,
details: challenge.description,
video: challenge.challengeSeed[0],
verb: resources.randomVerb(),
phrase: resources.randomPhrase(),
compliment: resources.randomCompliment(),
challengeId: challenge._id,
challengeType: challenge.challengeType
});
},
4: function() {
res.render('coursewares/showZiplineOrBasejump', {
title: challenge.name,
dashedName: dashedName,
name: challenge.name,
details: challenge.description,
video: challenge.challengeSeed[0],
verb: resources.randomVerb(),
phrase: resources.randomPhrase(),
compliment: resources.randomCompliment(),
challengeId: challenge._id,
challengeType: challenge.challengeType
});
},
5: function() {
res.render('coursewares/showBonfire', {
completedWith: null,
title: challenge.name,
dashedName: dashedName,
name: challenge.name,
difficulty: Math.floor(+challenge.difficulty),
brief: challenge.description.shift(),
details: challenge.description,
tests: challenge.tests,
challengeSeed: challenge.challengeSeed,
verb: resources.randomVerb(),
phrase: resources.randomPhrase(),
compliment: resources.randomCompliment(),
bonfires: challenge,
challengeId: challenge._id,
MDNkeys: challenge.MDNlinks,
MDNlinks: getMDNlinks(challenge.MDNlinks),
challengeType: challenge.challengeType
});
}
};
if (req.user) {
req.user.save(function (err) {
if (err) {
return next(err);
}
return challengeType[challenge.challengeType]();
});
} else {
return challengeType[challenge.challengeType]();
}
}); });
}
function completedBonfire(req, res, next) { req.user.uncompletedChallenges = resources.allChallengeIds()
var isCompletedWith = req.body.challengeInfo.completedWith || ''; .filter(function (elem) {
var isCompletedDate = Math.round(+new Date()); if (completed.indexOf(elem) === -1) {
var challengeId = req.body.challengeInfo.challengeId; return elem;
var isSolution = req.body.challengeInfo.solution; }
var challengeName = req.body.challengeInfo.challengeName; });
if (!req.user.currentChallenge) {
if (isCompletedWith) { req.user.currentChallenge = {};
var paired = User.find({'profile.username': isCompletedWith.toLowerCase()}) req.user.currentChallenge.challengeId = challengeMapWithIds['0'][0];
.limit(1); req.user.currentChallenge.challengeName = challengeMapWithNames['0'][0];
paired.exec(function (err, pairedWith) { req.user.currentChallenge.challengeBlock = '0';
req.user.save(function(err) {
if (err) {
return next(err);
}
});
}
var nameString = req.user.currentChallenge.challengeName.trim()
.toLowerCase()
.replace(/\s/g, '-')
.replace(/[^a-z0-9\-\/.]/gi, '');
req.user.save(function(err) {
if (err) { if (err) {
return next(err); return next(err);
} else { }
return res.redirect('../challenges/' + nameString);
});
}
function returnIndividualChallenge(req, res, next) {
var dashedName = req.params.challengeName;
var challengeName =
(/^(bonfire|waypoint|zipline|basejump)/i).test(dashedName) ?
dashedName
.replace(/\-/g, ' ')
.split(' ')
.slice(1)
.join(' ') :
dashedName.replace(/\-/g, ' ');
Challenge.find(
{ where: { name: new RegExp(challengeName, 'i') } },
function(err, challengeFromMongo) {
if (err) { return next(err); }
// Handle not found
if (challengeFromMongo.length < 1) {
req.flash('errors', {
msg: '404: We couldn\'t find a challenge with that name. ' +
'Please double check the name.'
});
return res.redirect('/challenges');
}
var challenge = challengeFromMongo.pop();
// Redirect to full name if the user only entered a partial
var dashedNameFull = challenge.name
.toLowerCase()
.replace(/\s/g, '-')
.replace(/[^a-z0-9\-\.]/gi, '');
if (dashedNameFull !== dashedName) {
return res.redirect('../challenges/' + dashedNameFull);
} else if (req.user) {
req.user.currentChallenge = {
challengeId: challenge._id,
challengeName: challenge.name,
challengeBlock: R.head(R.flatten(Object.keys(challengeMapWithIds).
map(function (key) {
return challengeMapWithIds[key]
.filter(function (elem) {
return String(elem) === String(challenge._id);
}).map(function () {
return key;
});
})
))
};
}
var challengeType = {
0: function() {
res.render('coursewares/showHTML', {
title: challenge.name,
dashedName: dashedName,
name: challenge.name,
brief: challenge.description[0],
details: challenge.description.slice(1),
tests: challenge.tests,
challengeSeed: challenge.challengeSeed,
verb: resources.randomVerb(),
phrase: resources.randomPhrase(),
compliment: resources.randomCompliment(),
challengeId: challenge._id,
environment: resources.whichEnvironment(),
challengeType: challenge.challengeType
});
},
1: function() {
res.render('coursewares/showJS', {
title: challenge.name,
dashedName: dashedName,
name: challenge.name,
brief: challenge.description[0],
details: challenge.description.slice(1),
tests: challenge.tests,
challengeSeed: challenge.challengeSeed,
verb: resources.randomVerb(),
phrase: resources.randomPhrase(),
compliment: resources.randomCompliment(),
challengeId: challenge._id,
challengeType: challenge.challengeType
});
},
2: function() {
res.render('coursewares/showVideo', {
title: challenge.name,
dashedName: dashedName,
name: challenge.name,
details: challenge.description,
tests: challenge.tests,
video: challenge.challengeSeed[0],
verb: resources.randomVerb(),
phrase: resources.randomPhrase(),
compliment: resources.randomCompliment(),
challengeId: challenge._id,
challengeType: challenge.challengeType
});
},
3: function() {
res.render('coursewares/showZiplineOrBasejump', {
title: challenge.name,
dashedName: dashedName,
name: challenge.name,
details: challenge.description,
video: challenge.challengeSeed[0],
verb: resources.randomVerb(),
phrase: resources.randomPhrase(),
compliment: resources.randomCompliment(),
challengeId: challenge._id,
challengeType: challenge.challengeType
});
},
4: function() {
res.render('coursewares/showZiplineOrBasejump', {
title: challenge.name,
dashedName: dashedName,
name: challenge.name,
details: challenge.description,
video: challenge.challengeSeed[0],
verb: resources.randomVerb(),
phrase: resources.randomPhrase(),
compliment: resources.randomCompliment(),
challengeId: challenge._id,
challengeType: challenge.challengeType
});
},
5: function() {
res.render('coursewares/showBonfire', {
completedWith: null,
title: challenge.name,
dashedName: dashedName,
name: challenge.name,
difficulty: Math.floor(+challenge.difficulty),
brief: challenge.description.shift(),
details: challenge.description,
tests: challenge.tests,
challengeSeed: challenge.challengeSeed,
verb: resources.randomVerb(),
phrase: resources.randomPhrase(),
compliment: resources.randomCompliment(),
bonfires: challenge,
challengeId: challenge._id,
MDNkeys: challenge.MDNlinks,
MDNlinks: getMDNlinks(challenge.MDNlinks),
challengeType: challenge.challengeType
});
}
};
if (req.user) {
req.user.save(function (err) {
if (err) {
return next(err);
}
return challengeType[challenge.challengeType]();
});
} else {
return challengeType[challenge.challengeType]();
}
});
}
function completedBonfire(req, res, next) {
var isCompletedWith = req.body.challengeInfo.completedWith || '';
var isCompletedDate = Math.round(+new Date());
var challengeId = req.body.challengeInfo.challengeId;
var isSolution = req.body.challengeInfo.solution;
var challengeName = req.body.challengeInfo.challengeName;
if (isCompletedWith) {
User.find({
where: { 'profile.username': isCompletedWith.toLowerCase() },
limit: 1
}, function (err, pairedWith) {
if (err) { return next(err); }
var index = req.user.uncompletedChallenges.indexOf(challengeId); var index = req.user.uncompletedChallenges.indexOf(challengeId);
if (index > -1) { if (index > -1) {
req.user.progressTimestamps.push(Date.now() || 0); req.user.progressTimestamps.push(Date.now() || 0);
@ -379,20 +381,18 @@ function completedBonfire(req, res, next) {
}); });
} }
// User said they paired, but pair wasn't found // User said they paired, but pair wasn't found
req.user.completedChallenges.push({ req.user.completedChallenges.push({
_id: challengeId, _id: challengeId,
name: challengeName, name: challengeName,
completedWith: null, completedWith: null,
completedDate: isCompletedDate, completedDate: isCompletedDate,
solution: isSolution, solution: isSolution,
challengeType: 5 challengeType: 5
}); });
req.user.save(function (err, user) { req.user.save(function (err, user) {
if (err) { if (err) { return next(err); }
return next(err);
}
if (pairedWith) { if (pairedWith) {
pairedWith.save(function (err, paired) { pairedWith.save(function (err, paired) {
if (err) { if (err) {
@ -406,21 +406,47 @@ function completedBonfire(req, res, next) {
res.send(true); res.send(true);
} }
}); });
});
} else {
req.user.completedChallenges.push({
_id: challengeId,
name: challengeName,
completedWith: null,
completedDate: isCompletedDate,
solution: isSolution,
challengeType: 5
});
var index = req.user.uncompletedChallenges.indexOf(challengeId);
if (index > -1) {
req.user.progressTimestamps.push(Date.now() || 0);
req.user.uncompletedChallenges.splice(index, 1);
} }
});
} else { req.user.save(function (err) {
if (err) { return next(err); }
res.send(true);
});
}
}
function completedChallenge(req, res, next) {
var isCompletedDate = Math.round(+new Date());
var challengeId = req.body.challengeInfo.challengeId;
req.user.completedChallenges.push({ req.user.completedChallenges.push({
_id: challengeId, _id: challengeId,
name: challengeName,
completedWith: null,
completedDate: isCompletedDate, completedDate: isCompletedDate,
solution: isSolution, name: req.body.challengeInfo.challengeName,
challengeType: 5 solution: null,
githubLink: null,
verified: true
}); });
var index = req.user.uncompletedChallenges.indexOf(challengeId); var index = req.user.uncompletedChallenges.indexOf(challengeId);
if (index > -1) {
if (index > -1) {
req.user.progressTimestamps.push(Date.now() || 0); req.user.progressTimestamps.push(Date.now() || 0);
req.user.uncompletedChallenges.splice(index, 1); req.user.uncompletedChallenges.splice(index, 1);
} }
@ -429,70 +455,36 @@ function completedBonfire(req, res, next) {
if (err) { if (err) {
return next(err); return next(err);
} }
// NOTE(berks): Under certain conditions the res is never ended
if (user) { if (user) {
res.send(true); res.sendStatus(200);
} }
}); });
} }
}
function completedChallenge(req, res, next) { function completedZiplineOrBasejump(req, res, next) {
var isCompletedDate = Math.round(+new Date()); var isCompletedWith = req.body.challengeInfo.completedWith || false;
var challengeId = req.body.challengeInfo.challengeId; var isCompletedDate = Math.round(+new Date());
var challengeId = req.body.challengeInfo.challengeId;
req.user.completedChallenges.push({ var solutionLink = req.body.challengeInfo.publicURL;
_id: challengeId, var githubLink = req.body.challengeInfo.challengeType === '4'
completedDate: isCompletedDate, ? req.body.challengeInfo.githubURL : true;
name: req.body.challengeInfo.challengeName, var challengeType = req.body.challengeInfo.challengeType === '4' ?
solution: null, 4 : 3;
githubLink: null, if (!solutionLink || !githubLink) {
verified: true req.flash('errors', {
}); msg: 'You haven\'t supplied the necessary URLs for us to inspect ' +
var index = req.user.uncompletedChallenges.indexOf(challengeId); 'your work.'
});
if (index > -1) { return res.sendStatus(403);
req.user.progressTimestamps.push(Date.now() || 0);
req.user.uncompletedChallenges.splice(index, 1);
}
req.user.save(function (err, user) {
if (err) {
return next(err);
} }
if (user) {
res.sendStatus(200);
}
});
}
function completedZiplineOrBasejump(req, res, next) { if (isCompletedWith) {
User.find({
var isCompletedWith = req.body.challengeInfo.completedWith || false; where: { 'profile.username': isCompletedWith.toLowerCase() },
var isCompletedDate = Math.round(+new Date()); limit: 1
var challengeId = req.body.challengeInfo.challengeId; }, function (err, pairedWithFromMongo) {
var solutionLink = req.body.challengeInfo.publicURL; if (err) { return next(err); }
var githubLink = req.body.challengeInfo.challengeType === '4'
? req.body.challengeInfo.githubURL : true;
var challengeType = req.body.challengeInfo.challengeType === '4' ?
4 : 3;
if (!solutionLink || !githubLink) {
req.flash('errors', {
msg: 'You haven\'t supplied the necessary URLs for us to inspect ' +
'your work.'
});
return res.sendStatus(403);
}
if (isCompletedWith) {
var paired = User.find({'profile.username': isCompletedWith.toLowerCase()})
.limit(1);
paired.exec(function (err, pairedWithFromMongo) {
if (err) {
return next(err);
} else {
var index = req.user.uncompletedChallenges.indexOf(challengeId); var index = req.user.uncompletedChallenges.indexOf(challengeId);
if (index > -1) { if (index > -1) {
req.user.progressTimestamps.push(Date.now() || 0); req.user.progressTimestamps.push(Date.now() || 0);
@ -512,9 +504,7 @@ function completedZiplineOrBasejump(req, res, next) {
}); });
req.user.save(function (err, user) { req.user.save(function (err, user) {
if (err) { if (err) { return next(err); }
return next(err);
}
if (req.user._id.toString() === pairedWith._id.toString()) { if (req.user._id.toString() === pairedWith._id.toString()) {
return res.sendStatus(200); return res.sendStatus(200);
@ -545,37 +535,36 @@ function completedZiplineOrBasejump(req, res, next) {
} }
}); });
}); });
});
} else {
req.user.completedChallenges.push({
_id: challengeId,
name: req.body.challengeInfo.challengeName,
completedWith: null,
completedDate: isCompletedDate,
solution: solutionLink,
githubLink: githubLink,
challengeType: challengeType,
verified: false
});
var index = req.user.uncompletedChallenges.indexOf(challengeId);
if (index > -1) {
req.user.progressTimestamps.push(Date.now() || 0);
req.user.uncompletedChallenges.splice(index, 1);
} }
});
} else {
req.user.completedChallenges.push({ req.user.save(function (err, user) {
_id: challengeId, if (err) {
name: req.body.challengeInfo.challengeName, return next(err);
completedWith: null, }
completedDate: isCompletedDate, // NOTE(berks): under certain conditions this will not close
solution: solutionLink, // the response.
githubLink: githubLink, if (user) {
challengeType: challengeType, return res.sendStatus(200);
verified: false }
}); });
var index = req.user.uncompletedChallenges.indexOf(challengeId);
if (index > -1) {
req.user.progressTimestamps.push(Date.now() || 0);
req.user.uncompletedChallenges.splice(index, 1);
} }
req.user.save(function (err, user) {
if (err) {
return next(err);
}
// NOTE(berks): under certain conditions this will not close the response.
if (user) {
return res.sendStatus(200);
}
});
} }
} };
module.exports = router;

View File

@ -1,65 +1,63 @@
var R = require('ramda'), var R = require('ramda'),
express = require('express'),
// debug = require('debug')('freecc:cntr:challengeMap'), // debug = require('debug')('freecc:cntr:challengeMap'),
User = require('../../common/models/User'),
resources = require('./../resources/resources'), resources = require('./../resources/resources'),
middleware = require('../resources/middleware'), middleware = require('../resources/middleware');
router = express.Router();
router.get('/map', middleware.userMigration, challengeMap);
router.get('/learn-to-code', function(req, res) { module.exports = function(app) {
res.redirect(301, '/map'); var User = app.models.User;
}); var router = app.Router();
router.get('/about', function(req, res) { router.get('/map', middleware.userMigration, challengeMap);
res.redirect(301, '/map'); router.get('/learn-to-code', function(req, res) {
}); res.redirect(301, '/map');
});
function challengeMap(req, res, next) { router.get('/about', function(req, res) {
var completedList = []; res.redirect(301, '/map');
if (req.user) {
completedList = req.user.completedChallenges;
}
var noDuplicatedChallenges = R.uniq(completedList);
var completedChallengeList = noDuplicatedChallenges
.map(function(challenge) {
return challenge._id;
});
var challengeList = resources.
getChallengeMapForDisplay(completedChallengeList);
Object.keys(challengeList).forEach(function(key) {
challengeList[key].completed = challengeList[key]
.challenges.filter(function(elem) {
return completedChallengeList.indexOf(elem._id) > -1;
});
}); });
function numberWithCommas(x) { function challengeMap(req, res, next) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); var completedList = [];
}
var date1 = new Date('10/15/2014'); if (req.user) {
var date2 = new Date(); completedList = req.user.completedChallenges;
var timeDiff = Math.abs(date2.getTime() - date1.getTime());
var daysRunning = Math.ceil(timeDiff / (1000 * 3600 * 24));
User.count({}, function (err, camperCount) {
if (err) {
return next(err);
} }
res.render('challengeMap/show', {
daysRunning: daysRunning,
camperCount: numberWithCommas(camperCount),
title: "A map of all Free Code Camp's Challenges",
challengeList: challengeList,
completedChallengeList: completedChallengeList
});
});
}
module.exports = router; var noDuplicatedChallenges = R.uniq(completedList);
var completedChallengeList = noDuplicatedChallenges
.map(function(challenge) {
return challenge._id;
});
var challengeList = resources.
getChallengeMapForDisplay(completedChallengeList);
Object.keys(challengeList).forEach(function(key) {
challengeList[key].completed = challengeList[key]
.challenges.filter(function(elem) {
return completedChallengeList.indexOf(elem._id) > -1;
});
});
function numberWithCommas(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}
var date1 = new Date('10/15/2014');
var date2 = new Date();
var timeDiff = Math.abs(date2.getTime() - date1.getTime());
var daysRunning = Math.ceil(timeDiff / (1000 * 3600 * 24));
User.count(function(err, camperCount) {
if (err) { return next(err); }
res.render('challengeMap/show', {
daysRunning: daysRunning,
camperCount: numberWithCommas(camperCount),
title: "A map of all Free Code Camp's Challenges",
challengeList: challengeList,
completedChallengeList: completedChallengeList
});
});
}
};

View File

@ -1,18 +1,17 @@
var express = require('express'); module.exports = function(app) {
var Job = require('../../common/models/Job'); var Job = app.models.Job;
var router = express.Router(); var router = app.Router();
router.get('/jobs', jobsDirectory); router.get('/jobs', jobsDirectory);
function jobsDirectory(req, res, next) { function jobsDirectory(req, res, next) {
Job.find({}, function(err, jobs) { Job.find({}, function(err, jobs) {
if (err) { return next(err); } if (err) { return next(err); }
res.render('jobs/directory', { res.render('jobs/directory', {
title: 'Junior JavaScript Engineer Jobs', title: 'Junior JavaScript Engineer Jobs',
jobs: jobs jobs: jobs
});
}); });
}); }
} };
module.exports = router;