From 8c48626f031c40b5ffc6fc20684f846260181f93 Mon Sep 17 00:00:00 2001 From: Berkeley Martinez Date: Fri, 2 Oct 2015 11:47:36 -0700 Subject: [PATCH 1/2] Add certification page --- client/commonFramework.js | 51 ++++++- common/models/user.json | 21 ++- public/fonts/saxmono.ttf | Bin 0 -> 103740 bytes .../front-end-development-certificate.json | 17 ++- .../full-stack-development-certificate.json | 16 ++- server/boot/certificate.js | 131 ++++++++++++++++++ server/boot/challenge.js | 9 +- server/boot/user.js | 94 ++++++++++++- server/utils/middleware.js | 48 +------ server/utils/rx.js | 23 +-- server/views/account/show.jade | 7 +- server/views/certificate/font.jade | 45 ++++++ server/views/certificate/front-end.jade | 6 + server/views/certificate/full-stack.jade | 6 + server/views/certificate/index.jade | 7 + server/views/certificate/script.jade | 8 ++ server/views/coursewares/showStep.jade | 8 +- 17 files changed, 415 insertions(+), 82 deletions(-) create mode 100755 public/fonts/saxmono.ttf create mode 100644 server/boot/certificate.js create mode 100644 server/views/certificate/font.jade create mode 100644 server/views/certificate/front-end.jade create mode 100644 server/views/certificate/full-stack.jade create mode 100644 server/views/certificate/index.jade create mode 100644 server/views/certificate/script.jade diff --git a/client/commonFramework.js b/client/commonFramework.js index 8abcb6a9dc..fcb1ccc58d 100644 --- a/client/commonFramework.js +++ b/client/commonFramework.js @@ -865,14 +865,53 @@ common.init.push((function() { } next(); }); - } - function handleActionClick() { - $(this) - .parent() - .find('.disabled') - .removeClass('disabled'); + function handleActionClick(e) { + var props = common.challengeSeed[0] || + { stepIndex: [] }; + + var $el = $(this); + var index = +$el.attr('id'); + var propIndex = props.stepIndex.indexOf(index); + + if (propIndex === -1) { + return $el + .parent() + .find('.disabled') + .removeClass('disabled'); + } + + // an API action + // prevent link from opening + e.preventDefault(); + var prop = props.properties[propIndex]; + var api = props.apis[propIndex]; + if (common[prop]) { + return $el + .parent() + .find('.disabled') + .removeClass('disabled'); + } + $ + .post(api) + .done(function(data) { + // assume a boolean indicates passing + if (typeof data === 'boolean') { + return $el + .parent() + .find('.disabled') + .removeClass('disabled'); + } + // assume api returns string when fails + $el + .parent() + .find('.disabled') + .replaceWith('

' + data + '

'); + }) + .fail(function() { + console.log('failed'); + }); } function handleFinishClick(e) { diff --git a/common/models/user.json b/common/models/user.json index c46d1c2f13..cb34389b80 100644 --- a/common/models/user.json +++ b/common/models/user.json @@ -102,14 +102,31 @@ }, "isLocked": { "type": "boolean", - "default": false + "default": false, + "description": "Campers profile does not show challenges to the public" }, "currentChallenge": { "type": {} }, "isUniqMigrated": { "type": "boolean", - "default": false + "default": false, + "description": "Campers completedChallenges array is free of duplicates" + }, + "isHonest": { + "type": "boolean", + "default": false, + "description": "Camper has signed academic honesty policy" + }, + "isFrontEndCert": { + "type": "boolean", + "defaut": false, + "description": "Camper is front end certified" + }, + "isFullStackCert": { + "type": "boolean", + "default": false, + "description": "Campers is full stack certified" }, "completedChallenges": { "type": [ diff --git a/public/fonts/saxmono.ttf b/public/fonts/saxmono.ttf new file mode 100755 index 0000000000000000000000000000000000000000..76c77d6411749741383ddb3d6d95ecb43835b4ae GIT binary patch literal 103740 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̫a4HfJEnEAo2AhAn|(;Na;KZB))$Fr2PC8NWVW0 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 literal 0 HcmV?d00001 diff --git a/seed/challenges/front-end-development-certificate.json b/seed/challenges/front-end-development-certificate.json index fa0bb1ce40..ac8b53ee21 100644 --- a/seed/challenges/front-end-development-certificate.json +++ b/seed/challenges/front-end-development-certificate.json @@ -5,14 +5,25 @@ { "id": "561add10cb82ac38a17513be", "title": "Claim Your Front End Development Certificate", - "difficulty": 0.00, - "challengeSeed": [], + "challengeSeed": [ + { + "properties": ["isHonest", "isFrontEndCert"], + "apis": ["/certificate/honest", "/certificate/verify/front-end"], + "stepIndex": [0, 1] + } + ], "description": [ [ "http://i.imgur.com/RlEk2IF.jpg", "a picture of Free Code Camp's 4 benefits: Get connected, Learn JavaScript, Build your Portfolio, Help nonprofits", "Welcome to Free Code Camp. We're an open source community of busy people who learn to code and help nonprofits.", - "" + "#" + ], + [ + "http://i.imgur.com/RlEk2IF.jpg", + "a picture of Free Code Camp's 4 benefits: Get connected, Learn JavaScript, Build your Portfolio, Help nonprofits", + "Welcome to Free Code Camp. We're an open source community of busy people who learn to code and help nonprofits.", + "#" ] ], "type": "Waypoint", diff --git a/seed/challenges/full-stack-development-certificate.json b/seed/challenges/full-stack-development-certificate.json index 901883aebc..bfb2f7df4a 100644 --- a/seed/challenges/full-stack-development-certificate.json +++ b/seed/challenges/full-stack-development-certificate.json @@ -6,13 +6,25 @@ "id": "660add10cb82ac38a17513be", "title": "Claim Your Full Stack Development Certificate", "difficulty": 0.00, - "challengeSeed": [], + "challengeSeed": [ + { + "properties": ["isHonest", "isFullStackCert"], + "apis": ["/certificate/honest", "/certificate/verify/full-stack"], + "stepIndex": [0, 1] + } + ], "description": [ [ "http://i.imgur.com/RlEk2IF.jpg", "a picture of Free Code Camp's 4 benefits: Get connected, Learn JavaScript, Build your Portfolio, Help nonprofits", "Welcome to Free Code Camp. We're an open source community of busy people who learn to code and help nonprofits.", - "" + "#" + ], + [ + "http://i.imgur.com/RlEk2IF.jpg", + "a picture of Free Code Camp's 4 benefits: Get connected, Learn JavaScript, Build your Portfolio, Help nonprofits", + "Welcome to Free Code Camp. We're an open source community of busy people who learn to code and help nonprofits.", + "#" ] ], "type": "Waypoint", diff --git a/server/boot/certificate.js b/server/boot/certificate.js new file mode 100644 index 0000000000..b6a3db9461 --- /dev/null +++ b/server/boot/certificate.js @@ -0,0 +1,131 @@ +import _ from 'lodash'; +import dedent from 'dedent'; +import { Observable } from 'rx'; +import debugFactory from 'debug'; + +import { + ifNoUser401, + ifNoUserSend +} from '../utils/middleware'; + +import { + saveUser, + observeQuery +} from '../utils/rx'; + +const frontEndChallangeId = '561add10cb82ac38a17513be'; +const fullStackChallangeId = '660add10cb82ac38a17513be'; +const debug = debugFactory('freecc:certification'); +const sendMessageToNonUser = ifNoUserSend( + 'must be logged in to complete.' +); + +function isCertified(frontEndIds, { completedChallenges, isFrontEndCert }) { + if (isFrontEndCert) { + return true; + } + return _.every(frontEndIds, ({ id }) => _.some(completedChallenges, { id })); +} + +export default function certificate(app) { + const router = app.loopback.Router(); + const { Challenge } = app.models; + + const frontEndChallangeIds$ = observeQuery( + Challenge, + 'findById', + frontEndChallangeId, + { + tests: true + } + ) + .map(({ tests = [] }) => tests) + .shareReplay(); + + const fullStackChallangeIds$ = observeQuery( + Challenge, + 'findById', + fullStackChallangeId, + { + tests: true + } + ) + .map(({ tests = [] }) => tests) + .shareReplay(); + + router.post( + '/certificate/verify/front-end', + ifNoUser401, + verifyCert + ); + + router.post( + '/certificate/verify/full-stack', + ifNoUser401, + verifyCert + ); + + router.post( + '/certificate/honest', + sendMessageToNonUser, + postHonest + ); + + app.use(router); + + function verifyCert(req, res, next) { + const isFront = req.path.split('/').pop() === 'front-end'; + Observable.just({}) + .flatMap(() => { + if (isFront) { + return frontEndChallangeIds$; + } + return fullStackChallangeIds$; + }) + .flatMap((tests) => { + const { user } = req; + if ( + isFront && !user.isFrontEndCert && isCertified(tests, user) || + !isFront && !user.isFullStackCert && isCertified(tests, user) + ) { + debug('certified'); + if (isFront) { + user.isFrontEndCert = true; + } else { + user.isFullStackCert = true; + } + return saveUser(user); + } + return Observable.just(user); + }) + .subscribe( + user => { + if ( + isFront && user.isFrontEndCert || + !isFront && user.isFullStackCert + ) { + return res.status(200).send(true); + } + return res.status(200).send( + dedent` + Looks like you have not completed the neccessary steps, + Please return the map + ` + ); + }, + next + ); + } + + function postHonest(req, res, next) { + const { user } = req; + user.isHonest = true; + saveUser(user) + .subscribe( + (user) => { + res.status(200).send(!!user.isHonest); + }, + next + ); + } +} diff --git a/server/boot/challenge.js b/server/boot/challenge.js index 15cb507855..6a056b705d 100644 --- a/server/boot/challenge.js +++ b/server/boot/challenge.js @@ -9,11 +9,10 @@ import utils from '../utils'; import { saveUser, observeMethod, - observableQueryFromModel + observeQuery } from '../utils/rx'; import { - userMigration, ifNoUserSend } from '../utils/middleware'; @@ -147,8 +146,6 @@ module.exports = function(app) { completedBonfire ); - // the follow routes are covered by userMigration - router.use(userMigration); router.get('/map', challengeMap); router.get( '/challenges/next-challenge', @@ -330,7 +327,7 @@ module.exports = function(app) { challengeType: 5 }; - observableQueryFromModel( + observeQuery( User, 'findOne', { where: { username: ('' + completedWith).toLowerCase() } } @@ -458,7 +455,7 @@ module.exports = function(app) { verified: false }; - observableQueryFromModel( + observeQuery( User, 'findOne', { where: { username: completedWith.toLowerCase() } } diff --git a/server/boot/user.js b/server/boot/user.js index 214c0b9264..9567a5066a 100644 --- a/server/boot/user.js +++ b/server/boot/user.js @@ -1,8 +1,11 @@ +import _ from 'lodash'; import dedent from 'dedent'; import moment from 'moment'; +import { Observable } from 'rx'; import debugFactory from 'debug'; import { ifNoUser401, ifNoUserRedirectTo } from '../utils/middleware'; +import { observeQuery } from '../utils/rx'; const debug = debugFactory('freecc:boot:user'); const daysBetween = 1.5; @@ -52,7 +55,16 @@ function dayDiff([head, tail]) { module.exports = function(app) { var router = app.loopback.Router(); var User = app.models.User; - // var Story = app.models.Story; + function findUserByUsername$(username, fields) { + return observeQuery( + User, + 'findOne', + { + where: { username }, + fields + } + ); + } router.get('/login', function(req, res) { res.redirect(301, '/signin'); @@ -85,7 +97,18 @@ module.exports = function(app) { ); router.get('/vote1', vote1); router.get('/vote2', vote2); - // Ensure this is the last route! + + // Ensure these are the last routes! + router.get( + '/:username/front-end-certification', + showCert + ); + + router.get( + '/:username/full-stack-certification', + showCert + ); + router.get('/:username', returnUser); app.use(router); @@ -184,14 +207,20 @@ module.exports = function(app) { return (obj.name || '').match(/^Waypoint/i); }); + debug('user is fec', profileUser.isFrontEndCert); res.render('account/show', { title: 'Camper ' + profileUser.username + '\'s portfolio', username: profileUser.username, name: profileUser.name, + isMigrationGrandfathered: profileUser.isMigrationGrandfathered, isGithubCool: profileUser.isGithubCool, isLocked: !!profileUser.isLocked, + isFrontEndCert: profileUser.isFrontEndCert, + isFullStackCert: profileUser.isFullStackCert, + isHonest: profileUser.isHonest, + location: profileUser.location, calender: data, @@ -216,6 +245,62 @@ module.exports = function(app) { ); } + function showCert(req, res, next) { + const username = req.params.username.toLowerCase(); + const { user } = req; + const showFront = req.path.split('/').pop() === 'front-end-certification'; + Observable.just(user) + .flatMap(user => { + if (user && user.username === username) { + return Observable.just(user); + } + return findUserByUsername$(username, { + isFrontEndCert: true, + isFullStackCert: true, + completedChallenges: true, + username: true, + name: true + }); + }) + .subscribe( + (user) => { + if (!user) { + req.flash('errors', { + msg: `404: We couldn't find the user ${username}` + }); + return res.redirect('/'); + } + if ( + showFront && user.isFrontEndCert || + !showFront && user.isFullStackCert + ) { + var { completedDate } = _.find(user.completedChallenges, { + id: '561add10cb82ac38a17513be' + }); + + return res.render( + showFront ? + 'certificate/front-end.jade' : + 'certificate/full-stack.jade', + { + username: user.username, + date: moment(new Date(completedDate)) + .format('MMMM, Do YYYY'), + name: user.name + } + ); + } + req.flash('errors', { + msg: showFront ? + `Looks like user ${username} is not Front End certified` : + `Looks like user ${username} is not Full Stack certified` + }); + res.redirect('/map'); + }, + next + ); + } + function toggleLockdownMode(req, res, next) { if (req.user.isLocked === true) { req.user.isLocked = false; @@ -297,11 +382,6 @@ module.exports = function(app) { }); } - /** - * POST /forgot - * Create a random token, then the send user an email with a reset link. - */ - function postForgot(req, res) { const errors = req.validationErrors(); const email = req.body.email.toLowerCase(); diff --git a/server/utils/middleware.js b/server/utils/middleware.js index 1edec7a59b..3c541cbb11 100644 --- a/server/utils/middleware.js +++ b/server/utils/middleware.js @@ -1,60 +1,24 @@ -var R = require('ramda'); - -/* - * Middleware to migrate users from fragmented challenge structure to unified - * challenge structure - * - * @param req - * @param res - * @returns null - */ -exports.userMigration = function userMigration(req, res, next) { - if (!req.user || req.user.completedChallenges.length !== 0) { - return next(); - } - req.user.completedChallenges = R.filter(function(elem) { - // getting rid of undefined - return elem; - }, R.concat( - req.user.completedCoursewares, - req.user.completedBonfires.map(function(bonfire) { - return ({ - completedDate: bonfire.completedDate, - id: bonfire.id, - name: bonfire.name, - completedWith: bonfire.completedWith, - solution: bonfire.solution, - githubLink: '', - verified: false, - challengeType: 5 - }); - }) - ) - ); - return next(); -}; - -exports.ifNoUserRedirectTo = function ifNoUserRedirectTo(url) { +export function ifNoUserRedirectTo(url) { return function(req, res, next) { if (req.user) { return next(); } return res.redirect(url); }; -}; +} -exports.ifNoUserSend = function ifNoUserSend(sendThis) { +export function ifNoUserSend(sendThis) { return function(req, res, next) { if (req.user) { return next(); } return res.status(200).send(sendThis); }; -}; +} -exports.ifNoUser401 = function ifNoUser401(req, res, next) { +export function ifNoUser401(req, res, next) { if (req.user) { return next(); } return res.status(401).end(); -}; +} diff --git a/server/utils/rx.js b/server/utils/rx.js index d3b1ac41b0..68086d2563 100644 --- a/server/utils/rx.js +++ b/server/utils/rx.js @@ -1,7 +1,9 @@ -var Rx = require('rx'); -var debug = require('debug')('freecc:rxUtils'); +import Rx from 'rx'; +import debugFactory from 'debug'; -exports.saveInstance = function saveInstance(instance) { +const debug = debugFactory('freecc:rxUtils'); + +export function saveInstance(instance) { return new Rx.Observable.create(function(observer) { if (!instance || typeof instance.save !== 'function') { debug('no instance or save method'); @@ -17,16 +19,15 @@ exports.saveInstance = function saveInstance(instance) { observer.onCompleted(); }); }); -}; +} // alias saveInstance -exports.saveUser = exports.saveInstance; +export const saveUser = saveInstance; -exports.observeQuery = exports.observableQueryFromModel = - function observableQueryFromModel(Model, method, query) { - return Rx.Observable.fromNodeCallback(Model[method], Model)(query); - }; +export function observeQuery(Model, method, query) { + return Rx.Observable.fromNodeCallback(Model[method], Model)(query); +} -exports.observeMethod = function observeMethod(context, methodName) { +export function observeMethod(context, methodName) { return Rx.Observable.fromNodeCallback(context[methodName], context); -}; +} diff --git a/server/views/account/show.jade b/server/views/account/show.jade index 5f07918815..530f74b746 100644 --- a/server/views/account/show.jade +++ b/server/views/account/show.jade @@ -58,8 +58,13 @@ block content h1.flat-top.wrappable= name h1.flat-top.wrappable= location h1.flat-top.text-primary= "[ " + (progressTimestamps.length) + " ]" + if isFrontEndCert + a.btn.btn-primary(href='/' + username + '/front-end-certification') View My Front End Development Certification + if isFullStackCert + .button-spacer + a.btn.btn-success(href='/' + username + '/full-stack-certification') View My Full Stack Development Certification if (user && user.username !== username) - a.btn.btn-lg.btn-block.btn-twitter.btn-link-social(href='/link/twitter') + a.btn.btn-lg.btn-block.btn-twitter.btn-link-social(href='/leaderboard/add?username=#{username}') i.fa.fa-plus-square | Add them to my personal leaderboard diff --git a/server/views/certificate/font.jade b/server/views/certificate/font.jade new file mode 100644 index 0000000000..54b76b935f --- /dev/null +++ b/server/views/certificate/font.jade @@ -0,0 +1,45 @@ +style. + @font-face { + font-family: "Sax Mono"; + src: url("/fonts/saxmono.ttf") format("truetype"); + } + + body { + display: inline-block; + font-family: "Sax Mono", monospace; + margin: 0; + position: absolute; + text-align: center; + } + + .img-abs { + left 0; + position: relative; + top: 0; + width: 2000px + } + + .cert-name { + font-size: 64px; + left: 1000px; + position: absolute; + top: 704px; + z-index: 1000; + } + + .cert-date { + font-size: 60px; + left: 760px; + position: absolute; + top: 1004.8px; + z-index: 1000; + } + + .cert-link { + font-size: 22px; + left: 120px; + position: absolute; + top: 1488px; + z-index: 1000; + } + diff --git a/server/views/certificate/front-end.jade b/server/views/certificate/front-end.jade new file mode 100644 index 0000000000..379dfb7dd1 --- /dev/null +++ b/server/views/certificate/front-end.jade @@ -0,0 +1,6 @@ +include font +#name.cert-name= name +img#cert.img-abs(src='http://i.imgur.com/ToFZKBd.jpg') +.cert-date= date +.cert-link verify this certification at: http://freecodecamp.com/#{username}/front-end-certification +include script diff --git a/server/views/certificate/full-stack.jade b/server/views/certificate/full-stack.jade new file mode 100644 index 0000000000..95c94a6eb0 --- /dev/null +++ b/server/views/certificate/full-stack.jade @@ -0,0 +1,6 @@ +include font +#name.cert-name= name +img#cert.img-abs(src='http://i.imgur.com/Z4PgjBQ.jpg') +.cert-date= date +.cert-link verify this certification at: http://freecodecamp.com/#{username}/full-stack-certification +include script diff --git a/server/views/certificate/index.jade b/server/views/certificate/index.jade new file mode 100644 index 0000000000..51e0294db2 --- /dev/null +++ b/server/views/certificate/index.jade @@ -0,0 +1,7 @@ +extends ../layout +block content + .panel.panel-info + .panel-heading.text-center + h1 Certificate + .panel-body + p foo diff --git a/server/views/certificate/script.jade b/server/views/certificate/script.jade new file mode 100644 index 0000000000..ccb83323c5 --- /dev/null +++ b/server/views/certificate/script.jade @@ -0,0 +1,8 @@ +script. + (function() { + var containerWidth = document.getElementById('cert').offsetWidth; + var nameDiv = document.getElementById('name'); + var nameWidth = nameDiv.offsetWidth; + console.log(containerWidth, nameWidth); + nameDiv.style.left = ((containerWidth - nameWidth) / 2) + 15; + })(); diff --git a/server/views/coursewares/showStep.jade b/server/views/coursewares/showStep.jade index f89d65eda2..fa8f11431a 100644 --- a/server/views/coursewares/showStep.jade +++ b/server/views/coursewares/showStep.jade @@ -9,7 +9,7 @@ block content .caption p.large-p= step[2] if step[3] - a.btn.btn-block.btn-primary.challenge-step-btn-action(href='#{step[3]}' target='_blank') Go To Link + a.btn.btn-block.btn-primary.challenge-step-btn-action(id='#{index}' href='#{step[3]}' target='_blank') Go To Link if index + 1 === description.length .btn.btn-block.btn-primary.challenge-step-btn-finish(id='last' class=step[3] ? 'disabled' : '') Finish challenge else @@ -32,8 +32,12 @@ block content a.btn.btn-lg.btn-primary.btn-block(href='/challenges/next-challenge?id=' + challengeId) Go to my next challenge script(src=rev('/js', 'commonFramework.js')) script. - var common = common || { init: [] }; + var common = window.common || { init: [] }; common.challengeId = !{JSON.stringify(challengeId)}; common.challengeName = !{JSON.stringify(name)}; common.challengeType = 7; common.dashedName = !{JSON.stringify(dashedName || '')}; + common.isHonest = !{JSON.stringify(isHonest || false)}; + common.isFrontEndCert = !{JSON.stringify(isFrontEndCert || false)}; + common.isFullStackCert = !{JSON.stringify(isFullStackCert || false)}; + common.challengeSeed = !{JSON.stringify(challengeSeed || [])}; From 34efc43f6a5cf5c0d1d6d76eb4fa5ca85ce8c110 Mon Sep 17 00:00:00 2001 From: Quincy Larson Date: Mon, 5 Oct 2015 17:18:35 -0700 Subject: [PATCH 2/2] update copy of certificate flows --- .../front-end-development-certificate.json | 26 ++++++++++++++----- .../full-stack-development-certificate.json | 26 ++++++++++++++----- server/boot/certificate.js | 8 ++++++ server/boot/user.js | 4 ++- 4 files changed, 49 insertions(+), 15 deletions(-) diff --git a/seed/challenges/front-end-development-certificate.json b/seed/challenges/front-end-development-certificate.json index ac8b53ee21..351809e702 100644 --- a/seed/challenges/front-end-development-certificate.json +++ b/seed/challenges/front-end-development-certificate.json @@ -9,21 +9,33 @@ { "properties": ["isHonest", "isFrontEndCert"], "apis": ["/certificate/honest", "/certificate/verify/front-end"], - "stepIndex": [0, 1] + "stepIndex": [1, 2] } ], "description": [ [ - "http://i.imgur.com/RlEk2IF.jpg", - "a picture of Free Code Camp's 4 benefits: Get connected, Learn JavaScript, Build your Portfolio, Help nonprofits", - "Welcome to Free Code Camp. We're an open source community of busy people who learn to code and help nonprofits.", + "http://i.imgur.com/luMkKst.jpg", + "An image of our Front End Development Certificate", + "This challenge will give you your verified Front End Development Certificate. Before we issue your certificate, we must verify that you have completed all of our basic and intermediate Bonfires, and all our basic and intermediate Ziplines. You must also accept our Academic Honesty Pledge. Click the button below to start this process.", + "" + ], + [ + "http://i.imgur.com/HArFfMN.jpg", + "The definition of plagiarism: Plagiarism (noun) - copying someone else’s work and presenting it as your own without crediting them", + "By clicking below, you pledge that all of your submitted code A) is code you or your pair personally wrote, or B) comes from open source libraries like jQuery, or C) has been clearly attributed to its original authors. You also give us permission to audit your challenge solutions and revoke your certificate if we discover evidence of plagiarism.", "#" ], [ - "http://i.imgur.com/RlEk2IF.jpg", - "a picture of Free Code Camp's 4 benefits: Get connected, Learn JavaScript, Build your Portfolio, Help nonprofits", - "Welcome to Free Code Camp. We're an open source community of busy people who learn to code and help nonprofits.", + "http://i.imgur.com/14F2Van.jpg", + "An image of the text \"Front End Development Certificate requirements\"", + "Let's confirm that you have completed all of our basic and intermediate Bonfires, and all our basic and intermediate Ziplines. Click the button below to verify this.", "#" + ], + [ + "http://i.imgur.com/16SIhHO.jpg", + "An image of the word \"Congratulations\"", + "Congratulations! We've added your Front End Development Certificate to your certificate to your portfolio page. Unless you choose to hide your solutions, this certificate will remain publicly visible and verifiable.", + "" ] ], "type": "Waypoint", diff --git a/seed/challenges/full-stack-development-certificate.json b/seed/challenges/full-stack-development-certificate.json index bfb2f7df4a..7ae95c94e7 100644 --- a/seed/challenges/full-stack-development-certificate.json +++ b/seed/challenges/full-stack-development-certificate.json @@ -10,21 +10,33 @@ { "properties": ["isHonest", "isFullStackCert"], "apis": ["/certificate/honest", "/certificate/verify/full-stack"], - "stepIndex": [0, 1] + "stepIndex": [1, 2] } ], "description": [ [ - "http://i.imgur.com/RlEk2IF.jpg", - "a picture of Free Code Camp's 4 benefits: Get connected, Learn JavaScript, Build your Portfolio, Help nonprofits", - "Welcome to Free Code Camp. We're an open source community of busy people who learn to code and help nonprofits.", + "http://i.imgur.com/qXublEe.jpg", + "An image of our Full Stack Development Certificate", + "This challenge will give you your verified Full Stack Development Certificate. Before we issue your certificate, we must verify that you have completed all of Bonfires, Ziplines and Basejumps. You must also accept our Academic Honesty Pledge. Click the button below to start this process.", + "" + ], + [ + "http://i.imgur.com/HArFfMN.jpg", + "The definition of plagiarism: Plagiarism (noun) - copying someone else’s work and presenting it as your own without crediting them", + "By clicking below, you pledge that all of your submitted code A) is code you or your pair personally wrote, or B) comes from open source libraries like jQuery, or C) has been clearly attributed to its original authors. You also give us permission to audit your challenge solutions and revoke your certificate if we discover evidence of plagiarism.", "#" ], [ - "http://i.imgur.com/RlEk2IF.jpg", - "a picture of Free Code Camp's 4 benefits: Get connected, Learn JavaScript, Build your Portfolio, Help nonprofits", - "Welcome to Free Code Camp. We're an open source community of busy people who learn to code and help nonprofits.", + "http://i.imgur.com/2qn7tHp.jpg", + "An image of the text \"Full Stack Development Certificate requirements\"", + "Let's confirm that you have completed all of our Bonfires, Ziplines and Basejumps. Click the button below to verify this.", "#" + ], + [ + "http://i.imgur.com/16SIhHO.jpg", + "An image of the word \"Congratulations\"", + "Congratulations! We've added your Full Stack Development Certificate to your certificate to your portfolio page. Unless you choose to hide your solutions, this certificate will remain publicly visible and verifiable.", + "" ] ], "type": "Waypoint", diff --git a/server/boot/certificate.js b/server/boot/certificate.js index b6a3db9461..ba28cb8a16 100644 --- a/server/boot/certificate.js +++ b/server/boot/certificate.js @@ -91,8 +91,16 @@ export default function certificate(app) { debug('certified'); if (isFront) { user.isFrontEndCert = true; + user.completedChallenges.push({ + completedDate: new Date(), + id: frontEndChallangeId + }) } else { user.isFullStackCert = true; + user.completedChallenges.push({ + completedDate: new Date(), + id: fullStackChallangeId + }) } return saveUser(user); } diff --git a/server/boot/user.js b/server/boot/user.js index 9567a5066a..a7c6fe2978 100644 --- a/server/boot/user.js +++ b/server/boot/user.js @@ -275,7 +275,9 @@ module.exports = function(app) { !showFront && user.isFullStackCert ) { var { completedDate } = _.find(user.completedChallenges, { - id: '561add10cb82ac38a17513be' + id: showFront ? + '561add10cb82ac38a17513be' : + '660add10cb82ac38a17513be' }); return res.render(