Abstract map and showChallenge logic
Rename some legacy naming conventions Remove logic for waypoint,basejumps, etc...
This commit is contained in:
@ -31,11 +31,7 @@ destroy()
|
||||
|
||||
var challenges = challengeSpec.challenges
|
||||
.map(function(challenge, index) {
|
||||
// NOTE(berks): add title for displaying in views
|
||||
challenge.name =
|
||||
_.capitalize(challenge.type) +
|
||||
': ' +
|
||||
challenge.title.replace(/[^a-zA-Z0-9\s]/g, '');
|
||||
challenge.name = challenge.title.replace(/[^a-zA-Z0-9\s]/g, '');
|
||||
|
||||
challenge.dashedName = challenge.name
|
||||
.toLowerCase()
|
||||
|
@ -33,13 +33,13 @@ const debug = debugFactory('freecc:challenges');
|
||||
const challengesRegex = /^(bonfire|waypoint|zipline|basejump|checkpoint)/i;
|
||||
const firstChallenge = 'waypoint-learn-how-free-code-camp-works';
|
||||
const challengeView = {
|
||||
0: 'coursewares/showHTML',
|
||||
1: 'coursewares/showJS',
|
||||
2: 'coursewares/showVideo',
|
||||
3: 'coursewares/showZiplineOrBasejump',
|
||||
4: 'coursewares/showZiplineOrBasejump',
|
||||
5: 'coursewares/showBonfire',
|
||||
7: 'coursewares/showStep'
|
||||
0: 'challenges/showHTML',
|
||||
1: 'challenges/showJS',
|
||||
2: 'challenges/showVideo',
|
||||
3: 'challenges/showZiplineOrBasejump',
|
||||
4: 'challenges/showZiplineOrBasejump',
|
||||
5: 'challenges/showBonfire',
|
||||
7: 'challenges/showStep'
|
||||
};
|
||||
|
||||
function isChallengeCompleted(user, challengeId) {
|
||||
@ -50,9 +50,11 @@ function isChallengeCompleted(user, challengeId) {
|
||||
challenge.id === challengeId );
|
||||
}
|
||||
|
||||
/*
|
||||
function numberWithCommas(x) {
|
||||
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
||||
}
|
||||
*/
|
||||
|
||||
function updateUserProgress(user, challengeId, completedChallenge) {
|
||||
let { completedChallenges } = user;
|
||||
@ -116,6 +118,131 @@ function shouldNotFilterComingSoon({ isComingSoon, isBeta: challengeIsBeta }) {
|
||||
(isBeta && challengeIsBeta);
|
||||
}
|
||||
|
||||
function getRenderData$(user, challenge$, origChallengeName, solution) {
|
||||
const challengeName = unDasherize(origChallengeName)
|
||||
.replace(challengesRegex, '');
|
||||
|
||||
const testChallengeName = new RegExp(challengeName, 'i');
|
||||
debug('looking for %s', testChallengeName);
|
||||
|
||||
return challenge$
|
||||
.filter((challenge) => {
|
||||
return testChallengeName.test(challenge.name) &&
|
||||
shouldNotFilterComingSoon(challenge);
|
||||
})
|
||||
.last({ defaultValue: null })
|
||||
.flatMap(challenge => {
|
||||
if (challenge && isDev) {
|
||||
return getFromDisk$(challenge);
|
||||
}
|
||||
return Observable.just(challenge);
|
||||
})
|
||||
.flatMap(challenge => {
|
||||
|
||||
// Handle not found
|
||||
if (!challenge) {
|
||||
debug('did not find challenge for ' + origChallengeName);
|
||||
return Observable.just({
|
||||
type: 'redirect',
|
||||
redirectUrl: '/map',
|
||||
message: dedent`
|
||||
404: We couldn\'t find a challenge with the name ${origChallengeName}.
|
||||
Please double check the name.
|
||||
`
|
||||
});
|
||||
}
|
||||
|
||||
if (dasherize(challenge.name) !== origChallengeName) {
|
||||
let redirectUrl = `/challenges/${dasherize(challenge.name)}`;
|
||||
|
||||
if (solution) {
|
||||
redirectUrl += `?solution=${encodeURIComponent(solution)}`;
|
||||
}
|
||||
|
||||
return Observable.just({
|
||||
type: 'redirect',
|
||||
redirectUrl
|
||||
});
|
||||
}
|
||||
|
||||
// save user does nothing if user does not exist
|
||||
return Observable.just({
|
||||
data: {
|
||||
...challenge,
|
||||
// identifies if a challenge is completed
|
||||
isCompleted: isChallengeCompleted(user, challenge.id),
|
||||
|
||||
// video challenges
|
||||
video: challenge.challengeSeed[0],
|
||||
|
||||
// bonfires specific
|
||||
bonfires: challenge,
|
||||
MDNkeys: challenge.MDNlinks,
|
||||
MDNlinks: getMDNLinks(challenge.MDNlinks),
|
||||
|
||||
// htmls specific
|
||||
verb: randomVerb(),
|
||||
phrase: randomPhrase(),
|
||||
compliment: randomCompliment()
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// create a stream of an array of all the challenge blocks
|
||||
function getSuperBlocks$(challenge$, completedChallenges) {
|
||||
return challenge$
|
||||
// mark challenge completed
|
||||
.map(challengeModel => {
|
||||
const challenge = challengeModel.toJSON();
|
||||
if (completedChallenges.indexOf(challenge.id) !== -1) {
|
||||
challenge.completed = true;
|
||||
}
|
||||
challenge.markNew = shouldShowNew(challenge);
|
||||
return challenge;
|
||||
})
|
||||
// group challenges by block | returns a stream of observables
|
||||
.groupBy(challenge => challenge.block)
|
||||
// turn block group stream into an array
|
||||
.flatMap(block$ => block$.toArray())
|
||||
.map(blockArray => {
|
||||
const completedCount = blockArray.reduce((sum, { completed }) => {
|
||||
if (completed) {
|
||||
return sum + 1;
|
||||
}
|
||||
return sum;
|
||||
}, 0);
|
||||
const isBeta = _.every(blockArray, 'isBeta');
|
||||
const isComingSoon = _.every(blockArray, 'isComingSoon');
|
||||
|
||||
return {
|
||||
isBeta,
|
||||
isComingSoon,
|
||||
name: blockArray[0].block,
|
||||
superBlock: blockArray[0].superBlock,
|
||||
dashedName: dasherize(blockArray[0].block),
|
||||
markNew: shouldShowNew(null, blockArray),
|
||||
challenges: blockArray,
|
||||
completed: completedCount / blockArray.length * 100,
|
||||
time: blockArray[0] && blockArray[0].time || '???'
|
||||
};
|
||||
})
|
||||
// filter out hikes
|
||||
.filter(({ superBlock }) => {
|
||||
return !(/hikes/i).test(superBlock);
|
||||
})
|
||||
// turn stream of blocks into a stream of an array
|
||||
.toArray()
|
||||
.flatMap(blocks => Observable.from(blocks, null, null, Scheduler.default))
|
||||
.groupBy(block => block.superBlock)
|
||||
.flatMap(blocks$ => blocks$.toArray())
|
||||
.map(superBlockArray => ({
|
||||
name: superBlockArray[0].superBlock,
|
||||
blocks: superBlockArray
|
||||
}))
|
||||
.toArray();
|
||||
}
|
||||
|
||||
module.exports = function(app) {
|
||||
const router = app.loopback.Router();
|
||||
|
||||
@ -167,8 +294,6 @@ module.exports = function(app) {
|
||||
.shareReplay();
|
||||
|
||||
const User = app.models.User;
|
||||
const userCount$ = observeMethod(User, 'count');
|
||||
|
||||
const send200toNonUser = ifNoUserSend(true);
|
||||
|
||||
router.post(
|
||||
@ -182,13 +307,13 @@ module.exports = function(app) {
|
||||
completedZiplineOrBasejump
|
||||
);
|
||||
|
||||
router.get('/map', challengeMap);
|
||||
router.get('/map', showMap);
|
||||
router.get(
|
||||
'/challenges/next-challenge',
|
||||
returnNextChallenge
|
||||
);
|
||||
|
||||
router.get('/challenges/:challengeName', returnIndividualChallenge);
|
||||
router.get('/challenges/:challengeName', showChallenge);
|
||||
|
||||
app.use(router);
|
||||
|
||||
@ -279,92 +404,20 @@ module.exports = function(app) {
|
||||
);
|
||||
}
|
||||
|
||||
function returnIndividualChallenge(req, res, next) {
|
||||
const origChallengeName = req.params.challengeName;
|
||||
const solutionCode = req.query.solution;
|
||||
const unDashedName = unDasherize(origChallengeName);
|
||||
function showChallenge(req, res, next) {
|
||||
const solution = req.query.solution;
|
||||
|
||||
const challengeName = challengesRegex.test(unDashedName) ?
|
||||
// remove first word if matches
|
||||
unDashedName.split(' ').slice(1).join(' ') :
|
||||
unDashedName;
|
||||
|
||||
const testChallengeName = new RegExp(challengeName, 'i');
|
||||
debug('looking for %s', testChallengeName);
|
||||
challenge$
|
||||
.filter((challenge) => {
|
||||
return testChallengeName.test(challenge.name) &&
|
||||
shouldNotFilterComingSoon(challenge);
|
||||
})
|
||||
.last({ defaultValue: null })
|
||||
.flatMap(challenge => {
|
||||
if (challenge && isDev) {
|
||||
return getFromDisk$(challenge);
|
||||
}
|
||||
return Observable.just(challenge);
|
||||
})
|
||||
.flatMap(challenge => {
|
||||
|
||||
// Handle not found
|
||||
if (!challenge) {
|
||||
debug('did not find challenge for ' + origChallengeName);
|
||||
req.flash('errors', {
|
||||
msg:
|
||||
'404: We couldn\'t find a challenge with the name `' +
|
||||
origChallengeName +
|
||||
'` Please double check the name.'
|
||||
});
|
||||
return Observable.just('/map');
|
||||
}
|
||||
|
||||
if (dasherize(challenge.name) !== origChallengeName) {
|
||||
let redirectUrl = `/challenges/${dasherize(challenge.name)}`;
|
||||
|
||||
if (solutionCode) {
|
||||
redirectUrl += `?solution=${encodeURIComponent(solutionCode)}`;
|
||||
}
|
||||
|
||||
return Observable.just(redirectUrl);
|
||||
}
|
||||
|
||||
// save user does nothing if user does not exist
|
||||
return Observable.just({
|
||||
|
||||
title: challenge.name,
|
||||
name: challenge.name,
|
||||
details: challenge.description,
|
||||
description: challenge.description,
|
||||
challengeId: challenge.id,
|
||||
challengeType: challenge.challengeType,
|
||||
dashedName: origChallengeName,
|
||||
|
||||
challengeSeed: challenge.challengeSeed,
|
||||
head: challenge.head,
|
||||
tail: challenge.tail,
|
||||
tests: challenge.tests,
|
||||
|
||||
// identifies if a challenge is completed
|
||||
isCompleted: isChallengeCompleted(req.user, challenge.id),
|
||||
|
||||
// video challenges
|
||||
video: challenge.challengeSeed[0],
|
||||
|
||||
// bonfires specific
|
||||
bonfires: challenge,
|
||||
MDNkeys: challenge.MDNlinks,
|
||||
MDNlinks: getMDNLinks(challenge.MDNlinks),
|
||||
|
||||
// htmls specific
|
||||
verb: randomVerb(),
|
||||
phrase: randomPhrase(),
|
||||
compliment: randomCompliment()
|
||||
});
|
||||
})
|
||||
getRenderData$(req.user, challenge$, req.params.challengeName, solution)
|
||||
.subscribe(
|
||||
function(data) {
|
||||
if (typeof data === 'string') {
|
||||
debug('redirecting to %s', data);
|
||||
return res.redirect(data);
|
||||
({ type, redirectUrl, message, data }) => {
|
||||
if (message) {
|
||||
req.flash('info', {
|
||||
msg: message
|
||||
});
|
||||
}
|
||||
if (type === 'redirect') {
|
||||
debug('redirecting to %s', redirectUrl);
|
||||
return res.redirect(redirectUrl);
|
||||
}
|
||||
var view = challengeView[data.challengeType];
|
||||
res.render(view, data);
|
||||
@ -500,93 +553,18 @@ module.exports = function(app) {
|
||||
);
|
||||
}
|
||||
|
||||
function challengeMap({ user = {} }, res, next) {
|
||||
|
||||
let lastCompleted;
|
||||
const daysRunning = moment().diff(new Date('10/15/2014'), 'days');
|
||||
|
||||
function showMap({ user = {} }, res, next) {
|
||||
// if user
|
||||
// get the id's of all the users completed challenges
|
||||
const completedChallenges = !user.completedChallenges ?
|
||||
[] :
|
||||
_.uniq(user.completedChallenges).map(({ id, _id }) => id || _id);
|
||||
|
||||
const camperCount$ = userCount$()
|
||||
.map(camperCount => numberWithCommas(camperCount));
|
||||
|
||||
// create a stream of an array of all the challenge blocks
|
||||
const superBlocks$ = challenge$
|
||||
// mark challenge completed
|
||||
.map(challengeModel => {
|
||||
const challenge = challengeModel.toJSON();
|
||||
if (completedChallenges.indexOf(challenge.id) !== -1) {
|
||||
challenge.completed = true;
|
||||
}
|
||||
challenge.markNew = shouldShowNew(challenge);
|
||||
return challenge;
|
||||
})
|
||||
// group challenges by block | returns a stream of observables
|
||||
.groupBy(challenge => challenge.block)
|
||||
// turn block group stream into an array
|
||||
.flatMap(block$ => block$.toArray())
|
||||
.map(blockArray => {
|
||||
const completedCount = blockArray.reduce((sum, { completed }) => {
|
||||
if (completed) {
|
||||
return sum + 1;
|
||||
}
|
||||
return sum;
|
||||
}, 0);
|
||||
const isBeta = _.every(blockArray, 'isBeta');
|
||||
const isComingSoon = _.every(blockArray, 'isComingSoon');
|
||||
|
||||
return {
|
||||
isBeta,
|
||||
isComingSoon,
|
||||
name: blockArray[0].block,
|
||||
superBlock: blockArray[0].superBlock,
|
||||
dashedName: dasherize(blockArray[0].block),
|
||||
markNew: shouldShowNew(null, blockArray),
|
||||
challenges: blockArray,
|
||||
completed: completedCount / blockArray.length * 100,
|
||||
time: blockArray[0] && blockArray[0].time || '???'
|
||||
};
|
||||
})
|
||||
// filter out hikes
|
||||
.filter(({ superBlock }) => {
|
||||
return !(/hikes/i).test(superBlock);
|
||||
})
|
||||
// turn stream of blocks into a stream of an array
|
||||
.toArray()
|
||||
.doOnNext(blocks => {
|
||||
const lastCompletedBlock = _.findLast(blocks, (block) => {
|
||||
return block.completed === 100;
|
||||
});
|
||||
lastCompleted = lastCompletedBlock && lastCompletedBlock.name || null;
|
||||
})
|
||||
.flatMap(blocks => Observable.from(blocks, null, null, Scheduler.default))
|
||||
.groupBy(block => block.superBlock)
|
||||
.flatMap(blocks$ => blocks$.toArray())
|
||||
.map(superBlockArray => ({
|
||||
name: superBlockArray[0].superBlock,
|
||||
blocks: superBlockArray
|
||||
}))
|
||||
.toArray();
|
||||
|
||||
Observable.combineLatest(
|
||||
camperCount$,
|
||||
superBlocks$,
|
||||
(camperCount, superBlocks) => ({ camperCount, superBlocks })
|
||||
)
|
||||
getSuperBlocks$(challenge$, completedChallenges)
|
||||
.subscribe(
|
||||
({ camperCount, superBlocks }) => {
|
||||
res.render('challengeMap/show', {
|
||||
superBlocks => {
|
||||
res.render('map/show', {
|
||||
superBlocks,
|
||||
daysRunning,
|
||||
globalCompletedCount: numberWithCommas(
|
||||
5612952 + (Math.floor((Date.now() - 1446268581061) / 2000))
|
||||
),
|
||||
camperCount,
|
||||
lastCompleted,
|
||||
title: 'A Map to Learn to Code and Become a Software Engineer'
|
||||
});
|
||||
},
|
||||
|
@ -1,4 +1,3 @@
|
||||
import _ from 'lodash';
|
||||
import path from 'path';
|
||||
import { Observable } from 'rx';
|
||||
|
||||
@ -22,10 +21,7 @@ export default function getFromDisk$(challenge) {
|
||||
challenge.tail = challenge.tail || [];
|
||||
challenge.challengeType = '' + challenge.challengeType;
|
||||
|
||||
challenge.name =
|
||||
_.capitalize(challenge.type) +
|
||||
': ' +
|
||||
challenge.title.replace(/[^a-zA-Z0-9\s]/g, '');
|
||||
challenge.name = challenge.title.replace(/[^a-zA-Z0-9\s]/g, '');
|
||||
|
||||
challenge.dashedName = challenge.name
|
||||
.toLowerCase()
|
||||
|
@ -17,7 +17,7 @@ block content
|
||||
.row
|
||||
.col-xs-12
|
||||
.bonfire-instructions
|
||||
for sentence in details
|
||||
for sentence in description
|
||||
if (/blockquote|h4|table/.test(sentence))
|
||||
!=sentence
|
||||
else
|
||||
@ -83,7 +83,7 @@ block content
|
||||
i.fa.fa-twitter  
|
||||
= phrase
|
||||
else
|
||||
a#next-challenge.btn.btn-lg.btn-primary.btn-block(href="/challenges/next-challenge?id="+challengeId) Go to my next challenge (ctrl + enter)
|
||||
a#next-challenge.btn.btn-lg.btn-primary.btn-block(href="/challenges/next-challenge?id="+id) Go to my next challenge (ctrl + enter)
|
||||
include ../partials/challenge-modals
|
||||
script(type="text/javascript").
|
||||
var common = window.common = window.common || { init: [] };
|
||||
@ -92,7 +92,7 @@ block content
|
||||
common.head = !{JSON.stringify(head)};
|
||||
common.tail = !{JSON.stringify(tail)};
|
||||
|
||||
common.challengeId = !{JSON.stringify(challengeId)};
|
||||
common.challengeId = !{JSON.stringify(id)};
|
||||
common.challengeName = !{JSON.stringify(name)};
|
||||
common.challengeSeed = !{JSON.stringify(challengeSeed)};
|
||||
common.challengeType = !{JSON.stringify(challengeType)};
|
@ -16,7 +16,7 @@ block content
|
||||
i.ion-checkmark-circled.text-primary(title="Completed")
|
||||
hr
|
||||
.bonfire-instructions
|
||||
for sentence in details
|
||||
for sentence in description
|
||||
p.wrappable.negative-10!= sentence
|
||||
.negative-bottom-margin-30
|
||||
.button-spacer
|
||||
@ -74,7 +74,7 @@ block content
|
||||
if(user)
|
||||
#submit-challenge.animated.fadeIn.btn.btn-lg.btn-primary.btn-block Submit and go to my next challenge (ctrl + enter)
|
||||
else
|
||||
a#next-challenge.btn.btn-lg.btn-primary.btn-block(href="/challenges/next-challenge?id="+challengeId) Go to my next challenge (ctrl + enter)
|
||||
a#next-challenge.btn.btn-lg.btn-primary.btn-block(href="/challenges/next-challenge?id="+id) Go to my next challenge (ctrl + enter)
|
||||
include ../partials/challenge-modals
|
||||
script(type="text/javascript").
|
||||
$('#next-courseware-button').attr('disabled', 'disabled');
|
||||
@ -84,7 +84,7 @@ block content
|
||||
common.head = !{JSON.stringify(head)};
|
||||
common.tail = !{JSON.stringify(tail)};
|
||||
|
||||
common.challengeId = !{JSON.stringify(challengeId)};
|
||||
common.challengeId = !{JSON.stringify(id)};
|
||||
common.challengeName = !{JSON.stringify(name)};
|
||||
common.challengeSeed = !{JSON.stringify(challengeSeed)};
|
||||
common.challengeType = !{JSON.stringify(challengeType)};
|
@ -17,7 +17,7 @@ block content
|
||||
.row
|
||||
.col-xs-12
|
||||
.bonfire-instructions
|
||||
for sentence in details
|
||||
for sentence in description
|
||||
if (/blockquote|h4|table/.test(sentence))
|
||||
!=sentence
|
||||
else
|
||||
@ -82,7 +82,7 @@ block content
|
||||
if (user)
|
||||
#submit-challenge.animated.fadeIn.btn.btn-lg.btn-primary.btn-block Submit and go to my next challenge (ctrl + enter)
|
||||
else
|
||||
a#next-challenge.animated.fadeIn.btn.btn-lg.btn-primary.btn-block(href="/challenges/next-challenge?id="+challengeId) Go to my next challenge (ctrl + enter)
|
||||
a#next-challenge.animated.fadeIn.btn.btn-lg.btn-primary.btn-block(href="/challenges/next-challenge?id="+id) Go to my next challenge (ctrl + enter)
|
||||
include ../partials/challenge-modals
|
||||
script(type="text/javascript").
|
||||
var common = window.common = { init: [] };
|
||||
@ -91,7 +91,7 @@ block content
|
||||
common.head = !{JSON.stringify(head)};
|
||||
common.tail = !{JSON.stringify(tail)};
|
||||
|
||||
common.challengeId = !{JSON.stringify(challengeId)};
|
||||
common.challengeId = !{JSON.stringify(id)};
|
||||
common.challengeName = !{JSON.stringify(name)};
|
||||
common.challengeSeed = !{JSON.stringify(challengeSeed)};
|
||||
common.challengeType = !{JSON.stringify(challengeType)};
|
@ -37,11 +37,11 @@ block content
|
||||
if (user)
|
||||
#challenge-step-btn-submit.animated.fadeIn.btn.btn-lg.btn-primary.btn-block Submit and go to my next challenge
|
||||
else
|
||||
a.btn.btn-lg.btn-primary.btn-block(href='/challenges/next-challenge?id=' + challengeId) Go to my next challenge
|
||||
a.btn.btn-lg.btn-primary.btn-block(href='/challenges/next-challenge?id=' + id) Go to my next challenge
|
||||
script.
|
||||
var common = window.common || { init: [] };
|
||||
|
||||
common.challengeId = !{JSON.stringify(challengeId)};
|
||||
common.challengeId = !{JSON.stringify(id)};
|
||||
common.challengeName = !{JSON.stringify(name)};
|
||||
common.challengeType = !{JSON.stringify(challengeType)};
|
||||
common.dashedName = !{JSON.stringify(dashedName || '')};
|
@ -6,7 +6,7 @@ block content
|
||||
.well
|
||||
h4
|
||||
ol
|
||||
for step, index in details
|
||||
for step, index in description
|
||||
.row.checklist-element(id="#{dashedName + index}")
|
||||
.col-xs-3.col-sm-1.col-md-2.padded-ionic-icon.text-center
|
||||
input(type='checkbox' class='challenge-list-checkbox')
|
||||
@ -19,7 +19,7 @@ block content
|
||||
if (user)
|
||||
a.btn.btn-primary.btn-big.btn-block#completed-courseware-editorless I've completed this challenge (ctrl + enter)
|
||||
else
|
||||
a.btn.btn-big.btn-primary.btn-block(href='/challenges/next-challenge?id=' + challengeId) I've completed this challenge (ctrl + enter)
|
||||
a.btn.btn-big.btn-primary.btn-block(href='/challenges/next-challenge?id=' + id) I've completed this challenge (ctrl + enter)
|
||||
script.
|
||||
var userLoggedIn = true;
|
||||
.button-spacer
|
||||
@ -51,13 +51,13 @@ block content
|
||||
if (user)
|
||||
a.btn.btn-lg.btn-primary.btn-block#next-courseware-button(name='_csrf', value=_csrf) I've completed this challenge (ctrl + enter)
|
||||
else
|
||||
a.animated.fadeIn.btn.btn-lg.btn-primary.btn-block(href='/challenges/next-challenge?id=' + challengeId) I've completed this challenge (ctrl + enter)
|
||||
a.animated.fadeIn.btn.btn-lg.btn-primary.btn-block(href='/challenges/next-challenge?id=' + id) I've completed this challenge (ctrl + enter)
|
||||
|
||||
include ../partials/challenge-modals
|
||||
script.
|
||||
var common = window.common || { init: [] };
|
||||
|
||||
common.challengeId = !{JSON.stringify(challengeId)};
|
||||
common.challengeId = !{JSON.stringify(id)};
|
||||
common.challengeName = !{JSON.stringify(name)};
|
||||
common.challengeType = !{JSON.stringify(challengeType)};
|
||||
common.dashedName = !{JSON.stringify(dashedName)};
|
@ -6,7 +6,7 @@ block content
|
||||
hr
|
||||
h4
|
||||
ol
|
||||
for step, index in details
|
||||
for step, index in description
|
||||
.row.checklist-element(id="#{dashedName + index}")
|
||||
.col-xs-3.col-sm-1.col-md-2.padded-ionic-icon.text-center
|
||||
input(type='checkbox' class='challenge-list-checkbox')
|
||||
@ -21,7 +21,7 @@ block content
|
||||
script.
|
||||
var userLoggedIn = true;
|
||||
else
|
||||
a.btn.btn-big.btn-primary.btn-block(href='/challenges/next-challenge?id=' + challengeId) Go to my next challenge (ctrl + enter)
|
||||
a.btn.btn-big.btn-primary.btn-block(href='/challenges/next-challenge?id=' + id) Go to my next challenge (ctrl + enter)
|
||||
.button-spacer
|
||||
.btn-group.input-group.btn-group-justified
|
||||
.btn.btn-primary.btn-primary-ghost.btn-big#challenge-help-btn
|
||||
@ -65,12 +65,12 @@ block content
|
||||
a.btn.btn-lg.btn-block.btn-twitter(target="_blank", href="https://twitter.com/intent/tweet?text=Check%20out%20the%20project%20I%20just%20built%20with%20%40FreeCodeCamp:%20PASTE_YOUR_CODEPEN_URL_HERE_USING_FULL_INSTEAD_OF_PEN%20%0A%20%23LearnToCode%20%23JavaScript", onclick="ga('send', 'event', 'twitter', 'share', 'challenge completion share');")
|
||||
i.fa.fa-twitter  Tweet this project
|
||||
else
|
||||
a.btn.btn-lg.btn-primary.btn-block(href='/challenges/next-challenge?id=' + challengeId) Go to my next challenge
|
||||
a.btn.btn-lg.btn-primary.btn-block(href='/challenges/next-challenge?id=' + id) Go to my next challenge
|
||||
|
||||
include ../partials/challenge-modals
|
||||
script.
|
||||
var common = window.common || { init: [] };
|
||||
common.challengeId = !{JSON.stringify(challengeId)};
|
||||
common.challengeId = !{JSON.stringify(id)};
|
||||
common.challengeName = !{JSON.stringify(name)};
|
||||
common.dashedName = !{JSON.stringify(dashedName)};
|
||||
common.challengeType = !{JSON.stringify(challengeType)};
|
Reference in New Issue
Block a user