From a197e99b1e294e0077469d462b360e79206312eb Mon Sep 17 00:00:00 2001 From: Nathan Leniz Date: Sun, 22 Feb 2015 16:27:38 +0900 Subject: [PATCH 1/4] Starting bonfires view partial, ajax call works, need to work into view --- app.js | 4 ++++ controllers/bonfire.js | 14 +++++++++++--- views/partials/bonfires.jade | 25 +++++++++++++++++++------ 3 files changed, 34 insertions(+), 9 deletions(-) diff --git a/app.js b/app.js index bbc0e6192a..9ed01a4f1e 100644 --- a/app.js +++ b/app.js @@ -301,6 +301,8 @@ app.get('/api/trello', resourcesController.trelloCalls); /** * Bonfire related routes */ +app.get('/bonfires/pooproute', bonfireController.poopRoute); +app.get('/bonfires/getBonfireList', bonfireController.showAllBonfires); app.get('/playground', bonfireController.index); app.get('/bonfires', bonfireController.returnNextBonfire); app.get('/bonfire-json-generator', bonfireController.returnGenerator); @@ -315,6 +317,8 @@ app.get('/bonfire', function(req, res) { res.redirect(301, '/playground'); }); + + app.post('/completed-bonfire/', bonfireController.completedBonfire); /** diff --git a/controllers/bonfire.js b/controllers/bonfire.js index 83431a390d..d18ca1a8bd 100644 --- a/controllers/bonfire.js +++ b/controllers/bonfire.js @@ -8,11 +8,19 @@ var _ = require('lodash'), * Bonfire controller */ -exports.bonfireNames = function(req, res) { - res.render('bonfires/showList', { - bonfireList: resources.allBonfireNames() +exports.showAllBonfires = function(req, res) { + var completedBonfires = req.user.completedBonfires.map(function(elem) { + return elem._id; }); + var data = {}; + data.bonfireList = resources.allBonfireNames(); + //data.completedList = completedBonfires; + res.send(data); }; +// FIXME: remove this +exports.poopRoute = function(req, res) { + res.render('partials/bonfires.jade'); +} exports.index = function(req, res) { res.render('bonfire/show.jade', { diff --git a/views/partials/bonfires.jade b/views/partials/bonfires.jade index cabd9ecf93..c856ea9bf6 100644 --- a/views/partials/bonfires.jade +++ b/views/partials/bonfires.jade @@ -1,7 +1,20 @@ h3 - ol(start='0') - for bonfire in bonfires - li - a(href="/bonfires/#{bonfire.bonfireNumber}", class="#{ (cc && cc[bonfire.bonfireNumber] > 0) ? 'strikethrough' : '' }") #{bonfire.name} - |   (Level #{bonfire.difficulty}) -a.btn.btn-lg.btn-primary.btn-block(href="/done-with-first-100-hours", class="#{ ((cc && cc[53] === 0) || (!cc)) ? 'disabled' : '' }") I'm done with all the challenges! \ No newline at end of file + ol#bonfireList + script. + var getLinkedName = function getLinkedName(name) { + return name.toLowerCase().replace(/\s/g, '-'); + } + $.ajax({ + url: '/bonfires/getBonfireList', + type: 'GET' + }) + .success( + function(data) { + for (var i = 0; i < data.bonfireList.length; i++) { + var li = document.createElement('li'); + var linkedName = getLinkedName(data.bonfireList[i]); + $(li) + .html("" + data.bonfireList[i] + ""); + $(li).appendTo($('#bonfireList')); + } + }); From 90caed3369b8925d81b4e3292be08458a678f2e8 Mon Sep 17 00:00:00 2001 From: Nathan Leniz Date: Sun, 22 Feb 2015 16:46:55 +0900 Subject: [PATCH 2/4] More UX improvements --- public/css/lib/bootstrap/variables.less | 2 +- public/css/main.less | 11 +++++++++++ public/js/main.js | 10 ++++++++-- views/bonfire/show.jade | 15 ++++++++------- 4 files changed, 28 insertions(+), 10 deletions(-) diff --git a/public/css/lib/bootstrap/variables.less b/public/css/lib/bootstrap/variables.less index 3de76507c7..01e26f3433 100755 --- a/public/css/lib/bootstrap/variables.less +++ b/public/css/lib/bootstrap/variables.less @@ -16,7 +16,7 @@ @brand-primary: #215f1e; @brand-success: #457E86; -@brand-info: #5bc0de; +@brand-info: #4A2B0F; @brand-warning: #f0ad4e; @brand-danger: #d9534f; diff --git a/public/css/main.less b/public/css/main.less index cf8b467ed8..5a15dc0f8b 100644 --- a/public/css/main.less +++ b/public/css/main.less @@ -543,6 +543,17 @@ thead { padding-left: 50px; } +.all-list-header { + background-color: #4A2B0F; + color: #eee; + font-size: 36px; + text-align: center; + margin-bottom: -30px; + border-radius: 5px 5px 0px 0px; + padding-left: 50px; + +} + .closing-x { color: #eee; font-size: 50px; diff --git a/public/js/main.js b/public/js/main.js index 7976c4f6d1..07a805ae9b 100644 --- a/public/js/main.js +++ b/public/js/main.js @@ -74,6 +74,11 @@ $(document).ready(function() { editor.focus(); }); + $('#all-bonfires-dialog').on('hidden.bs.modal', function() { + editor.focus(); + }); + + $('#complete-courseware-dialog').on('hidden.bs.modal', function() { editor.focus(); }); @@ -92,13 +97,14 @@ $(document).ready(function() { } }) } - }) + }); + $('.all-challenges').on('click', function() { $('#all-challenges-dialog').modal('show'); }); - $('.all-bonfires').on('click', function() { + $('#showAllButton').on('click', function() { $('#all-bonfires-dialog').modal('show'); }); diff --git a/views/bonfire/show.jade b/views/bonfire/show.jade index bfa7fdbd77..4c1d217b4c 100644 --- a/views/bonfire/show.jade +++ b/views/bonfire/show.jade @@ -79,6 +79,7 @@ block content span.ion-help-circled | Less information #submitButton.btn.btn-primary.btn-big.btn-block Run code (ctrl + enter) + #showAllButton.btn.btn-info.btn-big.btn-block Show all coding challenges br form.code .form-group.codeMirrorView @@ -133,11 +134,11 @@ block content - else a.animated.fadeIn.btn.btn-lg.signup-btn.btn-block(href='/login') Sign in so you can save your progress - //#all-bonfires-dialog.modal(tabindex='-1') - // .modal-dialog.animated.fadeInUp.fast-animation - // .modal-content - // .modal-header.challenge-list-header Bonfires - // a.close.closing-x(href='#', data-dismiss='modal', aria-hidden='true') × - // .modal-body - // include ../partials/bonfires + #all-bonfires-dialog.modal(tabindex='-1') + .modal-dialog.animated.fadeInUp.fast-animation + .modal-content + .modal-header.all-list-header Bonfires + a.close.closing-x(href='#', data-dismiss='modal', aria-hidden='true') × + .modal-body + include ../partials/bonfires From b5a449cb1cdf8dc9c1e317f009f6ef2b58d1605a Mon Sep 17 00:00:00 2001 From: Nathan Leniz Date: Sun, 22 Feb 2015 17:36:43 +0900 Subject: [PATCH 3/4] Cross off completed bonfires in list of all bonfires in modal --- app.js | 2 +- controllers/bonfire.js | 11 +++++------ controllers/resources.js | 10 +++++++--- views/partials/bonfires.jade | 9 ++++++--- 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/app.js b/app.js index 9ed01a4f1e..530d5b2c01 100644 --- a/app.js +++ b/app.js @@ -301,7 +301,7 @@ app.get('/api/trello', resourcesController.trelloCalls); /** * Bonfire related routes */ -app.get('/bonfires/pooproute', bonfireController.poopRoute); + app.get('/bonfires/getBonfireList', bonfireController.showAllBonfires); app.get('/playground', bonfireController.index); app.get('/bonfires', bonfireController.returnNextBonfire); diff --git a/controllers/bonfire.js b/controllers/bonfire.js index d18ca1a8bd..e36be01ccd 100644 --- a/controllers/bonfire.js +++ b/controllers/bonfire.js @@ -2,7 +2,8 @@ var _ = require('lodash'), debug = require('debug')('freecc:cntr:bonfires'), Bonfire = require('./../models/Bonfire'), User = require('./../models/User'), - resources = require('./resources'); + resources = require('./resources'), + R = require('ramda'); /** * Bonfire controller @@ -12,15 +13,13 @@ exports.showAllBonfires = function(req, res) { var completedBonfires = req.user.completedBonfires.map(function(elem) { return elem._id; }); + + var noDuplicateBonfires = R.uniq(completedBonfires); var data = {}; data.bonfireList = resources.allBonfireNames(); - //data.completedList = completedBonfires; + data.completedList = noDuplicateBonfires; res.send(data); }; -// FIXME: remove this -exports.poopRoute = function(req, res) { - res.render('partials/bonfires.jade'); -} exports.index = function(req, res) { res.render('bonfire/show.jade', { diff --git a/controllers/resources.js b/controllers/resources.js index 99844a3095..e02680289e 100644 --- a/controllers/resources.js +++ b/controllers/resources.js @@ -206,14 +206,18 @@ module.exports = { return bonfires.map(function(elem) { return { name: elem.name, - difficulty: elem.difficulty + difficulty: elem.difficulty, + _id: elem._id } }) .sort(function(a, b) { return a.difficulty - b.difficulty; }) - .map(function(elem) { - return elem.name; + .map (function(elem) { + return { + name : elem.name, + _id: elem._id + } }); }, diff --git a/views/partials/bonfires.jade b/views/partials/bonfires.jade index c856ea9bf6..3dfb6da030 100644 --- a/views/partials/bonfires.jade +++ b/views/partials/bonfires.jade @@ -12,9 +12,12 @@ h3 function(data) { for (var i = 0; i < data.bonfireList.length; i++) { var li = document.createElement('li'); - var linkedName = getLinkedName(data.bonfireList[i]); - $(li) - .html("" + data.bonfireList[i] + ""); + var linkedName = getLinkedName(data.bonfireList[i].name); + if (R.contains(data.bonfireList[i]._id, data.completedList)) { + $(li).addClass('strikethrough'); + } + $(li).html("" + data.bonfireList[i].name + ""); $(li).appendTo($('#bonfireList')); + } }); From 3e65298e35873055b17e6fecf7cbe1fc29b3ab1a Mon Sep 17 00:00:00 2001 From: Nathan Leniz Date: Sun, 22 Feb 2015 18:23:50 +0900 Subject: [PATCH 4/4] All coursewares list now displays properly, coursewares properly direct to the follow on, courseware controller now properly finds the next courseware --- app.js | 1 + controllers/courseware.js | 21 +++++++++++++++------ controllers/resources.js | 12 ++++++++---- public/js/main.js | 20 ++++++++++++++------ seed_data/seed.js | 24 +++--------------------- views/coursewares/showHTML.jade | 11 +++++++++++ views/coursewares/showJS.jade | 10 +++++----- views/partials/bonfires.jade | 2 +- views/partials/coursewares.jade | 23 +++++++++++++++++++++++ 9 files changed, 81 insertions(+), 43 deletions(-) create mode 100644 views/partials/coursewares.jade diff --git a/app.js b/app.js index 530d5b2c01..846acd690b 100644 --- a/app.js +++ b/app.js @@ -326,6 +326,7 @@ app.post('/completed-bonfire/', bonfireController.completedBonfire); */ app.get('/coursewares/', coursewareController.returnNextCourseware); +app.get('/coursewares/getCoursewareList', coursewareController.showAllCoursewares); app.get( '/coursewares/:coursewareName', coursewareController.returnIndividualCourseware diff --git a/controllers/courseware.js b/controllers/courseware.js index 58e57cef7d..4dcf0e1cb3 100644 --- a/controllers/courseware.js +++ b/controllers/courseware.js @@ -2,16 +2,23 @@ var _ = require('lodash'), debug = require('debug')('freecc:cntr:courseware'), Courseware = require('./../models/Courseware'), User = require('./../models/User'), - resources = require('./resources'); + resources = require('./resources'), + R = require('ramda'); /** * Courseware controller */ -exports.coursewareNames = function(req, res) { - res.render('coursewares/showList', { - coursewareList: resources.allCoursewareNames() +exports.showAllCoursewares = function(req, res) { + var completedCoursewares = req.user.completedCoursewares.map(function(elem) { + return elem._id; }); + + var noDuplicatedCoursewares = R.uniq(completedCoursewares); + var data = {}; + data.coursewareList = resources.allCoursewareNames(); + data.completedList = noDuplicatedCoursewares; + res.send(data); }; exports.returnNextCourseware = function(req, res) { @@ -29,13 +36,15 @@ exports.returnNextCourseware = function(req, res) { }); req.user.save(); - var uncompletedCoursewares = req.user.uncompletedCoursewares; + var uncompletedCoursewares = req.user.uncompletedCoursewares.shift(); - var displayedCoursewares = Courseware.find({'_id': uncompletedCoursewares[0]}); + + var displayedCoursewares = Courseware.find({'_id': uncompletedCoursewares}); displayedCoursewares.exec(function(err, courseware) { if (err) { next(err); } + debug('This is the courseware object returned from mongo', courseware); courseware = courseware.pop(); if (courseware === undefined) { req.flash('errors', { diff --git a/controllers/resources.js b/controllers/resources.js index e02680289e..b8c7be6a4e 100644 --- a/controllers/resources.js +++ b/controllers/resources.js @@ -239,15 +239,19 @@ module.exports = { return coursewares.map(function(elem) { return { name: elem.name, - difficulty: elem.difficulty + difficulty: elem.difficulty, + _id: elem._id } }) .sort(function(a, b) { return a.difficulty - b.difficulty; }) - .map(function(elem) { - return elem.name; - }); + .map (function(elem) { + return { + name : elem.name, + _id: elem._id + } + }); }, whichEnvironment: function() { return process.env.NODE_ENV; diff --git a/public/js/main.js b/public/js/main.js index 07a805ae9b..d9162a53c9 100644 --- a/public/js/main.js +++ b/public/js/main.js @@ -78,6 +78,14 @@ $(document).ready(function() { editor.focus(); }); + $('#showAllCoursewares').on('click', function() { + $('#all-coursewares-dialog').modal('show'); + }); + + $('#all-coursewares-dialog').on('hidden.bs.modal', function() { + editor.focus(); + }); + $('#complete-courseware-dialog').on('hidden.bs.modal', function() { editor.focus(); @@ -90,12 +98,12 @@ $(document).ready(function() { coursewareInfo: { coursewareHash: passedCoursewareHash } - }, - function(res) { - if (res) { - window.location.href = '/coursewares' - } - }) + }).success( + function() { + window.location.href = '/coursewares'; + } + ) + } }); diff --git a/seed_data/seed.js b/seed_data/seed.js index 6549c3cc71..6e2b34794d 100644 --- a/seed_data/seed.js +++ b/seed_data/seed.js @@ -1,17 +1,15 @@ require('dotenv').load(); -var Challenge = require('../models/Challenge.js'), - Bonfire = require('../models/Bonfire.js'), +var Bonfire = require('../models/Bonfire.js'), Courseware = require('../models/Courseware.js'), mongoose = require('mongoose'), secrets = require('../config/secrets'), - challenges = require('./challenges.json'), coursewares = require('./coursewares.json'), bonfires = require('./bonfires.json'); mongoose.connect(secrets.db); var counter = 0; -var offerings = 3; +var offerings = 2; var CompletionMonitor = function() { counter++; @@ -22,24 +20,8 @@ var CompletionMonitor = function() { } else { process.exit(0); } -} +}; -Challenge.remove({}, function(err, data) { - if (err) { - console.error(err); - } else { - console.log('Deleted ', data); - } - Challenge.create(challenges, function(err, data) { - if (err) { - console.log(err); - } else { - console.log('Saved ', data); - } - CompletionMonitor(); - }); - console.log('challenges'); -}); Bonfire.remove({}, function(err, data) { if (err) { diff --git a/views/coursewares/showHTML.jade b/views/coursewares/showHTML.jade index 676aadf774..b54649a318 100644 --- a/views/coursewares/showHTML.jade +++ b/views/coursewares/showHTML.jade @@ -18,6 +18,8 @@ block content script(src='/js/lib/codemirror/mode/xml/xml.js') script(src='/js/lib/codemirror/mode/css/css.js') script(src='/js/lib/codemirror/mode/htmlmixed/htmlmixed.js') + script(src="https://cdn.jsdelivr.net/ramda/0.10.0/ramda.min.js") + .row.courseware-height .col-xs-12.col-sm-12.col-md-3.col-lg-3 .well @@ -40,6 +42,7 @@ block content span.ion-help-circled | Less information br + .btn.btn-info#showAllCoursewares - if (cc) a.btn.btn-primary.btn-lg.btn-block#next-courseware-button @@ -88,3 +91,11 @@ block content span.completion-icon.ion-checkmark-circled.text-primary a.animated.fadeIn.btn.btn-lg.signup-btn.btn-block(href='/login') Sign in so you can save your progress script(src="/js/lib/coursewares/coursewaresHCJQFramework_v0.1.1.js") + + #all-coursewares-dialog.modal(tabindex='-1') + .modal-dialog.animated.fadeInUp.fast-animation + .modal-content + .modal-header.all-list-header Challenges + a.close.closing-x(href='#', data-dismiss='modal', aria-hidden='true') × + .modal-body + include ../partials/coursewares diff --git a/views/coursewares/showJS.jade b/views/coursewares/showJS.jade index 3570432d41..4e4a364565 100644 --- a/views/coursewares/showJS.jade +++ b/views/coursewares/showJS.jade @@ -47,7 +47,7 @@ block content script(type="text/javascript"). var tests = !{JSON.stringify(tests)}; var challengeSeed = !{JSON.stringify(challengeSeed)}; - var passedBonfireHash = !{JSON.stringify(coursewareHash)}; + var passedCoursewareHash = !{JSON.stringify(coursewareHash)}; var challengeName = !{JSON.stringify(name)}; var started = Math.floor(Date.now() / 1000); .col-xs-12.col-sm-12.col-md-8 @@ -67,10 +67,10 @@ block content span.completion-icon.ion-checkmark-circled.text-primary - if (cc) - a.animated.fadeIn.btn.btn-lg.btn-primary.btn-block.next-courseware-button(name='_csrf', value=_csrf, ng-disabled='completedWithForm.$invalid && existingUser.length > 0') Go to my next challenge (ctrl + enter) + a.animated.fadeIn.btn.btn-lg.btn-primary.btn-block#next-courseware-button(name='_csrf', value=_csrf, ng-disabled='completedWithForm.$invalid && existingUser.length > 0') Go to my next challenge (ctrl + enter) - if (points && points > 2) - a.animated.fadeIn.btn.btn-lg.btn-block.btn-twitter(href="https://twitter.com/intent/tweet?text=I%20just%20#{verb}%20%40FreeCodeCamp%20Bonfire:%20#{name}&url=http%3A%2F%2Ffreecodecamp.com/bonfires/#{dashedName}&hashtags=LearnToCode, JavaScript" target="_blank") - i.fa.fa-twitter   - = phrase + a.animated.fadeIn.btn.btn-lg.btn-block.btn-twitter(href="https://twitter.com/intent/tweet?text=I%20just%20#{verb}%20%40FreeCodeCamp%20Challenge:%20#{name}&url=http%3A%2F%2Ffreecodecamp.com/challenges/#{dashedName}&hashtags=LearnToCode, JavaScript" target="_blank") + i.fa.fa-twitter   + = phrase - else a.animated.fadeIn.btn.btn-lg.signup-btn.btn-block(href='/login') Sign in so you can save your progress \ No newline at end of file diff --git a/views/partials/bonfires.jade b/views/partials/bonfires.jade index 3dfb6da030..33fb57c7b9 100644 --- a/views/partials/bonfires.jade +++ b/views/partials/bonfires.jade @@ -16,7 +16,7 @@ h3 if (R.contains(data.bonfireList[i]._id, data.completedList)) { $(li).addClass('strikethrough'); } - $(li).html("" + data.bonfireList[i].name + ""); + $(li).html("" + data.bonfireList[i].name + ""); $(li).appendTo($('#bonfireList')); } diff --git a/views/partials/coursewares.jade b/views/partials/coursewares.jade new file mode 100644 index 0000000000..8218b82c7a --- /dev/null +++ b/views/partials/coursewares.jade @@ -0,0 +1,23 @@ +h3 + ol#coursewareList + script. + var getLinkedName = function getLinkedName(name) { + return name.toLowerCase().replace(/\s/g, '-'); + } + $.ajax({ + url: '/coursewares/getCoursewareList', + type: 'GET' + }) + .success( + function(data) { + for (var i = 0; i < data.coursewareList.length; i++) { + var li = document.createElement('li'); + var linkedName = getLinkedName(data.coursewareList[i].name); + if (R.contains(data.coursewareList[i]._id, data.completedList)) { + $(li).addClass('strikethrough'); + } + $(li).html("" + data.coursewareList[i].name + ""); + $(li).appendTo($('#coursewareList')); + + } + });