build a functional challenge map and change navbar links
This commit is contained in:
4
app.js
4
app.js
@ -43,6 +43,8 @@ var express = require('express'),
|
|||||||
bonfireController = require('./controllers/bonfire'),
|
bonfireController = require('./controllers/bonfire'),
|
||||||
coursewareController = require('./controllers/courseware'),
|
coursewareController = require('./controllers/courseware'),
|
||||||
wikiController = require('./controllers/wiki'),
|
wikiController = require('./controllers/wiki'),
|
||||||
|
challengeMapController = require('./controllers/challengeMap'),
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stories
|
* Stories
|
||||||
@ -247,6 +249,8 @@ app.get('/jquery-exercises', resourcesController.jqueryExercises);
|
|||||||
|
|
||||||
app.get('/chat', resourcesController.chat);
|
app.get('/chat', resourcesController.chat);
|
||||||
|
|
||||||
|
app.get('/challenge-map', challengeMapController.challengeMap);
|
||||||
|
|
||||||
app.get('/live-pair-programming', function(req, res) {
|
app.get('/live-pair-programming', function(req, res) {
|
||||||
res.redirect(301, '/wiki/live-stream-pair-programming-on-twitch.tv');
|
res.redirect(301, '/wiki/live-stream-pair-programming-on-twitch.tv');
|
||||||
});
|
});
|
||||||
|
69
controllers/challengeMap.js
Normal file
69
controllers/challengeMap.js
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
var async = require('async'),
|
||||||
|
User = require('../models/User'),
|
||||||
|
Bonfire = require('./../models/Bonfire'),
|
||||||
|
Story = require('./../models/Story'),
|
||||||
|
Wiki = require('./../models/Wiki'),
|
||||||
|
Nonprofit = require('./../models/Nonprofit'),
|
||||||
|
Comment = require('./../models/Comment'),
|
||||||
|
Courseware = require('./../models/Courseware'),
|
||||||
|
resources = require('./resources'),
|
||||||
|
steps = resources.steps,
|
||||||
|
secrets = require('./../config/secrets'),
|
||||||
|
bonfires = require('../seed_data/bonfires.json'),
|
||||||
|
nonprofits = require('../seed_data/nonprofits.json'),
|
||||||
|
coursewares = require('../seed_data/coursewares.json'),
|
||||||
|
wikis = require('../seed_data/wikis.json'),
|
||||||
|
moment = require('moment'),
|
||||||
|
https = require('https'),
|
||||||
|
debug = require('debug')('freecc:cntr:resources'),
|
||||||
|
cheerio = require('cheerio'),
|
||||||
|
request = require('request'),
|
||||||
|
R = require('ramda');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
challengeMap: function challengeMap(req, res) {
|
||||||
|
var completedBonfires = [];
|
||||||
|
var completedList = [];
|
||||||
|
|
||||||
|
if (req.user) {
|
||||||
|
completedBonfires = req.user.completedBonfires.map(function (elem) {
|
||||||
|
return elem._id;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req.user) {
|
||||||
|
completedList = req.user.completedCoursewares.map(function (elem) {
|
||||||
|
return elem._id;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var noDuplicateBonfires = R.uniq(completedBonfires);
|
||||||
|
var noDuplicatedCoursewares = R.uniq(completedList);
|
||||||
|
|
||||||
|
bonfireList = resources.allBonfireNames();
|
||||||
|
completedBonfireList = noDuplicateBonfires;
|
||||||
|
coursewareList = resources.allCoursewareNames();
|
||||||
|
completedCoursewareList = noDuplicatedCoursewares;
|
||||||
|
waypoints = coursewareList.filter(function(challenge) {
|
||||||
|
if (challenge.challengeType === 2) { return challenge }
|
||||||
|
});
|
||||||
|
ziplines = coursewareList.filter(function(challenge) {
|
||||||
|
if (challenge.challengeType === 3) { return challenge }
|
||||||
|
});
|
||||||
|
basejumps = coursewareList.filter(function(challenge) {
|
||||||
|
if (challenge.challengeType === 4) { return challenge }
|
||||||
|
});
|
||||||
|
console.log('completed', completedCoursewareList);
|
||||||
|
console.log('waypoints', waypoints);
|
||||||
|
|
||||||
|
res.render('challengeMap/show', {
|
||||||
|
title: "A map of all Free Code Camp's Challenges",
|
||||||
|
bonfires: bonfireList,
|
||||||
|
waypoints: waypoints,
|
||||||
|
ziplines: ziplines,
|
||||||
|
basejumps: basejumps,
|
||||||
|
completedBonfireList: completedBonfireList,
|
||||||
|
completedCoursewareList: completedCoursewareList
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
@ -134,46 +134,45 @@ module.exports = {
|
|||||||
var progressTimestamps = req.user.progressTimestamps;
|
var progressTimestamps = req.user.progressTimestamps;
|
||||||
var now = Date.now() || 0;
|
var now = Date.now() || 0;
|
||||||
|
|
||||||
if (req.user.pointsNeedMigration) {
|
//if (req.user.pointsNeedMigration) {
|
||||||
var challengesHash = req.user.challengesHash;
|
// var challengesHash = req.user.challengesHash;
|
||||||
for (var key in challengesHash) {
|
// for (var key in challengesHash) {
|
||||||
if (challengesHash[key] > 0) {
|
// if (challengesHash[key] > 0) {
|
||||||
req.user.progressTimestamps.push(challengesHash[key]);
|
// req.user.progressTimestamps.push(challengesHash[key]);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
var oldChallengeKeys = R.keys(req.user.challengesHash);
|
// var oldChallengeKeys = R.keys(req.user.challengesHash);
|
||||||
|
//
|
||||||
var updatedTimesFromOldChallenges = oldChallengeKeys.map(function(timeStamp) {
|
// var updatedTimesFromOldChallenges = oldChallengeKeys.map(function(timeStamp) {
|
||||||
if (timeStamp.toString().length !== 13) {
|
// if (timeStamp.toString().length !== 13) {
|
||||||
timeStamp *= 1000;
|
// timeStamp *= 1000;
|
||||||
}
|
// }
|
||||||
return timeStamp;
|
// return timeStamp;
|
||||||
});
|
// });
|
||||||
|
//
|
||||||
var newTimeStamps = R.map(function(timeStamp) {
|
// var newTimeStamps = R.map(function(timeStamp) {
|
||||||
if (timeStamp.toString().length !== 13) {
|
// if (timeStamp.toString().length !== 13) {
|
||||||
timeStamp *= 1000;
|
// timeStamp *= 1000;
|
||||||
}
|
// }
|
||||||
return timeStamp;
|
// return timeStamp;
|
||||||
}, req.user.progressTimestamps);
|
// }, req.user.progressTimestamps);
|
||||||
|
//
|
||||||
req.user.progressTimestamps = newTimeStamps;
|
// req.user.progressTimestamps = newTimeStamps;
|
||||||
|
//
|
||||||
|
// req.user.completedCoursewares = Array.zip(updatedTimesFromOldChallenges, coursewares,
|
||||||
req.user.completedCoursewares = Array.zip(updatedTimesFromOldChallenges, coursewares,
|
// function(left, right) {
|
||||||
function(left, right) {
|
// return ({
|
||||||
return ({
|
// completedDate: left.timeStamp,
|
||||||
completedDate: left.timeStamp,
|
// _id: right._id,
|
||||||
_id: right._id,
|
// name: right.name
|
||||||
name: right.name
|
// });
|
||||||
});
|
// }).filter(function(elem) {
|
||||||
}).filter(function(elem) {
|
// return elem.completedDate !== 0;
|
||||||
return elem.completedDate !== 0;
|
// });
|
||||||
});
|
// req.user.pointsNeedMigration = false;
|
||||||
req.user.pointsNeedMigration = false;
|
// req.user.save();
|
||||||
req.user.save();
|
//}
|
||||||
}
|
|
||||||
if (progressTimestamps[progressTimestamps.length - 1] <= (now - 43200)) {
|
if (progressTimestamps[progressTimestamps.length - 1] <= (now - 43200)) {
|
||||||
req.user.progressTimestamps.push(now);
|
req.user.progressTimestamps.push(now);
|
||||||
}
|
}
|
||||||
@ -196,7 +195,7 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
res.render('resources/learn-to-code', {
|
res.render('resources/learn-to-code', {
|
||||||
title: 'About Free Code Camp and Our Team of Volunteers',
|
title: 'About Free Code Camp',
|
||||||
daysRunning: daysRunning,
|
daysRunning: daysRunning,
|
||||||
c3: numberWithCommas(c3),
|
c3: numberWithCommas(c3),
|
||||||
all: all,
|
all: all,
|
||||||
@ -296,6 +295,7 @@ module.exports = {
|
|||||||
return {
|
return {
|
||||||
name: elem.name,
|
name: elem.name,
|
||||||
difficulty: elem.difficulty,
|
difficulty: elem.difficulty,
|
||||||
|
challengeType: elem.challengeType,
|
||||||
_id: elem._id
|
_id: elem._id
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
@ -305,6 +305,7 @@ module.exports = {
|
|||||||
.map (function(elem) {
|
.map (function(elem) {
|
||||||
return {
|
return {
|
||||||
name: elem.name,
|
name: elem.name,
|
||||||
|
challengeType: elem.challengeType,
|
||||||
_id: elem._id
|
_id: elem._id
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
@ -16,7 +16,7 @@ var coursewareSchema = new mongoose.Schema({
|
|||||||
tests: Array,
|
tests: Array,
|
||||||
challengeSeed: Array,
|
challengeSeed: Array,
|
||||||
completionMessage: String, // Congratulations! You've finished our HTML and CSS track!
|
completionMessage: String, // Congratulations! You've finished our HTML and CSS track!
|
||||||
challengeType: Number // 0 = html, 1 = javascript only, 2 = video, 3 = bonfire, 4 = zipline, 5 = basejump
|
challengeType: Number // 0 = html, 1 = javascript only, 2 = video, 3 = zipline, 4 = basejump
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = mongoose.model('Courseware', coursewareSchema);
|
module.exports = mongoose.model('Courseware', coursewareSchema);
|
||||||
|
@ -41,7 +41,7 @@ block content
|
|||||||
.col-xs-12.col-sm-12.col-md-3.text-center
|
.col-xs-12.col-sm-12.col-md-3.text-center
|
||||||
.background-svg.img-center
|
.background-svg.img-center
|
||||||
.points-on-top
|
.points-on-top
|
||||||
= "[ " + user.progressTimestamps.length + " ]"
|
= "[ " + (user ? user.progressTimestamps.length : 0) + " ]"
|
||||||
|
|
||||||
|
|
||||||
.row
|
.row
|
||||||
@ -98,7 +98,10 @@ block content
|
|||||||
|
|
||||||
.hidden-xs.col-sm-12
|
.hidden-xs.col-sm-12
|
||||||
#cal-heatmap.img-center
|
#cal-heatmap.img-center
|
||||||
|
script(src="//d3js.org/d3.v3.min.js")
|
||||||
|
script(src="//cdn.jsdelivr.net/cal-heatmap/3.3.10/cal-heatmap.min.js")
|
||||||
script.
|
script.
|
||||||
|
$(document).ready(function() {
|
||||||
var cal = new CalHeatMap();
|
var cal = new CalHeatMap();
|
||||||
var calendar = !{JSON.stringify(calender)};
|
var calendar = !{JSON.stringify(calender)};
|
||||||
cal.init({
|
cal.init({
|
||||||
@ -116,6 +119,7 @@ block content
|
|||||||
legendColors: ["#cccccc", "#215f1e"],
|
legendColors: ["#cccccc", "#215f1e"],
|
||||||
legend: [1, 2, 3]
|
legend: [1, 2, 3]
|
||||||
});
|
});
|
||||||
|
});
|
||||||
.row
|
.row
|
||||||
.hidden-xs.col-sm-12.text-center
|
.hidden-xs.col-sm-12.text-center
|
||||||
.row.text-primary
|
.row.text-primary
|
||||||
|
43
views/challengeMap/show.jade
Normal file
43
views/challengeMap/show.jade
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
extends ../layout
|
||||||
|
block content
|
||||||
|
.col-xs-12.col-sm-12.col-md-12
|
||||||
|
.panel.panel-info
|
||||||
|
.panel-heading.text-center
|
||||||
|
h1 Challenge Map
|
||||||
|
.panel-body
|
||||||
|
h3 Waypoints
|
||||||
|
ol.col-md-offset-2
|
||||||
|
for waypoint in waypoints
|
||||||
|
if completedCoursewareList.indexOf(waypoint._id) > -1
|
||||||
|
li.strikethrough
|
||||||
|
a(href="/challenges/#{waypoint.name}")= waypoint.name
|
||||||
|
else
|
||||||
|
li
|
||||||
|
a(href="/challenges/#{waypoint.name}")= waypoint.name
|
||||||
|
h3 Bonfires
|
||||||
|
ol.col-md-offset-2
|
||||||
|
for bonfire in bonfires
|
||||||
|
if completedBonfireList.indexOf(bonfire._id) > -1
|
||||||
|
li.strikethrough
|
||||||
|
a(href="/bonfires/#{bonfire.name}")= bonfire.name
|
||||||
|
else
|
||||||
|
li
|
||||||
|
a(href="/bonfires/#{bonfire.name}")= bonfire.name
|
||||||
|
h3 Ziplines
|
||||||
|
ol.col-md-offset-2
|
||||||
|
for zipline in ziplines
|
||||||
|
if completedCoursewareList.indexOf(zipline._id) > -1
|
||||||
|
li.strikethrough
|
||||||
|
a(href="/challenges/#{zipline.name}")= zipline.name
|
||||||
|
else
|
||||||
|
li
|
||||||
|
a(href="/challenges/#{zipline.name}")= zipline.name
|
||||||
|
h3 Basejumps
|
||||||
|
ol.col-md-offset-2
|
||||||
|
for basejump in basejumps
|
||||||
|
if completedCoursewareList.indexOf(basejump._id) > -1
|
||||||
|
li.strikethrough
|
||||||
|
a(href="/challenges/#{basejump.name}")= basejump.name
|
||||||
|
else
|
||||||
|
li
|
||||||
|
a(href="/challenges/#{basejump.name}")= basejump.name
|
@ -12,13 +12,15 @@
|
|||||||
.collapse.navbar-collapse
|
.collapse.navbar-collapse
|
||||||
ul.nav.navbar-nav.navbar-right.hamburger-dropdown
|
ul.nav.navbar-nav.navbar-right.hamburger-dropdown
|
||||||
li
|
li
|
||||||
a(href='/challenges') Challenges
|
a(href='/challenge-map') Challenges
|
||||||
|
if (user && user.progressTimestamps.length > 5)
|
||||||
|
li
|
||||||
|
a(href='https://gitter.im/freecodecamp/freecodecamp') Chat
|
||||||
|
else
|
||||||
li
|
li
|
||||||
a(href='/chat') Chat
|
a(href='/chat') Chat
|
||||||
li
|
li
|
||||||
a(href='/stories/hot') News
|
a(href='/stories/hot') News
|
||||||
li
|
|
||||||
a(href='/bonfires') Bonfires
|
|
||||||
if !user
|
if !user
|
||||||
li      
|
li      
|
||||||
li
|
li
|
||||||
@ -26,9 +28,11 @@
|
|||||||
else
|
else
|
||||||
li
|
li
|
||||||
if (user.profile.username)
|
if (user.profile.username)
|
||||||
|
|
||||||
a(href='/' + user.profile.username) [ #{user.progressTimestamps.length} ]
|
a(href='/' + user.profile.username) [ #{user.progressTimestamps.length} ]
|
||||||
|
|
||||||
else
|
else
|
||||||
a(href='/account') [ #{user.progressTimestamps.length} ]
|
a(href='/account') [ #{user.points} ]
|
||||||
.hidden-xs
|
.hidden-xs
|
||||||
if user.profile.picture
|
if user.profile.picture
|
||||||
if (user.profile.username)
|
if (user.profile.username)
|
||||||
@ -40,7 +44,7 @@
|
|||||||
else
|
else
|
||||||
if (user.profile.username)
|
if (user.profile.username)
|
||||||
a(href='/' + user.profile.username)
|
a(href='/' + user.profile.username)
|
||||||
img.profile-picture.float-right(src='https://s3.amazonaws.com/freecodecamp/camper-image-placeholder.png')
|
img.profile-picture.float-right(src='#{user.gravatar(60)}')
|
||||||
else
|
else
|
||||||
a(href='/account')
|
a(href='/account')
|
||||||
img.profile-picture.float-right(src='https://s3.amazonaws.com/freecodecamp/camper-image-placeholder.png')
|
img.profile-picture.float-right(src='#{user.gravatar(60)}')
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
script(src="//ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js")
|
script(src="//ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js")
|
||||||
script(src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.min.js")
|
script(src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.min.js")
|
||||||
script(src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.12.0/ui-bootstrap-tpls.min.js")
|
script(src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.12.0/ui-bootstrap-tpls.min.js")
|
||||||
script(src="//d3js.org/d3.v3.min.js")
|
|
||||||
script(src="//cdn.jsdelivr.net/cal-heatmap/3.3.10/cal-heatmap.min.js")
|
|
||||||
include meta
|
include meta
|
||||||
title #{title} | Free Code Camp
|
title #{title} | Free Code Camp
|
||||||
meta(charset='utf-8')
|
meta(charset='utf-8')
|
||||||
|
Reference in New Issue
Block a user