From 4101a6c34a4566fbc8d96a0cda8a98eb126656ae Mon Sep 17 00:00:00 2001 From: Quincy Larson Date: Sat, 9 Jan 2016 15:32:52 -0600 Subject: [PATCH 01/65] start simplifying views --- client/less/lib/bootstrap/variables.less | 2 +- client/less/main.less | 28 +- server/views/account/show.jade | 404 ++++++++++-------- server/views/challengeMap/show.jade | 378 ++++++++-------- server/views/coursewares/showBonfire.jade | 8 +- server/views/coursewares/showHTML.jade | 30 +- server/views/coursewares/showStep.jade | 6 +- .../coursewares/showZiplineOrBasejump.jade | 22 +- server/views/home.jade | 201 +++++---- server/views/stories/index.jade | 36 +- server/views/stories/news-nav.jade | 8 +- 11 files changed, 593 insertions(+), 530 deletions(-) diff --git a/client/less/lib/bootstrap/variables.less b/client/less/lib/bootstrap/variables.less index 8b8fefa81d..37c18097bc 100755 --- a/client/less/lib/bootstrap/variables.less +++ b/client/less/lib/bootstrap/variables.less @@ -26,7 +26,7 @@ //## Settings for some of the most global styles. //** Background color for ``. -@body-bg: #457E86; +@body-bg: #fefefe; //** Global text color on ``. @text-color: @gray-dark; diff --git a/client/less/main.less b/client/less/main.less index 0780dde86e..a513acf2e1 100644 --- a/client/less/main.less +++ b/client/less/main.less @@ -42,13 +42,17 @@ html { overflow-x: hidden; } -input[type=checkbox] { - /* Double-sized Checkboxes */ - -ms-transform: scale(2); /* IE */ - -moz-transform: scale(2); /* FF */ - -webkit-transform: scale(2); /* Safari and Chrome */ - -o-transform: scale(2); /* Opera */ - padding: 10px; +//input[type=checkbox] { +// /* Double-sized Checkboxes */ +// -ms-transform: scale(2); /* IE */ +// -moz-transform: scale(2); /* FF */ +// -webkit-transform: scale(2); /* Safari and Chrome */ +// -o-transform: scale(2); /* Opera */ +// padding: 10px; +//} + +.btn-group { + border-color: @brand-primary; } body.full-screen-body-background { @@ -327,13 +331,13 @@ ul { } .navbar { - background-color: #4a2b0f; + background-color: #215f1e; } .navbar-nav > li > a { color: @gray-lighter; &:hover { - color: #4a2b0f; + color: #215f1e; } } @@ -441,7 +445,7 @@ thead { } .navbar-right { - background-color: #4a2b0f; + background-color: #215f1e; text-align: center; } @@ -586,7 +590,7 @@ thead { width: 100%; height: 50px; text-align: center; - background-color: #4a2b0f; + background-color: #215f1e; padding: 12px; bottom: 0; left: 0; @@ -601,7 +605,7 @@ thead { padding-top: 14px; padding-bottom: 12px; &:hover { - color: #4a2b0f; + color: #215f1e; background-color: @gray-lighter; text-decoration: none; } diff --git a/server/views/account/show.jade b/server/views/account/show.jade index 545d2341e4..d24e22b261 100644 --- a/server/views/account/show.jade +++ b/server/views/account/show.jade @@ -4,185 +4,181 @@ block content script. var challengeName = 'Profile View'; if (user && user.username === username) - .panel.panel-info - .panel-heading.text-center Update your code portfolio - .panel-body - .row - .col-xs-12 - if (!user.isGithubCool) - a.btn.btn-lg.btn-block.btn-github.btn-link-social(href='/link/github') - i.fa.fa-github - | Link my GitHub to unlock my portfolio - else - a.btn.btn-lg.btn-block.btn-github.btn-link-social(href='/link/github') - i.fa.fa-github - | Update my name, username, and location with data from my GitHub account - if (!user.twitter) - a.btn.btn-lg.btn-block.btn-twitter.btn-link-social(href='/link/twitter') - i.fa.fa-twitter - | Add my Twitter to my portfolio - if (!user.facebook) - a.btn.btn-lg.btn-block.btn-facebook.btn-link-social(href='/link/facebook') - i.fa.fa-facebook - | Add my Facebook to my portfolio - if (!user.linkedin) - a.btn.btn-lg.btn-block.btn-linkedin.btn-link-social(href='/link/linkedin') - i.fa.fa-linkedin - | Add my LinkedIn to my portfolio - if (!user.google) - a.btn.btn-lg.btn-block.btn-google-plus.btn-link-social(href='/link/google') - i.fa.fa-google-plus - | Add my Google+ to my portfolio + h1.text-center Update your code portfolio + .row + .col-xs-12 + if (!user.isGithubCool) + a.btn.btn-lg.btn-block.btn-github.btn-link-social(href='/link/github') + i.fa.fa-github + | Link my GitHub to unlock my portfolio + else + a.btn.btn-lg.btn-block.btn-github.btn-link-social(href='/link/github') + i.fa.fa-github + | Update my portfolio from GitHub + if (!user.twitter) + a.btn.btn-lg.btn-block.btn-twitter.btn-link-social(href='/link/twitter') + i.fa.fa-twitter + | Add my Twitter to my portfolio + if (!user.facebook) + a.btn.btn-lg.btn-block.btn-facebook.btn-link-social(href='/link/facebook') + i.fa.fa-facebook + | Add my Facebook to my portfolio + if (!user.linkedin) + a.btn.btn-lg.btn-block.btn-linkedin.btn-link-social(href='/link/linkedin') + i.fa.fa-linkedin + | Add my LinkedIn to my portfolio + if (!user.google) + a.btn.btn-lg.btn-block.btn-google-plus.btn-link-social(href='/link/google') + i.fa.fa-google-plus + | Add my Google+ to my portfolio - .panel.panel-info - .panel-heading.text-center - h1 #{username}'s code portfolio - .panel-body + h1.text-center #{username}'s code portfolio + hr + .row + .col-xs-12.col-sm-10.col-sm-offset-1.col-md-8.col-md-offset-2.text-center + if picture + img.img-center.img-responsive.public-profile-img(src=picture) + else + img.img-center.img-responsive.public-profile-img(src='https://s3.amazonaws.com/freecodecamp/camper-image-placeholder.png') + h1.text-center.negative-5.profile-social-icons + if (twitter) + a.fa.fa-twitter-square.text-primary(title="@#{username}'s Twitter Profile", href='https://twitter.com/' + twitter, target='_blank') + if (github) + a.fa.fa-github-square.text-primary(title="@#{username}'s GitHub Profile", href=github, target='_blank') + if (linkedin) + a.fa.fa-linkedin-square.text-primary(title="@#{username}'s LinkedIn Profile", href=linkedin, target='_blank') + if (facebook) + a.fa.fa-facebook-square.text-primary(title="@#{username}'s Facebook Profile", href='https://facebook.com/' + facebook, target='_blank') + if (google) + a.fa.fa-google-plus-square.text-primary(title="@#{username}'s Google Profile", href='https://plus.google.com/' + google, target='_blank') + h1.flat-top.wrappable= name + h1.flat-top.wrappable= location + h1.flat-top.text-primary= "[ " + (progressTimestamps.length) + " ]" + if pledge + .spacer + h4 + | This camper has committed to giving $#{pledge.amount} to + a(href='#{pledge.donateUrl}?ref=freecodecamp.com' target='_blank') #{pledge.displayName} + | each month until they have completed their #{pledge.goal}. + .spacer + if isFrontEndCert + a.btn.btn-primary(href='/' + username + '/front-end-certification') View My Front End Development Certification + if isDataVisCert + .button-spacer + a.btn.btn-success(href='/' + username + '/data-visualization-certification') View My Data Visualization Certification + if isBackEndCert + .button-spacer + a.btn.btn-success(href='/' + username + '/back-end-certification') View My Back End Development Certification + //if (user && user.username !== username) + // 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 + .spacer + .col-md-12 + #cal-heatmap.hidden-xs.hidden-sm.d3-centered + script. + $(document).ready(function () { + var cal = new CalHeatMap(); + var calendar = !{JSON.stringify(calender)}; + /* + var estUTCOffset = -5; + // moment returns the utc offset in minutes + var userUTCOffset = moment().utcOffset() / 60; + var secondsToOffset = + (estUTCOffset - userUTCOffset) * 3600; + var offsetCalendar = {}; + for (var prop in calendar) { + if (calendar.hasOwnProperty(prop)) { + var offsetProp = prop + secondsToOffset; + offsetCalendar[offsetProp] = calendar[prop]; + } + } + */ + cal.init({ + itemSelector: "#cal-heatmap", + domain: "month", + subDomain: "x_day", + domainGutter: 10, + data: calendar, + cellSize: 15, + align: 'center', + cellRadius: 3, + cellPadding: 2, + tooltip: true, + range: 6, + start: new Date().setDate(new Date().getDate() - 150), + legendColors: ["#cccccc", "#215f1e"], + legend: [1, 2, 3], + label: { + position: "top" + } + }); + }); .row - .col-xs-12.col-sm-10.col-sm-offset-1.col-md-8.col-md-offset-2.text-center - if picture - img.img-center.img-responsive.public-profile-img(src=picture) - else - img.img-center.img-responsive.public-profile-img(src='https://s3.amazonaws.com/freecodecamp/camper-image-placeholder.png') - h1.text-center.negative-5.profile-social-icons - if (twitter) - a.fa.fa-twitter-square.text-primary(title="@#{username}'s Twitter Profile", href='https://twitter.com/' + twitter, target='_blank') - if (github) - a.fa.fa-github-square.text-primary(title="@#{username}'s GitHub Profile", href=github, target='_blank') - if (linkedin) - a.fa.fa-linkedin-square.text-primary(title="@#{username}'s LinkedIn Profile", href=linkedin, target='_blank') - if (facebook) - a.fa.fa-facebook-square.text-primary(title="@#{username}'s Facebook Profile", href='https://facebook.com/' + facebook, target='_blank') - if (google) - a.fa.fa-google-plus-square.text-primary(title="@#{username}'s Google Profile", href='https://plus.google.com/' + google, target='_blank') - h1.flat-top.wrappable= name - h1.flat-top.wrappable= location - h1.flat-top.text-primary= "[ " + (progressTimestamps.length) + " ]" - if pledge - .spacer - h4 - | This camper has committed to giving $#{pledge.amount} to - a(href='#{pledge.donateUrl}?ref=freecodecamp.com' target='_blank') #{pledge.displayName} - | each month until they have completed their #{pledge.goal}. - .spacer - if isFrontEndCert - a.btn.btn-primary(href='/' + username + '/front-end-certification') View My Front End Development Certification - if isDataVisCert - .button-spacer - a.btn.btn-success(href='/' + username + '/data-visualization-certification') View My Data Visualization Certification - if isBackEndCert - .button-spacer - a.btn.btn-success(href='/' + username + '/back-end-certification') View My Back End Development Certification - //if (user && user.username !== username) - // 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 - - .spacer - .col-md-12 - #cal-heatmap.hidden-xs.hidden-sm.d3-centered - script. - $(document).ready(function () { - var cal = new CalHeatMap(); - var calendar = !{JSON.stringify(calender)}; - /* - var estUTCOffset = -5; - // moment returns the utc offset in minutes - var userUTCOffset = moment().utcOffset() / 60; - var secondsToOffset = - (estUTCOffset - userUTCOffset) * 3600; - var offsetCalendar = {}; - for (var prop in calendar) { - if (calendar.hasOwnProperty(prop)) { - var offsetProp = prop + secondsToOffset; - offsetCalendar[offsetProp] = calendar[prop]; - } - } - */ - cal.init({ - itemSelector: "#cal-heatmap", - domain: "month", - subDomain: "x_day", - domainGutter: 10, - data: calendar, - cellSize: 15, - align: 'center', - cellRadius: 3, - cellPadding: 2, - tooltip: true, - range: 6, - start: new Date().setDate(new Date().getDate() - 150), - legendColors: ["#cccccc", "#215f1e"], - legend: [1, 2, 3], - label: { - position: "top" - } - }); - }); - .row - .hidden-xs.col-sm-12.text-center - .row.text-primary - h4.col-sm-6.text-right Longest Streak: #{longestStreak} #{longestStreak === 1 ? ' day' : ' days'} - h4.col-sm-6.text-left Current Streak: #{currentStreak} #{currentStreak === 1 ? ' day' : ' days'} + .hidden-xs.col-sm-12.text-center + .row.text-primary + h4.col-sm-6.text-right Longest Streak: #{longestStreak} #{longestStreak === 1 ? ' day' : ' days'} + h4.col-sm-6.text-left Current Streak: #{currentStreak} #{currentStreak === 1 ? ' day' : ' days'} - if (user && user.username == username || !isLocked) - if (baseAndZip.length > 0) - .col-sm-12 - table.table.table-striped - thead - tr - th.col-xs-6 Projects - th.col-xs-3.hidden-xs Completed - th.col-xs-3.hidden-xs Link - for challenge in baseAndZip - tr - td.col-xs-4.hidden-xs - a(href='/challenges/' + challenge.name, target='_blank')= challenge.name - td.col-xs-2.hidden-xs= challenge.completedDate ? moment(challenge.completedDate, 'x').format("MMM DD, YYYY") : 'Not Available' - td.col-xs-6.hidden-xs - a(href=challenge.solution, target='_blank') View my project - td.col-xs-12.visible-xs - a(href=challenge.solution, target='_blank')=challenge.name - if (bonfires.length > 0) - .col-sm-12 - table.table.table-striped - thead - tr - th.col-xs-6 Bonfires - th.col-xs-3.hidden-xs Completed - th.col-xs-3.hidden-xs Solution - for bonfire in bonfires - tr - td.col-xs-6.hidden-xs= bonfire.name - td.col-xs-3.hidden-xs= bonfire.completedDate ? moment(bonfire.completedDate, 'x').format("MMM DD, YYYY") : 'Not Available' - td.col-xs-3.hidden-xs - a(href='/challenges/' + bonfire.name + '?solution=' + encodeURIComponent(encodeFcc(bonfire.solution)), target='_blank') View my solution - td.col-xs-12.visible-xs - a(href='/challenges/' + bonfire.name + '?solution=' + encodeURIComponent(encodeFcc(bonfire.solution)), target='_blank')= bonfire.name - if (waypoints.length > 0) - .col-sm-12 - table.table.table-striped - thead - tr - th.col-xs-6 Waypoints - th.col-xs-3.hidden-xs Completed - th.col-xs-3.hidden-xs Solution - for challenge in waypoints - tr - td.col-xs-6.hidden-xs= challenge.name - td.col-xs-3.hidden-xs= challenge.completedDate ?moment(challenge.completedDate, 'x').format("MMM DD, YYYY") : 'Not Available' - td.col-xs-3.hidden-xs - if (challenge.solution) - a(href='/challenges/' + challenge.name + '?solution=' + encodeURIComponent(encodeFcc(challenge.solution)), target='_blank') View my solution - else - a(href='/challenges/' + challenge.name) View this challenge - td.col-xs-12.visible-xs - if (challenge.solution) - a(href='/challenges/' + challenge.name + '?solution=' + encodeURIComponent(encodeFcc(challenge.solution)), target='_blank')= challenge.name - else - a(href='/challenges/' + challenge.name)= challenge.name + if (user && user.username == username || !isLocked) + if (baseAndZip.length > 0) + .col-sm-12 + table.table.table-striped + thead + tr + th.col-xs-6 Projects + th.col-xs-3.hidden-xs Completed + th.col-xs-3.hidden-xs Link + for challenge in baseAndZip + tr + td.col-xs-4.hidden-xs + a(href='/challenges/' + challenge.name, target='_blank')= challenge.name + td.col-xs-2.hidden-xs= challenge.completedDate ? moment(challenge.completedDate, 'x').format("MMM DD, YYYY") : 'Not Available' + td.col-xs-6.hidden-xs + a(href=challenge.solution, target='_blank') View my project + td.col-xs-12.visible-xs + a(href=challenge.solution, target='_blank')=challenge.name + if (bonfires.length > 0) + .col-sm-12 + table.table.table-striped + thead + tr + th.col-xs-6 Bonfires + th.col-xs-3.hidden-xs Completed + th.col-xs-3.hidden-xs Solution + for bonfire in bonfires + tr + td.col-xs-6.hidden-xs= bonfire.name + td.col-xs-3.hidden-xs= bonfire.completedDate ? moment(bonfire.completedDate, 'x').format("MMM DD, YYYY") : 'Not Available' + td.col-xs-3.hidden-xs + a(href='/challenges/' + bonfire.name + '?solution=' + encodeURIComponent(encodeFcc(bonfire.solution)), target='_blank') View my solution + td.col-xs-12.visible-xs + a(href='/challenges/' + bonfire.name + '?solution=' + encodeURIComponent(encodeFcc(bonfire.solution)), target='_blank')= bonfire.name + if (waypoints.length > 0) + .col-sm-12 + table.table.table-striped + thead + tr + th.col-xs-6 Waypoints + th.col-xs-3.hidden-xs Completed + th.col-xs-3.hidden-xs Solution + for challenge in waypoints + tr + td.col-xs-6.hidden-xs= challenge.name + td.col-xs-3.hidden-xs= challenge.completedDate ?moment(challenge.completedDate, 'x').format("MMM DD, YYYY") : 'Not Available' + td.col-xs-3.hidden-xs + if (challenge.solution) + a(href='/challenges/' + challenge.name + '?solution=' + encodeURIComponent(encodeFcc(challenge.solution)), target='_blank') View my solution + else + a(href='/challenges/' + challenge.name) View this challenge + td.col-xs-12.visible-xs + if (challenge.solution) + a(href='/challenges/' + challenge.name + '?solution=' + encodeURIComponent(encodeFcc(challenge.solution)), target='_blank')= challenge.name + else + a(href='/challenges/' + challenge.name)= challenge.name if (user && user.username === username) +<<<<<<< b157fa3095437bb5d39b91e23581589744f6aca0 .panel.panel-info .panel-heading.text-center Manage your account .panel-body @@ -242,3 +238,63 @@ block content button.btn.btn-danger.btn-block(type='submit') span.ion-trash-b | I am 100% sure I want to delete my account and all of my progress +======= + h1.text-center Manage your account + hr + .col-xs-12 + a.btn.btn-lg.btn-block.btn-warning.btn-link-social(href='/logout') + span.ion-android-exit + | Sign me out of Free Code Camp + .col-xs-12 + a.btn.btn-lg.btn-block.btn-primary.btn-link-social(href='mailto:team@freecodecamp.com') + span.ion-email + | Email us at team@freecodecamp.com + if (!user.isLocked) + .col-xs-12 + a.btn.btn-lg.btn-block.btn-info.btn-link-social(href='/toggle-lockdown-mode') + span.ion-locked + | Hide all my solutions from other people + br + | (this will disable your certificates) + else + .col-xs-12 + a.btn.btn-lg.btn-block.btn-info.btn-link-social(href='/toggle-lockdown-mode') + span.ion-unlocked + | Let other people see all my solutions + br + | (this will enable your certificates) + .col-xs-12 + a.btn.btn-lg.btn-block.btn-success.btn-link-social(href='/commit') + span.ion-edit + | Edit my pledge + .col-xs-12 + a.btn.btn-lg.btn-block.btn-danger.btn-link-social.confirm-deletion + span.ion-trash-b + | Delete my Free Code Camp account + script. + $('.confirm-deletion').on("click", function () { + $('#modal-dialog').modal('show'); + }); + #modal-dialog.modal.animated.wobble + .modal-dialog + .modal-content + .modal-header + a.close(href='#', data-dismiss='modal', aria-hidden='true') × + h3 You don't really want to delete your account, do you? + .modal-body + p This will really delete all your data, including all your progress, news stories and brownie points. + p We won't be able to recover any of it for you later, even if you change your mind. + p If there's something we could do better, send us an email instead and we'll do our best:   + a(href="mailto:team@freecodecamp.com") team@freecodecamp.com + | . + .modal-footer + a.btn.btn-success.btn-block(href='#', data-dismiss='modal', aria-hidden='true') + span.ion-happy + | Nevermind, I don't want to delete all of my progress + .spacer + form(action='/account/delete', method='POST') + input(type='hidden', name='_csrf', value=_csrf) + button.btn.btn-danger.btn-block(type='submit') + span.ion-trash-b + | I am 100% sure I want to delete my account and all of my progress +>>>>>>> start simplifying views diff --git a/server/views/challengeMap/show.jade b/server/views/challengeMap/show.jade index fc5f39d629..9f7b3929e5 100644 --- a/server/views/challengeMap/show.jade +++ b/server/views/challengeMap/show.jade @@ -1,201 +1,199 @@ extends ../layout block content - .panel.panel-info - .panel-heading.text-center - h1 Challenge Map - .panel-body - if (Math.random() > 0.999) - img.img-responsive.img-center.border-radius-5(src='https://s3.amazonaws.com/freecodecamp/wide-social-banner-dino.png') - audio(autoplay src='https://s3.amazonaws.com/freecodecamp/t-rex-roar.mp3') - else - img.img-responsive.img-center.border-radius-5(src='https://s3.amazonaws.com/freecodecamp/wide-social-banner.png') - .col-xs-12.col-md-8.col-md-offset-2 - h2 - table.population-table.img-center - tr - td Established:  - td - span.text-primary #{daysRunning}  - | days ago - tr - td Population:    - td - span.text-primary #{camperCount}  - | campers - tr - td Completed:    - td - span.text-primary #{globalCompletedCount}  - | challenges + h1.text-center Challenge Map + hr + if (Math.random() > 0.999) + img.img-responsive.img-center.border-radius-5(src='https://s3.amazonaws.com/freecodecamp/wide-social-banner-dino.png') + audio(autoplay src='https://s3.amazonaws.com/freecodecamp/t-rex-roar.mp3') + else + img.img-responsive.img-center.border-radius-5(src='https://s3.amazonaws.com/freecodecamp/wide-social-banner.png') + .col-xs-12.col-md-8.col-md-offset-2 + h2 + table.population-table.img-center + tr + td Established:  + td + span.text-primary #{daysRunning}  + | days ago + tr + td Population:    + td + span.text-primary #{camperCount}  + | campers + tr + td Completed:    + td + span.text-primary #{globalCompletedCount}  + | challenges - .spacer - if (user && user.progressTimestamps.length > 100) - .row - #map-notice.col-xs-12.col-md-8.col-md-offset-2.hidden - h2.text-center Reddit or not, here we come - img.thumbnail.img-center.img-responsive(src="http://i.imgur.com/lyd0bfM.jpg") - h4.text-center Come ask questions and share your thoughts with our entire open source community on our subreddit. - a.button.btn.btn-block.btn-primary(href="https://reddit.com/r/freecodecamp" target="_blank") Check it out - .button-spacer - .text-center - a#hide-map-notice-button(href='#') Hide this forever - .spacer - - ul - for superBlock in superBlocks - h2= superBlock.name - - var i = 0 - for challengeBlock in superBlock.blocks - - i++ - .row - if (user) - if (challengeBlock.completed === 100) - .hidden-xs.col-sm-3.col-md-2.text-primary.ion-checkmark-circled.padded-ionic-icon.text-center.map-p.negative-10 - .col-xs-1.col-sm-1.col-md-1.map-row-numbers.negative-5 - span.map-p.negative-10 #{i}. - .col-xs-11.col-sm-8.col-md-9 - li.map-p.faded.negative-10 - a(href='#' + challengeBlock.dashedName)= challengeBlock.name - if challengeBlock.markNew - span.text-info.small     - strong - em NEW - if challengeBlock.isComingSoon - span.text-info.small     - strong - em Coming Soon - else - .hidden-xs.col-sm-3.col-md-2 - .progress.progress-bar-padding.text-center.thin-progress-bar - .progress-bar(role='progressbar', aria-valuenow=(challengeBlock.completed), aria-valuemin='0', aria-valuemax='100', style='width: ' + challengeBlock.completed + '%;') - .col-xs-1.col-sm-1.col-md-1.map-row-numbers.negative-5 - span.map-p #{i}. - .col-xs-11.col-sm-8.col-md-9 - li.map-p.negative-10 - a(href='#' + challengeBlock.dashedName)= challengeBlock.name - if challengeBlock.markNew - span.text-info.small     - strong - em NEW - if challengeBlock.isComingSoon - span.text-info.small     - strong - em Coming Soon - else - .hidden-xs.col-sm-3.col-md-2 - .col-xs-1.col-sm-1.col-md-1.map-row-numbers - span.map-p.negative-10 #{i}. - .col-xs-10.col-sm-8.col-md-9 - span.map-p.negative-10 - a(href='#' + challengeBlock.dashedName)= challengeBlock.name - if challengeBlock.markNew - span.text-info.small     - strong - em NEW - if challengeBlock.isComingSoon - span.text-info.small     - strong - em Coming Soon - h2 Full Stack Development Certification - .row - .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 Greenfield Nonprofit Project 1 - .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 Greenfield Nonprofit Project 2 - .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 Legacy Nonprofit Project 1 - .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 Legacy Nonprofit Project 2 - .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 Claim your Full Stack Development Certification - - h2 Coding Interview Preparation - .row - .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 Whiteboard Coding Interview Training - .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 Critical Thinking Interview Training - .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 Mock Interview 1 - .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 Mock Interview 2 - .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 Mock Interview 3 - - hr - - for superBlock, index in superBlocks - for challengeBlock in superBlock.blocks - .row - a(href='#' name=challengeBlock.dashedName) - .spacer.negative-55 - - .row - .hidden-xs.col-sm-3.col-md-2 - h3.text-primary.text-right.nowrap - i.fa.fa-clock-o - = challengeBlock.time - .col-xs-12.col-sm-9.col-md-10 - h3 #{challengeBlock.name}   - - - var i = 0 - for challenge in challengeBlock.challenges - - i++ - .row - if challenge.completed - .hidden-xs.col-sm-3.col-md-2.text-primary.ion-checkmark-circled.padded-ionic-icon.text-center.map-p.negative-10 - .col-xs-1.col-sm-1.col-md-1.map-row-numbers - span.map-p.negative-10 #{i}. - .col-xs-10.col-sm-8.col-md-9 - span.faded.map-p.negative-10 - a(href="/challenges/#{challenge.dashedName}") - span.capitalize= challenge.type + ': ' - span= challenge.title - span.sr-only= " Complete" - - else - .hidden-xs.col-sm-3.col-md-2 - span.negative-10 - .col-xs-1.col-sm-1.col-md-1.map-row-numbers - span.map-p.negative-10 #{i}. - .col-xs-10.col-sm-8.col-md-9 - span.map-p.negative-10 - a(href="/challenges/#{challenge.dashedName}" class=challenge.isComingSoon ? 'disabled' : '') - span.capitalize= challenge.type + ': ' - span= challenge.title - span.sr-only= " Incomplete" - if challenge.markNew - span.text-info.small     - strong - em NEW - if challengeBlock.isComingSoon - span.text-info.small     - strong - em Coming Soon + .spacer + if (user && user.progressTimestamps.length > 100) + .row + #map-notice.col-xs-12.col-md-8.col-md-offset-2.hidden + h2.text-center Reddit or not, here we come + img.thumbnail.img-center.img-responsive(src="http://i.imgur.com/lyd0bfM.jpg") + h4.text-center Come ask questions and share your thoughts with our entire open source community on our subreddit. + a.button.btn.btn-block.btn-primary(href="https://reddit.com/r/freecodecamp" target="_blank") Check it out + .button-spacer + .text-center + a#hide-map-notice-button(href='#') Hide this forever + .spacer + ul + for superBlock in superBlocks + h2= superBlock.name + - var i = 0 + for challengeBlock in superBlock.blocks + - i++ + .row + if (user) if (challengeBlock.completed === 100) - .button-spacer - .row - .col-xs-12.col-sm-8.col-md-6.col-sm-offset-3.col-md-offset-2.hidden - a.btn.btn-lg.btn-block.signup-btn.map-challenge-block-share Section complete. Share your code portfolio with your friends. - .hidden(id="#{challengeBlock.name}") + .hidden-xs.col-sm-3.col-md-2.text-primary.ion-checkmark-circled.padded-ionic-icon.text-center.map-p.negative-10 + .col-xs-1.col-sm-1.col-md-1.map-row-numbers.negative-5 + span.map-p.negative-10 #{i}. + .col-xs-11.col-sm-8.col-md-9 + li.map-p.faded.negative-10 + a(href='#' + challengeBlock.dashedName)= challengeBlock.name + if challengeBlock.markNew + span.text-info.small     + strong + em NEW + if challengeBlock.isComingSoon + span.text-info.small     + strong + em Coming Soon + else + .hidden-xs.col-sm-3.col-md-2 + .progress.progress-bar-padding.text-center.thin-progress-bar + .progress-bar(role='progressbar', aria-valuenow=(challengeBlock.completed), aria-valuemin='0', aria-valuemax='100', style='width: ' + challengeBlock.completed + '%;') + .col-xs-1.col-sm-1.col-md-1.map-row-numbers.negative-5 + span.map-p #{i}. + .col-xs-11.col-sm-8.col-md-9 + li.map-p.negative-10 + a(href='#' + challengeBlock.dashedName)= challengeBlock.name + if challengeBlock.markNew + span.text-info.small     + strong + em NEW + if challengeBlock.isComingSoon + span.text-info.small     + strong + em Coming Soon + else + .hidden-xs.col-sm-3.col-md-2 + .col-xs-1.col-sm-1.col-md-1.map-row-numbers + span.map-p.negative-10 #{i}. + .col-xs-10.col-sm-8.col-md-9 + span.map-p.negative-10 + a(href='#' + challengeBlock.dashedName)= challengeBlock.name + if challengeBlock.markNew + span.text-info.small     + strong + em NEW + if challengeBlock.isComingSoon + span.text-info.small     + strong + em Coming Soon + h2 Full Stack Development Certification + .row + .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 Greenfield Nonprofit Project 1 + .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 Greenfield Nonprofit Project 2 + .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 Legacy Nonprofit Project 1 + .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 Legacy Nonprofit Project 2 + .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 Claim your Full Stack Development Certification - if (index < superBlocks.length - 1) - .spacer - hr - .spacer + h2 Coding Interview Preparation + .row + .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 Whiteboard Coding Interview Training + .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 Critical Thinking Interview Training + .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 Mock Interview 1 + .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 Mock Interview 2 + .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 Mock Interview 3 + + hr + + for superBlock, index in superBlocks + for challengeBlock in superBlock.blocks + .row + a(href='#' name=challengeBlock.dashedName) + .spacer.negative-55 + + .row + .hidden-xs.col-sm-3.col-md-2 + h3.text-primary.text-right.nowrap + i.fa.fa-clock-o + = challengeBlock.time + .col-xs-12.col-sm-9.col-md-10 + h3 #{challengeBlock.name}   + + - var i = 0 + for challenge in challengeBlock.challenges + - i++ + .row + if challenge.completed + .hidden-xs.col-sm-3.col-md-2.text-primary.ion-checkmark-circled.padded-ionic-icon.text-center.map-p.negative-10 + .col-xs-1.col-sm-1.col-md-1.map-row-numbers + span.map-p.negative-10 #{i}. + .col-xs-10.col-sm-8.col-md-9 + span.faded.map-p.negative-10 + a(href="/challenges/#{challenge.dashedName}") + span.capitalize= challenge.type + ': ' + span= challenge.title + span.sr-only= " Complete" + + else + .hidden-xs.col-sm-3.col-md-2 + span.negative-10 + .col-xs-1.col-sm-1.col-md-1.map-row-numbers + span.map-p.negative-10 #{i}. + .col-xs-10.col-sm-8.col-md-9 + span.map-p.negative-10 + a(href="/challenges/#{challenge.dashedName}" class=challenge.isComingSoon ? 'disabled' : '') + span.capitalize= challenge.type + ': ' + span= challenge.title + span.sr-only= " Incomplete" + if challenge.markNew + span.text-info.small     + strong + em NEW + if challengeBlock.isComingSoon + span.text-info.small     + strong + em Coming Soon + + if (challengeBlock.completed === 100) + .button-spacer + .row + .col-xs-12.col-sm-8.col-md-6.col-sm-offset-3.col-md-offset-2.hidden + a.btn.btn-lg.btn-block.signup-btn.map-challenge-block-share Section complete. Share your code portfolio with your friends. + .hidden(id="#{challengeBlock.name}") + + if (index < superBlocks.length - 1) + .spacer + hr + .spacer script. var username = !{JSON.stringify(user && user.username || '')}; diff --git a/server/views/coursewares/showBonfire.jade b/server/views/coursewares/showBonfire.jade index a3a584d876..c7d508d882 100644 --- a/server/views/coursewares/showBonfire.jade +++ b/server/views/coursewares/showBonfire.jade @@ -9,7 +9,7 @@ block content .col-md-4.col-lg-3 .scroll-locker(id = "scroll-locker") .innerMarginFix(style=' width: 99%') - #testCreatePanel.well + #testCreatePanel h3.text-center.negative-10= name if (isCompleted) |   @@ -36,13 +36,13 @@ block content |   Run tests (ctrl + enter) .button-spacer .btn-group.input-group.btn-group-justified - label.btn.btn-success#trigger-reset-modal + label.btn.btn-primary.btn-primary-ghost#trigger-reset-modal i.fa.fa-refresh |   Reset - label.btn.btn-success#challenge-help-btn + label.btn.btn-primary.btn-primary-ghost#challenge-help-btn i.fa.fa-medkit |   Help - label.btn.btn-success#trigger-issue-modal + label.btn.btn-primary.btn-primary-ghost#trigger-issue-modal i.fa.fa-bug |   Bug if (!user) diff --git a/server/views/coursewares/showHTML.jade b/server/views/coursewares/showHTML.jade index 163c813689..9b3e558ef3 100644 --- a/server/views/coursewares/showHTML.jade +++ b/server/views/coursewares/showHTML.jade @@ -8,33 +8,33 @@ block content .col-md-3.col-lg-3 .scroll-locker(id = "scroll-locker") .innerMarginFix(style = "width: 99%;") - .well - .row - .col-xs-12 - h3.text-center.negative-10= name - if (isCompleted) - |   - i.ion-checkmark-circled.text-primary(title="Completed") - .bonfire-instructions - for sentence in details - p.wrappable.negative-10!= sentence - .negative-bottom-margin-30 + .row + .col-xs-12 + h3.text-center.negative-10= name + if (isCompleted) + |   + i.ion-checkmark-circled.text-primary(title="Completed") + hr + .bonfire-instructions + for sentence in details + p.wrappable.negative-10!= sentence + .negative-bottom-margin-30 label.negative-10.btn.btn-primary.btn-lg.btn-block#submitButton i.fa.fa-play |   Run tests (ctrl + enter) .button-spacer .btn-group.input-group.btn-group-justified - label.btn.btn-success#trigger-reset-modal + label.btn.btn-primary.btn-primary-ghost#trigger-reset-modal i.fa.fa-refresh |   Reset - label.btn.btn-success.hidden-sm.hidden-md.hidden-lg + label.btn.btn-primary.btn-primary-ghost.hidden-sm.hidden-md.hidden-lg a(href='//gitter.im/freecodecamp/help') i.fa.fa-medkit |   Help - label.btn.btn-success.hidden-xs#challenge-help-btn + label.btn.btn-primary.btn-primary-ghost.hidden-xs#challenge-help-btn i.fa.fa-medkit |   Help - label.btn.btn-success#trigger-issue-modal + label.btn.btn-primary.btn-primary-ghost#trigger-issue-modal i.fa.fa-bug |   Bug script. diff --git a/server/views/coursewares/showStep.jade b/server/views/coursewares/showStep.jade index 53a120143e..96bda010c0 100644 --- a/server/views/coursewares/showStep.jade +++ b/server/views/coursewares/showStep.jade @@ -3,9 +3,9 @@ block content .row .col-md-8.col-md-offset-2 for step, index in description - .thumbnail.challenge-step(class=index !== 0 ? 'hidden': '') + .challenge-step(class=index !== 0 ? 'hidden': '') a(href=step[0] data-lightbox='img-enlarge') - img.gif-block.img-center.img-responsive.thumbnail(src='#{step[0]}' alt='#{step[1]}') + img.gif-block.img-center.img-responsive(src='#{step[0]}' alt='#{step[1]}') .caption p.large-p!= step[2] .challenge-button-block @@ -15,7 +15,7 @@ block content if index === 0 .col-sm-5.hidden-xs   else - .btn.btn-warning.col-sm-5.col-xs-12.challenge-step-btn-prev(id='#{index - 1}') Go to my previous step + .btn.btn-primary.btn-primary-ghost.col-sm-5.col-xs-12.challenge-step-btn-prev(id='#{index - 1}') Go to my previous step .challenge-step-counter.large-p.col-sm-2.col-xs-12.text-center (#{index + 1} / #{description.length}) if index + 1 === description.length .btn.btn-primary.col-sm-5.col-xs-12.challenge-step-btn-finish(id='last' class=step[3] && !isCompleted ? 'disabled' : '') Finish challenge diff --git a/server/views/coursewares/showZiplineOrBasejump.jade b/server/views/coursewares/showZiplineOrBasejump.jade index 03c1ebb19e..5d14b605d6 100644 --- a/server/views/coursewares/showZiplineOrBasejump.jade +++ b/server/views/coursewares/showZiplineOrBasejump.jade @@ -3,15 +3,15 @@ block content .row .col-md-4.bonfire-top h1.text-center= name - .well - h4 - ol - for step, index in details - .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') - .col-xs-9.col-sm-11.col-md-10 - li.step-text.wrappable!= step + hr + h4 + ol + for step, index in details + .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') + .col-xs-9.col-sm-11.col-md-10 + li.step-text.wrappable!= step .col-md-8 .embed-responsive.embed-responsive-16by9 iframe.embed-responsive-item(src='//player.vimeo.com/video/#{video}') @@ -24,10 +24,10 @@ block content a.btn.btn-big.btn-primary.btn-block(href='/challenges/next-challenge?id=' + challengeId) Go to my next challenge (ctrl + enter) .button-spacer .btn-group.input-group.btn-group-justified - .btn.btn-success.btn-big#challenge-help-btn + .btn.btn-primary.btn-primary-ghost.btn-big#challenge-help-btn i.fa.fa-medkit |   Help - .btn.btn-success.btn-big#trigger-issue-modal + .btn.btn-primary.btn-primary-ghost.btn-big#trigger-issue-modal i.fa.fa-bug |   Bug if (!user) diff --git a/server/views/home.jade b/server/views/home.jade index 68b69c5c03..84bc7e2639 100644 --- a/server/views/home.jade +++ b/server/views/home.jade @@ -1,107 +1,106 @@ extends layout block content - .jumbotron - .text-center - h1.landing-heading Learn to code and help nonprofits. - .spacer - .row + .text-center + h1.landing-heading Learn to code and help nonprofits. + .spacer + .row + .col-xs-12.col-sm-12.col-md-3 + h3.nowrap Get connected + img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_connect.svg.gz', alt='Get great references and connections to start your software engineer career') + p.landing-p Join a community of 100,000+ motivated people. + .col-xs-12.col-sm-12.col-md-3 + h3.nowrap Learn JavaScript + img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_learn.svg.gz', alt='Learn to code and learn full stack JavaScript') + p.landing-p Work together on Full Stack JavaScript coding challenges. + .col-xs-12.col-sm-12.col-md-3 + h3.nowrap Build your portfolio + img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_portfolio.svg.gz', alt='Build a portfolio of apps for nonprofits') + p.landing-p Build apps that solve real problems for real people. + .col-xs-12.col-sm-12.col-md-3 + h3.nowrap Help nonprofits + img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_nonprofits.svg.gz', alt='Help empower nonprofits with code') + p.landing-p Give nonprofits a boost by empowering them with code. + .big-break + .row + .col-xs-12.col-sm-8.col-sm-offset-2 + a.btn.btn-cta.signup-btn.btn-block(href="/signin") Start learning to code (it's free) + .button-spacer + a.btn.btn-lg.btn-primary.btn-primary-ghost.btn-block(href="/nonprofits") My nonprofit needs coding help + .spacer + h2 As featured in: + img.img-center.img-responsive(src='https://s3.amazonaws.com/freecodecamp/as-seen-on.png') + .spacer + hr + .spacer + h2 Launch your career as a software engineer: + .spacer + .row + .col-xs-12.col-sm-12.col-md-4 + img.img-responsive.testimonial-image.img-center(src="http://i.imgur.com/nsvNixW.jpg", alt="Meta's testimonial image") + p.testimonial-copy Through Free Code Camp, I built a robust and highly functional web app for a nonprofit. This led me to getting a fantastic job. + h3 - Meta Hirschl + .col-xs-12.col-sm-12.col-md-4 + img.img-responsive.testimonial-image.img-center(src="http://i.imgur.com/QPpjPac.jpg", alt="Brian's testimonial image") + p.testimonial-copy Free Code Camp's a great way for disabled veterans like me to retrain. I'm receiving engineering job offers, and I haven't even finished yet. + h3 - Brian Grant + .col-xs-12.col-sm-12.col-md-4 + img.img-responsive.testimonial-image.img-center(src="http://i.imgur.com/wjlDigg.jpg", alt="Maxim Orlov's testimonial image") + p.testimonial-copy I started Free Code Camp with zero knowledge of web development. 6 months later, I landed my first job as a back end engineer. + h3 - Maxim Orlov + .spacer + .row + .col-xs-12.col-sm-8.col-sm-offset-2 + a.btn.btn-lg.btn-primary.btn-primary-ghost.btn-block(href='/stories') Hear from more of our campers + .spacer + .spacer + hr + .spacer + h2 Skills you'll learn: + .spacer + .row + .text-center.negative-35 .col-xs-12.col-sm-12.col-md-3 - h3.nowrap Get connected - img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_connect.svg.gz', alt='Get great references and connections to start your software engineer career') - p.landing-p Join a community of 100,000+ motivated people. + .landing-skill-icon.ion-social-html5 + h2.black-text HTML5 .col-xs-12.col-sm-12.col-md-3 - h3.nowrap Learn JavaScript - img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_learn.svg.gz', alt='Learn to code and learn full stack JavaScript') - p.landing-p Work together on Full Stack JavaScript coding challenges. + .landing-skill-icon.ion-social-css3 + h2.black-text CSS3 .col-xs-12.col-sm-12.col-md-3 - h3.nowrap Build your portfolio - img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_portfolio.svg.gz', alt='Build a portfolio of apps for nonprofits') - p.landing-p Build apps that solve real problems for real people. + .landing-skill-icon.ion-social-javascript + h2.black-text JavaScript .col-xs-12.col-sm-12.col-md-3 - h3.nowrap Help nonprofits - img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_nonprofits.svg.gz', alt='Help empower nonprofits with code') - p.landing-p Give nonprofits a boost by empowering them with code. - .big-break - .row - .col-xs-12.col-sm-8.col-sm-offset-2 - a.btn.btn-cta.signup-btn.btn-block(href="/signin") Start learning to code (it's free) - .button-spacer - a.btn.btn-lg.btn-primary.btn-primary-ghost.btn-block(href="/nonprofits") My nonprofit needs coding help - .spacer - h2 As featured in: - img.img-center.img-responsive(src='https://s3.amazonaws.com/freecodecamp/as-seen-on.png') - .spacer - hr - .spacer - h2 Launch your career as a software engineer: - .spacer - .row - .col-xs-12.col-sm-12.col-md-4 - img.img-responsive.testimonial-image.img-center(src="http://i.imgur.com/nsvNixW.jpg", alt="Meta's testimonial image") - p.testimonial-copy Through Free Code Camp, I built a robust and highly functional web app for a nonprofit. This led me to getting a fantastic job. - h3 - Meta Hirschl - .col-xs-12.col-sm-12.col-md-4 - img.img-responsive.testimonial-image.img-center(src="http://i.imgur.com/QPpjPac.jpg", alt="Brian's testimonial image") - p.testimonial-copy Free Code Camp's a great way for disabled veterans like me to retrain. I'm receiving engineering job offers, and I haven't even finished yet. - h3 - Brian Grant - .col-xs-12.col-sm-12.col-md-4 - img.img-responsive.testimonial-image.img-center(src="http://i.imgur.com/wjlDigg.jpg", alt="Maxim Orlov's testimonial image") - p.testimonial-copy I started Free Code Camp with zero knowledge of web development. 6 months later, I landed my first job as a back end engineer. - h3 - Maxim Orlov - .spacer - .row - .col-xs-12.col-sm-8.col-sm-offset-2 - a.btn.btn-lg.btn-primary.btn-primary-ghost.btn-block(href='/stories') Hear from more of our campers - .spacer - .spacer - hr - .spacer - h2 Skills you'll learn: - .spacer - .row - .text-center.negative-35 - .col-xs-12.col-sm-12.col-md-3 - .landing-skill-icon.ion-social-html5 - h2.black-text HTML5 - .col-xs-12.col-sm-12.col-md-3 - .landing-skill-icon.ion-social-css3 - h2.black-text CSS3 - .col-xs-12.col-sm-12.col-md-3 - .landing-skill-icon.ion-social-javascript - h2.black-text JavaScript - .col-xs-12.col-sm-12.col-md-3 - .landing-skill-icon.fa.fa-database.font-awesome-padding - h2.black-text Databases - .col-xs-12.col-sm-12.col-md-3 - .landing-skill-icon.ion-social-github - h2.black-text Git & GitHub - .col-xs-12.col-sm-12.col-md-3 - .landing-skill-icon.ion-social-nodejs - h2.black-text Node.js - .col-xs-12.col-sm-12.col-md-3 - .landing-skill-icon.custom-landing-skill-icon - img(src='https://s3.amazonaws.com/freecodecamp/react.svg') - h2.black-text React.js - .col-xs-12.col-sm-12.col-md-3 - .landing-skill-icon.custom-landing-skill-icon - img(src='https://s3.amazonaws.com/freecodecamp/d3-logo.svg') - h2.black-text D3.js - .spacer - hr - .spacer - .col-xs-offset-0.col-sm-offset-1.text-left - h2 Here's why you should join our open source community right now: - ul.large-li - li.ion-code   You'll get help in real time from our community chat rooms. - li.ion-code   You'll meet up with other coders in your city. - li.ion-code   You'll learn to code at your own pace, in your browser or on your phone. - li.ion-code   You'll work through our focused, interactive courses and tutorials. - li.ion-code   You'll learn state-of-the-art full stack JavaScript technologies. - li.ion-code   You'll build projects that help nonprofits carry out their missions more effectively. - li.ion-code   You'll assemble a portfolio of real apps used by real people. - .big-break - .row - .col-xs-12.col-sm-8.col-sm-offset-2 - a.btn.btn-cta.signup-btn.btn-block(href="/signin") Learn to code today (it's free) - script. - challengeName = 'Home' + .landing-skill-icon.fa.fa-database.font-awesome-padding + h2.black-text Databases + .col-xs-12.col-sm-12.col-md-3 + .landing-skill-icon.ion-social-github + h2.black-text Git & GitHub + .col-xs-12.col-sm-12.col-md-3 + .landing-skill-icon.ion-social-nodejs + h2.black-text Node.js + .col-xs-12.col-sm-12.col-md-3 + .landing-skill-icon.custom-landing-skill-icon + img(src='https://s3.amazonaws.com/freecodecamp/react.svg') + h2.black-text React.js + .col-xs-12.col-sm-12.col-md-3 + .landing-skill-icon.custom-landing-skill-icon + img(src='https://s3.amazonaws.com/freecodecamp/d3-logo.svg') + h2.black-text D3.js + .spacer + hr + .spacer + .col-xs-offset-0.col-sm-offset-1.text-left + h2 Here's why you should join our open source community right now: + ul.large-li + li.ion-code   You'll get help in real time from our community chat rooms. + li.ion-code   You'll meet up with other coders in your city. + li.ion-code   You'll learn to code at your own pace, in your browser or on your phone. + li.ion-code   You'll work through our focused, interactive courses and tutorials. + li.ion-code   You'll learn state-of-the-art full stack JavaScript technologies. + li.ion-code   You'll build projects that help nonprofits carry out their missions more effectively. + li.ion-code   You'll assemble a portfolio of real apps used by real people. + .big-break + .row + .col-xs-12.col-sm-8.col-sm-offset-2 + a.btn.btn-cta.signup-btn.btn-block(href="/signin") Learn to code today (it's free) + script. + challengeName = 'Home' diff --git a/server/views/stories/index.jade b/server/views/stories/index.jade index 196c1bcd3d..56958a7a08 100644 --- a/server/views/stories/index.jade +++ b/server/views/stories/index.jade @@ -11,22 +11,22 @@ block content script. var challengeName = 'Camper News'; var page = !{JSON.stringify(page)}; - .panel.panel-info - .panel-heading.text-center Camper News - .panel-body - include news-nav + h1.text-center Camper News + hr + .spacer + include news-nav + .spacer + if (page === 'hot') + include hot-stories + if (page === 'submit') + if (user) + include preliminary-submit + else .spacer - if (page === 'hot') - include hot-stories - if (page === 'submit') - if (user) - include preliminary-submit - else - .spacer - .text-center - a.btn.btn-cta.signup-btn.btn-primary(href="/login") Sign in to post your story (it's free) - .spacer - if (page === 'storySubmission') - include submit-story - if (page === 'show') - include show + .text-center + a.btn.btn-cta.signup-btn.btn-primary(href="/login") Sign in to post your story (it's free) + .spacer + if (page === 'storySubmission') + include submit-story + if (page === 'show') + include show diff --git a/server/views/stories/news-nav.jade b/server/views/stories/news-nav.jade index c15c30b5d4..d78c17aab5 100644 --- a/server/views/stories/news-nav.jade +++ b/server/views/stories/news-nav.jade @@ -7,11 +7,17 @@ .spacer .col-xs-12.col-sm-3 span - a.btn.btn-primary.btn-big.btn-block.btn-responsive(href='/stories/submit' class="#{ page === 'hot' ? '' : 'hidden' }") Submit + a.btn.btn-primary.btn-big.btn-block.btn-responsive(href='/stories/submit' class="#{ page === 'hot' ? '' : 'hidden' }") Submit a link span a.btn.btn-success.btn-big.btn-block.btn-responsive(href='/news/' class="#{ (page !== 'hot') ? '' : 'hidden' }") All .visible-xs .button-spacer + .col-xs-12.col-sm-9 + .input-group + input#searchArea.big-text-field.field-responsive.form-control(type='text', placeholder='Search our links') + span.input-group-btn + button#searchbutton.btn.btn-big.btn-primary.btn-responsive(type='button') Search + .spacer #search-results From 345b0a55138cc925d14e09dcf3ff50d194b48c78 Mon Sep 17 00:00:00 2001 From: Quincy Larson Date: Sat, 9 Jan 2016 20:03:51 -0600 Subject: [PATCH 02/65] make navbar brown again --- client/less/lib/bootstrap/variables.less | 2 +- client/less/main.less | 42 +++++++++++------------- 2 files changed, 20 insertions(+), 24 deletions(-) diff --git a/client/less/lib/bootstrap/variables.less b/client/less/lib/bootstrap/variables.less index 37c18097bc..968b70b7c6 100755 --- a/client/less/lib/bootstrap/variables.less +++ b/client/less/lib/bootstrap/variables.less @@ -26,7 +26,7 @@ //## Settings for some of the most global styles. //** Background color for ``. -@body-bg: #fefefe; +@body-bg: #eee; //** Global text color on ``. @text-color: @gray-dark; diff --git a/client/less/main.less b/client/less/main.less index a513acf2e1..01936a5c1b 100644 --- a/client/less/main.less +++ b/client/less/main.less @@ -42,17 +42,13 @@ html { overflow-x: hidden; } -//input[type=checkbox] { -// /* Double-sized Checkboxes */ -// -ms-transform: scale(2); /* IE */ -// -moz-transform: scale(2); /* FF */ -// -webkit-transform: scale(2); /* Safari and Chrome */ -// -o-transform: scale(2); /* Opera */ -// padding: 10px; -//} - -.btn-group { - border-color: @brand-primary; +input[type=checkbox] { + /* Double-sized Checkboxes */ + -ms-transform: scale(2); /* IE */ + -moz-transform: scale(2); /* FF */ + -webkit-transform: scale(2); /* Safari and Chrome */ + -o-transform: scale(2); /* Opera */ + padding: 10px; } body.full-screen-body-background { @@ -94,7 +90,7 @@ h1, h2, h3, h4, h5, h6, p, li { .thumbnail { background-color: #EEEEEE; -// box-shadow: 0 0 5px #ccc, inset 0 0 0 #000; + // box-shadow: 0 0 5px #ccc, inset 0 0 0 #000; } // Font Icons @@ -331,13 +327,13 @@ ul { } .navbar { - background-color: #215f1e; + background-color: #4a2b0f; } .navbar-nav > li > a { color: @gray-lighter; &:hover { - color: #215f1e; + color: #4a2b0f; } } @@ -376,7 +372,7 @@ ul { } *, *:before, *:after { - box-sizing: border-box !important; + box-sizing: border-box !important; } .btn-big { @@ -445,7 +441,7 @@ thead { } .navbar-right { - background-color: #215f1e; + background-color: #4a2b0f; text-align: center; } @@ -590,7 +586,7 @@ thead { width: 100%; height: 50px; text-align: center; - background-color: #215f1e; + background-color: #4a2b0f; padding: 12px; bottom: 0; left: 0; @@ -605,7 +601,7 @@ thead { padding-top: 14px; padding-bottom: 12px; &:hover { - color: #215f1e; + color: #4a2b0f; background-color: @gray-lighter; text-decoration: none; } @@ -693,8 +689,8 @@ div.CodeMirror-scroll { border-radius: 5px; } .bonfire-flames { - margin-top: -20px; - margin-bottom: -2px; + margin-top: -20px; + margin-bottom: -2px; } .bonfire-top { @@ -965,8 +961,8 @@ hr { } .checklist-element { - margin-left: -60px; - margin-right: -20px; + margin-left: -60px; + margin-right: -20px; } .profile-social-icons { @@ -1027,7 +1023,7 @@ code { } .gitter-chat-embed { - z-index: 20000 !important; + z-index: 20000 !important; } From 7e481833cd4e51f9bdbbf25d14efcd6a14063e7e Mon Sep 17 00:00:00 2001 From: Quincy Larson Date: Sat, 9 Jan 2016 21:02:31 -0600 Subject: [PATCH 03/65] Revert "make navbar brown again" This reverts commit 18224e14f7b9ee356450bae54959b770c5ec4c7c. --- client/less/lib/bootstrap/variables.less | 2 +- client/less/main.less | 42 +++++++++++++----------- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/client/less/lib/bootstrap/variables.less b/client/less/lib/bootstrap/variables.less index 968b70b7c6..37c18097bc 100755 --- a/client/less/lib/bootstrap/variables.less +++ b/client/less/lib/bootstrap/variables.less @@ -26,7 +26,7 @@ //## Settings for some of the most global styles. //** Background color for ``. -@body-bg: #eee; +@body-bg: #fefefe; //** Global text color on ``. @text-color: @gray-dark; diff --git a/client/less/main.less b/client/less/main.less index 01936a5c1b..a513acf2e1 100644 --- a/client/less/main.less +++ b/client/less/main.less @@ -42,13 +42,17 @@ html { overflow-x: hidden; } -input[type=checkbox] { - /* Double-sized Checkboxes */ - -ms-transform: scale(2); /* IE */ - -moz-transform: scale(2); /* FF */ - -webkit-transform: scale(2); /* Safari and Chrome */ - -o-transform: scale(2); /* Opera */ - padding: 10px; +//input[type=checkbox] { +// /* Double-sized Checkboxes */ +// -ms-transform: scale(2); /* IE */ +// -moz-transform: scale(2); /* FF */ +// -webkit-transform: scale(2); /* Safari and Chrome */ +// -o-transform: scale(2); /* Opera */ +// padding: 10px; +//} + +.btn-group { + border-color: @brand-primary; } body.full-screen-body-background { @@ -90,7 +94,7 @@ h1, h2, h3, h4, h5, h6, p, li { .thumbnail { background-color: #EEEEEE; - // box-shadow: 0 0 5px #ccc, inset 0 0 0 #000; +// box-shadow: 0 0 5px #ccc, inset 0 0 0 #000; } // Font Icons @@ -327,13 +331,13 @@ ul { } .navbar { - background-color: #4a2b0f; + background-color: #215f1e; } .navbar-nav > li > a { color: @gray-lighter; &:hover { - color: #4a2b0f; + color: #215f1e; } } @@ -372,7 +376,7 @@ ul { } *, *:before, *:after { - box-sizing: border-box !important; + box-sizing: border-box !important; } .btn-big { @@ -441,7 +445,7 @@ thead { } .navbar-right { - background-color: #4a2b0f; + background-color: #215f1e; text-align: center; } @@ -586,7 +590,7 @@ thead { width: 100%; height: 50px; text-align: center; - background-color: #4a2b0f; + background-color: #215f1e; padding: 12px; bottom: 0; left: 0; @@ -601,7 +605,7 @@ thead { padding-top: 14px; padding-bottom: 12px; &:hover { - color: #4a2b0f; + color: #215f1e; background-color: @gray-lighter; text-decoration: none; } @@ -689,8 +693,8 @@ div.CodeMirror-scroll { border-radius: 5px; } .bonfire-flames { - margin-top: -20px; - margin-bottom: -2px; + margin-top: -20px; + margin-bottom: -2px; } .bonfire-top { @@ -961,8 +965,8 @@ hr { } .checklist-element { - margin-left: -60px; - margin-right: -20px; + margin-left: -60px; + margin-right: -20px; } .profile-social-icons { @@ -1023,7 +1027,7 @@ code { } .gitter-chat-embed { - z-index: 20000 !important; + z-index: 20000 !important; } From 7eefcb0705146ce087d2abc96f46c45d180b3b0d Mon Sep 17 00:00:00 2001 From: Quincy Larson Date: Sat, 9 Jan 2016 22:12:32 -0600 Subject: [PATCH 04/65] more redesign work on challenge views --- client/less/lib/bootstrap/variables.less | 2 +- client/less/main.less | 18 +-- server/views/account/email-signin.jade | 33 +++-- server/views/account/email-signup.jade | 9 +- server/views/account/forgot.jade | 5 +- server/views/coursewares/showBonfire.jade | 2 +- server/views/coursewares/showHTML.jade | 2 +- server/views/coursewares/showJS.jade | 3 +- server/views/home.jade | 27 ++-- server/views/nonprofits/show.jade | 139 ++++++++++---------- server/views/partials/navbar.jade | 3 +- server/views/resources/links.jade | 54 ++++++++ server/views/resources/nonprofits.jade | 146 +++++++++++----------- server/views/resources/stories.jade | 44 ++++--- 14 files changed, 261 insertions(+), 226 deletions(-) create mode 100644 server/views/resources/links.jade diff --git a/client/less/lib/bootstrap/variables.less b/client/less/lib/bootstrap/variables.less index 37c18097bc..968b70b7c6 100755 --- a/client/less/lib/bootstrap/variables.less +++ b/client/less/lib/bootstrap/variables.less @@ -26,7 +26,7 @@ //## Settings for some of the most global styles. //** Background color for ``. -@body-bg: #fefefe; +@body-bg: #eee; //** Global text color on ``. @text-color: @gray-dark; diff --git a/client/less/main.less b/client/less/main.less index a513acf2e1..86f11b3eb7 100644 --- a/client/less/main.less +++ b/client/less/main.less @@ -291,6 +291,8 @@ ul { margin-right: 10px; white-space: nowrap; } + background-color: #215f1e; + text-align: center; } .navbar { white-space: nowrap; @@ -427,13 +429,6 @@ thead { } } -.signin-button-nav { - @media (min-width: 991px) and (max-width: 1010px) { - margin-left: -10px; - margin-right: -5px; - } -} - .navbar-nav a { color: @gray-lighter; font-size: 20px; @@ -444,16 +439,15 @@ thead { color: @gray-lighter; } -.navbar-right { - background-color: #215f1e; - text-align: center; -} - .signup-btn-nav { margin-top: -2px !important; padding-top: 10px !important; padding-bottom: 10px !important; margin-right: -12px; + @media (min-width: 991px) and (max-width: 1010px) { + margin-left: -10px; + margin-right: -5px; + } } .public-profile-img { diff --git a/server/views/account/email-signin.jade b/server/views/account/email-signin.jade index e36d19b97b..fed5792311 100644 --- a/server/views/account/email-signin.jade +++ b/server/views/account/email-signin.jade @@ -1,19 +1,18 @@ extends ../layout block content - .jumbotron.text-center - .row - .col-xs-12 - h2 Sign in with an email address here: - .col-sm-6.col-sm-offset-3 - form(method='POST', action='/api/users/login') - input(type='hidden', name='_csrf', value=_csrf) - .form-group - input.input-lg.form-control(type='email', name='email', id='email', placeholder='Email', autofocus=true) - .form-group - input.input-lg.form-control(type='password', name='password', id='password', placeholder='Password') - button.btn.btn-primary.btn-lg.btn-block(type='submit') - span.ion-android-hand - | Login - .button-spacer - .button-spacer - a.btn.btn-info.btn-lg.btn-block(href='/forgot') Forgot your password? + .row + .col-xs-12 + h2.text-center Sign in with an email address here: + .col-sm-6.col-sm-offset-3 + form(method='POST', action='/api/users/login') + input(type='hidden', name='_csrf', value=_csrf) + .form-group + input.input-lg.form-control(type='email', name='email', id='email', placeholder='Email', autofocus=true) + .form-group + input.input-lg.form-control(type='password', name='password', id='password', placeholder='Password') + button.btn.btn-primary.btn-lg.btn-block(type='submit') + span.ion-android-hand + | Login + .button-spacer + .button-spacer + a.btn.btn-info.btn-lg.btn-block(href='/forgot') Forgot your password? diff --git a/server/views/account/email-signup.jade b/server/views/account/email-signup.jade index 15ab666565..e8a2ce9b23 100644 --- a/server/views/account/email-signup.jade +++ b/server/views/account/email-signup.jade @@ -1,9 +1,8 @@ extends ../layout block content - script. - var challengeName = 'Email Signup' - .jumbotron.text-center - h2 Sign up with an email address here: + script. + var challengeName = 'Email Signup' + h2.text-center Sign up with an email address here: form.form-horizontal(method='POST', action='/api/users', name="signupForm") .row .col-sm-6.col-sm-offset-3 @@ -13,6 +12,6 @@ block content .form-group input.input-lg.form-control(type='password', name='password', id='password', placeholder='password', required, pattern=".{8,50}", title="Must be at least 8 characters and no longer than 50 characters.") .form-group - button.btn.btn-lg.btn-success.btn-block(type='submit') + button.btn.btn-lg.btn-primary.btn-block(type='submit') span.ion-person-add | Signup diff --git a/server/views/account/forgot.jade b/server/views/account/forgot.jade index c5da16558c..4b1e94c606 100644 --- a/server/views/account/forgot.jade +++ b/server/views/account/forgot.jade @@ -1,12 +1,11 @@ extends ../layout - block content - .col-sm-8.col-sm-offset-2.jumbotron + .col-sm-6.col-sm-offset-3 form(method='POST', action="/forgot") h2.text-center Forgot Password Reset input(type='hidden', name='_csrf', value=_csrf) .form-group - p Enter your email address. We'll send you password reset instructions. + p.large-p Enter your email address. We'll send you password reset instructions. input.form-control.input-lg(type='email', name='email', id='email', placeholder='Email', autofocus=true required) .form-group button.btn.btn-primary.btn-lg.btn-block(type='submit') diff --git a/server/views/coursewares/showBonfire.jade b/server/views/coursewares/showBonfire.jade index c7d508d882..b931e109c0 100644 --- a/server/views/coursewares/showBonfire.jade +++ b/server/views/coursewares/showBonfire.jade @@ -4,7 +4,6 @@ block content link(rel='stylesheet', href='/bower_components/CodeMirror/addon/lint/lint.css') link(rel='stylesheet', href='/bower_components/CodeMirror/theme/monokai.css') link(rel='stylesheet', href='/css/ubuntu.css') - .row .col-md-4.col-lg-3 .scroll-locker(id = "scroll-locker") @@ -14,6 +13,7 @@ block content if (isCompleted) |   i.ion-checkmark-circled.text-primary(title="Completed") + hr .row .col-xs-12 .bonfire-instructions diff --git a/server/views/coursewares/showHTML.jade b/server/views/coursewares/showHTML.jade index 9b3e558ef3..78d7e8670a 100644 --- a/server/views/coursewares/showHTML.jade +++ b/server/views/coursewares/showHTML.jade @@ -4,7 +4,7 @@ block content link(rel='stylesheet', href='/bower_components/CodeMirror/addon/lint/lint.css') link(rel='stylesheet', href='/bower_components/CodeMirror/theme/monokai.css') link(rel='stylesheet', href='/css/ubuntu.css') - .row.courseware-height + .row .col-md-3.col-lg-3 .scroll-locker(id = "scroll-locker") .innerMarginFix(style = "width: 99%;") diff --git a/server/views/coursewares/showJS.jade b/server/views/coursewares/showJS.jade index c4b2aa5386..8253b33c82 100644 --- a/server/views/coursewares/showJS.jade +++ b/server/views/coursewares/showJS.jade @@ -8,11 +8,12 @@ block content .col-md-4.col-lg-3 .scroll-locker(id = "scroll-locker") .innerMarginFix(style = "width: 99%;") - #testCreatePanel.well + #testCreatePanel h3.text-center.negative-10= name if (isCompleted) |   i.ion-checkmark-circled.text-primary(title="Completed") + hr .row .col-xs-12 .bonfire-instructions diff --git a/server/views/home.jade b/server/views/home.jade index 84bc7e2639..9c59ed0b96 100644 --- a/server/views/home.jade +++ b/server/views/home.jade @@ -5,21 +5,17 @@ block content .spacer .row .col-xs-12.col-sm-12.col-md-3 - h3.nowrap Get connected img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_connect.svg.gz', alt='Get great references and connections to start your software engineer career') - p.landing-p Join a community of 100,000+ motivated people. + p.large-p Join a community of 100,000+ developers. .col-xs-12.col-sm-12.col-md-3 - h3.nowrap Learn JavaScript img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_learn.svg.gz', alt='Learn to code and learn full stack JavaScript') - p.landing-p Work together on Full Stack JavaScript coding challenges. + p.large-p Work together on coding challenges. .col-xs-12.col-sm-12.col-md-3 - h3.nowrap Build your portfolio img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_portfolio.svg.gz', alt='Build a portfolio of apps for nonprofits') - p.landing-p Build apps that solve real problems for real people. + p.large-p Build a portfolio of apps that solve real problems. .col-xs-12.col-sm-12.col-md-3 - h3.nowrap Help nonprofits img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_nonprofits.svg.gz', alt='Help empower nonprofits with code') - p.landing-p Give nonprofits a boost by empowering them with code. + p.large-p Empowering nonprofits with code. .big-break .row .col-xs-12.col-sm-8.col-sm-offset-2 @@ -90,14 +86,15 @@ block content .spacer .col-xs-offset-0.col-sm-offset-1.text-left h2 Here's why you should join our open source community right now: + .spacer ul.large-li - li.ion-code   You'll get help in real time from our community chat rooms. - li.ion-code   You'll meet up with other coders in your city. - li.ion-code   You'll learn to code at your own pace, in your browser or on your phone. - li.ion-code   You'll work through our focused, interactive courses and tutorials. - li.ion-code   You'll learn state-of-the-art full stack JavaScript technologies. - li.ion-code   You'll build projects that help nonprofits carry out their missions more effectively. - li.ion-code   You'll assemble a portfolio of real apps used by real people. + li.ion-code.large-p   You'll get help in real time from our community chat rooms. + li.ion-code.large-p   You'll meet up with other coders in your city. + li.ion-code.large-p   You'll learn to code at your own pace, in your browser or on your phone. + li.ion-code.large-p   You'll work through our focused, interactive courses and tutorials. + li.ion-code.large-p   You'll learn state-of-the-art full stack JavaScript technologies. + li.ion-code.large-p   You'll build projects that help nonprofits carry out their missions more effectively. + li.ion-code.large-p   You'll assemble a portfolio of real apps used by real people. .big-break .row .col-xs-12.col-sm-8.col-sm-offset-2 diff --git a/server/views/nonprofits/show.jade b/server/views/nonprofits/show.jade index f408a70aab..18b5e261b3 100644 --- a/server/views/nonprofits/show.jade +++ b/server/views/nonprofits/show.jade @@ -2,77 +2,74 @@ extends ../layout block content script. var challengeName = 'Nonprofits View'; - .panel.panel-info - .panel-heading.text-center= title - .panel-body + .row + .col-xs-12.col-sm-10.col-sm-offset-1 .row - .col-xs-12.col-sm-10.col-sm-offset-1 - .row - .col-xs-12 - img.img-center.img-responsive(src=imageUrl) + .col-xs-12 + img.img-center.img-responsive(src=imageUrl) + .spacer + .row + .col-xs-12.col-sm-4 + img.img-responsive(src=logoUrl) + .col-xs-12.col-sm-8 + .col-xs-12 + h4= whatDoesNonprofitDo + h4 + a(href=websiteLink)= websiteLink .spacer - .row - .col-xs-12.col-sm-4 - img.img-responsive(src=logoUrl) - .col-xs-12.col-sm-8 - .col-xs-12 - h4= whatDoesNonprofitDo - h4 - a(href=websiteLink)= websiteLink - .spacer - h3 Project Description: - .col-xs-12 - h4.negative-15 #{projectDescription} (About #{estimatedHours} hours per camper) - .spacer - h3 This project involves building: - h4.negative-15.col-xs-12 - if (approvedWebsite) - .ion-android-globe   Website - if (approvedDonor) - .ion-card   Donor Management System - if (approvedInventory) - .ion-ios-box   Inventory Management System - if (approvedVolunteer) - .ion-android-calendar   Volunteer Management System - if (approvedForm) - .ion-ios-list   Webform - if (approvedCommunity) - .ion-ios-people   Community Management System - if (approvedELearning) - .ion-university   E-learning Platform - if (approvedOther) - .ion-settings   Other tools - h3 Project Status: #{currentStatus} - if (moneySaved > 0) - h3.text-primary Estimated Cost Savings for Nonprofit: $#{moneySaved.toString().replace(/000$/, ',000')} + h3 Project Description: + .col-xs-12 + h4.negative-15 #{projectDescription} (About #{estimatedHours} hours per camper) + .spacer + h3 This project involves building: + h4.negative-15.col-xs-12 + if (approvedWebsite) + .ion-android-globe   Website + if (approvedDonor) + .ion-card   Donor Management System + if (approvedInventory) + .ion-ios-box   Inventory Management System + if (approvedVolunteer) + .ion-android-calendar   Volunteer Management System + if (approvedForm) + .ion-ios-list   Webform + if (approvedCommunity) + .ion-ios-people   Community Management System + if (approvedELearning) + .ion-university   E-learning Platform + if (approvedOther) + .ion-settings   Other tools + h3 Project Status: #{currentStatus} + if (moneySaved > 0) + h3.text-primary Estimated Cost Savings for Nonprofit: $#{moneySaved.toString().replace(/000$/, ',000')} - if (interestedCampers && interestedCampers.length > 0) - h3 Interested campers: - .col-xs-12.text-left - for interestedCamper in interestedCampers - a(href='/' + interestedCamper.username class="interested-camper-image") - img.profile-picture.float-right(src=interestedCamper.picture) - if (assignedCampers && assignedCampers.length > 0) - h3 Assigned campers: - .col-xs-12.text-left - for assignedCamper in assignedCampers - a(href='/' + assignedCamper.username class="interested-camper-image") - img.profile-picture.float-right(src=assignedCamper.picture) - if (!buttonActive) - .col-xs-12.col-sm-8.col-sm-offset-2 - .text-center - if !user - a.btn.btn-cta.signup-btn.btn-block(href="/login") Start learning to code (it's free) - .button-spacer - else - a.btn.btn-primary.btn-big.btn-block.disabled(href='/nonprofits/interested-in-nonprofit/#{dashedName}') I'm interested in building this project * - p * Complete all our Bonfires, Ziplines, and Basejumps to unlock this. - a.btn.btn-info.btn-big.btn-block(href='/nonprofits/directory') Show all Nonprofit Projects - .spacer - if (buttonActive) - .col-xs-12.col-sm-8.col-sm-offset-2 - .text-center - a.btn.btn-primary.btn-big.btn-block(href='/nonprofits/interested-in-nonprofit/#{dashedName}') I'm interested in building this project - .button-spacer - a.btn.btn-info.btn-big.btn-block(href='/nonprofits/directory') Show all Nonprofit Projects - .spacer + if (interestedCampers && interestedCampers.length > 0) + h3 Interested campers: + .col-xs-12.text-left + for interestedCamper in interestedCampers + a(href='/' + interestedCamper.username class="interested-camper-image") + img.profile-picture.float-right(src=interestedCamper.picture) + if (assignedCampers && assignedCampers.length > 0) + h3 Assigned campers: + .col-xs-12.text-left + for assignedCamper in assignedCampers + a(href='/' + assignedCamper.username class="interested-camper-image") + img.profile-picture.float-right(src=assignedCamper.picture) + if (!buttonActive) + .col-xs-12.col-sm-8.col-sm-offset-2 + .text-center + if !user + a.btn.btn-cta.signup-btn.btn-block(href="/login") Start learning to code (it's free) + .button-spacer + else + a.btn.btn-primary.btn-big.btn-block.disabled(href='/nonprofits/interested-in-nonprofit/#{dashedName}') I'm interested in building this project * + p * Complete all our Bonfires, Ziplines, and Basejumps to unlock this. + a.btn.btn-info.btn-big.btn-block(href='/nonprofits/directory') Show all Nonprofit Projects + .spacer + if (buttonActive) + .col-xs-12.col-sm-8.col-sm-offset-2 + .text-center + a.btn.btn-primary.btn-big.btn-block(href='/nonprofits/interested-in-nonprofit/#{dashedName}') I'm interested in building this project + .button-spacer + a.btn.btn-info.btn-big.btn-block(href='/nonprofits/directory') Show all Nonprofit Projects + .spacer diff --git a/server/views/partials/navbar.jade b/server/views/partials/navbar.jade index 04a029faf5..a248fcdf2f 100644 --- a/server/views/partials/navbar.jade +++ b/server/views/partials/navbar.jade @@ -24,9 +24,8 @@ nav.navbar.navbar-default.navbar-fixed-top.nav-height li a(href='/about') About if !user - li       li - a.btn.signup-btn.signup-btn-nav.signin-button-nav(href='/login') Sign in + a(href='/login') Sign in else li.brownie-points-nav a(href='/' + user.username) [ #{user.progressTimestamps.length} ] diff --git a/server/views/resources/links.jade b/server/views/resources/links.jade new file mode 100644 index 0000000000..269382fab2 --- /dev/null +++ b/server/views/resources/links.jade @@ -0,0 +1,54 @@ +extends ../layout +block content + table.table.link-table + tr + td.text-right + .ion-erlenmeyer-flask + td + a(href="/labs") Cool Apps Built by Campers + tr + td.text-right + .ion-chatbox + td + a(href="/stories") Stories from Campers + tr + td.text-right + .ion-speakerphone + td + a(href='//medium.freecodecamp.com', target='_blank') Medium Publication + tr + td.text-right + .ion-social-github + td + a(href="//github.com/freecodecamp", target='_blank') GitHub Repository + tr + td.text-right + .ion-social-reddit + td + a(href="//www.reddit.com/r/freecodecamp", target='_blank') Subreddit + tr + td.text-right + .ion-social-linkedin + td + a(href="//www.linkedin.com/edu/school?id=166029", target='_blank') LinkedIn University Page + tr + td.text-right + .ion-social-twitter + td + a(href="//twitter.com/freecodecamp", target='_blank') Twitter Feed + tr + td.text-right + .ion-social-facebook + td + a(href="//facebook.com/freecodecamp") Facebook Page + tr + td.text-right + .ion-social-twitch-outline + td + a(href="//twitch.tv/freecodecamp", target='_blank') Twitch.tv Channel + tr + td.text-right + .ion-locked + td + a(href="//github.com/FreeCodeCamp/freecodecamp/wiki/Free-Code-Camp's-Privacy-Policy") Privacy Policy + .spacer diff --git a/server/views/resources/nonprofits.jade b/server/views/resources/nonprofits.jade index ea3b7d931a..70522f6e45 100644 --- a/server/views/resources/nonprofits.jade +++ b/server/views/resources/nonprofits.jade @@ -1,77 +1,75 @@ extends ../layout block content - .jumbotron - .text-center - .row - .col-xs-12 - h1.landing-heading Get pro bono code for your nonprofit. + .text-center + .row + .col-xs-12 + h1.landing-heading Get pro bono code for your nonprofit. + .big-break + .col-xs-12.col-sm-12.col-md-12 + .embed-responsive.embed-responsive-16by9 + iframe.embed-responsive-item(src='//player.vimeo.com/video/126228100') .big-break - .col-xs-12.col-sm-12.col-md-12 - .embed-responsive.embed-responsive-16by9 - iframe.embed-responsive-item(src='//player.vimeo.com/video/126228100') - .big-break - h2 As featured in: - img.img-center.img-responsive(src='https://s3.amazonaws.com/freecodecamp/as-seen-on.png') - .spacer - hr - .spacer - h2 Our process: - .row - .col-xs-12.col-sm-12.col-md-4 - h3.nowrap Your idea - img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_portfolio.svg.gz', alt='Image of a briefcase') - p.landing-p You tell us how we can help you. - .col-xs-12.col-sm-12.col-md-4 - h3.nowrap Our team - img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_nonprofits.svg.gz', alt='Image of people putting their hands together in a huddle') - p.landing-p We'll hand pick developers and a project manager. - .col-xs-12.col-sm-12.col-md-4 - h3.nowrap Your solution - img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_connect.svg.gz', alt='image of two people high-fiving') - p.landing-p Together we'll set milestones and complete your project. - .spacer - hr - .spacer - h2 Solutions we can help you build: - .text-center.negative-35 - .col-xs-12.col-sm-12.col-md-3 - .landing-skill-icon.ion-android-globe - h2.black-text Websites - .col-xs-12.col-sm-12.col-md-3 - .landing-skill-icon.ion-card - h2.black-text Donation Systems - .col-xs-12.col-sm-12.col-md-3 - .landing-skill-icon.ion-android-calendar - h2.black-text Volunteer Systems - .col-xs-12.col-sm-12.col-md-3 - .landing-skill-icon.ion-ios-box - h2.black-text Inventory Systems - .col-xs-12.col-sm-12.col-md-3 - .landing-skill-icon.ion-university - h2.black-text E-learning Platforms - .col-xs-12.col-sm-12.col-md-3 - .landing-skill-icon.ion-ios-list - h2.black-text Paperless Workflows - .col-xs-12.col-sm-12.col-md-3 - .landing-skill-icon.ion-ios-people - h2.black-text Community Tools - .col-xs-12.col-sm-12.col-md-3 - .landing-skill-icon.ion-settings - h2.black-text ...and other tools - .spacer - hr - .spacer - .large-p.text-left.col-xs-offset-0.col-sm-offset-1 - h2 Our developers build projects for nonprofits who: - ul.large-li - li.ion-code   already have people who benefit from their services. - li.ion-code   are registered with their government and have tax-exempt status. - li.ion-code   have a stakeholder who can meet with our developers to direct the project. - li.ion-code   can budget at least $20 per month for their own cloud servers. - li.ion-code   can commit to using and maintaining the solution that our developers build. - .big-break - .row - .col-xs-12.col-sm-8.col-sm-offset-2 - a.btn.btn-cta.signup-btn.btn-block(href="/nonprofits-form") My nonprofit needs coding help - .button-spacer - a.btn.btn-lg.btn-primary.btn-primary-ghost.btn-block(href="/nonprofits/directory") Browse our directory of nonprofits we've helped + h2 As featured in: + img.img-center.img-responsive(src='https://s3.amazonaws.com/freecodecamp/as-seen-on.png') + .spacer + hr + .spacer + h2 Our process: + .spacer + .row + .col-xs-12.col-sm-12.col-md-4 + img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_portfolio.svg.gz', alt='Image of a briefcase') + p.large-p You tell us how we can help you. + .col-xs-12.col-sm-12.col-md-4 + img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_nonprofits.svg.gz', alt='Image of people putting their hands together in a huddle') + p.large-p We'll hand pick developers and a project manager. + .col-xs-12.col-sm-12.col-md-4 + img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_connect.svg.gz', alt='image of two people high-fiving') + p.large-p Together we'll set milestones and complete your project. + .spacer + hr + .spacer + h2 Solutions we can help you build: + .spacer + .text-center.negative-35 + .col-xs-12.col-sm-12.col-md-3 + .landing-skill-icon.ion-android-globe + h2.black-text Websites + .col-xs-12.col-sm-12.col-md-3 + .landing-skill-icon.ion-card + h2.black-text Donation Systems + .col-xs-12.col-sm-12.col-md-3 + .landing-skill-icon.ion-android-calendar + h2.black-text Volunteer Systems + .col-xs-12.col-sm-12.col-md-3 + .landing-skill-icon.ion-ios-box + h2.black-text Inventory Systems + .col-xs-12.col-sm-12.col-md-3 + .landing-skill-icon.ion-university + h2.black-text E-learning Platforms + .col-xs-12.col-sm-12.col-md-3 + .landing-skill-icon.ion-ios-list + h2.black-text Paperless Workflows + .col-xs-12.col-sm-12.col-md-3 + .landing-skill-icon.ion-ios-people + h2.black-text Community Tools + .col-xs-12.col-sm-12.col-md-3 + .landing-skill-icon.ion-settings + h2.black-text ...and other tools + .spacer + hr + .spacer + .large-p.text-left.col-xs-offset-0.col-sm-offset-1 + h2 Our developers build projects for nonprofits who: + ul.large-li + li.ion-code   already have people who benefit from their services. + li.ion-code   are registered with their government and have tax-exempt status. + li.ion-code   have a stakeholder who can meet with our developers to direct the project. + li.ion-code   can budget at least $20 per month for their own cloud servers. + li.ion-code   can commit to using and maintaining the solution that our developers build. + .big-break + .row + .col-xs-12.col-sm-8.col-sm-offset-2 + a.btn.btn-cta.signup-btn.btn-block(href="/nonprofits-form") My nonprofit needs coding help + .button-spacer + a.btn.btn-lg.btn-primary.btn-primary-ghost.btn-block(href="/nonprofits/directory") Browse our directory of nonprofits we've helped diff --git a/server/views/resources/stories.jade b/server/views/resources/stories.jade index 794c4badea..17008cbd2e 100644 --- a/server/views/resources/stories.jade +++ b/server/views/resources/stories.jade @@ -1,27 +1,25 @@ extends ../layout block content - .panel.panel-info - .panel-heading.text-center Stories from happy campers - .panel-body.text-left + h1.text-center Stories from happy campers + hr + .row + .col-xs-12.col-sm-10.col-sm-offset-1 .row - .col-xs-12.col-sm-10.col-sm-offset-1 - .row - for story in stories - .col-xs-12.col-sm-6.col-md-4 - .height-500 - a(href=story.linkedin target='_blank') - img.testimonial-image.img-responsive.img-center(src=story.image) - h3.text-center= story.camper - |   - a.fa.fa-linkedin-square.text-primary(alt="#{story.camper}'s LinkedIn Profile", href=story.linkedin, target='_blank') - p.text-justify= story.quote - .col-xs-12.col-sm-10.col-sm-offset-1 - if moreStories - .text-center - a.btn.btn-lg.btn-primary.btn-primary-ghost.btn-block(href="/all-stories") Show more stories - .spacer + for story in stories + .col-xs-12.col-sm-6.col-md-4 + .height-500 + a(href=story.linkedin target='_blank') + img.testimonial-image.img-responsive.img-center(src=story.image) + h3.text-center= story.camper + |   + a.fa.fa-linkedin-square.text-primary(alt="#{story.camper}'s LinkedIn Profile", href=story.linkedin, target='_blank') + p.text-justify= story.quote + .col-xs-12.col-sm-10.col-sm-offset-1 + if moreStories + .text-center + a.btn.btn-lg.btn-primary.btn-primary-ghost.btn-block(href="/all-stories") Show more stories + .spacer - if !user - .text-center - a.btn.btn-cta.signup-btn.btn-block(href="/login") Start learning to code (it's free) - .spacer + if !user + .text-center + a.btn.btn-cta.signup-btn.btn-block(href="/login") Start learning to code (it's free) From 09b4f1caa26dc72ee3b5ce4af12d2cbbd56bf35c Mon Sep 17 00:00:00 2001 From: Quincy Larson Date: Sat, 9 Jan 2016 23:48:37 -0600 Subject: [PATCH 05/65] Update nonprofits structure and remove old directory --- seed/nonprofits.json | 329 ------------------------- server/boot/nonprofits.js | 107 -------- server/views/nonprofits/directory.jade | 27 -- server/views/nonprofits/show.jade | 75 ------ server/views/resources/nonprofits.jade | 2 - server/views/resources/sitemap.jade | 13 - 6 files changed, 553 deletions(-) delete mode 100644 seed/nonprofits.json delete mode 100644 server/boot/nonprofits.js delete mode 100644 server/views/nonprofits/directory.jade delete mode 100644 server/views/nonprofits/show.jade diff --git a/seed/nonprofits.json b/seed/nonprofits.json deleted file mode 100644 index 2f6ee0b77d..0000000000 --- a/seed/nonprofits.json +++ /dev/null @@ -1,329 +0,0 @@ -[ - { - "whatDoesNonprofitDo": "We help the many less-fortunate Jewish families in our community, by providing them with nutritious food and energy to grow, learn, work, and give them hope for a better and brighter future.", - "websiteLink": "http://chasdeikaduri.org/", - "name": "Chasdei Kaduri", - "endUser": "Clients, donors, and admin.", - "approvedDeliverables": [ - "website", - "donor", - "inventory", - "volunteer", - "form" - ], - "projectDescription": "Campers will create a system will integrate the food inventory, donor and delivery driver management systems as well as replace the current application system with a custom form solution. System will include a more streamlined operations management, with user printable lists of inventory, drivers, and deliveries.", - "logoUrl": "http://i.imgur.com/zQiM0P8.png", - "imageUrl": "http://i.imgur.com/xeRdA87.jpg", - "estimatedHours": 300, - "currentStatus": "completed", - "moneySaved": 60000 - }, - { - "whatDoesNonprofitDo": "We connect simple technology with last mile communities to reduce poverty.", - "websiteLink": "http://kopernik.info/", - "name": "Kopernik", - "endUser": "Women in rural Indonesia.", - "approvedDeliverables": [ - "other" - ], - "projectDescription": "Campers will create a Chrome browser extension to preserve sales data from a form, and upload in batches as the internet connection allows.", - "logoUrl": "http://i.imgur.com/xTqjIkC.png", - "imageUrl": "http://i.imgur.com/xBAUJSa.jpg", - "estimatedHours": 100, - "currentStatus": "completed", - "moneySaved": 20000 - }, - { - "whatDoesNonprofitDo": "We distribute biodegradable toothbrushes globally to children in need.", - "websiteLink": "http://www.operationbrush.org/", - "name": "Operation Brush", - "endUser": "Donors", - "approvedDeliverables": [ - "website" - ], - "projectDescription": "Campers will create a mobile responsive website for the organization, with donation capabilities.", - "logoUrl": "http://i.imgur.com/DEDhImE.png", - "imageUrl": "http://i.imgur.com/RuA9Rgy.jpg", - "estimatedHours": 100, - "currentStatus": "completed", - "moneySaved": 20000 - }, - { - "whatDoesNonprofitDo": "We are the largest roller derby league in the world with around 250 adults and 150 junior skater members plus 500+ volunteers.", - "websiteLink": "http://www.rosecityrollers.com/about/our-charities/", - "name": "Rose City Rollers", - "endUser": "Roller derby administrators, coaches, and volunteers", - "approvedDeliverables": [ - "community" - ], - "projectDescription": "Campers will create a volunteer management system with multi-user access and reporting capabilities.", - "logoUrl": "http://i.imgur.com/ZZAZSs4.jpg", - "imageUrl": "http://i.imgur.com/WKS4cZ8.jpg", - "estimatedHours": 200, - "currentStatus": "completed", - "moneySaved": 40000 - }, - { - "whatDoesNonprofitDo": "We provide urgently needed pediatric heart surgery and follow-up care for indigent children from developing countries", - "websiteLink": "http://www.saveachildsheart.com/global/young-leadership-program/", - "name": "Save a Child's Heart", - "endUser": "Donors", - "approvedDeliverables": [ - "website" - ], - "projectDescription": "Campers will create a single page fundraising website. In exchange for a donation, a user can customize a graphical 'heart' in someone's name or anonymously. The page will display all of the hearts on a 'wall of hearts.'", - "logoUrl": "http://i.imgur.com/t6tpiEW.jpg", - "imageUrl": "http://i.imgur.com/xqhvdn2.jpg", - "estimatedHours": 200, - "currentStatus": "completed", - "moneySaved": 40000 - }, - { - "whatDoesNonprofitDo": "We empower youth with technology by providing age appropriate resources and education.", - "websiteLink": "http://savvycyberkids.org/", - "name": "Savvy Cyber Kids", - "endUser": "Donors", - "approvedDeliverables": [ - "website" - ], - "projectDescription": "Campers will create a website where potential donors can view which schools already have the Savvy Cyber Kids books, and donate books to those schools that do not.", - "logoUrl": "http://i.imgur.com/JgxYVJ5.png", - "imageUrl": "http://i.imgur.com/ZTg12ao.jpg", - "estimatedHours": 200, - "currentStatus": "completed", - "moneySaved": 40000 - }, - { - "whatDoesNonprofitDo": "We bring a new edge to arts and medicine in the Bay Area through powerful live performances of new music to those who feel marginalized by their affliction.", - "websiteLink": "http://transcendentpathways.org/", - "name": "Transcendent Pathways", - "endUser": "Medical Facilities, Musicians", - "approvedDeliverables": [ - "other" - ], - "projectDescription": "Campers will build a website where medical facilities can list music therapy time slots, and musicians can sign up to fill these slots.", - "logoUrl": "http://i.imgur.com/JV4rcKX.png", - "imageUrl": "http://i.imgur.com/gyhrPee.jpg", - "estimatedHours": 200, - "currentStatus": "completed", - "moneySaved": 40000 - }, - { - "whatDoesNonprofitDo": "We have provide volunteer matching fairs and silent art auctions at events across Canada. Rather than bid money on artwork, participants bid volunteer hours.", - "websiteLink": "http://www.timeraiser.ca/", - "name": "Timeraiser", - "endUser": "Working professionals who want to donate their time and expertise", - "approvedDeliverables": [ - "other" - ], - "projectDescription": "Campers will build a mobile responsive web form to allow Timeraiser eventgoers to select which nonprofit organizations they're interested in volunteering with. System will have Salesforce integration and reporting capabilities.", - "logoUrl": "http://i.imgur.com/USK8ld7.png", - "imageUrl": "http://i.imgur.com/7apWppe.jpg", - "estimatedHours": 200, - "currentStatus": "completed", - "moneySaved": 40000 - }, - { - "whatDoesNonprofitDo": "We focus on raising funds to assist injured homeless animals.", - "websiteLink": "http://www.peoplesavinganimals.org/", - "name": "People Saving Animals", - "endUser": "Animal shelters in Central America and people adopting pets", - "approvedDeliverables": [ - "website", - "inventory", - "form" - ], - "projectDescription": "Campers will build an adoption database and all related web interfaces and forms to allow animal shelters to easily post animals, photos, and relevant medical information. They'll make it easy for locals to browse these animals and adopt them. Once completed, this project will be translated into Spanish.", - "logoUrl": "http://i.imgur.com/iKcKcpg.jpg", - "imageUrl": "http://i.imgur.com/b9ZeU7R.jpg", - "estimatedHours": 300, - "currentStatus": "completed", - "moneySaved": 60000 - }, - { - "whatDoesNonprofitDo": "We preserve Florida's health by regulating septic contractors and reviewing logs of sewage collection and disposal.", - "websiteLink": "http://www.floridahealth.gov/", - "name": "Florida Department of Health", - "endUser": "Government workers and independent contractors who must comply with regulations.", - "approvedDeliverables": [ - "inventory", - "form", - "other" - ], - "projectDescription": "Campers will build mobile responsive web forms to allow contractors to seamlessly log the chain of custody for potentially hazardous sewage. They'll also build a government-facing database that allows for easy monitoring and reporting of activity.", - "logoUrl": "http://i.imgur.com/J3Scbsp.png", - "imageUrl": "http://i.imgur.com/8LEFrKy.jpg", - "estimatedHours": 200, - "currentStatus": "completed", - "moneySaved": 40000 - }, - { - "whatDoesNonprofitDo": "We strengthen the value of songwriting and independent music in Columbus, Ohio.", - "websiteLink": "http://columbussongwritersassociation.com", - "name": "Columbus Songwriters Association", - "endUser": "Songwriters and their audiences in the Columbus, Ohio community.", - "approvedDeliverables": [ - "website" - ], - "projectDescription": "Build mobile responsive website that allows users to see browse our partners, their photos and information, and connect with them.", - "logoUrl": "http://i.imgur.com/UN85TI4.jpg", - "imageUrl": "http://i.imgur.com/NFxL1oS.jpg", - "estimatedHours": 100, - "currentStatus": "completed", - "moneySaved": 20000 - }, - { - "whatDoesNonprofitDo": "We leverage all the benefits of cycling to support and improve the lives of youth and teens in the Triangle region.", - "websiteLink": "http://www.trianglebikeworks.org", - "name": "Triangle Bike Works", - "endUser": "Youth and teens in the Triangle region.", - "approvedDeliverables": [ - "website" - ], - "projectDescription": "Campers will build a website with donation integration.", - "logoUrl": "http://i.imgur.com/T5OkXuT.png", - "imageUrl": "http://i.imgur.com/7bOaMPq.jpg", - "estimatedHours": 100, - "currentStatus": "open", - "moneySaved": 0 - }, - { - "whatDoesNonprofitDo": "We work to eradicate female genital mutilation in the US and Gambia. We work with survivors and communities.", - "websiteLink": "http://safehandsforgirls.org/", - "name": "Safe Hands for Girls", - "endUser": "Supporters", - "approvedDeliverables": [ - "website" - ], - "projectDescription": "Campers will build a website with donation management.", - "logoUrl": "http://i.imgur.com/QnAY6Ji.png", - "imageUrl": "http://i.imgur.com/s9E4oa9.jpg", - "estimatedHours": 100, - "currentStatus": "open", - "moneySaved": 0 - }, - { - "whatDoesNonprofitDo": "We're a part of the Department of Psychiatry at Mass General Hospital. We teach an innovative way for helping people that have challenging behaviors.", - "websiteLink": "http://www.thinkkids.org/", - "name": "Think Kids at Massachusetts General Hospital", - "endUser": "Volunteers, Administrators", - "approvedDeliverables": [ - "volunteer" - ], - "projectDescription": "We would like help developing a simple online based portal for both our trainees and trainers where we can store and share documents, track their progress, and incorporate a blackboard/chat forum.", - "logoUrl": "http://i.imgur.com/fu6dTmH.png", - "imageUrl": "http://i.imgur.com/hiGJms5.png", - "estimatedHours": 300, - "currentStatus": "started", - "moneySaved": 0 - }, - { - "whatDoesNonprofitDo": "We enable, educate, and empower students from rural backgrounds in Uttar Pradesh, India.", - "websiteLink": "http://www.milaan.in/", - "name": "Milaan", - "endUser": "Supporters", - "approvedDeliverables": [ - "website" - ], - "projectDescription": "Campers will build a basic website for the US operations of Milaan. ", - "logoUrl": "http://i.imgur.com/GLq1qqD.png", - "imageUrl": "http://i.imgur.com/PkMHQ8N.jpg", - "estimatedHours": 100, - "currentStatus": "open", - "moneySaved": 0 - }, - { - "whatDoesNonprofitDo": "We're committed to closing the opportunity gap for children in Baltimore City by providing high quality after school and in-school programs.", - "websiteLink": "http://childfirstauthority.org/", - "name": "Child First Authority", - "endUser": "School Coordinators", - "approvedDeliverables": [ - "volunteer" - ], - "projectDescription": "Campers will build a dynamic database that will allow 7 community school coordinators to (1) input student-level absenteeism data, (2) code and track outreach efforts, (3) code root causes for absenteeism, and (4) track trends in each area. Currently, Child First uses an unwieldy excel spreadsheet to do this.", - "logoUrl": "http://i.imgur.com/YlPsQmN.jpg", - "imageUrl": "http://i.imgur.com/Z2RfQku.gifv", - "estimatedHours": 200, - "currentStatus": "started", - "moneySaved": 0 - }, - { - "whatDoesNonprofitDo": "We are an interdisciplinary team that works towards harmony among humans and nature through three distinct branches: sustainable agriculture, environmental education and applied and appropriate technology; focused in Líbano, Tolima, Colombia.", - "websiteLink": "", - "name": "QET America", - "endUser": "Donors", - "approvedDeliverables": ["Website"], - "projectDescription": "Campers will build a multiple language website (English, Spanish) that accepts donations.", - "logoUrl": "http://i.imgur.com/jPuiPOy.jpg", - "imageUrl": "http://i.imgur.com/zaaL2pj.jpg", - "estimatedHours": 100, - "currentStatus": "open", - "moneySaved": 0 - }, - { - "whatDoesNonprofitDo": "1to1 Movement provides free environmental education in schools", - "websiteLink": "http://1to1movement.org/", - "name": "1 to 1 Movement", - "endUser": "Pledgers", - "approvedDeliverables": ["Web App"], - "projectDescription": "Campers will build a simple, social, data-driven application that allows people to see the impact of their actions. User can make a pledge and track the outcome. Will make use of the D3.js visualization library.", - "logoUrl": "http://i.imgur.com/jaqxg0O.png", - "imageUrl": "http://i.imgur.com/GXSWTZw.jpg", - "estimatedHours": 300, - "currentStatus": "open", - "moneySaved": 0 - }, - - { - "whatDoesNonprofitDo": "Our missions is to elevate the national dialogue and engage the American people around climate change policy and the promotion of real clean energy solutions in the United States.", - "websiteLink": "http://www.usclimateplan.org/", - "name": "US Climate Plan", - "endUser": "Donors", - "approvedDeliverables": ["Website"], - "projectDescription": "Campers will build a basic website for sharing information, feeds from different campaign’s websites.", - "logoUrl": "http://i.imgur.com/uAyUiMN.png", - "imageUrl": "http://i.imgur.com/2Og5tqy.jpg", - "estimatedHours": 100, - "currentStatus": "open", - "moneySaved": 0 - }, - { - "whatDoesNonprofitDo": "We empower the community through improved literacy.", - "websiteLink": "http://www.tleliteracy.com/", - "name": "The Learning Exchange", - "endUser": "Community members", - "approvedDeliverables": ["Website"], - "projectDescription": "Campers will build a simple website to replace essentialskillsquebec.com. Site will host many documents related to the Nine Essential Skills.", - "logoUrl": "http://i.imgur.com/jXQY01H.png", - "imageUrl": "http://i.imgur.com/iUXBpeL.jpg", - "estimatedHours": 100, - "currentStatus": "started", - "moneySaved": 0 - }, - { - "whatDoesNonprofitDo": "Options Inc. is an organization that was founded in 1979 to assist adults with disabilities in living and working in the community. We provide transportation to approximately 230 individuals.", - "websiteLink": "www.options-inc.org", - "name": "Options Inc.", - "endUser": "Administrators and Persons with Disabilities", - "approvedDeliverables": ["Web App"], - "projectDescription": "Campers will build a system to store all of Options Inc.'s clients addresses, optimize routes for our 23 vehicles, and schedule their staff for these routes.", - "logoUrl": "http://i.imgur.com/jGWRMuF.jpg", - "imageUrl": "http://i.imgur.com/VUuJJlM.jpg", - "estimatedHours": 300, - "currentStatus": "open", - "moneySaved": 0 - }, - { - "whatDoesNonprofitDo": "Our goal is to improve addiction treatment and recovery services through targeted outreach, policy development, and direct support services for addicts, their families and health professionals.", - "websiteLink": "http://www.taadas.org/", - "name": "Tennessee Association of Alcohol Drug and other Addiction Services", - "endUser": "Administrators and Persons with Disabilities", - "approvedDeliverables": ["Website"], - "projectDescription": "Campers will build a modern, mobile-responsive website.", - "logoUrl": "http://i.imgur.com/kYHgY0F.jpg", - "imageUrl": "http://i.imgur.com/W6L1sGV.jpg", - "estimatedHours": 100, - "currentStatus": "open", - "moneySaved": 0 - } -] diff --git a/server/boot/nonprofits.js b/server/boot/nonprofits.js deleted file mode 100644 index f042f34354..0000000000 --- a/server/boot/nonprofits.js +++ /dev/null @@ -1,107 +0,0 @@ -var Rx = require('rx'); -var debug = require('debug')('freecc:nonprofits'); -var observeMethod = require('../utils/rx').observeMethod; -var unDasherize = require('../utils').unDasherize; -var dasherize = require('../utils').dasherize; - -module.exports = function(app) { - var router = app.loopback.Router(); - var Nonprofit = app.models.Nonprofit; - var findNonprofits = observeMethod(Nonprofit, 'find'); - var findOneNonprofit = observeMethod(Nonprofit, 'findOne'); - - router.get('/nonprofits/directory', nonprofitsDirectory); - router.get('/nonprofits/:nonprofitName', returnIndividualNonprofit); - - app.use(router); - - function nonprofitsDirectory(req, res, next) { - findNonprofits({ - order: 'moneySaved DESC' - }) - .flatMap( - (nonprofits = []) => { - // turn array of nonprofits into observable array - return Rx.Observable.from(nonprofits) - .pluck('moneySaved') - .reduce((sum, moneySaved = 0) => sum + moneySaved, 0); - }, - (nonprofits = [], totalSavings) => ({ nonprofits, totalSavings }) - ) - .subscribe(({ nonprofits, totalSavings }) => { - res.render('nonprofits/directory', { - title: 'Nonprofits we help', - nonprofits: nonprofits, - totalSavings: totalSavings.toString().replace(/000$/, ',000') - }); - }, - next - ); - } - - function returnIndividualNonprofit(req, res, next) { - var dashedName = req.params.nonprofitName; - var nonprofitName = unDasherize(dashedName); - var query = { where: { name: { - like: nonprofitName, - options: 'i' - } } }; - - debug('looking for %s', nonprofitName); - debug('query', query); - findOneNonprofit(query).subscribe( - function(nonprofit) { - if (!nonprofit) { - req.flash('errors', { - msg: "404: We couldn't find a nonprofit with that name. " + - 'Please double check the name.' - }); - return res.redirect('/nonprofits'); - } - - var dashedNameFull = dasherize(nonprofit.name); - if (dashedNameFull !== dashedName) { - return res.redirect('../nonprofit/' + dashedNameFull); - } - - res.render('nonprofits/show', { - dashedName: dashedNameFull, - title: nonprofit.name, - logoUrl: nonprofit.logoUrl, - estimatedHours: nonprofit.estimatedHours, - projectDescription: nonprofit.projectDescription, - - approvedOther: - nonprofit.approvedDeliverables.indexOf('other') > -1, - approvedWebsite: - nonprofit.approvedDeliverables.indexOf('website') > -1, - - approvedDonor: - nonprofit.approvedDeliverables.indexOf('donor') > -1, - approvedInventory: - nonprofit.approvedDeliverables.indexOf('inventory') > -1, - - approvedVolunteer: - nonprofit.approvedDeliverables.indexOf('volunteer') > -1, - approvedForm: - nonprofit.approvedDeliverables.indexOf('form') > -1, - - approvedCommunity: - nonprofit.approvedDeliverables.indexOf('community') > -1, - approvedELearning: - nonprofit.approvedDeliverables.indexOf('eLearning') > -1, - - websiteLink: nonprofit.websiteLink, - imageUrl: nonprofit.imageUrl, - whatDoesNonprofitDo: nonprofit.whatDoesNonprofitDo, - interestedCampers: nonprofit.interestedCampers, - assignedCampers: nonprofit.assignedCampers, - buttonActive: false, - moneySaved: nonprofit.moneySaved, - currentStatus: nonprofit.currentStatus - }); - }, - next - ); - } -}; diff --git a/server/views/nonprofits/directory.jade b/server/views/nonprofits/directory.jade deleted file mode 100644 index e30a6671fd..0000000000 --- a/server/views/nonprofits/directory.jade +++ /dev/null @@ -1,27 +0,0 @@ -extends ../layout -block content - script. - var challengeName = 'Nonprofits View'; - .col-xs-12.col-sm-12.col-md-12 - .panel.panel-info - .panel-heading.text-center Nonprofits We Help - .panel-body - .col-xs-12.col-sm-12.col-md-10.col-md-offset-1 - h1.text-primary.text-center Our campers have saved nonprofits $#{totalSavings}. - .spacer - for nonprofit in nonprofits - .spacer - .row - .col-xs-12.col-sm-3 - img.img-responsive.img-center(src=nonprofit.logoUrl) - .col-xs-12.col-sm-9 - h2.negative-15= nonprofit.name - h3.negative-15= nonprofit.whatDoesNonprofitDo - if (nonprofit.moneySaved > 0) - h4.negative-15.text-primary Estimated Cost Savings for Nonprofit: $#{nonprofit.moneySaved.toString().replace(/000$/, ',000')} - a.text-center.btn.btn-primary.btn-lg(href='/nonprofits/' + nonprofit.name.toLowerCase().replace(/\s/g, '-')) Read more - .spacer - .col-xs-12.col-sm-8.col-sm-offset-2 - if (!user) - a.btn.btn-cta.signup-btn.btn-block(href="/nonprofits-form") My nonprofit needs coding help - .spacer diff --git a/server/views/nonprofits/show.jade b/server/views/nonprofits/show.jade deleted file mode 100644 index 18b5e261b3..0000000000 --- a/server/views/nonprofits/show.jade +++ /dev/null @@ -1,75 +0,0 @@ -extends ../layout -block content - script. - var challengeName = 'Nonprofits View'; - .row - .col-xs-12.col-sm-10.col-sm-offset-1 - .row - .col-xs-12 - img.img-center.img-responsive(src=imageUrl) - .spacer - .row - .col-xs-12.col-sm-4 - img.img-responsive(src=logoUrl) - .col-xs-12.col-sm-8 - .col-xs-12 - h4= whatDoesNonprofitDo - h4 - a(href=websiteLink)= websiteLink - .spacer - h3 Project Description: - .col-xs-12 - h4.negative-15 #{projectDescription} (About #{estimatedHours} hours per camper) - .spacer - h3 This project involves building: - h4.negative-15.col-xs-12 - if (approvedWebsite) - .ion-android-globe   Website - if (approvedDonor) - .ion-card   Donor Management System - if (approvedInventory) - .ion-ios-box   Inventory Management System - if (approvedVolunteer) - .ion-android-calendar   Volunteer Management System - if (approvedForm) - .ion-ios-list   Webform - if (approvedCommunity) - .ion-ios-people   Community Management System - if (approvedELearning) - .ion-university   E-learning Platform - if (approvedOther) - .ion-settings   Other tools - h3 Project Status: #{currentStatus} - if (moneySaved > 0) - h3.text-primary Estimated Cost Savings for Nonprofit: $#{moneySaved.toString().replace(/000$/, ',000')} - - if (interestedCampers && interestedCampers.length > 0) - h3 Interested campers: - .col-xs-12.text-left - for interestedCamper in interestedCampers - a(href='/' + interestedCamper.username class="interested-camper-image") - img.profile-picture.float-right(src=interestedCamper.picture) - if (assignedCampers && assignedCampers.length > 0) - h3 Assigned campers: - .col-xs-12.text-left - for assignedCamper in assignedCampers - a(href='/' + assignedCamper.username class="interested-camper-image") - img.profile-picture.float-right(src=assignedCamper.picture) - if (!buttonActive) - .col-xs-12.col-sm-8.col-sm-offset-2 - .text-center - if !user - a.btn.btn-cta.signup-btn.btn-block(href="/login") Start learning to code (it's free) - .button-spacer - else - a.btn.btn-primary.btn-big.btn-block.disabled(href='/nonprofits/interested-in-nonprofit/#{dashedName}') I'm interested in building this project * - p * Complete all our Bonfires, Ziplines, and Basejumps to unlock this. - a.btn.btn-info.btn-big.btn-block(href='/nonprofits/directory') Show all Nonprofit Projects - .spacer - if (buttonActive) - .col-xs-12.col-sm-8.col-sm-offset-2 - .text-center - a.btn.btn-primary.btn-big.btn-block(href='/nonprofits/interested-in-nonprofit/#{dashedName}') I'm interested in building this project - .button-spacer - a.btn.btn-info.btn-big.btn-block(href='/nonprofits/directory') Show all Nonprofit Projects - .spacer diff --git a/server/views/resources/nonprofits.jade b/server/views/resources/nonprofits.jade index 70522f6e45..aea1345642 100644 --- a/server/views/resources/nonprofits.jade +++ b/server/views/resources/nonprofits.jade @@ -71,5 +71,3 @@ block content .row .col-xs-12.col-sm-8.col-sm-offset-2 a.btn.btn-cta.signup-btn.btn-block(href="/nonprofits-form") My nonprofit needs coding help - .button-spacer - a.btn.btn-lg.btn-primary.btn-primary-ghost.btn-block(href="/nonprofits/directory") Browse our directory of nonprofits we've helped diff --git a/server/views/resources/sitemap.jade b/server/views/resources/sitemap.jade index 6b4907a199..7ce295adb1 100644 --- a/server/views/resources/sitemap.jade +++ b/server/views/resources/sitemap.jade @@ -37,12 +37,6 @@ urlset(xmlns="http://www.sitemaps.org/schemas/sitemap/0.9") lastmod= now priority= 0.9 - url - loc http://www.freecodecamp.com/twitch - changefreq weekly - lastmod= now - priority= 0.9 - url loc http://www.freecodecamp.com/jobs changefreq weekly @@ -76,10 +70,3 @@ urlset(xmlns="http://www.sitemaps.org/schemas/sitemap/0.9") lastmod= now changefreq weekly priority= 0.5 - - each nonprofit in nonprofits - url - loc #{appUrl}/nonprofits/#{nonprofit.replace(/\s/g, '-')} - lastmod= now - changefreq weekly - priority= 0.9 From bf06d0c6a024718764edfd271387f4e07056dbb5 Mon Sep 17 00:00:00 2001 From: Quincy Larson Date: Sat, 9 Jan 2016 23:49:07 -0600 Subject: [PATCH 06/65] Update commit views --- server/views/commit/directory.jade | 25 +++-- server/views/commit/index.jade | 154 ++++++++++++++--------------- 2 files changed, 88 insertions(+), 91 deletions(-) diff --git a/server/views/commit/directory.jade b/server/views/commit/directory.jade index e27ba5f1cd..d2e86ef426 100644 --- a/server/views/commit/directory.jade +++ b/server/views/commit/directory.jade @@ -1,15 +1,14 @@ extends ../layout block content - .panel.panel-info - .panel-heading.text-center Commit to one of these nonprofits - .panel-body - .row - .col-xs-12.col-sm-10.col-sm-offset-1 - for nonprofit in nonprofits - .col-xs-12.col-sm-6.col-md-4.height-400 - .text-center - h2= nonprofit.displayName - img.testimonial-image.img-responsive.img-center(src=nonprofit.imgUrl) - .button-spacer - a.text-center(href='/commit?nonprofit=#{nonprofit.name}') Commit to #{nonprofit.displayName} - p= nonprofit.description + h1.text-center Commit to one of these nonprofits + hr + .row + .col-xs-12.col-sm-10.col-sm-offset-1 + for nonprofit in nonprofits + .col-xs-12.col-sm-6.col-md-4.height-400 + .text-center + h2= nonprofit.displayName + img.testimonial-image.img-responsive.img-center(src=nonprofit.imgUrl) + .button-spacer + a.text-center(href='/commit?nonprofit=#{nonprofit.name}') Commit to #{nonprofit.displayName} + p= nonprofit.description diff --git a/server/views/commit/index.jade b/server/views/commit/index.jade index e9a919fd5a..722654e64c 100644 --- a/server/views/commit/index.jade +++ b/server/views/commit/index.jade @@ -1,86 +1,84 @@ extends ../layout block content - .panel.panel-info - .panel-body - h2.text-center Commit to yourself. Commit to a nonprofit. - .row - .col-xs-12.col-sm-6.col-sm-offset-3 - p Give yourself external motivation and help nonprofits right away. Pledge a monthly donation to a nonprofit until you’ve earned either your Front End or Full Stack Development Certification. + h2.text-center Commit to yourself. Commit to a nonprofit. + .row + .col-xs-12.col-sm-6.col-sm-offset-3 + p Give yourself external motivation and help nonprofits right away. Pledge a monthly donation to a nonprofit until you’ve earned either your Front End or Full Stack Development Certification. - .row - .col-xs-12.col-sm-6.col-sm-offset-3.text-center - h3 Pledge to #{displayName}  - .button-spacer - a(href='#{imgUrl}' data-lightbox='img-enlarge' alt='#{imgAlt}') - img.img-responsive(src='#{imgUrl}' alt='#{imgAlt}') - p.large-p - = description - a(href='/commit/directory') ...or see other nonprofits - .spacer - form.form(name='commit') - .hidden - input(type='text' value='#{name}' name='nonprofit') - .row - .col-xs-12.col-sm-6.col-sm-offset-3 - h3 Step 1: Which certification do you pledge to complete? - .btn-group.btn-group-justified(data-toggle='buttons' role='group') - label.btn.btn-primary.btn-lg.active - input(type='radio' id=frontEndCert value=frontEndCert name='goal' checked="checked") - | Front End - label.btn.btn-primary.btn-lg - input(type='radio' id=dataVisCert value=dataVisCert name='goal') - | Data - label.btn.btn-primary.btn-lg - input(type='radio' id=backEndCert value=backEndCert name='goal') - | Back End - label.btn.btn-primary.btn-lg - input(type='radio' id=fullStackCert value=fullStackCert name='goal') - | Full Stack - .spacer - .row - .col-xs-12.col-sm-6.col-sm-offset-3 - h3 Step 2: How much do you want to pledge monthly until you earn that certification? - .btn-group.btn-group-justified(data-toggle='buttons' role='group') - label.btn.btn-success - input(type='radio' id='5-dollar-pledge' value='5' name='amount') - | $5 per month - label.btn.btn-success.active - input(type='radio' id='10-dollar-pledge' value='10' name='amount' checked="checked") - | $10 per month - label.btn.btn-success - input(type='radio' id='25-dollar-pledge' value='25' name='amount') - | $25 per month - label.btn.btn-success - input(type='radio' id='50-dollar-pledge' value='50' name='amount') - | $50 per month - .spacer - .col-xs-12.col-sm-6.col-sm-offset-3 - h3 Step 3: Set up your monthly donation - .row - .col-xs-12.col-sm-6.col-sm-offset-3.text-center - a#commit-btn-donate.btn.btn-block.btn-lg.btn-primary(href=donateUrl target='_blank') Open the #{displayName} donation page + .row + .col-xs-12.col-sm-6.col-sm-offset-3.text-center + h3 Pledge to #{displayName}  + .button-spacer + a(href='#{imgUrl}' data-lightbox='img-enlarge' alt='#{imgAlt}') + img.img-responsive(src='#{imgUrl}' alt='#{imgAlt}') + p.large-p + = description + p + a(href='/commit/directory') ...or see other nonprofits + .spacer + form.form(name='commit') + .hidden + input(type='text' value='#{name}' name='nonprofit') + .row + .col-xs-12.col-sm-6.col-sm-offset-3 + h3 Step 1: Which certification do you pledge to complete? + .btn-group.btn-group-justified(data-toggle='buttons' role='group') + label.btn.btn-primary.btn-lg.active + input(type='radio' id=frontEndCert value=frontEndCert name='goal' checked="checked") + | Front End + label.btn.btn-primary.btn-lg + input(type='radio' id=dataVisCert value=dataVisCert name='goal') + | Data + label.btn.btn-primary.btn-lg + input(type='radio' id=backEndCert value=backEndCert name='goal') + | Back End + label.btn.btn-primary.btn-lg + input(type='radio' id=fullStackCert value=fullStackCert name='goal') + | Full Stack + .spacer + .row + .col-xs-12.col-sm-6.col-sm-offset-3 + h3 Step 2: How much do you want to pledge monthly until you earn that certification? + .btn-group.btn-group-justified(data-toggle='buttons' role='group') + label.btn.btn-primary + input(type='radio' id='5-dollar-pledge' value='5' name='amount') + | $5 per month + label.btn.btn-primary.active + input(type='radio' id='10-dollar-pledge' value='10' name='amount' checked="checked") + | $10 per month + label.btn.btn-primary + input(type='radio' id='25-dollar-pledge' value='25' name='amount') + | $25 per month + label.btn.btn-primary + input(type='radio' id='50-dollar-pledge' value='50' name='amount') + | $50 per month + .spacer + .col-xs-12.col-sm-6.col-sm-offset-3 + h3 Step 3: Set up your monthly donation + .row + .col-xs-12.col-sm-6.col-sm-offset-3.text-center + a#commit-btn-donate.btn.btn-block.btn-lg.btn-primary(href=donateUrl target='_blank') Open the #{displayName} donation page - .spacer - .col-xs-12.col-sm-6.col-sm-offset-3 - h3#commit-step4-text.disabled - Step 4: Confirm - span#commit-step4-hidden.disabled (Do step 3 first) - span#commit-step4-show.hidden your commitment to your goal - .row - .col-xs-12.col-sm-6.col-sm-offset-3.text-center - button#commit-btn-submit.btn.btn-block.btn-lg.btn-primary.disabled Commit + .spacer + .col-xs-12.col-sm-6.col-sm-offset-3 + h3#commit-step4-text.disabled + Step 4: Confirm + span#commit-step4-hidden.disabled (Do step 3 first) + span#commit-step4-show.hidden your commitment to your goal + .row + .col-xs-12.col-sm-6.col-sm-offset-3.text-center + button#commit-btn-submit.btn.btn-block.btn-lg.btn-primary.disabled Commit - if pledge - form.row(name='stop-pledge' action='/commit/stop-commitment' method='post') - .col-xs-12.col-sm-6.col-sm-offset-3.text-center - .button-spacer - button.btn.btn-block.btn-lg.btn-default(name='submit' type='submit') Stop my current pledge - else - .row - .col-xs-12.col-sm-6.col-sm-offset-3.text-center - .button-spacer - a.btn.btn-block.btn-lg.btn-default(href='/map') Maybe later - .spacer + if pledge + form.row(name='stop-pledge' action='/commit/stop-commitment' method='post') + .col-xs-12.col-sm-6.col-sm-offset-3.text-center + .button-spacer + button.btn.btn-block.btn-lg.btn-default(name='submit' type='submit') Stop my current pledge + else + .row + .col-xs-12.col-sm-6.col-sm-offset-3.text-center + .button-spacer + a.btn.btn-block.btn-lg.btn-default(href='/map') Maybe later script. $(function() { $('#commit-btn-donate').click(function() { From 7f0be44f9814a998df6daf2805e0e40bbbd3278b Mon Sep 17 00:00:00 2001 From: Quincy Larson Date: Sun, 10 Jan 2016 00:53:46 -0600 Subject: [PATCH 07/65] additional cleanup of nonprofit directory --- client/less/main.less | 1 - server/utils/index.js | 15 +-------------- server/views/home.jade | 16 ++++++++-------- server/views/resources/nonprofits.jade | 3 ++- 4 files changed, 11 insertions(+), 24 deletions(-) diff --git a/client/less/main.less b/client/less/main.less index 86f11b3eb7..48b37e4045 100644 --- a/client/less/main.less +++ b/client/less/main.less @@ -246,7 +246,6 @@ ul { @media (min-width: 767px) { font-size: 24px; } - } .capitalize { diff --git a/server/utils/index.js b/server/utils/index.js index 0975ee3662..d830b55850 100644 --- a/server/utils/index.js +++ b/server/utils/index.js @@ -1,13 +1,11 @@ var cheerio = require('cheerio'), request = require('request'), MDNlinks = require('../../seed/bonfireMDNlinks'), - resources = require('./resources.json'), - nonprofits = require('../../seed/nonprofits.json'); + resources = require('./resources.json'); /** * Cached values */ -var allNonprofitNames; module.exports = { dasherize: function dasherize(name) { @@ -44,17 +42,6 @@ module.exports = { ]; }, - allNonprofitNames: function() { - if (allNonprofitNames) { - return allNonprofitNames; - } else { - allNonprofitNames = nonprofits.map(function(elem) { - return {name: elem.name}; - }); - return allNonprofitNames; - } - }, - whichEnvironment: function() { return process.env.NODE_ENV; }, diff --git a/server/views/home.jade b/server/views/home.jade index 9c59ed0b96..197683a041 100644 --- a/server/views/home.jade +++ b/server/views/home.jade @@ -84,17 +84,17 @@ block content .spacer hr .spacer - .col-xs-offset-0.col-sm-offset-1.text-left + .col-xs-offset-0.col-sm-offset-1.text-left.large-p h2 Here's why you should join our open source community right now: .spacer ul.large-li - li.ion-code.large-p   You'll get help in real time from our community chat rooms. - li.ion-code.large-p   You'll meet up with other coders in your city. - li.ion-code.large-p   You'll learn to code at your own pace, in your browser or on your phone. - li.ion-code.large-p   You'll work through our focused, interactive courses and tutorials. - li.ion-code.large-p   You'll learn state-of-the-art full stack JavaScript technologies. - li.ion-code.large-p   You'll build projects that help nonprofits carry out their missions more effectively. - li.ion-code.large-p   You'll assemble a portfolio of real apps used by real people. + li.ion-code   You'll get help in real time from our community chat rooms. + li.ion-code   You'll meet up with other coders in your city. + li.ion-code   You'll learn to code at your own pace, in your browser or on your phone. + li.ion-code   You'll work through our focused, interactive courses and tutorials. + li.ion-code   You'll learn state-of-the-art full stack JavaScript technologies. + li.ion-code   You'll build projects that help nonprofits carry out their missions more effectively. + li.ion-code   You'll assemble a portfolio of real apps used by real people. .big-break .row .col-xs-12.col-sm-8.col-sm-offset-2 diff --git a/server/views/resources/nonprofits.jade b/server/views/resources/nonprofits.jade index aea1345642..731c463d3e 100644 --- a/server/views/resources/nonprofits.jade +++ b/server/views/resources/nonprofits.jade @@ -59,8 +59,9 @@ block content .spacer hr .spacer - .large-p.text-left.col-xs-offset-0.col-sm-offset-1 + .col-xs-offset-0.col-sm-offset-1.text-left.large-p h2 Our developers build projects for nonprofits who: + .spacer ul.large-li li.ion-code   already have people who benefit from their services. li.ion-code   are registered with their government and have tax-exempt status. From f410a94b54ece5f8ee3550af2f2bdcc866be5a33 Mon Sep 17 00:00:00 2001 From: Quincy Larson Date: Sun, 10 Jan 2016 23:49:09 -0600 Subject: [PATCH 08/65] Update --- client/less/lib/bootstrap/variables.less | 8 +- client/less/main.less | 26 +-- common/app/routes/Jobs/components/Jobs.jsx | 2 - server/views/challengeMap/show.jade | 223 +++------------------ server/views/home.jade | 8 +- 5 files changed, 50 insertions(+), 217 deletions(-) diff --git a/client/less/lib/bootstrap/variables.less b/client/less/lib/bootstrap/variables.less index 968b70b7c6..98b46a105f 100755 --- a/client/less/lib/bootstrap/variables.less +++ b/client/less/lib/bootstrap/variables.less @@ -14,9 +14,9 @@ @gray-light: lighten(@gray-base, 46.7%); // #777 @gray-lighter: lighten(@gray-base, 93.5%); // #eee -@brand-primary: #215f1e; -@brand-success: #457E86; -@brand-info: #4A2B0F; +@brand-primary: #407521; +@brand-success: #457e86; +@brand-info: #2b414f; @brand-warning: #f0ad4e; @brand-danger: #d9534f; @@ -26,7 +26,7 @@ //## Settings for some of the most global styles. //** Background color for ``. -@body-bg: #eee; +@body-bg: #ffffff; //** Global text color on ``. @text-color: @gray-dark; diff --git a/client/less/main.less b/client/less/main.less index 48b37e4045..0fa05e522a 100644 --- a/client/less/main.less +++ b/client/less/main.less @@ -56,7 +56,7 @@ html { } body.full-screen-body-background { - background-color: @gray-lighter; + background-color: @body-bg; } @@ -290,7 +290,7 @@ ul { margin-right: 10px; white-space: nowrap; } - background-color: #215f1e; + background-color: @brand-primary; text-align: center; } .navbar { @@ -332,13 +332,13 @@ ul { } .navbar { - background-color: #215f1e; + background-color: @brand-primary; } .navbar-nav > li > a { - color: @gray-lighter; + color: @body-bg; &:hover { - color: #215f1e; + color: @brand-primary; } } @@ -429,13 +429,13 @@ thead { } .navbar-nav a { - color: @gray-lighter; + color: @body-bg; font-size: 20px; margin-top: -5px; margin-bottom: -5px; } .navbar-toggle { - color: @gray-lighter; + color: @body-bg; } .signup-btn-nav { @@ -475,7 +475,7 @@ thead { } .points-on-top { - color: @gray-lighter; + color: @body-bg; font-size: 35px; z-index: 2; width: 60%; @@ -487,7 +487,7 @@ thead { } .landing-skill-icon { - color: #215f1e; + color: @brand-primary; font-size: 150px; } @@ -564,7 +564,7 @@ thead { } .challenge-list-header { - background-color: #215f1e; + background-color: @brand-primary; color: @gray-lighter; font-size: 36px; text-align: center; @@ -583,7 +583,7 @@ thead { width: 100%; height: 50px; text-align: center; - background-color: #215f1e; + background-color: @brand-primary; padding: 12px; bottom: 0; left: 0; @@ -598,7 +598,7 @@ thead { padding-top: 14px; padding-bottom: 12px; &:hover { - color: #215f1e; + color: @brand-primary; background-color: @gray-lighter; text-decoration: none; } @@ -923,7 +923,7 @@ hr { } .cal-heatmap-container { - background-color: @gray-lighter; + background-color: @body-bg; } .interested-camper-image { diff --git a/common/app/routes/Jobs/components/Jobs.jsx b/common/app/routes/Jobs/components/Jobs.jsx index 676cd8790a..a21215c73b 100644 --- a/common/app/routes/Jobs/components/Jobs.jsx +++ b/common/app/routes/Jobs/components/Jobs.jsx @@ -65,7 +65,6 @@ export default contain( } = this.props; return ( - - ); } }) diff --git a/server/views/challengeMap/show.jade b/server/views/challengeMap/show.jade index 9f7b3929e5..c03bec4de1 100644 --- a/server/views/challengeMap/show.jade +++ b/server/views/challengeMap/show.jade @@ -1,199 +1,34 @@ -extends ../layout +extends ../layout-wide block content - h1.text-center Challenge Map - hr - if (Math.random() > 0.999) - img.img-responsive.img-center.border-radius-5(src='https://s3.amazonaws.com/freecodecamp/wide-social-banner-dino.png') - audio(autoplay src='https://s3.amazonaws.com/freecodecamp/t-rex-roar.mp3') - else - img.img-responsive.img-center.border-radius-5(src='https://s3.amazonaws.com/freecodecamp/wide-social-banner.png') - .col-xs-12.col-md-8.col-md-offset-2 - h2 - table.population-table.img-center - tr - td Established:  - td - span.text-primary #{daysRunning}  - | days ago - tr - td Population:    - td - span.text-primary #{camperCount}  - | campers - tr - td Completed:    - td - span.text-primary #{globalCompletedCount}  - | challenges - - - - .spacer - if (user && user.progressTimestamps.length > 100) - .row - #map-notice.col-xs-12.col-md-8.col-md-offset-2.hidden - h2.text-center Reddit or not, here we come - img.thumbnail.img-center.img-responsive(src="http://i.imgur.com/lyd0bfM.jpg") - h4.text-center Come ask questions and share your thoughts with our entire open source community on our subreddit. - a.button.btn.btn-block.btn-primary(href="https://reddit.com/r/freecodecamp" target="_blank") Check it out - .button-spacer - .text-center - a#hide-map-notice-button(href='#') Hide this forever - .spacer - - ul - for superBlock in superBlocks - h2= superBlock.name - - var i = 0 - for challengeBlock in superBlock.blocks - - i++ - .row - if (user) - if (challengeBlock.completed === 100) - .hidden-xs.col-sm-3.col-md-2.text-primary.ion-checkmark-circled.padded-ionic-icon.text-center.map-p.negative-10 - .col-xs-1.col-sm-1.col-md-1.map-row-numbers.negative-5 - span.map-p.negative-10 #{i}. - .col-xs-11.col-sm-8.col-md-9 - li.map-p.faded.negative-10 - a(href='#' + challengeBlock.dashedName)= challengeBlock.name - if challengeBlock.markNew - span.text-info.small     - strong - em NEW - if challengeBlock.isComingSoon - span.text-info.small     - strong - em Coming Soon - else - .hidden-xs.col-sm-3.col-md-2 - .progress.progress-bar-padding.text-center.thin-progress-bar - .progress-bar(role='progressbar', aria-valuenow=(challengeBlock.completed), aria-valuemin='0', aria-valuemax='100', style='width: ' + challengeBlock.completed + '%;') - .col-xs-1.col-sm-1.col-md-1.map-row-numbers.negative-5 - span.map-p #{i}. - .col-xs-11.col-sm-8.col-md-9 - li.map-p.negative-10 - a(href='#' + challengeBlock.dashedName)= challengeBlock.name - if challengeBlock.markNew - span.text-info.small     - strong - em NEW - if challengeBlock.isComingSoon - span.text-info.small     - strong - em Coming Soon - else - .hidden-xs.col-sm-3.col-md-2 - .col-xs-1.col-sm-1.col-md-1.map-row-numbers - span.map-p.negative-10 #{i}. - .col-xs-10.col-sm-8.col-md-9 - span.map-p.negative-10 - a(href='#' + challengeBlock.dashedName)= challengeBlock.name - if challengeBlock.markNew - span.text-info.small     - strong - em NEW - if challengeBlock.isComingSoon - span.text-info.small     - strong - em Coming Soon - h2 Full Stack Development Certification - .row - .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 Greenfield Nonprofit Project 1 - .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 Greenfield Nonprofit Project 2 - .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 Legacy Nonprofit Project 1 - .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 Legacy Nonprofit Project 2 - .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 Claim your Full Stack Development Certification - - h2 Coding Interview Preparation - .row - .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 Whiteboard Coding Interview Training - .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 Critical Thinking Interview Training - .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 Mock Interview 1 - .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 Mock Interview 2 - .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 Mock Interview 3 - - hr - - for superBlock, index in superBlocks - for challengeBlock in superBlock.blocks - .row - a(href='#' name=challengeBlock.dashedName) - .spacer.negative-55 - - .row - .hidden-xs.col-sm-3.col-md-2 - h3.text-primary.text-right.nowrap - i.fa.fa-clock-o - = challengeBlock.time - .col-xs-12.col-sm-9.col-md-10 - h3 #{challengeBlock.name}   - - - var i = 0 + .col-xs-12.col-sm-3.col-sm-offset-9 + for superBlock, index in superBlocks + for challengeBlock in superBlock.blocks + h4.bold #{challengeBlock.name} (#{challengeBlock.time}) for challenge in challengeBlock.challenges - - i++ - .row - if challenge.completed - .hidden-xs.col-sm-3.col-md-2.text-primary.ion-checkmark-circled.padded-ionic-icon.text-center.map-p.negative-10 - .col-xs-1.col-sm-1.col-md-1.map-row-numbers - span.map-p.negative-10 #{i}. - .col-xs-10.col-sm-8.col-md-9 - span.faded.map-p.negative-10 - a(href="/challenges/#{challenge.dashedName}") - span.capitalize= challenge.type + ': ' - span= challenge.title - span.sr-only= " Complete" - - else - .hidden-xs.col-sm-3.col-md-2 - span.negative-10 - .col-xs-1.col-sm-1.col-md-1.map-row-numbers - span.map-p.negative-10 #{i}. - .col-xs-10.col-sm-8.col-md-9 - span.map-p.negative-10 - a(href="/challenges/#{challenge.dashedName}" class=challenge.isComingSoon ? 'disabled' : '') - span.capitalize= challenge.type + ': ' - span= challenge.title - span.sr-only= " Incomplete" - if challenge.markNew - span.text-info.small     - strong - em NEW - if challengeBlock.isComingSoon - span.text-info.small     - strong - em Coming Soon - - if (challengeBlock.completed === 100) - .button-spacer - .row - .col-xs-12.col-sm-8.col-md-6.col-sm-offset-3.col-md-offset-2.hidden - a.btn.btn-lg.btn-block.signup-btn.map-challenge-block-share Section complete. Share your code portfolio with your friends. - .hidden(id="#{challengeBlock.name}") - - if (index < superBlocks.length - 1) - .spacer - hr - .spacer + if challenge.completed + p.text-primary.ion-checkmark-circled.padded-ionic-icon.negative-15(name="#{challenge.dashedName}")   + a(href="/challenges/#{challenge.dashedName}") + = challenge.title + span.sr-only= " Complete" + else + p.negative-15 + a(name="#{challenge.dashedName}" href="/challenges/#{challenge.dashedName}" class=challenge.isComingSoon ? 'disabled' : '') + span= challenge.title + span.sr-only= " Incomplete" + if challenge.markNew + span.text-success.small     + strong + em New + if challengeBlock.isComingSoon + span.text-success.small     + strong + em Coming Soon + if challenge.type === "bonfire" + span.text-info.small     + strong + em Required + if (index < superBlocks.length) + hr script. var username = !{JSON.stringify(user && user.username || '')}; diff --git a/server/views/home.jade b/server/views/home.jade index 197683a041..0c80370c87 100644 --- a/server/views/home.jade +++ b/server/views/home.jade @@ -5,16 +5,16 @@ block content .spacer .row .col-xs-12.col-sm-12.col-md-3 - img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_connect.svg.gz', alt='Get great references and connections to start your software engineer career') + img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_connect.svg', alt='Get great references and connections to start your software engineer career') p.large-p Join a community of 100,000+ developers. .col-xs-12.col-sm-12.col-md-3 - img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_learn.svg.gz', alt='Learn to code and learn full stack JavaScript') + img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_learn.svg', alt='Learn to code and learn full stack JavaScript') p.large-p Work together on coding challenges. .col-xs-12.col-sm-12.col-md-3 - img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_portfolio.svg.gz', alt='Build a portfolio of apps for nonprofits') + img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_portfolio.svg', alt='Build a portfolio of apps for nonprofits') p.large-p Build a portfolio of apps that solve real problems. .col-xs-12.col-sm-12.col-md-3 - img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_nonprofits.svg.gz', alt='Help empower nonprofits with code') + img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_nonprofits.svg', alt='Help empower nonprofits with code') p.large-p Empowering nonprofits with code. .big-break .row From c36b8352d222d800a981d8606e214cdef1c1aad8 Mon Sep 17 00:00:00 2001 From: Quincy Larson Date: Mon, 11 Jan 2016 18:25:20 -0600 Subject: [PATCH 09/65] further build up challengemap --- server/views/account/signin.jade | 2 +- server/views/challengeMap/show.jade | 44 ++++++++++++++--------- server/views/coursewares/showBonfire.jade | 13 ++++--- server/views/coursewares/showHTML.jade | 1 + server/views/coursewares/showJS.jade | 1 + 5 files changed, 36 insertions(+), 25 deletions(-) diff --git a/server/views/account/signin.jade b/server/views/account/signin.jade index e6a01f3cee..eba1c665a9 100644 --- a/server/views/account/signin.jade +++ b/server/views/account/signin.jade @@ -1,6 +1,6 @@ extends ../layout block content - .jumbotron.text-center + .text-center h2 Sign in with one of these options: a.btn.btn-lg.btn-block.btn-github.btn-social(href='/auth/github') i.fa.fa-github diff --git a/server/views/challengeMap/show.jade b/server/views/challengeMap/show.jade index c03bec4de1..3e08c5e801 100644 --- a/server/views/challengeMap/show.jade +++ b/server/views/challengeMap/show.jade @@ -1,6 +1,6 @@ extends ../layout-wide block content - .col-xs-12.col-sm-3.col-sm-offset-9 + .col-xs-12.col-sm-4.col-sm-offset-8 for superBlock, index in superBlocks for challengeBlock in superBlock.blocks h4.bold #{challengeBlock.name} (#{challengeBlock.time}) @@ -11,22 +11,32 @@ block content = challenge.title span.sr-only= " Complete" else - p.negative-15 - a(name="#{challenge.dashedName}" href="/challenges/#{challenge.dashedName}" class=challenge.isComingSoon ? 'disabled' : '') - span= challenge.title - span.sr-only= " Incomplete" - if challenge.markNew - span.text-success.small     - strong - em New - if challengeBlock.isComingSoon - span.text-success.small     - strong - em Coming Soon - if challenge.type === "bonfire" - span.text-info.small     - strong - em Required + if challenge.type === "bonfire" + p.ion-asterisk.padded-ionic-icon.negative-15(name="#{challenge.dashedName}")   + a(name="#{challenge.dashedName}" href="/challenges/#{challenge.dashedName}" class=challenge.isComingSoon ? 'disabled' : '') + span= challenge.title + span.sr-only= " Incomplete" + if challenge.markNew + span.text-success.small     + strong + em New + if challengeBlock.isComingSoon + span.text-success.small     + strong + em Coming Soon + else + p.ion-ios-circle-outline.padded-ionic-icon.negative-15(name="#{challenge.dashedName}")   + a(name="#{challenge.dashedName}" href="/challenges/#{challenge.dashedName}" class=challenge.isComingSoon ? 'disabled' : '') + span= challenge.title + span.sr-only= " Incomplete" + if challenge.markNew + span.text-success.small     + strong + em New + if challengeBlock.isComingSoon + span.text-success.small     + strong + em Coming Soon if (index < superBlocks.length) hr diff --git a/server/views/coursewares/showBonfire.jade b/server/views/coursewares/showBonfire.jade index b931e109c0..7e0d32ac6e 100644 --- a/server/views/coursewares/showBonfire.jade +++ b/server/views/coursewares/showBonfire.jade @@ -23,13 +23,12 @@ block content else p.wrappable.negative-10!= sentence if (MDNlinks.length) - .negative-30-bottom - #MDN-links - p.negative-10 Here are some helpful links: - for link, index in MDNlinks - .negative-10 - ul: li: a(href=""+link, target="_blank") !{MDNkeys[index]} - + #MDN-links + p.negative-10 Here are some helpful links: + for link, index in MDNlinks + .negative-10 + ul: li: a(href=""+link, target="_blank") !{MDNkeys[index]} + .button-spacer if (user) label.negative-10.btn.btn-primary.btn-block.btn-lg#submitButton i.fa.fa-play diff --git a/server/views/coursewares/showHTML.jade b/server/views/coursewares/showHTML.jade index 78d7e8670a..0aec76b139 100644 --- a/server/views/coursewares/showHTML.jade +++ b/server/views/coursewares/showHTML.jade @@ -19,6 +19,7 @@ block content for sentence in details p.wrappable.negative-10!= sentence .negative-bottom-margin-30 + .button-spacer label.negative-10.btn.btn-primary.btn-lg.btn-block#submitButton i.fa.fa-play |   Run tests (ctrl + enter) diff --git a/server/views/coursewares/showJS.jade b/server/views/coursewares/showJS.jade index 8253b33c82..4eb7c2bb59 100644 --- a/server/views/coursewares/showJS.jade +++ b/server/views/coursewares/showJS.jade @@ -29,6 +29,7 @@ block content for link, index in MDNlinks .negative-10 ul: li: a(href="" + link, target="_blank") !{MDNkeys[index]} + .button-spacer if (user) form.form-horizontal(novalidate='novalidate', name='completedWithForm') .form-group.text-center.negative-10 From 8e71cdd4b8b6e7a3678f3b18145e44a970285c4f Mon Sep 17 00:00:00 2001 From: Quincy Larson Date: Mon, 11 Jan 2016 18:56:15 -0600 Subject: [PATCH 10/65] start working on ghost-only buttons --- client/less/main.less | 25 ++----------------------- server/views/account/show.jade | 10 +++++----- 2 files changed, 7 insertions(+), 28 deletions(-) diff --git a/client/less/main.less b/client/less/main.less index 0fa05e522a..b3dc2a87b5 100644 --- a/client/less/main.less +++ b/client/less/main.less @@ -124,13 +124,6 @@ h1, h2, h3, h4, h5, h6, p, li { box-shadow: 2px 4px 1px rgba(0, 0, 0, 0.3); } -.btn, .shadow { - white-space: normal; - -webkit-box-shadow: 2px 4px 1px rgba(0, 0, 0, 0.3); - -moz-box-shadow: 2px 4px 1px rgba(0, 0, 0, 0.3); - box-shadow: 2px 4px 1px rgba(0, 0, 0, 0.3); -} - .btn-nav { margin-top: 10px; } @@ -724,23 +717,9 @@ iframe.iphone { min-height: 650px; } -.btn-primary-ghost { +.btn { background: transparent; - color: @brand-primary; - - /* CSS Transition */ - -webkit-transition: background .2s ease-in-out, border .2s ease-in-out; - -moz-transition: background .2s ease-in-out, border .2s ease-in-out; - -ms-transition: background .2s ease-in-out, border .2s ease-in-out; - -o-transition: background .2s ease-in-out, border .2s ease-in-out; - transition: background .2s ease-in-out, border .2s ease-in-out; -} - -.btn-warning-ghost { - background: transparent; - color: @brand-warning; - - /* CSS Transition */ + color: #fff; -webkit-transition: background .2s ease-in-out, border .2s ease-in-out; -moz-transition: background .2s ease-in-out, border .2s ease-in-out; -ms-transition: background .2s ease-in-out, border .2s ease-in-out; diff --git a/server/views/account/show.jade b/server/views/account/show.jade index d24e22b261..313f5f066e 100644 --- a/server/views/account/show.jade +++ b/server/views/account/show.jade @@ -242,29 +242,29 @@ block content h1.text-center Manage your account hr .col-xs-12 - a.btn.btn-lg.btn-block.btn-warning.btn-link-social(href='/logout') + a.btn.btn-lg.btn-block.btn-primary.btn-primary-ghost.btn-link-social(href='/logout') span.ion-android-exit | Sign me out of Free Code Camp .col-xs-12 - a.btn.btn-lg.btn-block.btn-primary.btn-link-social(href='mailto:team@freecodecamp.com') + a.btn.btn-lg.btn-block.btn-primary.btn-primary-ghost.btn-link-social(href='mailto:team@freecodecamp.com') span.ion-email | Email us at team@freecodecamp.com if (!user.isLocked) .col-xs-12 - a.btn.btn-lg.btn-block.btn-info.btn-link-social(href='/toggle-lockdown-mode') + a.btn.btn-lg.btn-block.btn-primary.btn-primary-ghost.btn-link-social(href='/toggle-lockdown-mode') span.ion-locked | Hide all my solutions from other people br | (this will disable your certificates) else .col-xs-12 - a.btn.btn-lg.btn-block.btn-info.btn-link-social(href='/toggle-lockdown-mode') + a.btn.btn-lg.btn-block.btn-primary.btn-primary-ghost.btn-link-social(href='/toggle-lockdown-mode') span.ion-unlocked | Let other people see all my solutions br | (this will enable your certificates) .col-xs-12 - a.btn.btn-lg.btn-block.btn-success.btn-link-social(href='/commit') + a.btn.btn-lg.btn-block.btn-primary.btn-primary-ghost.btn-link-social(href='/commit') span.ion-edit | Edit my pledge .col-xs-12 From 0e52466163601cfa1da08736bc4f71e2358160d0 Mon Sep 17 00:00:00 2001 From: Berkeley Martinez Date: Mon, 11 Jan 2016 17:35:44 -0800 Subject: [PATCH 11/65] Add less source maps Watch bootstrap less files --- gulpfile.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/gulpfile.js b/gulpfile.js index a73cab824b..e04a60ecb7 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -131,7 +131,7 @@ var paths = { ], less: './client/less/main.less', - lessFiles: './client/less/*.less', + lessFiles: './client/less/**/*.less', manifest: 'server/manifests/', @@ -357,10 +357,15 @@ gulp.task('less', function() { var dest = paths.css; return gulp.src(paths.less) .pipe(plumber({ errorHandler: errorHandler })) + .pipe(__DEV__ ? sourcemaps.init() : gutil.noop()) // compile .pipe(less({ paths: [ path.join(__dirname, 'less', 'includes') ] })) + .pipe(__DEV__ ? + sourcemaps.write({ sourceRoot: '/less' }) : + gutil.noop() + ) .pipe(gulp.dest(dest)) // add revision .pipe(rev()) From 1661550c689c03559b1d0cba4387bfdfb0251520 Mon Sep 17 00:00:00 2001 From: Berkeley Martinez Date: Mon, 11 Jan 2016 17:36:05 -0800 Subject: [PATCH 12/65] Change buttons to ghost type --- client/less/lib/bootstrap/buttons.less | 2 +- client/less/lib/bootstrap/mixins/buttons.less | 4 ++-- client/less/lib/bootstrap/variables.less | 12 ++++++------ client/less/main.less | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/client/less/lib/bootstrap/buttons.less b/client/less/lib/bootstrap/buttons.less index 40553c6386..66a19bd066 100755 --- a/client/less/lib/bootstrap/buttons.less +++ b/client/less/lib/bootstrap/buttons.less @@ -32,7 +32,7 @@ &:hover, &:focus, &.focus { - color: @btn-default-color; + color: @gray-lighter; text-decoration: none; } diff --git a/client/less/lib/bootstrap/mixins/buttons.less b/client/less/lib/bootstrap/mixins/buttons.less index 92d8a056cd..c8289d0cd8 100755 --- a/client/less/lib/bootstrap/mixins/buttons.less +++ b/client/less/lib/bootstrap/mixins/buttons.less @@ -14,8 +14,8 @@ &:active, &.active, .open > .dropdown-toggle& { - color: @color; - background-color: darken(@background, 10%); + color: @gray-lighter; + background-color: lighten(@background, 10%); border-color: darken(@border, 12%); } &:active, diff --git a/client/less/lib/bootstrap/variables.less b/client/less/lib/bootstrap/variables.less index 98b46a105f..fdd43df500 100755 --- a/client/less/lib/bootstrap/variables.less +++ b/client/less/lib/bootstrap/variables.less @@ -144,27 +144,27 @@ @btn-font-weight: normal; -@btn-default-color: #333; +@btn-default-color: @gray-lighter; @btn-default-bg: @gray-lighter; @btn-default-border: #ccc; -@btn-primary-color: @gray-lighter; +@btn-primary-color: @brand-primary; @btn-primary-bg: @brand-primary; @btn-primary-border: darken(@btn-primary-bg, 5%); -@btn-success-color: @gray-lighter; +@btn-success-color: @brand-primary; @btn-success-bg: @brand-success; @btn-success-border: darken(@btn-success-bg, 5%); -@btn-info-color: @gray-lighter; +@btn-info-color: @brand-info; @btn-info-bg: @brand-info; @btn-info-border: darken(@btn-info-bg, 5%); -@btn-warning-color: @gray-lighter; +@btn-warning-color: @brand-primary; @btn-warning-bg: @brand-warning; @btn-warning-border: darken(@btn-warning-bg, 5%); -@btn-danger-color: @gray-lighter; +@btn-danger-color: @brand-danger; @btn-danger-bg: @brand-danger; @btn-danger-border: darken(@btn-danger-bg, 5%); diff --git a/client/less/main.less b/client/less/main.less index b3dc2a87b5..12dc2e3c06 100644 --- a/client/less/main.less +++ b/client/less/main.less @@ -117,7 +117,7 @@ h1, h2, h3, h4, h5, h6, p, li { font-size: 40px; } -.btn, .shadow { +.shadow { white-space: normal; -webkit-box-shadow: 2px 4px 1px rgba(0, 0, 0, 0.3); -moz-box-shadow: 2px 4px 1px rgba(0, 0, 0, 0.3); @@ -719,7 +719,7 @@ iframe.iphone { .btn { background: transparent; - color: #fff; + -webkit-transition: background .2s ease-in-out, border .2s ease-in-out; -moz-transition: background .2s ease-in-out, border .2s ease-in-out; -ms-transition: background .2s ease-in-out, border .2s ease-in-out; From f75aea4a9d2605eec5e5af0ff7ba077f28a200c1 Mon Sep 17 00:00:00 2001 From: Berkeley Martinez Date: Mon, 11 Jan 2016 17:42:55 -0800 Subject: [PATCH 13/65] Fix social button colors --- client/less/lib/bootstrap-social/bootstrap-social.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/less/lib/bootstrap-social/bootstrap-social.less b/client/less/lib/bootstrap-social/bootstrap-social.less index 82c91f5d2f..a2b61fae6c 100755 --- a/client/less/lib/bootstrap-social/bootstrap-social.less +++ b/client/less/lib/bootstrap-social/bootstrap-social.less @@ -86,7 +86,7 @@ } } -.btn-social(@color-bg, @color: #fff) { +.btn-social(@color-bg, @color: @color-bg) { background-color: @color-bg; .button-variant(@color, @color-bg, rgba(0,0,0,.2)); } From b7c071bcfb62895f6f1a77b71026284062408bd8 Mon Sep 17 00:00:00 2001 From: Berkeley Martinez Date: Mon, 11 Jan 2016 18:04:56 -0800 Subject: [PATCH 14/65] Fix btn success color --- client/less/lib/bootstrap/variables.less | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/less/lib/bootstrap/variables.less b/client/less/lib/bootstrap/variables.less index fdd43df500..849aaa4440 100755 --- a/client/less/lib/bootstrap/variables.less +++ b/client/less/lib/bootstrap/variables.less @@ -152,7 +152,7 @@ @btn-primary-bg: @brand-primary; @btn-primary-border: darken(@btn-primary-bg, 5%); -@btn-success-color: @brand-primary; +@btn-success-color: @brand-success; @btn-success-bg: @brand-success; @btn-success-border: darken(@btn-success-bg, 5%); @@ -160,7 +160,7 @@ @btn-info-bg: @brand-info; @btn-info-border: darken(@btn-info-bg, 5%); -@btn-warning-color: @brand-primary; +@btn-warning-color: @brand-warning; @btn-warning-bg: @brand-warning; @btn-warning-border: darken(@btn-warning-bg, 5%); From 8965790949e137d80d66269fdb2914870ab73929 Mon Sep 17 00:00:00 2001 From: Berkeley Martinez Date: Mon, 11 Jan 2016 18:05:16 -0800 Subject: [PATCH 15/65] Use base color for btn:hover color --- client/less/lib/bootstrap/mixins/buttons.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/less/lib/bootstrap/mixins/buttons.less b/client/less/lib/bootstrap/mixins/buttons.less index c8289d0cd8..9714cc206b 100755 --- a/client/less/lib/bootstrap/mixins/buttons.less +++ b/client/less/lib/bootstrap/mixins/buttons.less @@ -15,7 +15,7 @@ &.active, .open > .dropdown-toggle& { color: @gray-lighter; - background-color: lighten(@background, 10%); + background-color: @background; border-color: darken(@border, 12%); } &:active, From 5b681bfdfdabd71cfc02691cc3ccb60a8e0c3fda Mon Sep 17 00:00:00 2001 From: Berkeley Martinez Date: Mon, 11 Jan 2016 18:05:42 -0800 Subject: [PATCH 16/65] Re-add btn classes to account page --- server/views/account/show.jade | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/server/views/account/show.jade b/server/views/account/show.jade index 313f5f066e..d24e22b261 100644 --- a/server/views/account/show.jade +++ b/server/views/account/show.jade @@ -242,29 +242,29 @@ block content h1.text-center Manage your account hr .col-xs-12 - a.btn.btn-lg.btn-block.btn-primary.btn-primary-ghost.btn-link-social(href='/logout') + a.btn.btn-lg.btn-block.btn-warning.btn-link-social(href='/logout') span.ion-android-exit | Sign me out of Free Code Camp .col-xs-12 - a.btn.btn-lg.btn-block.btn-primary.btn-primary-ghost.btn-link-social(href='mailto:team@freecodecamp.com') + a.btn.btn-lg.btn-block.btn-primary.btn-link-social(href='mailto:team@freecodecamp.com') span.ion-email | Email us at team@freecodecamp.com if (!user.isLocked) .col-xs-12 - a.btn.btn-lg.btn-block.btn-primary.btn-primary-ghost.btn-link-social(href='/toggle-lockdown-mode') + a.btn.btn-lg.btn-block.btn-info.btn-link-social(href='/toggle-lockdown-mode') span.ion-locked | Hide all my solutions from other people br | (this will disable your certificates) else .col-xs-12 - a.btn.btn-lg.btn-block.btn-primary.btn-primary-ghost.btn-link-social(href='/toggle-lockdown-mode') + a.btn.btn-lg.btn-block.btn-info.btn-link-social(href='/toggle-lockdown-mode') span.ion-unlocked | Let other people see all my solutions br | (this will enable your certificates) .col-xs-12 - a.btn.btn-lg.btn-block.btn-primary.btn-primary-ghost.btn-link-social(href='/commit') + a.btn.btn-lg.btn-block.btn-success.btn-link-social(href='/commit') span.ion-edit | Edit my pledge .col-xs-12 From b03e71e7c029e5c32ad120369bd387b7e9276d66 Mon Sep 17 00:00:00 2001 From: Berkeley Martinez Date: Mon, 11 Jan 2016 22:47:49 -0800 Subject: [PATCH 17/65] Abstract map and showChallenge logic Rename some legacy naming conventions Remove logic for waypoint,basejumps, etc... --- seed/index.js | 6 +- server/boot/challenge.js | 326 ++++++++---------- server/utils/getFromDisk$.js | 6 +- .../showBonfire.jade | 6 +- .../{coursewares => challenges}/showHTML.jade | 6 +- .../{coursewares => challenges}/showJS.jade | 6 +- .../{coursewares => challenges}/showStep.jade | 4 +- .../showVideo.jade | 8 +- .../showZiplineOrBasejump.jade | 8 +- server/views/{challengeMap => map}/show.jade | 0 10 files changed, 173 insertions(+), 203 deletions(-) rename server/views/{coursewares => challenges}/showBonfire.jade (96%) rename server/views/{coursewares => challenges}/showHTML.jade (95%) rename server/views/{coursewares => challenges}/showJS.jade (96%) rename server/views/{coursewares => challenges}/showStep.jade (95%) rename server/views/{coursewares => challenges}/showVideo.jade (92%) rename server/views/{coursewares => challenges}/showZiplineOrBasejump.jade (95%) rename server/views/{challengeMap => map}/show.jade (100%) diff --git a/seed/index.js b/seed/index.js index 121a9ba953..0920aeb8f0 100644 --- a/seed/index.js +++ b/seed/index.js @@ -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() diff --git a/server/boot/challenge.js b/server/boot/challenge.js index c88e377b04..34fc38f5b3 100644 --- a/server/boot/challenge.js +++ b/server/boot/challenge.js @@ -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' }); }, diff --git a/server/utils/getFromDisk$.js b/server/utils/getFromDisk$.js index b6e24fe3ca..87517465be 100644 --- a/server/utils/getFromDisk$.js +++ b/server/utils/getFromDisk$.js @@ -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() diff --git a/server/views/coursewares/showBonfire.jade b/server/views/challenges/showBonfire.jade similarity index 96% rename from server/views/coursewares/showBonfire.jade rename to server/views/challenges/showBonfire.jade index 7e0d32ac6e..6529ca175b 100644 --- a/server/views/coursewares/showBonfire.jade +++ b/server/views/challenges/showBonfire.jade @@ -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)}; diff --git a/server/views/coursewares/showHTML.jade b/server/views/challenges/showHTML.jade similarity index 95% rename from server/views/coursewares/showHTML.jade rename to server/views/challenges/showHTML.jade index 0aec76b139..0ca3eb9bf5 100644 --- a/server/views/coursewares/showHTML.jade +++ b/server/views/challenges/showHTML.jade @@ -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)}; diff --git a/server/views/coursewares/showJS.jade b/server/views/challenges/showJS.jade similarity index 96% rename from server/views/coursewares/showJS.jade rename to server/views/challenges/showJS.jade index 4eb7c2bb59..b726ec1978 100644 --- a/server/views/coursewares/showJS.jade +++ b/server/views/challenges/showJS.jade @@ -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)}; diff --git a/server/views/coursewares/showStep.jade b/server/views/challenges/showStep.jade similarity index 95% rename from server/views/coursewares/showStep.jade rename to server/views/challenges/showStep.jade index 96bda010c0..b3d90e484f 100644 --- a/server/views/coursewares/showStep.jade +++ b/server/views/challenges/showStep.jade @@ -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 || '')}; diff --git a/server/views/coursewares/showVideo.jade b/server/views/challenges/showVideo.jade similarity index 92% rename from server/views/coursewares/showVideo.jade rename to server/views/challenges/showVideo.jade index df8d00dc92..1655d94ecc 100644 --- a/server/views/coursewares/showVideo.jade +++ b/server/views/challenges/showVideo.jade @@ -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)}; diff --git a/server/views/coursewares/showZiplineOrBasejump.jade b/server/views/challenges/showZiplineOrBasejump.jade similarity index 95% rename from server/views/coursewares/showZiplineOrBasejump.jade rename to server/views/challenges/showZiplineOrBasejump.jade index 5d14b605d6..d3daf29848 100644 --- a/server/views/coursewares/showZiplineOrBasejump.jade +++ b/server/views/challenges/showZiplineOrBasejump.jade @@ -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)}; diff --git a/server/views/challengeMap/show.jade b/server/views/map/show.jade similarity index 100% rename from server/views/challengeMap/show.jade rename to server/views/map/show.jade From 0c54adfb07ff7c862162b918605a60f914ac51ee Mon Sep 17 00:00:00 2001 From: Berkeley Martinez Date: Tue, 12 Jan 2016 22:26:19 -0800 Subject: [PATCH 18/65] Add map aside to challenges --- client/less/main.less | 1 + client/less/map.less | 125 ++++++++++++++++++++ client/main.js | 9 ++ server/boot/challenge.js | 31 +++-- server/views/partials/challenge-footer.jade | 44 +++++++ server/views/partials/navbar.jade | 4 +- 6 files changed, 205 insertions(+), 9 deletions(-) create mode 100644 client/less/map.less diff --git a/client/less/main.less b/client/less/main.less index 12dc2e3c06..c01dc70836 100644 --- a/client/less/main.less +++ b/client/less/main.less @@ -1115,3 +1115,4 @@ code { @import "jobs.less"; @import "challenge.less"; @import "toastr.less"; +@import "map.less"; diff --git a/client/less/map.less b/client/less/map.less new file mode 100644 index 0000000000..92832b339c --- /dev/null +++ b/client/less/map.less @@ -0,0 +1,125 @@ +/* + * based off of https://github.com/gitterHQ/sidecar + * license: MIT + */ +.map-aside { + + z-index: 20000; + position: fixed; + top: 0; + left: 60%; + bottom: 0; + right: 0; + + display: flex; + flex-direction: row; + + background-color: @body-bg; + border-left: 1px solid #333; + box-shadow: -12px 0 18px 0 rgba(50, 50, 50, 0.3); + + transition: transform 0.3s cubic-bezier(0.16, 0.22, 0.22, 1.7); + + &.is-collapsed { + transform: translateX(110%); + } + + /* Add some "extension" so that there isn't a gap + * when we translate(via animation) more than 100% */ + &:after { + content: ''; + + z-index: -1; + position: absolute; + top: 0; + left: 100%; + bottom: 0; + right: -100%; + + background-color: @body-bg; + } + + @media (max-width: 1150px) { + left: 45%; + } + @media (max-width: 944px) { + left: 30%; + } + @media (max-width: 600px) { + left: 15%; + } + @media (max-width: 500px) { + left: 0; + border-left: none; + } + + & > .map-aside-container { + flex: 1; + width: 100%; + height: 100%; + + border: 0; + overflow: auto + } +} + +.map-aside-action-bar { + position: absolute; + top: 0; + left: 0; + right: 0; + + display: flex; + justify-content: flex-end; + + padding-bottom: 0.7em; + + background: linear-gradient(to bottom, #ffffff 0%, #ffffff 50%, rgba(255, 255, 255, 0) 100%); + + z-index: 100; +} + +.map-aside-action-item { + display: flex; + /* main axis */ + justify-content: center; + /* cross axis */ + align-items: center; + + width: 40px; + height: 40px; + + padding-left: 0; + padding-right: 0; + + opacity: 0.65; + background: none; + background-position: center center; + background-repeat: no-repeat; + background-size: 22px 22px; + border: 0; + outline: none; + + cursor: pointer; + cursor: hand; + + transition: all 0.2s ease; + + &:hover, + &:focus { + opacity: 1; + } + + &:active { + filter: hue-rotate(80deg) saturate(150); + } +} + +.map-aside-action-pop-out { + margin-right: -4px; + background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMDAgMTcxLjQyOSIgZmlsbD0iIzNhMzEzMyI+PHBhdGggZD0iTTE1Ny4xNDMsMTAzLjU3MXYzNS43MTRjMCw4Ljg1NC0zLjE0NCwxNi40MjYtOS40MzEsMjIuNzEzcy0xMy44NTgsOS40MzEtMjIuNzEyLDkuNDMxSDMyLjE0MyBjLTguODU0LDAtMTYuNDI1LTMuMTQ0LTIyLjcxMi05LjQzMVMwLDE0OC4xNCwwLDEzOS4yODVWNDYuNDI5YzAtOC44NTQsMy4xNDQtMTYuNDI1LDkuNDMxLTIyLjcxMiBjNi4yODctNi4yODcsMTMuODU4LTkuNDMxLDIyLjcxMi05LjQzMWg3OC41NzJjMS4wNDEsMCwxLjg5NiwwLjMzNSwyLjU2NiwxLjAwNGMwLjY3LDAuNjcsMS4wMDQsMS41MjUsMS4wMDQsMi41NjdWMjUgYzAsMS4wNDItMC4zMzQsMS44OTctMS4wMDQsMi41NjdjLTAuNjcsMC42Ny0xLjUyNSwxLjAwNC0yLjU2NiwxLjAwNEgzMi4xNDNjLTQuOTExLDAtOS4xMTUsMS43NDktMTIuNjEyLDUuMjQ2IHMtNS4yNDYsNy43MDEtNS4yNDYsMTIuNjEydjkyLjg1NmMwLDQuOTExLDEuNzQ5LDkuMTE1LDUuMjQ2LDEyLjYxMnM3LjcwMSw1LjI0NSwxMi42MTIsNS4yNDVIMTI1YzQuOTEsMCw5LjExNS0xLjc0OCwxMi42MTEtNS4yNDUgYzMuNDk3LTMuNDk3LDUuMjQ2LTcuNzAxLDUuMjQ2LTEyLjYxMnYtMzUuNzE0YzAtMS4wNDIsMC4zMzQtMS44OTcsMS4wMDQtMi41NjdjMC42Ny0wLjY2OSwxLjUyNS0xLjAwNCwyLjU2Ny0xLjAwNGg3LjE0MyBjMS4wNDIsMCwxLjg5NywwLjMzNSwyLjU2NywxLjAwNEMxNTYuODA5LDEwMS42NzQsMTU3LjE0MywxMDIuNTI5LDE1Ny4xNDMsMTAzLjU3MXogTTIwMCw3LjE0M3Y1Ny4xNDMgYzAsMS45MzUtMC43MDcsMy42MDktMi4xMjEsNS4wMjJjLTEuNDEzLDEuNDE0LTMuMDg4LDIuMTIxLTUuMDIxLDIuMTIxYy0xLjkzNSwwLTMuNjA5LTAuNzA3LTUuMDIyLTIuMTIxbC0xOS42NDQtMTkuNjQzIGwtNzIuNzY3LDcyLjc2OWMtMC43NDQsMC43NDQtMS42LDEuMTE1LTIuNTY3LDEuMTE1cy0xLjgyMy0wLjM3MS0yLjU2Ny0xLjExNUw3Ny41NjcsMTA5LjcxYy0wLjc0NC0wLjc0NC0xLjExNi0xLjYtMS4xMTYtMi41NjcgYzAtMC45NjcsMC4zNzItMS44MjIsMS4xMTYtMi41NjZsNzIuNzY4LTcyLjc2OGwtMTkuNjQ0LTE5LjY0M2MtMS40MTMtMS40MTQtMi4xMi0zLjA4OC0yLjEyLTUuMDIyYzAtMS45MzUsMC43MDctMy42MDksMi4xMi01LjAyMiBDMTMyLjEwNSwwLjcwNywxMzMuNzc5LDAsMTM1LjcxNSwwaDU3LjE0M2MxLjkzNCwwLDMuNjA4LDAuNzA3LDUuMDIxLDIuMTIxQzE5OS4yOTMsMy41MzQsMjAwLDUuMjA4LDIwMCw3LjE0M3oiLz48L3N2Zz4=) +} + +.map-aside-action-collapse { + background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNzEuNDI5IDE3MS40MjkiIGZpbGw9IiMzYTMxMzMiPjxwYXRoIGQ9Ik0xMjIuNDMzLDEwNi4xMzhsLTE2LjI5NSwxNi4yOTVjLTAuNzQ0LDAuNzQ0LTEuNiwxLjExNi0yLjU2NiwxLjExNmMtMC45NjgsMC0xLjgyMy0wLjM3Mi0yLjU2Ny0xLjExNmwtMTUuMjktMTUuMjkgbC0xNS4yOSwxNS4yOWMtMC43NDQsMC43NDQtMS42LDEuMTE2LTIuNTY3LDEuMTE2cy0xLjgyMy0wLjM3Mi0yLjU2Ny0xLjExNmwtMTYuMjk0LTE2LjI5NWMtMC43NDQtMC43NDQtMS4xMTYtMS42LTEuMTE2LTIuNTY2IGMwLTAuOTY4LDAuMzcyLTEuODIzLDEuMTE2LTIuNTY3bDE1LjI5LTE1LjI5bC0xNS4yOS0xNS4yOWMtMC43NDQtMC43NDQtMS4xMTYtMS42LTEuMTE2LTIuNTY3czAuMzcyLTEuODIzLDEuMTE2LTIuNTY3IEw2NS4yOSw0OC45OTZjMC43NDQtMC43NDQsMS42LTEuMTE2LDIuNTY3LTEuMTE2czEuODIzLDAuMzcyLDIuNTY3LDEuMTE2bDE1LjI5LDE1LjI5bDE1LjI5LTE1LjI5IGMwLjc0NC0wLjc0NCwxLjYtMS4xMTYsMi41NjctMS4xMTZjMC45NjcsMCwxLjgyMiwwLjM3MiwyLjU2NiwxLjExNmwxNi4yOTUsMTYuMjk0YzAuNzQ0LDAuNzQ0LDEuMTE2LDEuNiwxLjExNiwyLjU2NyBzLTAuMzcyLDEuODIzLTEuMTE2LDIuNTY3bC0xNS4yOSwxNS4yOWwxNS4yOSwxNS4yOWMwLjc0NCwwLjc0NCwxLjExNiwxLjYsMS4xMTYsMi41NjcgQzEyMy41NDksMTA0LjUzOSwxMjMuMTc3LDEwNS4zOTQsMTIyLjQzMywxMDYuMTM4eiBNMTQ2LjQyOSw4NS43MTRjMC0xMS4wMTItMi43MTctMjEuMTY4LTguMTQ4LTMwLjQ2OSBzLTEyLjc5Ny0xNi42NjctMjIuMDk4LTIyLjA5OFM5Ni43MjYsMjUsODUuNzE0LDI1cy0yMS4xNjgsMi43MTYtMzAuNDY5LDguMTQ3UzM4LjU3OSw0NS45NDUsMzMuMTQ3LDU1LjI0NlMyNSw3NC43MDMsMjUsODUuNzE0IHMyLjcxNiwyMS4xNjgsOC4xNDcsMzAuNDY5czEyLjc5NywxNi42NjYsMjIuMDk4LDIyLjA5OHMxOS40NTcsOC4xNDgsMzAuNDY5LDguMTQ4czIxLjE2OC0yLjcxNywzMC40NjktOC4xNDggczE2LjY2Ni0xMi43OTcsMjIuMDk4LTIyLjA5OFMxNDYuNDI5LDk2LjcyNiwxNDYuNDI5LDg1LjcxNHogTTE3MS40MjksODUuNzE0YzAsMTUuNTUxLTMuODMyLDI5Ljg5My0xMS40OTYsNDMuMDI0IGMtNy42NjQsMTMuMTMzLTE4LjA2MiwyMy41My0zMS4xOTQsMzEuMTk0Yy0xMy4xMzIsNy42NjQtMjcuNDc0LDExLjQ5Ni00My4wMjQsMTEuNDk2cy0yOS44OTItMy44MzItNDMuMDI0LTExLjQ5NiBjLTEzLjEzMy03LjY2NC0yMy41MzEtMTguMDYyLTMxLjE5NC0zMS4xOTRDMy44MzIsMTE1LjYwNywwLDEwMS4yNjUsMCw4NS43MTRTMy44MzIsNTUuODIyLDExLjQ5Niw0Mi42OSBjNy42NjQtMTMuMTMzLDE4LjA2Mi0yMy41MzEsMzEuMTk0LTMxLjE5NEM1NS44MjIsMy44MzIsNzAuMTY0LDAsODUuNzE0LDBzMjkuODkzLDMuODMyLDQzLjAyNCwxMS40OTYgYzEzLjEzMyw3LjY2NCwyMy41MywxOC4wNjIsMzEuMTk0LDMxLjE5NEMxNjcuNTk3LDU1LjgyMiwxNzEuNDI5LDcwLjE2NCwxNzEuNDI5LDg1LjcxNHoiLz48L3N2Zz4=) +} diff --git a/client/main.js b/client/main.js index b677fc2b80..8ce8aedc49 100644 --- a/client/main.js +++ b/client/main.js @@ -259,4 +259,13 @@ $(document).ready(function() { window.ga('send', 'event', 'FB_LINK', 'SHARE', 'Facebook map share'); window.location.href = link; }); + + // map + $('#nav-map-btn').on('click', () => { + $('.map-aside').removeClass('is-collapsed'); + }); + + $('.map-aside-action-collapse').on('click', () => { + $('.map-aside').addClass('is-collapsed'); + }); }); diff --git a/server/boot/challenge.js b/server/boot/challenge.js index 34fc38f5b3..5422711956 100644 --- a/server/boot/challenge.js +++ b/server/boot/challenge.js @@ -189,6 +189,15 @@ function getRenderData$(user, challenge$, origChallengeName, solution) { }); } +function getCompletedChallengeIds(user = {}) { + // if user + // get the id's of all the users completed challenges + return !user.completedChallenges ? + [] : + _.uniq(user.completedChallenges) + .map(({ id, _id }) => id || _id); +} + // create a stream of an array of all the challenge blocks function getSuperBlocks$(challenge$, completedChallenges) { return challenge$ @@ -406,8 +415,19 @@ module.exports = function(app) { function showChallenge(req, res, next) { const solution = req.query.solution; + const completedChallenges = getCompletedChallengeIds(req.user); - getRenderData$(req.user, challenge$, req.params.challengeName, solution) + Observable.combineLatest( + getRenderData$(req.user, challenge$, req.params.challengeName, solution), + getSuperBlocks$(challenge$, completedChallenges), + ({ data, ...rest }, superBlocks) => ({ + ...rest, + data: { + ...data, + superBlocks + } + }) + ) .subscribe( ({ type, redirectUrl, message, data }) => { if (message) { @@ -553,14 +573,9 @@ module.exports = function(app) { ); } - 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); + function showMap({ user }, res, next) { - getSuperBlocks$(challenge$, completedChallenges) + getSuperBlocks$(challenge$, getCompletedChallengeIds(user)) .subscribe( superBlocks => { res.render('map/show', { diff --git a/server/views/partials/challenge-footer.jade b/server/views/partials/challenge-footer.jade index ed6be20a3f..080b61a409 100644 --- a/server/views/partials/challenge-footer.jade +++ b/server/views/partials/challenge-footer.jade @@ -5,3 +5,47 @@ script. if (typeof localStorage !== 'undefined') { localStorage.setItem('currentDashedName', typeof common !== 'undefined' && common.dashedName || ''); } +aside.map-aside.is-collapsed + .map-aside-action-bar + a.map-aside-action-item.map-aside-action-pop-out(href='/map' target='_blank' aria-label='open map in new tap') + button.map-aside-action-item.map-aside-action-collapse(aria-label='close map aside') + .map-aside-container + .col-xs-10.col-xs-offset-1 + for superBlock, index in superBlocks + for challengeBlock in superBlock.blocks + h4.bold #{challengeBlock.name} (#{challengeBlock.time}) + for challenge in challengeBlock.challenges + if challenge.completed + p.text-primary.ion-checkmark-circled.padded-ionic-icon.negative-15(name="#{challenge.dashedName}")   + a(href="/challenges/#{challenge.dashedName}") + = challenge.title + span.sr-only= " Complete" + else + if challenge.type === "bonfire" + p.ion-asterisk.padded-ionic-icon.negative-15(name="#{challenge.dashedName}")   + a(name="#{challenge.dashedName}" href="/challenges/#{challenge.dashedName}" class=challenge.isComingSoon ? 'disabled' : '') + span= challenge.title + span.sr-only= " Incomplete" + if challenge.markNew + span.text-success.small     + strong + em New + if challengeBlock.isComingSoon + span.text-success.small     + strong + em Coming Soon + else + p.ion-ios-circle-outline.padded-ionic-icon.negative-15(name="#{challenge.dashedName}")   + a(name="#{challenge.dashedName}" href="/challenges/#{challenge.dashedName}" class=challenge.isComingSoon ? 'disabled' : '') + span= challenge.title + span.sr-only= " Incomplete" + if challenge.markNew + span.text-success.small     + strong + em New + if challengeBlock.isComingSoon + span.text-success.small     + strong + em Coming Soon + if (index < superBlocks.length) + hr diff --git a/server/views/partials/navbar.jade b/server/views/partials/navbar.jade index a248fcdf2f..ae73e565c2 100644 --- a/server/views/partials/navbar.jade +++ b/server/views/partials/navbar.jade @@ -9,7 +9,9 @@ nav.navbar.navbar-default.navbar-fixed-top.nav-height ul.nav.navbar-nav.navbar-right.hamburger-dropdown li a.learn-btn(href='#') Learn - li + li.hidden-xs + a#nav-map-btn(href='#' onclick='return false') Map + li.visible-xs a(href='/map') Map li.hidden-xs a#nav-chat-btn(href='#' onclick="return false") Chat From de95f0e0f31aab3c70ef4fd51fd6a12b438da754 Mon Sep 17 00:00:00 2001 From: Berkeley Martinez Date: Tue, 12 Jan 2016 23:19:00 -0800 Subject: [PATCH 19/65] Add back map overview to map page --- server/views/map/show.jade | 169 +++++++++++++++++++++++++++++-------- 1 file changed, 132 insertions(+), 37 deletions(-) diff --git a/server/views/map/show.jade b/server/views/map/show.jade index 3e08c5e801..6d41cbdd70 100644 --- a/server/views/map/show.jade +++ b/server/views/map/show.jade @@ -1,42 +1,137 @@ extends ../layout-wide block content - .col-xs-12.col-sm-4.col-sm-offset-8 - for superBlock, index in superBlocks - for challengeBlock in superBlock.blocks - h4.bold #{challengeBlock.name} (#{challengeBlock.time}) - for challenge in challengeBlock.challenges - if challenge.completed - p.text-primary.ion-checkmark-circled.padded-ionic-icon.negative-15(name="#{challenge.dashedName}")   - a(href="/challenges/#{challenge.dashedName}") - = challenge.title - span.sr-only= " Complete" - else - if challenge.type === "bonfire" - p.ion-asterisk.padded-ionic-icon.negative-15(name="#{challenge.dashedName}")   - a(name="#{challenge.dashedName}" href="/challenges/#{challenge.dashedName}" class=challenge.isComingSoon ? 'disabled' : '') - span= challenge.title - span.sr-only= " Incomplete" - if challenge.markNew - span.text-success.small     - strong - em New - if challengeBlock.isComingSoon - span.text-success.small     - strong - em Coming Soon - else - p.ion-ios-circle-outline.padded-ionic-icon.negative-15(name="#{challenge.dashedName}")   - a(name="#{challenge.dashedName}" href="/challenges/#{challenge.dashedName}" class=challenge.isComingSoon ? 'disabled' : '') - span= challenge.title - span.sr-only= " Incomplete" - if challenge.markNew - span.text-success.small     - strong - em New - if challengeBlock.isComingSoon - span.text-success.small     - strong - em Coming Soon + .row + .col-xs-12.col-md-6.col-md-offset-3 + ul + for superBlock in superBlocks + h2= superBlock.name + for challengeBlock in superBlock.blocks + .row + if (user) + .col-xs-11.col-sm-8.col-md-9 + li.map-p.negative-10 + |    + a(href='#' + challengeBlock.dashedName)= challengeBlock.name + if challengeBlock.markNew + span.text-info.small     + strong + em NEW + if challengeBlock.isComingSoon + span.text-info.small     + strong + em Coming Soon + else + .hidden-xs.col-sm-3.col-md-2 + .col-xs-10.col-sm-8.col-md-9 + span.map-p.negative-10 + a(href='#' + challengeBlock.dashedName)= challengeBlock.name + if challengeBlock.markNew + span.text-info.small     + strong + em NEW + if challengeBlock.isComingSoon + span.text-info.small     + strong + em Coming Soon + h2 Full Stack Development Certification + .row + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 + |    + span.ion-locked.padded-ionic-icon + | Greenfield Nonprofit Project 1 + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 + |    + span.ion-locked.padded-ionic-icon + | Greenfield Nonprofit Project 2 + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 + |    + span.ion-locked.padded-ionic-icon + | Legacy Nonprofit Project 1 + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 + |    + span.ion-locked.padded-ionic-icon + | Legacy Nonprofit Project 2 + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 + |    + span.ion-locked.padded-ionic-icon + | Claim your Full Stack Development Certification + + h2 Coding Interview Preparation + .row + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 + |    + span.ion-locked.padded-ionic-icon + | Whiteboard Coding Interview Training + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 + |    + span.ion-locked.padded-ionic-icon + | Critical Thinking Interview Training + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 + |    + span.ion-locked.padded-ionic-icon + | Mock Interview 1 + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 + |    + span.ion-locked.padded-ionic-icon + | Mock Interview 2 + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 + |    + span.ion-locked.padded-ionic-icon + | Mock Interview 3 + hr + .row + .col-xs-12.col-md-6.col-md-offset-3 + for superBlock, index in superBlocks + for challengeBlock in superBlock.blocks + .row + a(href='#' name=challengeBlock.dashedName) + .spacer.negative-55 + .row + h4.bold #{challengeBlock.name} (#{challengeBlock.time}) + for challenge in challengeBlock.challenges + + .col-xs-12.col-sm-9.col-md-10 + if challenge.completed + p.text-primary.ion-checkmark-circled.padded-ionic-icon.negative-15(name="#{challenge.dashedName}")   + a(href="/challenges/#{challenge.dashedName}") + = challenge.title + span.sr-only= " Complete" + else if (challenge.type === "bonfire") + p.ion-asterisk.padded-ionic-icon.negative-15(name="#{challenge.dashedName}")   + a(name="#{challenge.dashedName}" href="/challenges/#{challenge.dashedName}" class=challenge.isComingSoon ? 'disabled' : '') + span= challenge.title + span.sr-only= " Incomplete" + if challenge.markNew + span.text-success.small     + strong + em New + if challengeBlock.isComingSoon + span.text-success.small     + strong + em Coming Soon + else + p.ion-ios-circle-outline.padded-ionic-icon.negative-15(name="#{challenge.dashedName}")   + a(name="#{challenge.dashedName}" href="/challenges/#{challenge.dashedName}" class=challenge.isComingSoon ? 'disabled' : '') + span= challenge.title + span.sr-only= " Incomplete" + if challenge.markNew + span.text-success.small     + strong + em New + if challengeBlock.isComingSoon + span.text-success.small     + strong + em Coming Soon if (index < superBlocks.length) hr From bcba082efcea0c58fa1e454768060c12a120f12b Mon Sep 17 00:00:00 2001 From: Quincy Larson Date: Sat, 9 Jan 2016 15:32:52 -0600 Subject: [PATCH 20/65] start simplifying views --- client/less/main.less | 6 + server/views/account/show.jade | 7 + server/views/challengeMap/show.jade | 213 ++++++++++++++++++++++++++++ server/views/stories/news-nav.jade | 6 - 4 files changed, 226 insertions(+), 6 deletions(-) create mode 100644 server/views/challengeMap/show.jade diff --git a/client/less/main.less b/client/less/main.less index c01dc70836..a5a7a1ceda 100644 --- a/client/less/main.less +++ b/client/less/main.less @@ -431,6 +431,12 @@ thead { color: @body-bg; } +.navbar-right { + background-color: #215f1e; + text-align: center; +>>>>>>> start simplifying views +} + .signup-btn-nav { margin-top: -2px !important; padding-top: 10px !important; diff --git a/server/views/account/show.jade b/server/views/account/show.jade index d24e22b261..f0734fc2e9 100644 --- a/server/views/account/show.jade +++ b/server/views/account/show.jade @@ -121,6 +121,7 @@ block content h4.col-sm-6.text-left Current Streak: #{currentStreak} #{currentStreak === 1 ? ' day' : ' days'} +>>>>>>> start simplifying views if (user && user.username == username || !isLocked) if (baseAndZip.length > 0) .col-sm-12 @@ -178,6 +179,7 @@ block content else a(href='/challenges/' + challenge.name)= challenge.name if (user && user.username === username) +<<<<<<< de95f0e0f31aab3c70ef4fd51fd6a12b438da754 <<<<<<< b157fa3095437bb5d39b91e23581589744f6aca0 .panel.panel-info .panel-heading.text-center Manage your account @@ -239,6 +241,8 @@ block content span.ion-trash-b | I am 100% sure I want to delete my account and all of my progress ======= +======= +>>>>>>> start simplifying views h1.text-center Manage your account hr .col-xs-12 @@ -297,4 +301,7 @@ block content button.btn.btn-danger.btn-block(type='submit') span.ion-trash-b | I am 100% sure I want to delete my account and all of my progress +<<<<<<< de95f0e0f31aab3c70ef4fd51fd6a12b438da754 +>>>>>>> start simplifying views +======= >>>>>>> start simplifying views diff --git a/server/views/challengeMap/show.jade b/server/views/challengeMap/show.jade new file mode 100644 index 0000000000..9f7b3929e5 --- /dev/null +++ b/server/views/challengeMap/show.jade @@ -0,0 +1,213 @@ +extends ../layout +block content + h1.text-center Challenge Map + hr + if (Math.random() > 0.999) + img.img-responsive.img-center.border-radius-5(src='https://s3.amazonaws.com/freecodecamp/wide-social-banner-dino.png') + audio(autoplay src='https://s3.amazonaws.com/freecodecamp/t-rex-roar.mp3') + else + img.img-responsive.img-center.border-radius-5(src='https://s3.amazonaws.com/freecodecamp/wide-social-banner.png') + .col-xs-12.col-md-8.col-md-offset-2 + h2 + table.population-table.img-center + tr + td Established:  + td + span.text-primary #{daysRunning}  + | days ago + tr + td Population:    + td + span.text-primary #{camperCount}  + | campers + tr + td Completed:    + td + span.text-primary #{globalCompletedCount}  + | challenges + + + + .spacer + if (user && user.progressTimestamps.length > 100) + .row + #map-notice.col-xs-12.col-md-8.col-md-offset-2.hidden + h2.text-center Reddit or not, here we come + img.thumbnail.img-center.img-responsive(src="http://i.imgur.com/lyd0bfM.jpg") + h4.text-center Come ask questions and share your thoughts with our entire open source community on our subreddit. + a.button.btn.btn-block.btn-primary(href="https://reddit.com/r/freecodecamp" target="_blank") Check it out + .button-spacer + .text-center + a#hide-map-notice-button(href='#') Hide this forever + .spacer + + ul + for superBlock in superBlocks + h2= superBlock.name + - var i = 0 + for challengeBlock in superBlock.blocks + - i++ + .row + if (user) + if (challengeBlock.completed === 100) + .hidden-xs.col-sm-3.col-md-2.text-primary.ion-checkmark-circled.padded-ionic-icon.text-center.map-p.negative-10 + .col-xs-1.col-sm-1.col-md-1.map-row-numbers.negative-5 + span.map-p.negative-10 #{i}. + .col-xs-11.col-sm-8.col-md-9 + li.map-p.faded.negative-10 + a(href='#' + challengeBlock.dashedName)= challengeBlock.name + if challengeBlock.markNew + span.text-info.small     + strong + em NEW + if challengeBlock.isComingSoon + span.text-info.small     + strong + em Coming Soon + else + .hidden-xs.col-sm-3.col-md-2 + .progress.progress-bar-padding.text-center.thin-progress-bar + .progress-bar(role='progressbar', aria-valuenow=(challengeBlock.completed), aria-valuemin='0', aria-valuemax='100', style='width: ' + challengeBlock.completed + '%;') + .col-xs-1.col-sm-1.col-md-1.map-row-numbers.negative-5 + span.map-p #{i}. + .col-xs-11.col-sm-8.col-md-9 + li.map-p.negative-10 + a(href='#' + challengeBlock.dashedName)= challengeBlock.name + if challengeBlock.markNew + span.text-info.small     + strong + em NEW + if challengeBlock.isComingSoon + span.text-info.small     + strong + em Coming Soon + else + .hidden-xs.col-sm-3.col-md-2 + .col-xs-1.col-sm-1.col-md-1.map-row-numbers + span.map-p.negative-10 #{i}. + .col-xs-10.col-sm-8.col-md-9 + span.map-p.negative-10 + a(href='#' + challengeBlock.dashedName)= challengeBlock.name + if challengeBlock.markNew + span.text-info.small     + strong + em NEW + if challengeBlock.isComingSoon + span.text-info.small     + strong + em Coming Soon + h2 Full Stack Development Certification + .row + .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 Greenfield Nonprofit Project 1 + .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 Greenfield Nonprofit Project 2 + .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 Legacy Nonprofit Project 1 + .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 Legacy Nonprofit Project 2 + .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 Claim your Full Stack Development Certification + + h2 Coding Interview Preparation + .row + .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 Whiteboard Coding Interview Training + .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 Critical Thinking Interview Training + .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 Mock Interview 1 + .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 Mock Interview 2 + .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 Mock Interview 3 + + hr + + for superBlock, index in superBlocks + for challengeBlock in superBlock.blocks + .row + a(href='#' name=challengeBlock.dashedName) + .spacer.negative-55 + + .row + .hidden-xs.col-sm-3.col-md-2 + h3.text-primary.text-right.nowrap + i.fa.fa-clock-o + = challengeBlock.time + .col-xs-12.col-sm-9.col-md-10 + h3 #{challengeBlock.name}   + + - var i = 0 + for challenge in challengeBlock.challenges + - i++ + .row + if challenge.completed + .hidden-xs.col-sm-3.col-md-2.text-primary.ion-checkmark-circled.padded-ionic-icon.text-center.map-p.negative-10 + .col-xs-1.col-sm-1.col-md-1.map-row-numbers + span.map-p.negative-10 #{i}. + .col-xs-10.col-sm-8.col-md-9 + span.faded.map-p.negative-10 + a(href="/challenges/#{challenge.dashedName}") + span.capitalize= challenge.type + ': ' + span= challenge.title + span.sr-only= " Complete" + + else + .hidden-xs.col-sm-3.col-md-2 + span.negative-10 + .col-xs-1.col-sm-1.col-md-1.map-row-numbers + span.map-p.negative-10 #{i}. + .col-xs-10.col-sm-8.col-md-9 + span.map-p.negative-10 + a(href="/challenges/#{challenge.dashedName}" class=challenge.isComingSoon ? 'disabled' : '') + span.capitalize= challenge.type + ': ' + span= challenge.title + span.sr-only= " Incomplete" + if challenge.markNew + span.text-info.small     + strong + em NEW + if challengeBlock.isComingSoon + span.text-info.small     + strong + em Coming Soon + + if (challengeBlock.completed === 100) + .button-spacer + .row + .col-xs-12.col-sm-8.col-md-6.col-sm-offset-3.col-md-offset-2.hidden + a.btn.btn-lg.btn-block.signup-btn.map-challenge-block-share Section complete. Share your code portfolio with your friends. + .hidden(id="#{challengeBlock.name}") + + if (index < superBlocks.length - 1) + .spacer + hr + .spacer + + script. + var username = !{JSON.stringify(user && user.username || '')}; + var lastCompleted = !{JSON.stringify(lastCompleted || false)} + $(document).ready(function () { + if (!localStorage || !localStorage.hideRedditNotice) { + $("#map-notice").removeClass("hidden"); + } + $("#hide-map-notice-button").on("click", function(e) { + e.preventDefault(); + $("#map-notice").addClass('animated fadeOut'); + setTimeout(function() { + $("#map-notice").hide(); + }, 1000); + localStorage.hideRedditNotice = "true"; + }); + }); diff --git a/server/views/stories/news-nav.jade b/server/views/stories/news-nav.jade index d78c17aab5..5c93e82c11 100644 --- a/server/views/stories/news-nav.jade +++ b/server/views/stories/news-nav.jade @@ -1,10 +1,4 @@ .row - .col-xs-12.col-sm-9 - .input-group - input#searchArea.big-text-field.field-responsive.form-control(type='text', placeholder='search term or @username') - span.input-group-btn - button#searchbutton.btn.btn-big.btn-primary.btn-responsive(type='button') Search - .spacer .col-xs-12.col-sm-3 span a.btn.btn-primary.btn-big.btn-block.btn-responsive(href='/stories/submit' class="#{ page === 'hot' ? '' : 'hidden' }") Submit a link From a33d295231808d90c962457e8e5a2a9ce5fb9db5 Mon Sep 17 00:00:00 2001 From: Quincy Larson Date: Sat, 9 Jan 2016 20:03:51 -0600 Subject: [PATCH 21/65] make navbar brown again --- client/less/main.less | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/client/less/main.less b/client/less/main.less index a5a7a1ceda..1efd312a3d 100644 --- a/client/less/main.less +++ b/client/less/main.less @@ -42,17 +42,13 @@ html { overflow-x: hidden; } -//input[type=checkbox] { -// /* Double-sized Checkboxes */ -// -ms-transform: scale(2); /* IE */ -// -moz-transform: scale(2); /* FF */ -// -webkit-transform: scale(2); /* Safari and Chrome */ -// -o-transform: scale(2); /* Opera */ -// padding: 10px; -//} - -.btn-group { - border-color: @brand-primary; +input[type=checkbox] { + /* Double-sized Checkboxes */ + -ms-transform: scale(2); /* IE */ + -moz-transform: scale(2); /* FF */ + -webkit-transform: scale(2); /* Safari and Chrome */ + -o-transform: scale(2); /* Opera */ + padding: 10px; } body.full-screen-body-background { @@ -94,7 +90,7 @@ h1, h2, h3, h4, h5, h6, p, li { .thumbnail { background-color: #EEEEEE; -// box-shadow: 0 0 5px #ccc, inset 0 0 0 #000; + // box-shadow: 0 0 5px #ccc, inset 0 0 0 #000; } // Font Icons @@ -370,7 +366,7 @@ ul { } *, *:before, *:after { - box-sizing: border-box !important; + box-sizing: border-box !important; } .btn-big { @@ -432,7 +428,7 @@ thead { } .navbar-right { - background-color: #215f1e; + background-color: #4a2b0f; text-align: center; >>>>>>> start simplifying views } @@ -685,8 +681,8 @@ div.CodeMirror-scroll { border-radius: 5px; } .bonfire-flames { - margin-top: -20px; - margin-bottom: -2px; + margin-top: -20px; + margin-bottom: -2px; } .bonfire-top { @@ -943,8 +939,8 @@ hr { } .checklist-element { - margin-left: -60px; - margin-right: -20px; + margin-left: -60px; + margin-right: -20px; } .profile-social-icons { @@ -1005,7 +1001,7 @@ code { } .gitter-chat-embed { - z-index: 20000 !important; + z-index: 20000 !important; } From 4ee8cf08333b3a93faf81a2d894815699abff5eb Mon Sep 17 00:00:00 2001 From: Quincy Larson Date: Sat, 9 Jan 2016 21:02:31 -0600 Subject: [PATCH 22/65] Revert "make navbar brown again" This reverts commit 18224e14f7b9ee356450bae54959b770c5ec4c7c. --- client/less/main.less | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/client/less/main.less b/client/less/main.less index 1efd312a3d..a5a7a1ceda 100644 --- a/client/less/main.less +++ b/client/less/main.less @@ -42,13 +42,17 @@ html { overflow-x: hidden; } -input[type=checkbox] { - /* Double-sized Checkboxes */ - -ms-transform: scale(2); /* IE */ - -moz-transform: scale(2); /* FF */ - -webkit-transform: scale(2); /* Safari and Chrome */ - -o-transform: scale(2); /* Opera */ - padding: 10px; +//input[type=checkbox] { +// /* Double-sized Checkboxes */ +// -ms-transform: scale(2); /* IE */ +// -moz-transform: scale(2); /* FF */ +// -webkit-transform: scale(2); /* Safari and Chrome */ +// -o-transform: scale(2); /* Opera */ +// padding: 10px; +//} + +.btn-group { + border-color: @brand-primary; } body.full-screen-body-background { @@ -90,7 +94,7 @@ h1, h2, h3, h4, h5, h6, p, li { .thumbnail { background-color: #EEEEEE; - // box-shadow: 0 0 5px #ccc, inset 0 0 0 #000; +// box-shadow: 0 0 5px #ccc, inset 0 0 0 #000; } // Font Icons @@ -366,7 +370,7 @@ ul { } *, *:before, *:after { - box-sizing: border-box !important; + box-sizing: border-box !important; } .btn-big { @@ -428,7 +432,7 @@ thead { } .navbar-right { - background-color: #4a2b0f; + background-color: #215f1e; text-align: center; >>>>>>> start simplifying views } @@ -681,8 +685,8 @@ div.CodeMirror-scroll { border-radius: 5px; } .bonfire-flames { - margin-top: -20px; - margin-bottom: -2px; + margin-top: -20px; + margin-bottom: -2px; } .bonfire-top { @@ -939,8 +943,8 @@ hr { } .checklist-element { - margin-left: -60px; - margin-right: -20px; + margin-left: -60px; + margin-right: -20px; } .profile-social-icons { @@ -1001,7 +1005,7 @@ code { } .gitter-chat-embed { - z-index: 20000 !important; + z-index: 20000 !important; } From cb6f026fd0e88ace4e31df19be32a48b350242c8 Mon Sep 17 00:00:00 2001 From: Quincy Larson Date: Sat, 9 Jan 2016 22:12:32 -0600 Subject: [PATCH 23/65] more redesign work on challenge views --- client/less/main.less | 1 - server/views/home.jade | 14 +++--- server/views/nonprofits/show.jade | 75 +++++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+), 8 deletions(-) create mode 100644 server/views/nonprofits/show.jade diff --git a/client/less/main.less b/client/less/main.less index a5a7a1ceda..1df2ce5457 100644 --- a/client/less/main.less +++ b/client/less/main.less @@ -434,7 +434,6 @@ thead { .navbar-right { background-color: #215f1e; text-align: center; ->>>>>>> start simplifying views } .signup-btn-nav { diff --git a/server/views/home.jade b/server/views/home.jade index 0c80370c87..71ba6f5efd 100644 --- a/server/views/home.jade +++ b/server/views/home.jade @@ -88,13 +88,13 @@ block content h2 Here's why you should join our open source community right now: .spacer ul.large-li - li.ion-code   You'll get help in real time from our community chat rooms. - li.ion-code   You'll meet up with other coders in your city. - li.ion-code   You'll learn to code at your own pace, in your browser or on your phone. - li.ion-code   You'll work through our focused, interactive courses and tutorials. - li.ion-code   You'll learn state-of-the-art full stack JavaScript technologies. - li.ion-code   You'll build projects that help nonprofits carry out their missions more effectively. - li.ion-code   You'll assemble a portfolio of real apps used by real people. + li.ion-code.large-p   You'll get help in real time from our community chat rooms. + li.ion-code.large-p   You'll meet up with other coders in your city. + li.ion-code.large-p   You'll learn to code at your own pace, in your browser or on your phone. + li.ion-code.large-p   You'll work through our focused, interactive courses and tutorials. + li.ion-code.large-p   You'll learn state-of-the-art full stack JavaScript technologies. + li.ion-code.large-p   You'll build projects that help nonprofits carry out their missions more effectively. + li.ion-code.large-p   You'll assemble a portfolio of real apps used by real people. .big-break .row .col-xs-12.col-sm-8.col-sm-offset-2 diff --git a/server/views/nonprofits/show.jade b/server/views/nonprofits/show.jade new file mode 100644 index 0000000000..18b5e261b3 --- /dev/null +++ b/server/views/nonprofits/show.jade @@ -0,0 +1,75 @@ +extends ../layout +block content + script. + var challengeName = 'Nonprofits View'; + .row + .col-xs-12.col-sm-10.col-sm-offset-1 + .row + .col-xs-12 + img.img-center.img-responsive(src=imageUrl) + .spacer + .row + .col-xs-12.col-sm-4 + img.img-responsive(src=logoUrl) + .col-xs-12.col-sm-8 + .col-xs-12 + h4= whatDoesNonprofitDo + h4 + a(href=websiteLink)= websiteLink + .spacer + h3 Project Description: + .col-xs-12 + h4.negative-15 #{projectDescription} (About #{estimatedHours} hours per camper) + .spacer + h3 This project involves building: + h4.negative-15.col-xs-12 + if (approvedWebsite) + .ion-android-globe   Website + if (approvedDonor) + .ion-card   Donor Management System + if (approvedInventory) + .ion-ios-box   Inventory Management System + if (approvedVolunteer) + .ion-android-calendar   Volunteer Management System + if (approvedForm) + .ion-ios-list   Webform + if (approvedCommunity) + .ion-ios-people   Community Management System + if (approvedELearning) + .ion-university   E-learning Platform + if (approvedOther) + .ion-settings   Other tools + h3 Project Status: #{currentStatus} + if (moneySaved > 0) + h3.text-primary Estimated Cost Savings for Nonprofit: $#{moneySaved.toString().replace(/000$/, ',000')} + + if (interestedCampers && interestedCampers.length > 0) + h3 Interested campers: + .col-xs-12.text-left + for interestedCamper in interestedCampers + a(href='/' + interestedCamper.username class="interested-camper-image") + img.profile-picture.float-right(src=interestedCamper.picture) + if (assignedCampers && assignedCampers.length > 0) + h3 Assigned campers: + .col-xs-12.text-left + for assignedCamper in assignedCampers + a(href='/' + assignedCamper.username class="interested-camper-image") + img.profile-picture.float-right(src=assignedCamper.picture) + if (!buttonActive) + .col-xs-12.col-sm-8.col-sm-offset-2 + .text-center + if !user + a.btn.btn-cta.signup-btn.btn-block(href="/login") Start learning to code (it's free) + .button-spacer + else + a.btn.btn-primary.btn-big.btn-block.disabled(href='/nonprofits/interested-in-nonprofit/#{dashedName}') I'm interested in building this project * + p * Complete all our Bonfires, Ziplines, and Basejumps to unlock this. + a.btn.btn-info.btn-big.btn-block(href='/nonprofits/directory') Show all Nonprofit Projects + .spacer + if (buttonActive) + .col-xs-12.col-sm-8.col-sm-offset-2 + .text-center + a.btn.btn-primary.btn-big.btn-block(href='/nonprofits/interested-in-nonprofit/#{dashedName}') I'm interested in building this project + .button-spacer + a.btn.btn-info.btn-big.btn-block(href='/nonprofits/directory') Show all Nonprofit Projects + .spacer From 4517c597bc4cd9b002795e592cf3b7592207e77b Mon Sep 17 00:00:00 2001 From: Quincy Larson Date: Sat, 9 Jan 2016 23:48:37 -0600 Subject: [PATCH 24/65] Update nonprofits structure and remove old directory --- server/views/nonprofits/show.jade | 75 ------------------------------- 1 file changed, 75 deletions(-) delete mode 100644 server/views/nonprofits/show.jade diff --git a/server/views/nonprofits/show.jade b/server/views/nonprofits/show.jade deleted file mode 100644 index 18b5e261b3..0000000000 --- a/server/views/nonprofits/show.jade +++ /dev/null @@ -1,75 +0,0 @@ -extends ../layout -block content - script. - var challengeName = 'Nonprofits View'; - .row - .col-xs-12.col-sm-10.col-sm-offset-1 - .row - .col-xs-12 - img.img-center.img-responsive(src=imageUrl) - .spacer - .row - .col-xs-12.col-sm-4 - img.img-responsive(src=logoUrl) - .col-xs-12.col-sm-8 - .col-xs-12 - h4= whatDoesNonprofitDo - h4 - a(href=websiteLink)= websiteLink - .spacer - h3 Project Description: - .col-xs-12 - h4.negative-15 #{projectDescription} (About #{estimatedHours} hours per camper) - .spacer - h3 This project involves building: - h4.negative-15.col-xs-12 - if (approvedWebsite) - .ion-android-globe   Website - if (approvedDonor) - .ion-card   Donor Management System - if (approvedInventory) - .ion-ios-box   Inventory Management System - if (approvedVolunteer) - .ion-android-calendar   Volunteer Management System - if (approvedForm) - .ion-ios-list   Webform - if (approvedCommunity) - .ion-ios-people   Community Management System - if (approvedELearning) - .ion-university   E-learning Platform - if (approvedOther) - .ion-settings   Other tools - h3 Project Status: #{currentStatus} - if (moneySaved > 0) - h3.text-primary Estimated Cost Savings for Nonprofit: $#{moneySaved.toString().replace(/000$/, ',000')} - - if (interestedCampers && interestedCampers.length > 0) - h3 Interested campers: - .col-xs-12.text-left - for interestedCamper in interestedCampers - a(href='/' + interestedCamper.username class="interested-camper-image") - img.profile-picture.float-right(src=interestedCamper.picture) - if (assignedCampers && assignedCampers.length > 0) - h3 Assigned campers: - .col-xs-12.text-left - for assignedCamper in assignedCampers - a(href='/' + assignedCamper.username class="interested-camper-image") - img.profile-picture.float-right(src=assignedCamper.picture) - if (!buttonActive) - .col-xs-12.col-sm-8.col-sm-offset-2 - .text-center - if !user - a.btn.btn-cta.signup-btn.btn-block(href="/login") Start learning to code (it's free) - .button-spacer - else - a.btn.btn-primary.btn-big.btn-block.disabled(href='/nonprofits/interested-in-nonprofit/#{dashedName}') I'm interested in building this project * - p * Complete all our Bonfires, Ziplines, and Basejumps to unlock this. - a.btn.btn-info.btn-big.btn-block(href='/nonprofits/directory') Show all Nonprofit Projects - .spacer - if (buttonActive) - .col-xs-12.col-sm-8.col-sm-offset-2 - .text-center - a.btn.btn-primary.btn-big.btn-block(href='/nonprofits/interested-in-nonprofit/#{dashedName}') I'm interested in building this project - .button-spacer - a.btn.btn-info.btn-big.btn-block(href='/nonprofits/directory') Show all Nonprofit Projects - .spacer From 39e7e6e33b5069c430cdb450da24cd722dafb7b5 Mon Sep 17 00:00:00 2001 From: Quincy Larson Date: Sun, 10 Jan 2016 00:53:46 -0600 Subject: [PATCH 25/65] additional cleanup of nonprofit directory --- server/views/home.jade | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/server/views/home.jade b/server/views/home.jade index 71ba6f5efd..0c80370c87 100644 --- a/server/views/home.jade +++ b/server/views/home.jade @@ -88,13 +88,13 @@ block content h2 Here's why you should join our open source community right now: .spacer ul.large-li - li.ion-code.large-p   You'll get help in real time from our community chat rooms. - li.ion-code.large-p   You'll meet up with other coders in your city. - li.ion-code.large-p   You'll learn to code at your own pace, in your browser or on your phone. - li.ion-code.large-p   You'll work through our focused, interactive courses and tutorials. - li.ion-code.large-p   You'll learn state-of-the-art full stack JavaScript technologies. - li.ion-code.large-p   You'll build projects that help nonprofits carry out their missions more effectively. - li.ion-code.large-p   You'll assemble a portfolio of real apps used by real people. + li.ion-code   You'll get help in real time from our community chat rooms. + li.ion-code   You'll meet up with other coders in your city. + li.ion-code   You'll learn to code at your own pace, in your browser or on your phone. + li.ion-code   You'll work through our focused, interactive courses and tutorials. + li.ion-code   You'll learn state-of-the-art full stack JavaScript technologies. + li.ion-code   You'll build projects that help nonprofits carry out their missions more effectively. + li.ion-code   You'll assemble a portfolio of real apps used by real people. .big-break .row .col-xs-12.col-sm-8.col-sm-offset-2 From d5a2c6e4b86c013a0aba9f98fea21280bfde5630 Mon Sep 17 00:00:00 2001 From: Quincy Larson Date: Sun, 10 Jan 2016 23:49:09 -0600 Subject: [PATCH 26/65] Update --- server/views/challengeMap/show.jade | 223 ++++------------------------ 1 file changed, 29 insertions(+), 194 deletions(-) diff --git a/server/views/challengeMap/show.jade b/server/views/challengeMap/show.jade index 9f7b3929e5..c03bec4de1 100644 --- a/server/views/challengeMap/show.jade +++ b/server/views/challengeMap/show.jade @@ -1,199 +1,34 @@ -extends ../layout +extends ../layout-wide block content - h1.text-center Challenge Map - hr - if (Math.random() > 0.999) - img.img-responsive.img-center.border-radius-5(src='https://s3.amazonaws.com/freecodecamp/wide-social-banner-dino.png') - audio(autoplay src='https://s3.amazonaws.com/freecodecamp/t-rex-roar.mp3') - else - img.img-responsive.img-center.border-radius-5(src='https://s3.amazonaws.com/freecodecamp/wide-social-banner.png') - .col-xs-12.col-md-8.col-md-offset-2 - h2 - table.population-table.img-center - tr - td Established:  - td - span.text-primary #{daysRunning}  - | days ago - tr - td Population:    - td - span.text-primary #{camperCount}  - | campers - tr - td Completed:    - td - span.text-primary #{globalCompletedCount}  - | challenges - - - - .spacer - if (user && user.progressTimestamps.length > 100) - .row - #map-notice.col-xs-12.col-md-8.col-md-offset-2.hidden - h2.text-center Reddit or not, here we come - img.thumbnail.img-center.img-responsive(src="http://i.imgur.com/lyd0bfM.jpg") - h4.text-center Come ask questions and share your thoughts with our entire open source community on our subreddit. - a.button.btn.btn-block.btn-primary(href="https://reddit.com/r/freecodecamp" target="_blank") Check it out - .button-spacer - .text-center - a#hide-map-notice-button(href='#') Hide this forever - .spacer - - ul - for superBlock in superBlocks - h2= superBlock.name - - var i = 0 - for challengeBlock in superBlock.blocks - - i++ - .row - if (user) - if (challengeBlock.completed === 100) - .hidden-xs.col-sm-3.col-md-2.text-primary.ion-checkmark-circled.padded-ionic-icon.text-center.map-p.negative-10 - .col-xs-1.col-sm-1.col-md-1.map-row-numbers.negative-5 - span.map-p.negative-10 #{i}. - .col-xs-11.col-sm-8.col-md-9 - li.map-p.faded.negative-10 - a(href='#' + challengeBlock.dashedName)= challengeBlock.name - if challengeBlock.markNew - span.text-info.small     - strong - em NEW - if challengeBlock.isComingSoon - span.text-info.small     - strong - em Coming Soon - else - .hidden-xs.col-sm-3.col-md-2 - .progress.progress-bar-padding.text-center.thin-progress-bar - .progress-bar(role='progressbar', aria-valuenow=(challengeBlock.completed), aria-valuemin='0', aria-valuemax='100', style='width: ' + challengeBlock.completed + '%;') - .col-xs-1.col-sm-1.col-md-1.map-row-numbers.negative-5 - span.map-p #{i}. - .col-xs-11.col-sm-8.col-md-9 - li.map-p.negative-10 - a(href='#' + challengeBlock.dashedName)= challengeBlock.name - if challengeBlock.markNew - span.text-info.small     - strong - em NEW - if challengeBlock.isComingSoon - span.text-info.small     - strong - em Coming Soon - else - .hidden-xs.col-sm-3.col-md-2 - .col-xs-1.col-sm-1.col-md-1.map-row-numbers - span.map-p.negative-10 #{i}. - .col-xs-10.col-sm-8.col-md-9 - span.map-p.negative-10 - a(href='#' + challengeBlock.dashedName)= challengeBlock.name - if challengeBlock.markNew - span.text-info.small     - strong - em NEW - if challengeBlock.isComingSoon - span.text-info.small     - strong - em Coming Soon - h2 Full Stack Development Certification - .row - .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 Greenfield Nonprofit Project 1 - .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 Greenfield Nonprofit Project 2 - .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 Legacy Nonprofit Project 1 - .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 Legacy Nonprofit Project 2 - .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 Claim your Full Stack Development Certification - - h2 Coding Interview Preparation - .row - .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 Whiteboard Coding Interview Training - .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 Critical Thinking Interview Training - .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 Mock Interview 1 - .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 Mock Interview 2 - .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10 - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 Mock Interview 3 - - hr - - for superBlock, index in superBlocks - for challengeBlock in superBlock.blocks - .row - a(href='#' name=challengeBlock.dashedName) - .spacer.negative-55 - - .row - .hidden-xs.col-sm-3.col-md-2 - h3.text-primary.text-right.nowrap - i.fa.fa-clock-o - = challengeBlock.time - .col-xs-12.col-sm-9.col-md-10 - h3 #{challengeBlock.name}   - - - var i = 0 + .col-xs-12.col-sm-3.col-sm-offset-9 + for superBlock, index in superBlocks + for challengeBlock in superBlock.blocks + h4.bold #{challengeBlock.name} (#{challengeBlock.time}) for challenge in challengeBlock.challenges - - i++ - .row - if challenge.completed - .hidden-xs.col-sm-3.col-md-2.text-primary.ion-checkmark-circled.padded-ionic-icon.text-center.map-p.negative-10 - .col-xs-1.col-sm-1.col-md-1.map-row-numbers - span.map-p.negative-10 #{i}. - .col-xs-10.col-sm-8.col-md-9 - span.faded.map-p.negative-10 - a(href="/challenges/#{challenge.dashedName}") - span.capitalize= challenge.type + ': ' - span= challenge.title - span.sr-only= " Complete" - - else - .hidden-xs.col-sm-3.col-md-2 - span.negative-10 - .col-xs-1.col-sm-1.col-md-1.map-row-numbers - span.map-p.negative-10 #{i}. - .col-xs-10.col-sm-8.col-md-9 - span.map-p.negative-10 - a(href="/challenges/#{challenge.dashedName}" class=challenge.isComingSoon ? 'disabled' : '') - span.capitalize= challenge.type + ': ' - span= challenge.title - span.sr-only= " Incomplete" - if challenge.markNew - span.text-info.small     - strong - em NEW - if challengeBlock.isComingSoon - span.text-info.small     - strong - em Coming Soon - - if (challengeBlock.completed === 100) - .button-spacer - .row - .col-xs-12.col-sm-8.col-md-6.col-sm-offset-3.col-md-offset-2.hidden - a.btn.btn-lg.btn-block.signup-btn.map-challenge-block-share Section complete. Share your code portfolio with your friends. - .hidden(id="#{challengeBlock.name}") - - if (index < superBlocks.length - 1) - .spacer - hr - .spacer + if challenge.completed + p.text-primary.ion-checkmark-circled.padded-ionic-icon.negative-15(name="#{challenge.dashedName}")   + a(href="/challenges/#{challenge.dashedName}") + = challenge.title + span.sr-only= " Complete" + else + p.negative-15 + a(name="#{challenge.dashedName}" href="/challenges/#{challenge.dashedName}" class=challenge.isComingSoon ? 'disabled' : '') + span= challenge.title + span.sr-only= " Incomplete" + if challenge.markNew + span.text-success.small     + strong + em New + if challengeBlock.isComingSoon + span.text-success.small     + strong + em Coming Soon + if challenge.type === "bonfire" + span.text-info.small     + strong + em Required + if (index < superBlocks.length) + hr script. var username = !{JSON.stringify(user && user.username || '')}; From c026717aa4e2a6a1672aca2745acfe14c81dcebc Mon Sep 17 00:00:00 2001 From: Quincy Larson Date: Mon, 11 Jan 2016 18:25:20 -0600 Subject: [PATCH 27/65] further build up challengemap --- server/views/challengeMap/show.jade | 44 ++++++++++++++++++----------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/server/views/challengeMap/show.jade b/server/views/challengeMap/show.jade index c03bec4de1..3e08c5e801 100644 --- a/server/views/challengeMap/show.jade +++ b/server/views/challengeMap/show.jade @@ -1,6 +1,6 @@ extends ../layout-wide block content - .col-xs-12.col-sm-3.col-sm-offset-9 + .col-xs-12.col-sm-4.col-sm-offset-8 for superBlock, index in superBlocks for challengeBlock in superBlock.blocks h4.bold #{challengeBlock.name} (#{challengeBlock.time}) @@ -11,22 +11,32 @@ block content = challenge.title span.sr-only= " Complete" else - p.negative-15 - a(name="#{challenge.dashedName}" href="/challenges/#{challenge.dashedName}" class=challenge.isComingSoon ? 'disabled' : '') - span= challenge.title - span.sr-only= " Incomplete" - if challenge.markNew - span.text-success.small     - strong - em New - if challengeBlock.isComingSoon - span.text-success.small     - strong - em Coming Soon - if challenge.type === "bonfire" - span.text-info.small     - strong - em Required + if challenge.type === "bonfire" + p.ion-asterisk.padded-ionic-icon.negative-15(name="#{challenge.dashedName}")   + a(name="#{challenge.dashedName}" href="/challenges/#{challenge.dashedName}" class=challenge.isComingSoon ? 'disabled' : '') + span= challenge.title + span.sr-only= " Incomplete" + if challenge.markNew + span.text-success.small     + strong + em New + if challengeBlock.isComingSoon + span.text-success.small     + strong + em Coming Soon + else + p.ion-ios-circle-outline.padded-ionic-icon.negative-15(name="#{challenge.dashedName}")   + a(name="#{challenge.dashedName}" href="/challenges/#{challenge.dashedName}" class=challenge.isComingSoon ? 'disabled' : '') + span= challenge.title + span.sr-only= " Incomplete" + if challenge.markNew + span.text-success.small     + strong + em New + if challengeBlock.isComingSoon + span.text-success.small     + strong + em Coming Soon if (index < superBlocks.length) hr From bbf6d14ee7953672009ca8257cb630489518d111 Mon Sep 17 00:00:00 2001 From: Quincy Larson Date: Mon, 11 Jan 2016 18:56:15 -0600 Subject: [PATCH 28/65] start working on ghost-only buttons --- server/views/account/show.jade | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/server/views/account/show.jade b/server/views/account/show.jade index f0734fc2e9..aee51db2df 100644 --- a/server/views/account/show.jade +++ b/server/views/account/show.jade @@ -246,29 +246,29 @@ block content h1.text-center Manage your account hr .col-xs-12 - a.btn.btn-lg.btn-block.btn-warning.btn-link-social(href='/logout') + a.btn.btn-lg.btn-block.btn-primary.btn-primary-ghost.btn-link-social(href='/logout') span.ion-android-exit | Sign me out of Free Code Camp .col-xs-12 - a.btn.btn-lg.btn-block.btn-primary.btn-link-social(href='mailto:team@freecodecamp.com') + a.btn.btn-lg.btn-block.btn-primary.btn-primary-ghost.btn-link-social(href='mailto:team@freecodecamp.com') span.ion-email | Email us at team@freecodecamp.com if (!user.isLocked) .col-xs-12 - a.btn.btn-lg.btn-block.btn-info.btn-link-social(href='/toggle-lockdown-mode') + a.btn.btn-lg.btn-block.btn-primary.btn-primary-ghost.btn-link-social(href='/toggle-lockdown-mode') span.ion-locked | Hide all my solutions from other people br | (this will disable your certificates) else .col-xs-12 - a.btn.btn-lg.btn-block.btn-info.btn-link-social(href='/toggle-lockdown-mode') + a.btn.btn-lg.btn-block.btn-primary.btn-primary-ghost.btn-link-social(href='/toggle-lockdown-mode') span.ion-unlocked | Let other people see all my solutions br | (this will enable your certificates) .col-xs-12 - a.btn.btn-lg.btn-block.btn-success.btn-link-social(href='/commit') + a.btn.btn-lg.btn-block.btn-primary.btn-primary-ghost.btn-link-social(href='/commit') span.ion-edit | Edit my pledge .col-xs-12 From b4a63f799ac37e9b1c709c0558250888634b78ff Mon Sep 17 00:00:00 2001 From: Berkeley Martinez Date: Mon, 11 Jan 2016 17:36:05 -0800 Subject: [PATCH 29/65] Change buttons to ghost type --- client/less/lib/bootstrap/mixins/buttons.less | 2 +- client/less/lib/bootstrap/variables.less | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client/less/lib/bootstrap/mixins/buttons.less b/client/less/lib/bootstrap/mixins/buttons.less index 9714cc206b..c8289d0cd8 100755 --- a/client/less/lib/bootstrap/mixins/buttons.less +++ b/client/less/lib/bootstrap/mixins/buttons.less @@ -15,7 +15,7 @@ &.active, .open > .dropdown-toggle& { color: @gray-lighter; - background-color: @background; + background-color: lighten(@background, 10%); border-color: darken(@border, 12%); } &:active, diff --git a/client/less/lib/bootstrap/variables.less b/client/less/lib/bootstrap/variables.less index 849aaa4440..fdd43df500 100755 --- a/client/less/lib/bootstrap/variables.less +++ b/client/less/lib/bootstrap/variables.less @@ -152,7 +152,7 @@ @btn-primary-bg: @brand-primary; @btn-primary-border: darken(@btn-primary-bg, 5%); -@btn-success-color: @brand-success; +@btn-success-color: @brand-primary; @btn-success-bg: @brand-success; @btn-success-border: darken(@btn-success-bg, 5%); @@ -160,7 +160,7 @@ @btn-info-bg: @brand-info; @btn-info-border: darken(@btn-info-bg, 5%); -@btn-warning-color: @brand-warning; +@btn-warning-color: @brand-primary; @btn-warning-bg: @brand-warning; @btn-warning-border: darken(@btn-warning-bg, 5%); From 7187ae18413532a1767e9b8fd8a366f8486988b9 Mon Sep 17 00:00:00 2001 From: Berkeley Martinez Date: Mon, 11 Jan 2016 18:04:56 -0800 Subject: [PATCH 30/65] Fix btn success color --- client/less/lib/bootstrap/variables.less | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/less/lib/bootstrap/variables.less b/client/less/lib/bootstrap/variables.less index fdd43df500..849aaa4440 100755 --- a/client/less/lib/bootstrap/variables.less +++ b/client/less/lib/bootstrap/variables.less @@ -152,7 +152,7 @@ @btn-primary-bg: @brand-primary; @btn-primary-border: darken(@btn-primary-bg, 5%); -@btn-success-color: @brand-primary; +@btn-success-color: @brand-success; @btn-success-bg: @brand-success; @btn-success-border: darken(@btn-success-bg, 5%); @@ -160,7 +160,7 @@ @btn-info-bg: @brand-info; @btn-info-border: darken(@btn-info-bg, 5%); -@btn-warning-color: @brand-primary; +@btn-warning-color: @brand-warning; @btn-warning-bg: @brand-warning; @btn-warning-border: darken(@btn-warning-bg, 5%); From 65cc50f2fa1ee1f4123ad119762d7b722f1c4296 Mon Sep 17 00:00:00 2001 From: Berkeley Martinez Date: Mon, 11 Jan 2016 18:05:16 -0800 Subject: [PATCH 31/65] Use base color for btn:hover color --- client/less/lib/bootstrap/mixins/buttons.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/less/lib/bootstrap/mixins/buttons.less b/client/less/lib/bootstrap/mixins/buttons.less index c8289d0cd8..9714cc206b 100755 --- a/client/less/lib/bootstrap/mixins/buttons.less +++ b/client/less/lib/bootstrap/mixins/buttons.less @@ -15,7 +15,7 @@ &.active, .open > .dropdown-toggle& { color: @gray-lighter; - background-color: lighten(@background, 10%); + background-color: @background; border-color: darken(@border, 12%); } &:active, From 57507d84f5550a300f6dada7fa44045dcab42b7f Mon Sep 17 00:00:00 2001 From: Berkeley Martinez Date: Mon, 11 Jan 2016 18:05:42 -0800 Subject: [PATCH 32/65] Re-add btn classes to account page --- server/views/account/show.jade | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/server/views/account/show.jade b/server/views/account/show.jade index aee51db2df..f0734fc2e9 100644 --- a/server/views/account/show.jade +++ b/server/views/account/show.jade @@ -246,29 +246,29 @@ block content h1.text-center Manage your account hr .col-xs-12 - a.btn.btn-lg.btn-block.btn-primary.btn-primary-ghost.btn-link-social(href='/logout') + a.btn.btn-lg.btn-block.btn-warning.btn-link-social(href='/logout') span.ion-android-exit | Sign me out of Free Code Camp .col-xs-12 - a.btn.btn-lg.btn-block.btn-primary.btn-primary-ghost.btn-link-social(href='mailto:team@freecodecamp.com') + a.btn.btn-lg.btn-block.btn-primary.btn-link-social(href='mailto:team@freecodecamp.com') span.ion-email | Email us at team@freecodecamp.com if (!user.isLocked) .col-xs-12 - a.btn.btn-lg.btn-block.btn-primary.btn-primary-ghost.btn-link-social(href='/toggle-lockdown-mode') + a.btn.btn-lg.btn-block.btn-info.btn-link-social(href='/toggle-lockdown-mode') span.ion-locked | Hide all my solutions from other people br | (this will disable your certificates) else .col-xs-12 - a.btn.btn-lg.btn-block.btn-primary.btn-primary-ghost.btn-link-social(href='/toggle-lockdown-mode') + a.btn.btn-lg.btn-block.btn-info.btn-link-social(href='/toggle-lockdown-mode') span.ion-unlocked | Let other people see all my solutions br | (this will enable your certificates) .col-xs-12 - a.btn.btn-lg.btn-block.btn-primary.btn-primary-ghost.btn-link-social(href='/commit') + a.btn.btn-lg.btn-block.btn-success.btn-link-social(href='/commit') span.ion-edit | Edit my pledge .col-xs-12 From 5798537bcbae60357be449c0d3bb6c19f121c678 Mon Sep 17 00:00:00 2001 From: Berkeley Martinez Date: Mon, 11 Jan 2016 22:47:49 -0800 Subject: [PATCH 33/65] Abstract map and showChallenge logic Rename some legacy naming conventions Remove logic for waypoint,basejumps, etc... --- server/boot/challenge.js | 32 ++---- server/views/challengeMap/show.jade | 58 ---------- server/views/map/show.jade | 169 ++++++---------------------- 3 files changed, 45 insertions(+), 214 deletions(-) delete mode 100644 server/views/challengeMap/show.jade diff --git a/server/boot/challenge.js b/server/boot/challenge.js index 5422711956..9b81e6801c 100644 --- a/server/boot/challenge.js +++ b/server/boot/challenge.js @@ -189,15 +189,6 @@ function getRenderData$(user, challenge$, origChallengeName, solution) { }); } -function getCompletedChallengeIds(user = {}) { - // if user - // get the id's of all the users completed challenges - return !user.completedChallenges ? - [] : - _.uniq(user.completedChallenges) - .map(({ id, _id }) => id || _id); -} - // create a stream of an array of all the challenge blocks function getSuperBlocks$(challenge$, completedChallenges) { return challenge$ @@ -415,19 +406,7 @@ module.exports = function(app) { function showChallenge(req, res, next) { const solution = req.query.solution; - const completedChallenges = getCompletedChallengeIds(req.user); - - Observable.combineLatest( - getRenderData$(req.user, challenge$, req.params.challengeName, solution), - getSuperBlocks$(challenge$, completedChallenges), - ({ data, ...rest }, superBlocks) => ({ - ...rest, - data: { - ...data, - superBlocks - } - }) - ) + getRenderData$(req.user, challenge$, req.params.challengeName, solution) .subscribe( ({ type, redirectUrl, message, data }) => { if (message) { @@ -573,9 +552,14 @@ module.exports = function(app) { ); } - function showMap({ user }, res, next) { + 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); - getSuperBlocks$(challenge$, getCompletedChallengeIds(user)) + getSuperBlocks$(challenge$, completedChallenges) .subscribe( superBlocks => { res.render('map/show', { diff --git a/server/views/challengeMap/show.jade b/server/views/challengeMap/show.jade deleted file mode 100644 index 3e08c5e801..0000000000 --- a/server/views/challengeMap/show.jade +++ /dev/null @@ -1,58 +0,0 @@ -extends ../layout-wide -block content - .col-xs-12.col-sm-4.col-sm-offset-8 - for superBlock, index in superBlocks - for challengeBlock in superBlock.blocks - h4.bold #{challengeBlock.name} (#{challengeBlock.time}) - for challenge in challengeBlock.challenges - if challenge.completed - p.text-primary.ion-checkmark-circled.padded-ionic-icon.negative-15(name="#{challenge.dashedName}")   - a(href="/challenges/#{challenge.dashedName}") - = challenge.title - span.sr-only= " Complete" - else - if challenge.type === "bonfire" - p.ion-asterisk.padded-ionic-icon.negative-15(name="#{challenge.dashedName}")   - a(name="#{challenge.dashedName}" href="/challenges/#{challenge.dashedName}" class=challenge.isComingSoon ? 'disabled' : '') - span= challenge.title - span.sr-only= " Incomplete" - if challenge.markNew - span.text-success.small     - strong - em New - if challengeBlock.isComingSoon - span.text-success.small     - strong - em Coming Soon - else - p.ion-ios-circle-outline.padded-ionic-icon.negative-15(name="#{challenge.dashedName}")   - a(name="#{challenge.dashedName}" href="/challenges/#{challenge.dashedName}" class=challenge.isComingSoon ? 'disabled' : '') - span= challenge.title - span.sr-only= " Incomplete" - if challenge.markNew - span.text-success.small     - strong - em New - if challengeBlock.isComingSoon - span.text-success.small     - strong - em Coming Soon - if (index < superBlocks.length) - hr - - script. - var username = !{JSON.stringify(user && user.username || '')}; - var lastCompleted = !{JSON.stringify(lastCompleted || false)} - $(document).ready(function () { - if (!localStorage || !localStorage.hideRedditNotice) { - $("#map-notice").removeClass("hidden"); - } - $("#hide-map-notice-button").on("click", function(e) { - e.preventDefault(); - $("#map-notice").addClass('animated fadeOut'); - setTimeout(function() { - $("#map-notice").hide(); - }, 1000); - localStorage.hideRedditNotice = "true"; - }); - }); diff --git a/server/views/map/show.jade b/server/views/map/show.jade index 6d41cbdd70..3e08c5e801 100644 --- a/server/views/map/show.jade +++ b/server/views/map/show.jade @@ -1,137 +1,42 @@ extends ../layout-wide block content - .row - .col-xs-12.col-md-6.col-md-offset-3 - ul - for superBlock in superBlocks - h2= superBlock.name - for challengeBlock in superBlock.blocks - .row - if (user) - .col-xs-11.col-sm-8.col-md-9 - li.map-p.negative-10 - |    - a(href='#' + challengeBlock.dashedName)= challengeBlock.name - if challengeBlock.markNew - span.text-info.small     - strong - em NEW - if challengeBlock.isComingSoon - span.text-info.small     - strong - em Coming Soon - else - .hidden-xs.col-sm-3.col-md-2 - .col-xs-10.col-sm-8.col-md-9 - span.map-p.negative-10 - a(href='#' + challengeBlock.dashedName)= challengeBlock.name - if challengeBlock.markNew - span.text-info.small     - strong - em NEW - if challengeBlock.isComingSoon - span.text-info.small     - strong - em Coming Soon - h2 Full Stack Development Certification - .row - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 - |    - span.ion-locked.padded-ionic-icon - | Greenfield Nonprofit Project 1 - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 - |    - span.ion-locked.padded-ionic-icon - | Greenfield Nonprofit Project 2 - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 - |    - span.ion-locked.padded-ionic-icon - | Legacy Nonprofit Project 1 - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 - |    - span.ion-locked.padded-ionic-icon - | Legacy Nonprofit Project 2 - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 - |    - span.ion-locked.padded-ionic-icon - | Claim your Full Stack Development Certification - - h2 Coding Interview Preparation - .row - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 - |    - span.ion-locked.padded-ionic-icon - | Whiteboard Coding Interview Training - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 - |    - span.ion-locked.padded-ionic-icon - | Critical Thinking Interview Training - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 - |    - span.ion-locked.padded-ionic-icon - | Mock Interview 1 - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 - |    - span.ion-locked.padded-ionic-icon - | Mock Interview 2 - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 - |    - span.ion-locked.padded-ionic-icon - | Mock Interview 3 - hr - .row - .col-xs-12.col-md-6.col-md-offset-3 - for superBlock, index in superBlocks - for challengeBlock in superBlock.blocks - .row - a(href='#' name=challengeBlock.dashedName) - .spacer.negative-55 - .row - h4.bold #{challengeBlock.name} (#{challengeBlock.time}) - for challenge in challengeBlock.challenges - - .col-xs-12.col-sm-9.col-md-10 - if challenge.completed - p.text-primary.ion-checkmark-circled.padded-ionic-icon.negative-15(name="#{challenge.dashedName}")   - a(href="/challenges/#{challenge.dashedName}") - = challenge.title - span.sr-only= " Complete" - else if (challenge.type === "bonfire") - p.ion-asterisk.padded-ionic-icon.negative-15(name="#{challenge.dashedName}")   - a(name="#{challenge.dashedName}" href="/challenges/#{challenge.dashedName}" class=challenge.isComingSoon ? 'disabled' : '') - span= challenge.title - span.sr-only= " Incomplete" - if challenge.markNew - span.text-success.small     - strong - em New - if challengeBlock.isComingSoon - span.text-success.small     - strong - em Coming Soon - else - p.ion-ios-circle-outline.padded-ionic-icon.negative-15(name="#{challenge.dashedName}")   - a(name="#{challenge.dashedName}" href="/challenges/#{challenge.dashedName}" class=challenge.isComingSoon ? 'disabled' : '') - span= challenge.title - span.sr-only= " Incomplete" - if challenge.markNew - span.text-success.small     - strong - em New - if challengeBlock.isComingSoon - span.text-success.small     - strong - em Coming Soon + .col-xs-12.col-sm-4.col-sm-offset-8 + for superBlock, index in superBlocks + for challengeBlock in superBlock.blocks + h4.bold #{challengeBlock.name} (#{challengeBlock.time}) + for challenge in challengeBlock.challenges + if challenge.completed + p.text-primary.ion-checkmark-circled.padded-ionic-icon.negative-15(name="#{challenge.dashedName}")   + a(href="/challenges/#{challenge.dashedName}") + = challenge.title + span.sr-only= " Complete" + else + if challenge.type === "bonfire" + p.ion-asterisk.padded-ionic-icon.negative-15(name="#{challenge.dashedName}")   + a(name="#{challenge.dashedName}" href="/challenges/#{challenge.dashedName}" class=challenge.isComingSoon ? 'disabled' : '') + span= challenge.title + span.sr-only= " Incomplete" + if challenge.markNew + span.text-success.small     + strong + em New + if challengeBlock.isComingSoon + span.text-success.small     + strong + em Coming Soon + else + p.ion-ios-circle-outline.padded-ionic-icon.negative-15(name="#{challenge.dashedName}")   + a(name="#{challenge.dashedName}" href="/challenges/#{challenge.dashedName}" class=challenge.isComingSoon ? 'disabled' : '') + span= challenge.title + span.sr-only= " Incomplete" + if challenge.markNew + span.text-success.small     + strong + em New + if challengeBlock.isComingSoon + span.text-success.small     + strong + em Coming Soon if (index < superBlocks.length) hr From cc1c2e6aa157c9121b96b0e880587e5bb5885e94 Mon Sep 17 00:00:00 2001 From: Berkeley Martinez Date: Tue, 12 Jan 2016 22:26:19 -0800 Subject: [PATCH 34/65] Add map aside to challenges --- server/boot/challenge.js | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/server/boot/challenge.js b/server/boot/challenge.js index 9b81e6801c..5422711956 100644 --- a/server/boot/challenge.js +++ b/server/boot/challenge.js @@ -189,6 +189,15 @@ function getRenderData$(user, challenge$, origChallengeName, solution) { }); } +function getCompletedChallengeIds(user = {}) { + // if user + // get the id's of all the users completed challenges + return !user.completedChallenges ? + [] : + _.uniq(user.completedChallenges) + .map(({ id, _id }) => id || _id); +} + // create a stream of an array of all the challenge blocks function getSuperBlocks$(challenge$, completedChallenges) { return challenge$ @@ -406,7 +415,19 @@ module.exports = function(app) { function showChallenge(req, res, next) { const solution = req.query.solution; - getRenderData$(req.user, challenge$, req.params.challengeName, solution) + const completedChallenges = getCompletedChallengeIds(req.user); + + Observable.combineLatest( + getRenderData$(req.user, challenge$, req.params.challengeName, solution), + getSuperBlocks$(challenge$, completedChallenges), + ({ data, ...rest }, superBlocks) => ({ + ...rest, + data: { + ...data, + superBlocks + } + }) + ) .subscribe( ({ type, redirectUrl, message, data }) => { if (message) { @@ -552,14 +573,9 @@ module.exports = function(app) { ); } - 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); + function showMap({ user }, res, next) { - getSuperBlocks$(challenge$, completedChallenges) + getSuperBlocks$(challenge$, getCompletedChallengeIds(user)) .subscribe( superBlocks => { res.render('map/show', { From 56a7d0365822a0079485f39346ced68ee560bb56 Mon Sep 17 00:00:00 2001 From: Berkeley Martinez Date: Tue, 12 Jan 2016 23:19:00 -0800 Subject: [PATCH 35/65] Add back map overview to map page --- server/views/map/show.jade | 169 +++++++++++++++++++++++++++++-------- 1 file changed, 132 insertions(+), 37 deletions(-) diff --git a/server/views/map/show.jade b/server/views/map/show.jade index 3e08c5e801..6d41cbdd70 100644 --- a/server/views/map/show.jade +++ b/server/views/map/show.jade @@ -1,42 +1,137 @@ extends ../layout-wide block content - .col-xs-12.col-sm-4.col-sm-offset-8 - for superBlock, index in superBlocks - for challengeBlock in superBlock.blocks - h4.bold #{challengeBlock.name} (#{challengeBlock.time}) - for challenge in challengeBlock.challenges - if challenge.completed - p.text-primary.ion-checkmark-circled.padded-ionic-icon.negative-15(name="#{challenge.dashedName}")   - a(href="/challenges/#{challenge.dashedName}") - = challenge.title - span.sr-only= " Complete" - else - if challenge.type === "bonfire" - p.ion-asterisk.padded-ionic-icon.negative-15(name="#{challenge.dashedName}")   - a(name="#{challenge.dashedName}" href="/challenges/#{challenge.dashedName}" class=challenge.isComingSoon ? 'disabled' : '') - span= challenge.title - span.sr-only= " Incomplete" - if challenge.markNew - span.text-success.small     - strong - em New - if challengeBlock.isComingSoon - span.text-success.small     - strong - em Coming Soon - else - p.ion-ios-circle-outline.padded-ionic-icon.negative-15(name="#{challenge.dashedName}")   - a(name="#{challenge.dashedName}" href="/challenges/#{challenge.dashedName}" class=challenge.isComingSoon ? 'disabled' : '') - span= challenge.title - span.sr-only= " Incomplete" - if challenge.markNew - span.text-success.small     - strong - em New - if challengeBlock.isComingSoon - span.text-success.small     - strong - em Coming Soon + .row + .col-xs-12.col-md-6.col-md-offset-3 + ul + for superBlock in superBlocks + h2= superBlock.name + for challengeBlock in superBlock.blocks + .row + if (user) + .col-xs-11.col-sm-8.col-md-9 + li.map-p.negative-10 + |    + a(href='#' + challengeBlock.dashedName)= challengeBlock.name + if challengeBlock.markNew + span.text-info.small     + strong + em NEW + if challengeBlock.isComingSoon + span.text-info.small     + strong + em Coming Soon + else + .hidden-xs.col-sm-3.col-md-2 + .col-xs-10.col-sm-8.col-md-9 + span.map-p.negative-10 + a(href='#' + challengeBlock.dashedName)= challengeBlock.name + if challengeBlock.markNew + span.text-info.small     + strong + em NEW + if challengeBlock.isComingSoon + span.text-info.small     + strong + em Coming Soon + h2 Full Stack Development Certification + .row + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 + |    + span.ion-locked.padded-ionic-icon + | Greenfield Nonprofit Project 1 + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 + |    + span.ion-locked.padded-ionic-icon + | Greenfield Nonprofit Project 2 + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 + |    + span.ion-locked.padded-ionic-icon + | Legacy Nonprofit Project 1 + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 + |    + span.ion-locked.padded-ionic-icon + | Legacy Nonprofit Project 2 + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 + |    + span.ion-locked.padded-ionic-icon + | Claim your Full Stack Development Certification + + h2 Coding Interview Preparation + .row + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 + |    + span.ion-locked.padded-ionic-icon + | Whiteboard Coding Interview Training + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 + |    + span.ion-locked.padded-ionic-icon + | Critical Thinking Interview Training + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 + |    + span.ion-locked.padded-ionic-icon + | Mock Interview 1 + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 + |    + span.ion-locked.padded-ionic-icon + | Mock Interview 2 + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 + |    + span.ion-locked.padded-ionic-icon + | Mock Interview 3 + hr + .row + .col-xs-12.col-md-6.col-md-offset-3 + for superBlock, index in superBlocks + for challengeBlock in superBlock.blocks + .row + a(href='#' name=challengeBlock.dashedName) + .spacer.negative-55 + .row + h4.bold #{challengeBlock.name} (#{challengeBlock.time}) + for challenge in challengeBlock.challenges + + .col-xs-12.col-sm-9.col-md-10 + if challenge.completed + p.text-primary.ion-checkmark-circled.padded-ionic-icon.negative-15(name="#{challenge.dashedName}")   + a(href="/challenges/#{challenge.dashedName}") + = challenge.title + span.sr-only= " Complete" + else if (challenge.type === "bonfire") + p.ion-asterisk.padded-ionic-icon.negative-15(name="#{challenge.dashedName}")   + a(name="#{challenge.dashedName}" href="/challenges/#{challenge.dashedName}" class=challenge.isComingSoon ? 'disabled' : '') + span= challenge.title + span.sr-only= " Incomplete" + if challenge.markNew + span.text-success.small     + strong + em New + if challengeBlock.isComingSoon + span.text-success.small     + strong + em Coming Soon + else + p.ion-ios-circle-outline.padded-ionic-icon.negative-15(name="#{challenge.dashedName}")   + a(name="#{challenge.dashedName}" href="/challenges/#{challenge.dashedName}" class=challenge.isComingSoon ? 'disabled' : '') + span= challenge.title + span.sr-only= " Incomplete" + if challenge.markNew + span.text-success.small     + strong + em New + if challengeBlock.isComingSoon + span.text-success.small     + strong + em Coming Soon if (index < superBlocks.length) hr From dad1e1638e811a5a19ed1578cea19a927b9dda66 Mon Sep 17 00:00:00 2001 From: Quincy Larson Date: Wed, 13 Jan 2016 02:27:08 -0600 Subject: [PATCH 36/65] surface isRequired in view --- server/boot/challenge.js | 1 + server/views/partials/challenge-footer.jade | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/server/boot/challenge.js b/server/boot/challenge.js index 5422711956..0b9beb449e 100644 --- a/server/boot/challenge.js +++ b/server/boot/challenge.js @@ -223,6 +223,7 @@ function getSuperBlocks$(challenge$, completedChallenges) { }, 0); const isBeta = _.every(blockArray, 'isBeta'); const isComingSoon = _.every(blockArray, 'isComingSoon'); + const isRequired = _.every(blockArray, 'isRequired'); return { isBeta, diff --git a/server/views/partials/challenge-footer.jade b/server/views/partials/challenge-footer.jade index 080b61a409..c18450ef11 100644 --- a/server/views/partials/challenge-footer.jade +++ b/server/views/partials/challenge-footer.jade @@ -21,11 +21,14 @@ aside.map-aside.is-collapsed = challenge.title span.sr-only= " Complete" else - if challenge.type === "bonfire" - p.ion-asterisk.padded-ionic-icon.negative-15(name="#{challenge.dashedName}")   + if challenge.isRequired + p.ion-ios-circle-outline.negative-15(name="#{challenge.dashedName}")   a(name="#{challenge.dashedName}" href="/challenges/#{challenge.dashedName}" class=challenge.isComingSoon ? 'disabled' : '') span= challenge.title - span.sr-only= " Incomplete" + span.text-primary.small     + strong + em Required + span.sr-only= " Incomplete" if challenge.markNew span.text-success.small     strong From 97b614e467189ab71b76f7b044b5497f678db7b7 Mon Sep 17 00:00:00 2001 From: Quincy Larson Date: Wed, 13 Jan 2016 02:32:50 -0600 Subject: [PATCH 37/65] improve look of buttons and layout on portfolio view --- server/views/account/show.jade | 70 +--------------------------------- 1 file changed, 1 insertion(+), 69 deletions(-) diff --git a/server/views/account/show.jade b/server/views/account/show.jade index f0734fc2e9..7ac0476420 100644 --- a/server/views/account/show.jade +++ b/server/views/account/show.jade @@ -31,7 +31,7 @@ block content a.btn.btn-lg.btn-block.btn-google-plus.btn-link-social(href='/link/google') i.fa.fa-google-plus | Add my Google+ to my portfolio - + .spacer h1.text-center #{username}'s code portfolio hr .row @@ -121,7 +121,6 @@ block content h4.col-sm-6.text-left Current Streak: #{currentStreak} #{currentStreak === 1 ? ' day' : ' days'} ->>>>>>> start simplifying views if (user && user.username == username || !isLocked) if (baseAndZip.length > 0) .col-sm-12 @@ -179,8 +178,6 @@ block content else a(href='/challenges/' + challenge.name)= challenge.name if (user && user.username === username) -<<<<<<< de95f0e0f31aab3c70ef4fd51fd6a12b438da754 -<<<<<<< b157fa3095437bb5d39b91e23581589744f6aca0 .panel.panel-info .panel-heading.text-center Manage your account .panel-body @@ -240,68 +237,3 @@ block content button.btn.btn-danger.btn-block(type='submit') span.ion-trash-b | I am 100% sure I want to delete my account and all of my progress -======= -======= ->>>>>>> start simplifying views - h1.text-center Manage your account - hr - .col-xs-12 - a.btn.btn-lg.btn-block.btn-warning.btn-link-social(href='/logout') - span.ion-android-exit - | Sign me out of Free Code Camp - .col-xs-12 - a.btn.btn-lg.btn-block.btn-primary.btn-link-social(href='mailto:team@freecodecamp.com') - span.ion-email - | Email us at team@freecodecamp.com - if (!user.isLocked) - .col-xs-12 - a.btn.btn-lg.btn-block.btn-info.btn-link-social(href='/toggle-lockdown-mode') - span.ion-locked - | Hide all my solutions from other people - br - | (this will disable your certificates) - else - .col-xs-12 - a.btn.btn-lg.btn-block.btn-info.btn-link-social(href='/toggle-lockdown-mode') - span.ion-unlocked - | Let other people see all my solutions - br - | (this will enable your certificates) - .col-xs-12 - a.btn.btn-lg.btn-block.btn-success.btn-link-social(href='/commit') - span.ion-edit - | Edit my pledge - .col-xs-12 - a.btn.btn-lg.btn-block.btn-danger.btn-link-social.confirm-deletion - span.ion-trash-b - | Delete my Free Code Camp account - script. - $('.confirm-deletion').on("click", function () { - $('#modal-dialog').modal('show'); - }); - #modal-dialog.modal.animated.wobble - .modal-dialog - .modal-content - .modal-header - a.close(href='#', data-dismiss='modal', aria-hidden='true') × - h3 You don't really want to delete your account, do you? - .modal-body - p This will really delete all your data, including all your progress, news stories and brownie points. - p We won't be able to recover any of it for you later, even if you change your mind. - p If there's something we could do better, send us an email instead and we'll do our best:   - a(href="mailto:team@freecodecamp.com") team@freecodecamp.com - | . - .modal-footer - a.btn.btn-success.btn-block(href='#', data-dismiss='modal', aria-hidden='true') - span.ion-happy - | Nevermind, I don't want to delete all of my progress - .spacer - form(action='/account/delete', method='POST') - input(type='hidden', name='_csrf', value=_csrf) - button.btn.btn-danger.btn-block(type='submit') - span.ion-trash-b - | I am 100% sure I want to delete my account and all of my progress -<<<<<<< de95f0e0f31aab3c70ef4fd51fd6a12b438da754 ->>>>>>> start simplifying views -======= ->>>>>>> start simplifying views From 6d23e4931ba0cd84c99c526d5b7fe5cca7056885 Mon Sep 17 00:00:00 2001 From: Quincy Larson Date: Wed, 13 Jan 2016 15:37:00 -0600 Subject: [PATCH 38/65] update privacy, terms, code of conduct and add links to about page --- server/boot/randomAPIs.js | 26 +- server/views/resources/about.jade | 290 ++++++++++--------- server/views/resources/code-of-conduct.jade | 30 ++ server/views/resources/privacy.jade | 34 +++ server/views/resources/terms-of-service.jade | 43 +++ 5 files changed, 276 insertions(+), 147 deletions(-) create mode 100644 server/views/resources/code-of-conduct.jade create mode 100644 server/views/resources/privacy.jade create mode 100644 server/views/resources/terms-of-service.jade diff --git a/server/boot/randomAPIs.js b/server/boot/randomAPIs.js index 95b6997aee..12e141cea2 100644 --- a/server/boot/randomAPIs.js +++ b/server/boot/randomAPIs.js @@ -36,7 +36,9 @@ module.exports = function(app) { router.get('/stories', showTestimonials); router.get('/all-stories', showAllTestimonials); router.get('/about', showAbout); - router.get('/terms-and-privacy', termsAndPrivacy); + router.get('/terms', terms); + router.get('/privacy', privacy); + router.get('/code-of-conduct', codeOfConduct); router.get( '/the-fastest-web-page-on-the-internet', theFastestWebPageOnTheInternet @@ -203,11 +205,23 @@ module.exports = function(app) { }); } - function termsAndPrivacy(req, res) { - res.render('resources/terms-and-privacy', { - title: 'Terms of Service, Privacy Policy, and Code of Conduct' - }); - } + function terms(req, res) { + res.render('resources/terms-of-service', { + title: 'Terms of Service' + }); + } + + function privacy(req, res) { + res.render('resources/privacy', { + title: 'Privacy' + }); + } + + function codeOfConduct(req, res) { + res.render('resources/code-of-conduct', { + title: 'Code of Conduct' + }); + } function theFastestWebPageOnTheInternet(req, res) { res.render('resources/the-fastest-web-page-on-the-internet', { diff --git a/server/views/resources/about.jade b/server/views/resources/about.jade index 1478740876..11615bc177 100644 --- a/server/views/resources/about.jade +++ b/server/views/resources/about.jade @@ -1,146 +1,154 @@ extends ../layout block content .col-xs-12 - .panel.panel-info - .panel-body - h2.text-center We're an open source community of people - br - | who learn to code and help nonprofits. + h2.text-center We're an open source community of people + br + | who learn to code and help nonprofits. + .spacer + .row + .col-xs-12.col-sm-10.col-sm-offset-1.col-md-6.col-md-offset-3 + h2 Free Code Camp around the web: + table.table.link-table + tr + td.text-right + .ion-speakerphone + td + a(href='//medium.freecodecamp.com', target='_blank') Medium Publication + tr + td.text-right + .ion-social-github + td + a(href="//github.com/freecodecamp", target='_blank') GitHub Repository + tr + td.text-right + .ion-social-reddit + td + a(href="//www.reddit.com/r/freecodecamp", target='_blank') Subreddit + tr + td.text-right + .ion-social-linkedin + td + a(href="//www.linkedin.com/edu/school?id=166029", target='_blank') LinkedIn University Page + tr + td.text-right + .ion-social-twitter + td + a(href="//twitter.com/freecodecamp", target='_blank') Twitter Feed + tr + td.text-right + .ion-social-facebook + td + a(href="//facebook.com/freecodecamp") Facebook Page + tr + td.text-right + .ion-social-twitch-outline + td + a(href="//twitch.tv/freecodecamp", target='_blank') Twitch.tv Channel .spacer - .row - .col-xs-12.col-sm-10.col-sm-offset-1.col-md-6.col-md-offset-3 - h2 Free Code Camp around the web: - table.table.link-table - tr - td.text-right - .ion-speakerphone - td - a(href='//medium.freecodecamp.com', target='_blank') Medium Publication - tr - td.text-right - .ion-social-github - td - a(href="//github.com/freecodecamp", target='_blank') GitHub Repository - tr - td.text-right - .ion-social-reddit - td - a(href="//www.reddit.com/r/freecodecamp", target='_blank') Subreddit - tr - td.text-right - .ion-social-linkedin - td - a(href="//www.linkedin.com/edu/school?id=166029", target='_blank') LinkedIn University Page - tr - td.text-right - .ion-social-twitter - td - a(href="//twitter.com/freecodecamp", target='_blank') Twitter Feed - tr - td.text-right - .ion-social-facebook - td - a(href="//facebook.com/freecodecamp") Facebook Page - tr - td.text-right - .ion-social-twitch-outline - td - a(href="//twitch.tv/freecodecamp", target='_blank') Twitch.tv Channel - .spacer - h2 Other useful links: - table.table.link-table - tr - td.text-right - .ion-locked - td - a(href="/terms-and-privacy") Our Privacy Policy, Terms of Service and Code of Conduct - tr - td.text-right - .ion-erlenmeyer-flask - td - a(href="/labs") Extra-curricular Apps Built by Campers - tr - td.text-right - .ion-chatbox - td - a(href="/stories") Stories from campers who've become professional developers - .spacer - h2 Which camper to contact for: - table.table.table-stripe - tr - td Support (team@freecodecamp.com) - td - a(href='https://gitter.im/QuincyLarson' target='_blank') @QuincyLarson - tr - td Facebook page - td - a(href='https://gitter.im/QuincyLarson' target='_blank') @QuincyLarson - tr - td Twitter feed - td - a(href='https://gitter.im/QuincyLarson' target='_blank') @QuincyLarson - tr - td Medium publication - td - a(href='https://gitter.im/QuincyLarson' target='_blank') @QuincyLarson - tr - td Media inquiries - td - a(href='https://gitter.im/QuincyLarson' target='_blank') @QuincyLarson - tr - td Open source codebase contributions - td - a(href='https://gitter.im/BerkeleyTrue' target='_blank') @BerkeleyTrue - tr - td Server problems - td - a(href='https://gitter.im/BerkeleyTrue' target='_blank') @BerkeleyTrue - tr - td Nonprofit projects - td - a(href='https://gitter.im/CodeNonprofit' target='_blank') @CodeNonprofit - tr - td Volunteer agile project managers - td - a(href='https://gitter.im/CodeNonprofit' target='_blank') @CodeNonprofit - tr - td Commit program - td - a(href='https://gitter.im/CodeNonprofit' target='_blank') @CodeNonprofit - tr - td Hikes curriculum - td - a(href='https://gitter.im/BrianaMarie' target='_blank') @BrianaMarie - tr - td JavaScript curriculum - td - a(href='https://gitter.im/SaintPeter' target='_blank') @SaintPeter - tr - td Data Science and Open Data - td - a(href='https://gitter.im/Evaristoc' target='_blank') @Evaristoc - tr - td CamperBot - td - a(href='https://gitter.im/LTegman' target='_blank') @LTegman - tr - td Twitch.tv channel - td - a(href='https://gitter.im/Septimus' target='_blank') @Septimus - tr - td Youtube channel - td - a(href='https://gitter.im/Septimus' target='_blank') @Septimus - tr - td Translation and Internationalization - td - a(href='https://gitter.im/Vtamara' target='_blank') @Vtamara - tr - td Wiki - td - a(href='https://gitter.im/Rafase282' target='_blank') @Rafase282 - tr - td Campsites - td - a(href='https://gitter.im/Hallaathrad' target='_blank') @Hallaathrad + h2 Other useful links: + table.table.link-table + tr + td.text-right + .ion-erlenmeyer-flask + td + a(href="/labs") Extra-curricular apps built by campers + tr + td.text-right + .ion-chatbox + td + a(href="/stories") Stories from campers who've become professional developers + tr + td.text-right + .ion-locked + td + a(href="/privacy") Our privacy policy + tr + td.text-right + .ion-happy-outline + td + a(href="/code-of-conduct") Our code of conduct + tr + td.text-right + .ion-document-text + td + a(href="/terms") Our terms of service + .spacer + h2 Which camper to contact for: + table.table.table-stripe + tr + td Support (team@freecodecamp.com) + td + a(href='https://gitter.im/QuincyLarson' target='_blank') @QuincyLarson + tr + td Facebook page + td + a(href='https://gitter.im/QuincyLarson' target='_blank') @QuincyLarson + tr + td Twitter feed + td + a(href='https://gitter.im/QuincyLarson' target='_blank') @QuincyLarson + tr + td Medium publication + td + a(href='https://gitter.im/QuincyLarson' target='_blank') @QuincyLarson + tr + td Media inquiries + td + a(href='https://gitter.im/QuincyLarson' target='_blank') @QuincyLarson + tr + td Open source codebase contributions + td + a(href='https://gitter.im/BerkeleyTrue' target='_blank') @BerkeleyTrue + tr + td Server problems + td + a(href='https://gitter.im/BerkeleyTrue' target='_blank') @BerkeleyTrue + tr + td Nonprofit projects + td + a(href='https://gitter.im/CodeNonprofit' target='_blank') @CodeNonprofit + tr + td Volunteer agile project managers + td + a(href='https://gitter.im/CodeNonprofit' target='_blank') @CodeNonprofit + tr + td Commit program + td + a(href='https://gitter.im/CodeNonprofit' target='_blank') @CodeNonprofit + tr + td Hikes curriculum + td + a(href='https://gitter.im/BrianaMarie' target='_blank') @BrianaMarie + tr + td JavaScript curriculum + td + a(href='https://gitter.im/SaintPeter' target='_blank') @SaintPeter + tr + td Data Science and Open Data + td + a(href='https://gitter.im/Evaristoc' target='_blank') @Evaristoc + tr + td CamperBot + td + a(href='https://gitter.im/LTegman' target='_blank') @LTegman + tr + td Twitch.tv channel + td + a(href='https://gitter.im/Septimus' target='_blank') @Septimus + tr + td Youtube channel + td + a(href='https://gitter.im/Septimus' target='_blank') @Septimus + tr + td Translation and Internationalization + td + a(href='https://gitter.im/Vtamara' target='_blank') @Vtamara + tr + td Wiki + td + a(href='https://gitter.im/Rafase282' target='_blank') @Rafase282 + tr + td Campsites + td + a(href='https://gitter.im/Hallaathrad' target='_blank') @Hallaathrad diff --git a/server/views/resources/code-of-conduct.jade b/server/views/resources/code-of-conduct.jade new file mode 100644 index 0000000000..4fd01f03ad --- /dev/null +++ b/server/views/resources/code-of-conduct.jade @@ -0,0 +1,30 @@ +extends ../layout +block content + .col-xs-12.col-sm-8.col-sm-offset-2.col-md-6.col-md-offset-3 + h1.text-center Code of Conduct + hr + p + | Free Code Camp is friendly place to learn to code. We’re committed to keeping it that way. + p + | All campers are required to agree with the following code of conduct. We’ll enforce this code. We’re expecting cooperation from all campers in ensuring a friendly environment for everybody. + p In short: be nice to your fellow campers. + p Remember these 3 things and your fellow campers will like you: + ol + li Compliment your fellow campers when they do good work. Congratulate them when they accomplish something (like completing one of our certifications or getting a job). + li Critique the work, not the camper doing it. + li Only argue about something if it’s important to the greater discussion. + p + | Free Code Camp should be a harassment-free experience for everyone, regardless of gender, gender identity and expression, age, sexual orientation, disability, physical appearance, body size, race, national origin, or religion (or lack thereof). + p + | We do not tolerate harassment of campers in any form, anywhere on Free Code Camp’s online media (Gitter, Twitch, Facebook, etc.) or during pair programming. Harassment includes sexual language and imagery, deliberate intimidation, stalking, unwelcome sexual attention, libel, and any malicious hacking or social engineering. + p + | If a camper engages in harassing behavior, our team will take any action we deem appropriate, up to and including banning them from Free Code Camp. + p + | No bots are allowed in any of the Official Chat Rooms without prior explicit permission from the FCC Core Team. + p + | We want everyone to feel safe and respected. If you are being harassed or notice that someone else is being harassed, say something! Go to our   + a(href='https://gitter.im/freecodecamp/admin' target='_blank') Admin room in Gitter + |   and explain what has happened where (preferably with a screen shot of the offending language) so we can take fast action. + p + | If you have questions about this code of conduct, email us at  + a(href='mailto:team@freecodecamp.com') team@freecodecamp.com diff --git a/server/views/resources/privacy.jade b/server/views/resources/privacy.jade new file mode 100644 index 0000000000..6f12dc9f38 --- /dev/null +++ b/server/views/resources/privacy.jade @@ -0,0 +1,34 @@ +extends ../layout +block content + .col-xs-12.col-sm-8.col-sm-offset-2.col-md-6.col-md-offset-3 + html. +

Privacy Policy

+
+

Your privacy is critically important to us. At Free Code Camp we have a few fundamental principles:

+
    +
  1. We don’t ask you for personal information unless we truly need it. (We can’t stand services that ask you for things like your gender or income level for no apparent reason.)
  2. +
  3. We don’t share your personal information with anyone except to comply with the law, develop our products, or protect our rights.
  4. +
  5. Unless you ask us not to (by clicking the button that says "hide all my solutions from other people" located on your code portfolio), we will share your solutions and progress with the public as part of our open data initiative. This is intended for academics and researchers to better understand Free Code Camp as an educational model.
  6. +
  7. We don’t store personal information on our servers unless required for the on-going operation of one of our services.
  8. +
  9. We aim to make it as simple as possible for you to control what’s visible to the public, seen by search engines, kept private, and permanently deleted. Below is our privacy policy which incorporates these goals
  10. +
+

If you have questions about deleting or correcting your personal data please email us at team@freecodecamp.com

+

Free Code Camp Inc. (“Free Code Camp”) operates several websites including FreeCodeCamp.com. It is Free Code Camp’s policy to respect your privacy regarding any information we may collect while operating our websites.

+

Website Visitors

+

Like most website operators, Free Code Camp collects non-personally-identifying information of the sort that web browsers and servers typically make available, such as the browser type, language preference, referring site, and the date and time of each visitor request. Free Code Camp’s purpose in collecting non-personally identifying information is to better understand how Free Code Camp’s visitors use its website. From time to time, Free Code Camp may release non-personally-identifying information in the aggregate, e.g., by publishing a report on trends in the usage of its website.

+

Free Code Camp also collects potentially personally-identifying information like Internet Protocol (IP) addresses for logged in users and for users leaving comments on FreeCodeCamp.com blogs. Free Code Camp only discloses logged in user and commenter IP addresses under the same circumstances that it uses and discloses personally-identifying information as described below, except that blog commenter IP addresses and email addresses are visible and disclosed to the administrators of the blog where the comment was left.

+

Gathering of Personally-Identifying Information

+

Many visitors to Free Code Camp’s websites choose to interact with Free Code Camp in ways that require Free Code Camp to gather personally-identifying information. The amount and type of information that Free Code Camp gathers depends on the nature of the interaction. For example, we ask visitors who create an account for tracking their progress at FreeCodeCamp.com to provide either an email address or sign in with a social media oauth service like GitHub. Those who engage in transactions with Free Code Camp – by placing job ads, for example – are asked to provide additional information, including as necessary the personal and financial information required to process those transactions. In each case, Free Code Camp collects such information only insofar as is necessary or appropriate to fulfill the purpose of the visitor’s interaction with Free Code Camp. Free Code Camp does not disclose personally-identifying information other than as described below. And visitors can always refuse to supply personally-identifying information, with the caveat that it may prevent them from engaging in certain website-related activities.

+

Aggregated Statistics

+

Free Code Camp may collect statistics about the behavior of visitors to its websites. For instance, Free Code Camp may monitor the accounts to try and identify spammers. Free Code Camp may display this information publicly or provide it to others. However, Free Code Camp does not disclose personally-identifying information other than as described below.

+

Protection of Certain Personally-Identifying Information

+

Free Code Camp discloses potentially personally-identifying and personally-identifying information only to those of its employees, contractors and affiliated organizations that (i) need to know that information in order to process it on Free Code Camp’s behalf or to provide services available at Free Code Camp’s websites, and (ii) that have agreed not to disclose it to others. Some of those employees, contractors and affiliated organizations may be located outside of your home country; by using Free Code Camp’s websites, you consent to the transfer of such information to them. Free Code Camp will not rent or sell potentially personally-identifying and personally-identifying information to anyone. Other than to its employees, contractors and affiliated organizations, as described above, Free Code Camp discloses potentially personally-identifying and personally-identifying information only in response to a subpoena, court order or other governmental request, or when Free Code Camp believes in good faith that disclosure is reasonably necessary to protect the property or rights of Free Code Camp, third parties or the public at large. If you are a registered user of an Free Code Camp website and have supplied your email address, Free Code Camp may occasionally send you an email to tell you about new features, solicit your feedback, or just keep you up to date with what’s going on with Free Code Camp and our products. We primarily use our various product blogs to communicate this type of information, so we expect to keep this type of email to a minimum. If you send us a request (for example via a support email or via one of our feedback mechanisms), we reserve the right to publish it in order to help us clarify or respond to your request or to help us support other users. Free Code Camp takes all measures reasonably necessary to protect against the unauthorized access, use, alteration or destruction of potentially personally-identifying and personally-identifying information.

+

Cookies

+

A cookie is a string of information that a website stores on a visitor’s computer, and that the visitor’s browser provides to the website each time the visitor returns. Free Code Camp uses cookies to help Free Code Camp identify and track visitors, their usage of Free Code Camp website, and their website access preferences. Free Code Camp visitors who do not wish to have cookies placed on their computers should set their browsers to refuse cookies before using Free Code Camp’s websites, with the drawback that certain features of Free Code Camp’s websites may not function properly without the aid of cookies.

+

Business Transfers

+

If Free Code Camp, or substantially all of its assets, were acquired, or in the unlikely event that Free Code Camp goes out of business or enters bankruptcy, user information would be one of the assets that is transferred or acquired by a third party. You acknowledge that such transfers may occur, and that any acquirer of Free Code Camp may continue to use your personal information as set forth in this policy.

+

Ads

+

If in the future we show ads, ads appearing on any of our websites may be delivered to users by advertising partners, who may set cookies. These cookies allow the ad server to recognize your computer each time they send you an online advertisement to compile information about you or others who use your computer. This information allows ad networks to, among other things, deliver targeted advertisements that they believe will be of most interest to you. This Privacy Policy covers the use of cookies by Free Code Camp and does not cover the use of cookies by any advertisers.

+

Privacy Policy Changes

+

Although most changes are likely to be minor, Free Code Camp may change its Privacy Policy from time to time, and in Free Code Camp’s sole discretion. Free Code Camp encourages visitors to frequently check this page for any changes to its Privacy Policy. If you have a FreeCodeCamp.com account, you should also check your blog’s dashboard for alerts to these changes. Your continued use of this site after any change in this Privacy Policy will constitute your acceptance of such change.

+

This privacy policy is adopted from the Automattic (Free Code Camp) open source terms and are subject to the Creative Commons Attribution-ShareAlike 4.0 International license. We thank them for making this available.

diff --git a/server/views/resources/terms-of-service.jade b/server/views/resources/terms-of-service.jade new file mode 100644 index 0000000000..8097452cd6 --- /dev/null +++ b/server/views/resources/terms-of-service.jade @@ -0,0 +1,43 @@ +extends ../layout +block content + .col-xs-12.col-sm-8.col-sm-offset-2.col-md-6.col-md-offset-3 + html. +

Terms of Service

+
+

The gist:

+

We (the folks that run Free Code Camp's open source community) would love for you to use it. Our community is free, and our service is designed to give you as much control and ownership over the code you write as possible, and encourage you to express yourself freely. However, be responsible in what you publish. In particular, make sure that none of the prohibited items (like spam, viruses, or serious threats of violence) appear on your website. If you find anything on Free Code Camp that you believe violates these Terms of Service, please email us at team@freecodecamp.com

+

Terms of Service:

+

The following terms and conditions govern all use of the FreeCodeCamp.com website and all content, services, and products available at or through the website - taken together, our Services. Our Services are offered subject to your acceptance without modification of all of the terms and conditions contained herein and all other operating rules, policies (including, without limitation, Free Code Camp's Privacy Policy) and procedures that may be published from time to time by Free Code Camp (collectively, the “Agreement”). You agree that we may automatically upgrade our Services, and these terms will apply to any upgrades. Your agreement is with Free Code Camp Inc. Please read this Agreement carefully before accessing or using our Services. By accessing or using any part of our services, you agree to become bound by the terms and conditions of this agreement. If you do not agree to all the terms and conditions of this agreement, then you may not access or use any of our services. If these terms and conditions are considered an offer by Free Code Camp, acceptance is expressly limited to these terms. Our Services are not directed to children younger than 13, and access and use of our Services is only offered to users 13 years of age or older. If you are under 13 years old, please do not register to use our Services. Any person who registers as a user or provides their personal information to our Services represents that they are 13 years of age or older. Use of some aspects of our Services may require a FreeCodeCamp.com account. You agree to provide us with complete and accurate information when you register for an account. You will be solely responsible and liable for any activity that occurs under your username. You are responsible for keeping your password secure.

+

1. FreeCodeCamp.com.

+
    +
  • Your FreeCodeCamp.com Account and Website. If you create a website on FreeCodeCamp.com, you are responsible for maintaining the security of your account and website, and you are fully responsible for all activities that occur under the account and any other actions taken in connection with the website. You must immediately notify Free Code Camp of any unauthorized uses of your website, your account, or any other breaches of security. Free Code Camp will not be liable for any acts or omissions by you, including any damages of any kind incurred as a result of such acts or omissions.
  • +
  • Responsibility of Contributors. If you operate a website, comment on a website, post material to FreeCodeCamp.com, post links on FreeCodeCamp.com, or otherwise make (or allow any third party to make) material available (any such material, “Content”), you are entirely responsible for the content of, and any harm resulting from, that Content or your conduct. That is the case regardless of what form the Content takes, which includes, but is not limited to text, photo, video, audio, or code. By using FreeCodeCamp.com, you represent and warrant that your Content and conduct do not violate these terms or the Code of Conduct. By submitting Content to Free Code Camp for inclusion on your website, you grant Free Code Camp a world-wide, royalty-free, and non-exclusive license to reproduce, modify, adapt and publish the Content solely for the purpose of displaying, distributing, and promoting your website. This license allows Free Code Camp to make publicly-posted content available to third parties selected by Free Code Camp (through the Free Code Camp Firehose, for example) so that these third parties can analyze and distribute (but not publicly display) your content through their services. You also give other FreeCodeCamp.com users permission to share your Content on other FreeCodeCamp.com websites and add their own Content to it (aka to reblog your Content), so long as they use only a portion of your post and they give you credit as the original author by linking back to your website (the reblogging function on FreeCodeCamp.com does this automatically!). If you delete Content, Free Code Camp will use reasonable efforts to remove it from FreeCodeCamp.com, but you acknowledge that caching or references to the Content may not be made immediately unavailable. Without limiting any of those representations or warranties, Free Code Camp has the right (though not the obligation) to, in Free Code Camp’s sole discretion, (i) refuse or remove any content that, in Free Code Camp’s reasonable opinion, violates any Free Code Camp policy or is in any way harmful or objectionable, or (ii) terminate or deny access to and use of FreeCodeCamp.com to any individual or entity for any reason. Free Code Camp will have no obligation to provide a refund of any amounts previously paid.
  • +
  • Attribution. Free Code Camp reserves the right to display attribution links such as ‘Website at FreeCodeCamp.com,’ theme author, and font attribution in your website footer or toolbar.
  • +
+

4. Responsibility of Visitors.

+

Free Code Camp has not reviewed, and cannot review, all of the material, including computer software, posted to our Services, and cannot therefore be responsible for that material’s content, use or effects. By operating our Services, Free Code Camp does not represent or imply that it endorses the material there posted, or that it believes such material to be accurate, useful, or non-harmful. You are responsible for taking precautions as necessary to protect yourself and your computer systems from viruses, worms, Trojan horses, and other harmful or destructive content. Our Services may contain content that is offensive, indecent, or otherwise objectionable, as well as content containing technical inaccuracies, typographical mistakes, and other errors. Our Services may also contain material that violates the privacy or publicity rights, or infringes the intellectual property and other proprietary rights, of third parties, or the downloading, copying or use of which is subject to additional terms and conditions, stated or unstated. Free Code Camp disclaims any responsibility for any harm resulting from the use by visitors of our Services, or from any downloading by those visitors of content there posted.

+

5. Content Posted on Other Websites.

+

We have not reviewed, and cannot review, all of the material, including computer software, made available through the websites and webpages to which FreeCodeCamp.com links, and that link to FreeCodeCamp.com. Free Code Camp does not have any control over those non-FreeCodeCamp.com websites, and is not responsible for their contents or their use. By linking to a non-FreeCodeCamp.com website, Free Code Camp does not represent or imply that it endorses such website. You are responsible for taking precautions as necessary to protect yourself and your computer systems from viruses, worms, Trojan horses, and other harmful or destructive content. Free Code Camp disclaims any responsibility for any harm resulting from your use of non-FreeCodeCamp.com websites and webpages.

+

6. Copyright Infringement and DMCA Policy.

+

As Free Code Camp asks others to respect its intellectual property rights, it respects the intellectual property rights of others. If you believe that material located on or linked to by FreeCodeCamp.com violates your copyright, you are encouraged to notify Free Code Camp in accordance with Free Code Camp’s Digital Millennium Copyright Act (“DMCA”) Policy. Free Code Camp will respond to all such notices, including as required or appropriate by removing the infringing material or disabling all links to the infringing material. Free Code Camp will terminate a visitor’s access to and use of the Website if, under appropriate circumstances, the visitor is determined to be a repeat infringer of the copyrights or other intellectual property rights of Free Code Camp or others.

+

7. Intellectual Property.

+

This Agreement does not transfer from Free Code Camp to you any Free Code Camp or third party intellectual property, and all right, title, and interest in and to such property will remain (as between the parties) solely with Free Code Camp. Free Code Camp, FreeCodeCamp.com, the FreeCodeCamp.com logo, and all other trademarks, service marks, graphics and logos used in connection with FreeCodeCamp.com or our Services, are trademarks or registered trademarks of Free Code Camp or Free Code Camp’s licensors. Other trademarks, service marks, graphics and logos used in connection with our Services may be the trademarks of other third parties. Your use of our Services grants you no right or license to reproduce or otherwise use any Free Code Camp or third-party trademarks.

+

10. Changes.

+

We are constantly updating our Services, and that means sometimes we have to change the legal terms under which our Services are offered. If we make changes that are material, we will let you know by posting on one of our websites, or by sending you an email or other communication before the changes take effect. The notice will designate a reasonable period of time after which the new terms will take effect. If you disagree with our changes, then you should stop using our Services within the designated notice period. Your continued use of our Services will be subject to the new terms. However, any dispute that arose before the changes shall be governed by the Terms (including the binding individual arbitration clause) that were in place when the dispute arose.

+

11. Termination.

+

Free Code Camp may terminate your access to all or any part of our Services at any time, with or without cause, with or without notice, effective immediately. If you wish to terminate this Agreement or your FreeCodeCamp.com account (if you have one), you may simply discontinue using our Services. All provisions of this Agreement which by their nature should survive termination shall survive termination, including, without limitation, ownership provisions, warranty disclaimers, indemnity and limitations of liability.

+

12. Disclaimer of Warranties.

+

Our Services are provided “as is.” Free Code Camp and its suppliers and licensors hereby disclaim all warranties of any kind, express or implied, including, without limitation, the warranties of merchantability, fitness for a particular purpose and non-infringement. Neither Free Code Camp nor its suppliers and licensors, makes any warranty that our Services will be error free or that access thereto will be continuous or uninterrupted. If you’re actually reading this, we praise your diligence and concern. We'd be better off as a civilization if more people cared like you do. You understand that you download from, or otherwise obtain content or services through, our Services at your own discretion and risk.

+

13. Limitation of Liability.

+

In no event will Free Code Camp, or its suppliers or licensors, be liable with respect to any subject matter of this Agreement under any contract, negligence, strict liability or other legal or equitable theory for: (i) any special, incidental or consequential damages; (ii) the cost of procurement for substitute products or services; (iii) for interruption of use or loss or corruption of data; or (iv) for any amounts that exceed the fees paid by you to Free Code Camp under this agreement during the twelve (12) month period prior to the cause of action. Free Code Camp shall have no liability for any failure or delay due to matters beyond their reasonable control. The foregoing shall not apply to the extent prohibited by applicable law.

+

14. General Representation and Warranty.

+

You represent and warrant that (i) your use of our Services will be in strict accordance with the Free Code Camp Privacy Policy, with this Agreement, and with all applicable laws and regulations (including without limitation any local laws or regulations in your country, state, city, or other governmental area, regarding online conduct and acceptable content, and including all applicable laws regarding the transmission of technical data exported from the United States or the country in which you reside) and (ii) your use of our Services will not infringe or misappropriate the intellectual property rights of any third party.

+

15. US Economic Sanctions.

+

You expressly represent and warrant that your use of our Services and or associated services and products is not contrary to applicable U.S. Sanctions. Such use is prohibited, and Free Code Camp reserve the right to terminate accounts or access of those in the event of a breach of this condition.

+

16. Indemnification.

+

You agree to indemnify and hold harmless Free Code Camp, its contractors, and its licensors, and their respective directors, officers, employees, and agents from and against any and all claims and expenses, including attorneys’ fees, arising out of your use of our Services, including but not limited to your violation of this Agreement.

+

17. Translation.

+

These Terms of Service were originally written in English (US). We may translate these terms into other languages. In the event of a conflict between a translated version of these Terms of Service and the English version, the English version will control.

+

18. Miscellaneous.

+

This Agreement constitutes the entire agreement between Free Code Camp and you concerning the subject matter hereof, and they may only be modified by a written amendment signed by an authorized executive of Free Code Camp, or by the posting by Free Code Camp of a revised version. Except to the extent applicable law, if any, provides otherwise, this Agreement, any access to or use of our Services will be governed by the laws of the state of California, U.S.A., excluding its conflict of law provisions, and the proper venue for any disputes arising out of or relating to any of the same will be the state and federal courts located in San Francisco County, California. Except for claims for injunctive or equitable relief or claims regarding intellectual property rights (which may be brought in any competent court without the posting of a bond), any dispute arising under this Agreement shall be finally settled in accordance with the Comprehensive Arbitration Rules of the Judicial Arbitration and Mediation Service, Inc. (“JAMS”) by three arbitrators appointed in accordance with such Rules. The arbitration shall take place in San Francisco, California, in the English language and the arbitral decision may be enforced in any court. The prevailing party in any action or proceeding to enforce this Agreement shall be entitled to costs and attorneys’ fees. If any part of this Agreement is held invalid or unenforceable, that part will be construed to reflect the parties’ original intent, and the remaining portions will remain in full force and effect. A waiver by either party of any term or condition of this Agreement or any breach thereof, in any one instance, will not waive such term or condition or any subsequent breach thereof. You may assign your rights under this Agreement to any party that consents to, and agrees to be bound by, its terms and conditions; Free Code Camp may assign its rights under this Agreement without condition. This Agreement will be binding upon and will inure to the benefit of the parties, their successors and permitted assigns.

+

These terms are adopted from the Automattic (WordPress) open source terms and are subject to the Creative Commons Attribution-ShareAlike 4.0 International license. We thank them for making this available.

From 4e8082ece5c721782a0ccc4c944aea61f64bfa37 Mon Sep 17 00:00:00 2001 From: Quincy Larson Date: Wed, 13 Jan 2016 15:37:15 -0600 Subject: [PATCH 39/65] Quick fix for wikipedia biplane --- .../intermediate-ziplines.json | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/seed/challenges/01-front-end-development-certification/intermediate-ziplines.json b/seed/challenges/01-front-end-development-certification/intermediate-ziplines.json index 651214dc46..f7f21c95fd 100644 --- a/seed/challenges/01-front-end-development-certification/intermediate-ziplines.json +++ b/seed/challenges/01-front-end-development-certification/intermediate-ziplines.json @@ -121,9 +121,9 @@ "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.", "User Story: I can search Wikipedia entries in a search box and see the resulting Wikipedia entries.", "User Story: I can click a button to see a random Wikipedia entry.", - "User Story: When I type in the search box, I can see a dropdown menu with autocomplete options for matching Wikipedia entries.", - "Hint #1: Here's an entry on using Wikipedia's API: http://www.mediawiki.org/wiki/API:Main_page.", - "Hint #2: Use this link to experiment with Wikipedia's API.", + "Hint #1: Here's a URL you can use to get a random Wikipedia article: http://en.wikipedia.org/wiki/Special:Random.", + "Hint #2: Here's an entry on using Wikipedia's API: http://www.mediawiki.org/wiki/API:Main_page.", + "Hint #3: Use this link to experiment with Wikipedia's API.", "Remember to use Read-Search-Ask if you get stuck.", "When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen.", "You can get feedback on your project from fellow campers by sharing it in our Code Review Chatroom. You can also share it on Twitter and your city's Campsite (on Facebook)." @@ -283,13 +283,12 @@ "Rule #1: Don't look at the example project's code. Figure it out for yourself.", "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.", "User Story: I am presented with a random series of button presses.", - "User Story: each time I input a series of button presses correctly, I see the same series of button presses but with an additional step.", + "User Story: Each time I input a series of button presses correctly, I see the same series of button presses but with an additional step.", "User Story: I hear a sound that corresponds to each button both when the series of button presses plays, and when I personally press a button.", "User Story: If I press the wrong button, I am notified that I have done so, and that series of button presses starts again to remind me of the pattern so I can try again.", "User Story: I can see how many steps are in the current series of button presses.", "User Story: If I want to restart, I can hit a button to do so, and the game will return to a single step.", "User Story: I can play in strict mode where if I get a button press wrong, it notifies me that I have done so, and the game restarts at a new random series of button presses.", - "User Story: The tempo of the game speeds up incrementally on the 5th, 9th and 13th step.", "User Story: I can win the game by getting a series of 20 steps correct. I am notified of my victory, then the game starts over.", "Hint: Here are mp3s you can use for each button: https://s3.amazonaws.com/freecodecamp/simonSound1.mp3, https://s3.amazonaws.com/freecodecamp/simonSound2.mp3, https://s3.amazonaws.com/freecodecamp/simonSound3.mp3, https://s3.amazonaws.com/freecodecamp/simonSound4.mp3.", "Remember to use Read-Search-Ask if you get stuck.", From 98626d3be70d37e2c3541b372041b16810464c2b Mon Sep 17 00:00:00 2001 From: Quincy Larson Date: Wed, 13 Jan 2016 15:38:28 -0600 Subject: [PATCH 40/65] delete old terms-and-privacy page --- server/views/resources/terms-and-privacy.jade | 143 ------------------ 1 file changed, 143 deletions(-) delete mode 100644 server/views/resources/terms-and-privacy.jade diff --git a/server/views/resources/terms-and-privacy.jade b/server/views/resources/terms-and-privacy.jade deleted file mode 100644 index 3d5453a87e..0000000000 --- a/server/views/resources/terms-and-privacy.jade +++ /dev/null @@ -1,143 +0,0 @@ -extends ../layout -block content - .col-xs-12 - .panel.panel-info - .panel-body - h1 Privacy Policy - p - | Free Code Camp is committed to respecting the privacy of visitors to our web sites and web applications. The guidelines below explain how we protect the privacy of visitors to - a(href='http://FreeCodeCamp.com') FreeCodeCamp.com - | and its features. - h3 - a#Personally_Identifiable_Information_2 - | Personally Identifiable Information - p - | Free Code Camp protects the identity of visitors to - a(href='http://FreeCodeCamp.com') FreeCodeCamp.com - | by limiting the collection of personally identifiable information. - p - | Free Code Camp does not knowingly collect or solicit personally identifiable information from or about children under 13, except as permitted by law. If we discover we have received any information from a child under 13 in violation of this policy, we will delete that information immediately. If you believe Free Code Camp has any information from or about anyone under 13, please email us at - okies and software logs - a(href='mailto:team@freecodecamp.com') team@freecodecamp.com - | . - p - | All personally identifiable information you provide to us is used by Free Code Camp and its team to process and manage your account, analyze the demographic of our users, or to deliver services through the site. - p - | If you choose to provide personally identifiable information to us, you may receive occasional emails from us that are relevant to Free Code Camp, getting a job, or learning to code in general. - | Free Code Camp may also use other third-party providers to facilitate the delivery of the services described above, and these third-party providers may be supplied with or have access to personally identifiable information for the sole purpose of providing these services, to you on behalf of Free Code Camp. - p - | Free Code Camp may also disclose personally identifiable information in special legal circumstances. For instance, such information may be used where it is necessary to protect our copyright or intellectual property rights, or if the law requires us to do so. - h3 - a#Anonymous_Information_15 - | Anonymous Information - p - | Anonymous aggregated data may be provided to other organizations we associate with for statistical purposes. For example, we may report to an organization that a certain percentage of our site’s visitors are adults between the ages of 25 and 35. - h3 - a#Cookies_and_BeaconsUse_by_Free_Code_Camp_Opting_Out_18 - | Cookies and Beacons—Use by Free Code Camp; Opting Out - p - | We use cookies and software logs to monitor the use of - a(href='http://FreeCodeCamp.com') FreeCodeCamp.com - | and to gather non-personal information about visitors to the site. Cookies are small files that Free Code Camp transfers to the hard drives of visitors for record-keeping purposes. These monitoring systems allow us to track general information about our visitors, such as the type of browsers (for example, Firefox or Internet Explorer), the operating systems (for instance, Windows or Macintosh), or the Internet providers (for instance, Comcast) they use. This information is used for statistical and market research purposes to tailor content to usage patterns and to provide services requested by our customers. To delete these cookies, please see your browser’s privacy settings. - p - | A beacon is an electronic file object (typically a transparent image) placed in the code of a Web page. We use third party beacons to monitor the traffic patterns of visitors from one - a(href='http://FreeCodeCamp.com') Free Code Camp.com - | page to another and to improve site performance. - | None of the information we gather in this way can be used to identify any individual who visits our site. - h3 - a#Security_24 - | Security - p - | Any personally identifiable information collected through this site is stored on limited-access servers. We will maintain safeguards to protect these servers and the information they store. - h3 - a#Surveys_28 - | Surveys - p - | We may occasionally conduct on-line surveys. All surveys are voluntary and you may decline to participate. - h3 - a#Copyright_31 - | Copyright - p - | All of the content on - a(href='http://FreeCodeCamp.com') FreeCodeCamp.com - | is copyrighted by Free Code Camp. If you’d like to redistribute it beyond simply sharing it through social media, please contact us at - a(href='mailto:team@freecodecamp.com') team@freecodecamp.com - | . - h3 - a#Contacting_Us_34 - | Contacting Us - p - | If you have questions about Free Code Camp, or to correct, update, or remove personally identifiable information, please email us at - a(href='mailto:team@freecodecamp.com') team@freecodecamp.com - | . - h3 - a#Links_to_Other_Web_sites_37 - | Links to Other Web sites - p - | Free Code Camp’s sites each contain links to other Web sites. Free Code Camp is not responsible for the privacy practices or content of these third-party Web sites. We urge all - a(href='http://FreeCodeCamp.com') FreeCodeCamp.com - | visitors to follow safe Internet practices: Do not supply Personally Identifiable Information to these Web sites unless you have verified their security and privacy policies. - h3 - a#Data_Retention_40 - | Data Retention - p - | We retain your information for as long as necessary to permit us to use it for the purposes that we have communicated to you and comply with applicable law or regulations. - h3 - a#Business_Transfers_43 - | Business Transfers - p - | As we continue to develop our business, we might sell or buy subsidiaries, or business units. In such transactions, customer information generally is one of the transferred business assets but remains subject to the promises made in any pre-existing Privacy Policy (unless, of course, the customer consents otherwise). Also, in the unlikely event that Free Code Camp, or substantially all of its assets are acquired, customer information will be one of the transferred assets, and will remain subject to our Privacy Policy. - h3 - a#Your_California_Privacy_Rights_46 - | Your California Privacy Rights - p - | If you are a California resident, you are entitled to prevent sharing of your personal information with third parties for their own marketing purposes through a cost-free means. If you send a request to the address above, Free Code Camp will provide you with a California Customer Choice Notice that you may use to opt-out of such information sharing. To receive this notice, submit a written request to - a(target='_blank' href='mailto:href=%22mailto:team@freecodecamp.com') team@freecodecamp.com, - | specifying that you seek your “California Customer Choice Notice.” Please allow at least thirty (30) days for a response. - h3 - a#Acceptance_of_Privacy_Policy_Terms_and_Conditions_49 - | Acceptance of Privacy Policy Terms and Conditions - p - | By using this site, you signify your agreement to the terms and conditions of this - a(href='http://FreeCodeCamp.com') FreeCodeCamp.com - | Privacy Policy. If you do not agree to these terms, please do not use this site. We reserve the right, at our sole discretion, to change, modify, add, or remove portions of this policy at any time. All amended terms automatically take effect 30 days after they are initially posted on the site. Please check this page periodically for any modifications. Your continued use of - a(href='http://FreeCodeCamp.com') FreeCodeCamp.com - | following the posting of any changes to these terms shall mean that you have accepted those changes. - p - | If you have any questions or concerns, please send an email to - a(href='mailto:team@freecodecamp.com') team@freecodecamp.com - | . - .spacer - hr - .spacer - h1 Terms of Service - p Coming soon - .spacer - hr - .spacer - h1 Code of Conduct - p - | Free Code Camp is friendly place to learn to code. We’re committed to keeping it that way. - p - | All campers are required to agree with the following code of conduct. We’ll enforce this code. We’re expecting cooperation from all campers in ensuring a friendly environment for everybody. - p In short: be nice to your fellow campers. - p Remember these 3 things and your fellow campers will like you: - ul - li - | Compliment your fellow campers when they do good work. Congratulate them when they accomplish something (like completing one of our certifications or getting a job). - li Critique the work, not the camper doing it. - li Only argue about something if it’s important to the greater discussion. - p - | Free Code Camp should be a harassment-free experience for everyone, regardless of gender, gender identity and expression, age, sexual orientation, disability, physical appearance, body size, race, national origin, or religion (or lack thereof). - p - | We do not tolerate harassment of campers in any form, anywhere on Free Code Camp’s online media (Gitter, Twitch, Facebook, etc.) or during pair programming. Harassment includes sexual language and imagery, deliberate intimidation, stalking, unwelcome sexual attention, libel, and any malicious hacking or social engineering. - p - | If a camper engages in harassing behavior, our team will take any action we deem appropriate, up to and including banning them from Free Code Camp. - p - | No bots are allowed in any of the Official Chat Rooms without prior explicit permission from the FCC Core Team. - p - | We want everyone to feel safe and respected. If you are being harassed or notice that someone else is being harassed, say something! Message @quincylarson, @berkeleytrue, @brianamarie and @codenonprofit in Gitter (preferably with a screen shot of the offending language) so we can take fast action. - p - | If you have questions about this code of conduct, email us at - a(href='mailto:team@freecodecamp.com') team@freecodecamp.com - | . From 572026090e03ba6b703c2890b7d5a75cab5145a6 Mon Sep 17 00:00:00 2001 From: Berkeley Martinez Date: Wed, 13 Jan 2016 14:35:47 -0800 Subject: [PATCH 41/65] Add padding to map aside content --- client/less/map.less | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/less/map.less b/client/less/map.less index 92832b339c..9ae21fca67 100644 --- a/client/less/map.less +++ b/client/less/map.less @@ -59,7 +59,8 @@ height: 100%; border: 0; - overflow: auto + overflow: auto; + margin-top: 40px; } } From f960b3aa848a8368a8d9adfab5baac82aa82eac3 Mon Sep 17 00:00:00 2001 From: Berkeley Martinez Date: Wed, 13 Jan 2016 14:51:58 -0800 Subject: [PATCH 42/65] Normalize indenting on map/show --- server/views/map/show.jade | 80 +++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/server/views/map/show.jade b/server/views/map/show.jade index 6d41cbdd70..c4bfd3f5e2 100644 --- a/server/views/map/show.jade +++ b/server/views/map/show.jade @@ -89,49 +89,49 @@ block content span.ion-locked.padded-ionic-icon | Mock Interview 3 hr - .row - .col-xs-12.col-md-6.col-md-offset-3 - for superBlock, index in superBlocks - for challengeBlock in superBlock.blocks + .row + .col-xs-12.col-md-6.col-md-offset-3 + for superBlock, index in superBlocks + for challengeBlock in superBlock.blocks .row - a(href='#' name=challengeBlock.dashedName) - .spacer.negative-55 + a(href='#' name=challengeBlock.dashedName) + .spacer.negative-55 .row - h4.bold #{challengeBlock.name} (#{challengeBlock.time}) - for challenge in challengeBlock.challenges + h4.bold #{challengeBlock.name} (#{challengeBlock.time}) + for challenge in challengeBlock.challenges - .col-xs-12.col-sm-9.col-md-10 - if challenge.completed - p.text-primary.ion-checkmark-circled.padded-ionic-icon.negative-15(name="#{challenge.dashedName}")   - a(href="/challenges/#{challenge.dashedName}") - = challenge.title - span.sr-only= " Complete" - else if (challenge.type === "bonfire") - p.ion-asterisk.padded-ionic-icon.negative-15(name="#{challenge.dashedName}")   - a(name="#{challenge.dashedName}" href="/challenges/#{challenge.dashedName}" class=challenge.isComingSoon ? 'disabled' : '') - span= challenge.title - span.sr-only= " Incomplete" - if challenge.markNew - span.text-success.small     - strong - em New - if challengeBlock.isComingSoon - span.text-success.small     - strong - em Coming Soon - else - p.ion-ios-circle-outline.padded-ionic-icon.negative-15(name="#{challenge.dashedName}")   - a(name="#{challenge.dashedName}" href="/challenges/#{challenge.dashedName}" class=challenge.isComingSoon ? 'disabled' : '') - span= challenge.title - span.sr-only= " Incomplete" - if challenge.markNew - span.text-success.small     - strong - em New - if challengeBlock.isComingSoon - span.text-success.small     - strong - em Coming Soon + .col-xs-12.col-sm-9.col-md-10 + if challenge.completed + p.text-primary.ion-checkmark-circled.padded-ionic-icon.negative-15(name="#{challenge.dashedName}")   + a(href="/challenges/#{challenge.dashedName}") + = challenge.title + span.sr-only= " Complete" + else if (challenge.type === "bonfire") + p.ion-asterisk.padded-ionic-icon.negative-15(name="#{challenge.dashedName}")   + a(name="#{challenge.dashedName}" href="/challenges/#{challenge.dashedName}" class=challenge.isComingSoon ? 'disabled' : '') + span= challenge.title + span.sr-only= " Incomplete" + if challenge.markNew + span.text-success.small     + strong + em New + if challengeBlock.isComingSoon + span.text-success.small     + strong + em Coming Soon + else + p.ion-ios-circle-outline.padded-ionic-icon.negative-15(name="#{challenge.dashedName}")   + a(name="#{challenge.dashedName}" href="/challenges/#{challenge.dashedName}" class=challenge.isComingSoon ? 'disabled' : '') + span= challenge.title + span.sr-only= " Incomplete" + if challenge.markNew + span.text-success.small     + strong + em New + if challengeBlock.isComingSoon + span.text-success.small     + strong + em Coming Soon if (index < superBlocks.length) hr From a2fd213a867582fa86f74314b7c11992df69d037 Mon Sep 17 00:00:00 2001 From: Berkeley Martinez Date: Wed, 13 Jan 2016 14:59:51 -0800 Subject: [PATCH 43/65] Ad minimal map for iframe loading --- server/boot/challenge.js | 9 +- server/views/layout-wide.jade | 5 +- server/views/map/show.jade | 177 +++++++++++++++++----------------- 3 files changed, 98 insertions(+), 93 deletions(-) diff --git a/server/boot/challenge.js b/server/boot/challenge.js index 0b9beb449e..d9888479e4 100644 --- a/server/boot/challenge.js +++ b/server/boot/challenge.js @@ -228,6 +228,7 @@ function getSuperBlocks$(challenge$, completedChallenges) { return { isBeta, isComingSoon, + isRequired, name: blockArray[0].block, superBlock: blockArray[0].superBlock, dashedName: dasherize(blockArray[0].block), @@ -317,7 +318,8 @@ module.exports = function(app) { completedZiplineOrBasejump ); - router.get('/map', showMap); + router.get('/map', showMap.bind(null, false)); + router.get('/map-minimal', showMap.bind(null, true)); router.get( '/challenges/next-challenge', returnNextChallenge @@ -574,14 +576,15 @@ module.exports = function(app) { ); } - function showMap({ user }, res, next) { + function showMap(showMinimal, { user }, res, next) { getSuperBlocks$(challenge$, getCompletedChallengeIds(user)) .subscribe( superBlocks => { res.render('map/show', { superBlocks, - title: 'A Map to Learn to Code and Become a Software Engineer' + title: 'A Map to Learn to Code and Become a Software Engineer', + showMinimal }); }, next diff --git a/server/views/layout-wide.jade b/server/views/layout-wide.jade index df33c7b4aa..ef5a9d1cd1 100644 --- a/server/views/layout-wide.jade +++ b/server/views/layout-wide.jade @@ -5,7 +5,8 @@ html(lang='en') include partials/stylesheets body.no-top-and-bottom-margins.full-screen-body-background include partials/scripts - include partials/navbar - include partials/flash + if !showMinimal + include partials/navbar + include partials/flash block content include partials/footer diff --git a/server/views/map/show.jade b/server/views/map/show.jade index c4bfd3f5e2..3878524de3 100644 --- a/server/views/map/show.jade +++ b/server/views/map/show.jade @@ -1,94 +1,95 @@ extends ../layout-wide block content - .row - .col-xs-12.col-md-6.col-md-offset-3 - ul - for superBlock in superBlocks - h2= superBlock.name - for challengeBlock in superBlock.blocks - .row - if (user) - .col-xs-11.col-sm-8.col-md-9 - li.map-p.negative-10 - |    - a(href='#' + challengeBlock.dashedName)= challengeBlock.name - if challengeBlock.markNew - span.text-info.small     - strong - em NEW - if challengeBlock.isComingSoon - span.text-info.small     - strong - em Coming Soon - else - .hidden-xs.col-sm-3.col-md-2 - .col-xs-10.col-sm-8.col-md-9 - span.map-p.negative-10 - a(href='#' + challengeBlock.dashedName)= challengeBlock.name - if challengeBlock.markNew - span.text-info.small     - strong - em NEW - if challengeBlock.isComingSoon - span.text-info.small     - strong - em Coming Soon - h2 Full Stack Development Certification - .row - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 - |    - span.ion-locked.padded-ionic-icon - | Greenfield Nonprofit Project 1 - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 - |    - span.ion-locked.padded-ionic-icon - | Greenfield Nonprofit Project 2 - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 - |    - span.ion-locked.padded-ionic-icon - | Legacy Nonprofit Project 1 - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 - |    - span.ion-locked.padded-ionic-icon - | Legacy Nonprofit Project 2 - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 - |    - span.ion-locked.padded-ionic-icon - | Claim your Full Stack Development Certification + if !showMinimal + .row + .col-xs-12.col-md-6.col-md-offset-3 + ul + for superBlock in superBlocks + h2= superBlock.name + for challengeBlock in superBlock.blocks + .row + if (user) + .col-xs-11.col-sm-8.col-md-9 + li.map-p.negative-10 + |    + a(href='#' + challengeBlock.dashedName)= challengeBlock.name + if challengeBlock.markNew + span.text-info.small     + strong + em NEW + if challengeBlock.isComingSoon + span.text-info.small     + strong + em Coming Soon + else + .hidden-xs.col-sm-3.col-md-2 + .col-xs-10.col-sm-8.col-md-9 + span.map-p.negative-10 + a(href='#' + challengeBlock.dashedName)= challengeBlock.name + if challengeBlock.markNew + span.text-info.small     + strong + em NEW + if challengeBlock.isComingSoon + span.text-info.small     + strong + em Coming Soon + h2 Full Stack Development Certification + .row + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 + |    + span.ion-locked.padded-ionic-icon + | Greenfield Nonprofit Project 1 + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 + |    + span.ion-locked.padded-ionic-icon + | Greenfield Nonprofit Project 2 + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 + |    + span.ion-locked.padded-ionic-icon + | Legacy Nonprofit Project 1 + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 + |    + span.ion-locked.padded-ionic-icon + | Legacy Nonprofit Project 2 + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 + |    + span.ion-locked.padded-ionic-icon + | Claim your Full Stack Development Certification - h2 Coding Interview Preparation - .row - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 - |    - span.ion-locked.padded-ionic-icon - | Whiteboard Coding Interview Training - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 - |    - span.ion-locked.padded-ionic-icon - | Critical Thinking Interview Training - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 - |    - span.ion-locked.padded-ionic-icon - | Mock Interview 1 - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 - |    - span.ion-locked.padded-ionic-icon - | Mock Interview 2 - .col-xs-12.col-sm-9.col-md-10 - li.map-p.negative-10 - |    - span.ion-locked.padded-ionic-icon - | Mock Interview 3 - hr + h2 Coding Interview Preparation + .row + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 + |    + span.ion-locked.padded-ionic-icon + | Whiteboard Coding Interview Training + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 + |    + span.ion-locked.padded-ionic-icon + | Critical Thinking Interview Training + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 + |    + span.ion-locked.padded-ionic-icon + | Mock Interview 1 + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 + |    + span.ion-locked.padded-ionic-icon + | Mock Interview 2 + .col-xs-12.col-sm-9.col-md-10 + li.map-p.negative-10 + |    + span.ion-locked.padded-ionic-icon + | Mock Interview 3 + hr .row .col-xs-12.col-md-6.col-md-offset-3 for superBlock, index in superBlocks From 98b54e9fc779a698729851c647e5617ccfbaf588 Mon Sep 17 00:00:00 2001 From: Berkeley Martinez Date: Wed, 13 Jan 2016 15:35:39 -0800 Subject: [PATCH 44/65] Load map aside as an iframe on every page --- client/less/map.less | 6 ++- client/main.js | 6 +++ server/boot/challenge.js | 13 +----- server/views/layout-wide.jade | 14 +++--- server/views/partials/challenge-footer.jade | 47 --------------------- server/views/partials/footer.jade | 4 ++ 6 files changed, 25 insertions(+), 65 deletions(-) diff --git a/client/less/map.less b/client/less/map.less index 9ae21fca67..a1eda748d0 100644 --- a/client/less/map.less +++ b/client/less/map.less @@ -53,7 +53,7 @@ border-left: none; } - & > .map-aside-container { + & > iframe { flex: 1; width: 100%; height: 100%; @@ -116,6 +116,10 @@ } } +.map-aside-body { + margin: 0 20px 40px 60px +} + .map-aside-action-pop-out { margin-right: -4px; background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMDAgMTcxLjQyOSIgZmlsbD0iIzNhMzEzMyI+PHBhdGggZD0iTTE1Ny4xNDMsMTAzLjU3MXYzNS43MTRjMCw4Ljg1NC0zLjE0NCwxNi40MjYtOS40MzEsMjIuNzEzcy0xMy44NTgsOS40MzEtMjIuNzEyLDkuNDMxSDMyLjE0MyBjLTguODU0LDAtMTYuNDI1LTMuMTQ0LTIyLjcxMi05LjQzMVMwLDE0OC4xNCwwLDEzOS4yODVWNDYuNDI5YzAtOC44NTQsMy4xNDQtMTYuNDI1LDkuNDMxLTIyLjcxMiBjNi4yODctNi4yODcsMTMuODU4LTkuNDMxLDIyLjcxMi05LjQzMWg3OC41NzJjMS4wNDEsMCwxLjg5NiwwLjMzNSwyLjU2NiwxLjAwNGMwLjY3LDAuNjcsMS4wMDQsMS41MjUsMS4wMDQsMi41NjdWMjUgYzAsMS4wNDItMC4zMzQsMS44OTctMS4wMDQsMi41NjdjLTAuNjcsMC42Ny0xLjUyNSwxLjAwNC0yLjU2NiwxLjAwNEgzMi4xNDNjLTQuOTExLDAtOS4xMTUsMS43NDktMTIuNjEyLDUuMjQ2IHMtNS4yNDYsNy43MDEtNS4yNDYsMTIuNjEydjkyLjg1NmMwLDQuOTExLDEuNzQ5LDkuMTE1LDUuMjQ2LDEyLjYxMnM3LjcwMSw1LjI0NSwxMi42MTIsNS4yNDVIMTI1YzQuOTEsMCw5LjExNS0xLjc0OCwxMi42MTEtNS4yNDUgYzMuNDk3LTMuNDk3LDUuMjQ2LTcuNzAxLDUuMjQ2LTEyLjYxMnYtMzUuNzE0YzAtMS4wNDIsMC4zMzQtMS44OTcsMS4wMDQtMi41NjdjMC42Ny0wLjY2OSwxLjUyNS0xLjAwNCwyLjU2Ny0xLjAwNGg3LjE0MyBjMS4wNDIsMCwxLjg5NywwLjMzNSwyLjU2NywxLjAwNEMxNTYuODA5LDEwMS42NzQsMTU3LjE0MywxMDIuNTI5LDE1Ny4xNDMsMTAzLjU3MXogTTIwMCw3LjE0M3Y1Ny4xNDMgYzAsMS45MzUtMC43MDcsMy42MDktMi4xMjEsNS4wMjJjLTEuNDEzLDEuNDE0LTMuMDg4LDIuMTIxLTUuMDIxLDIuMTIxYy0xLjkzNSwwLTMuNjA5LTAuNzA3LTUuMDIyLTIuMTIxbC0xOS42NDQtMTkuNjQzIGwtNzIuNzY3LDcyLjc2OWMtMC43NDQsMC43NDQtMS42LDEuMTE1LTIuNTY3LDEuMTE1cy0xLjgyMy0wLjM3MS0yLjU2Ny0xLjExNUw3Ny41NjcsMTA5LjcxYy0wLjc0NC0wLjc0NC0xLjExNi0xLjYtMS4xMTYtMi41NjcgYzAtMC45NjcsMC4zNzItMS44MjIsMS4xMTYtMi41NjZsNzIuNzY4LTcyLjc2OGwtMTkuNjQ0LTE5LjY0M2MtMS40MTMtMS40MTQtMi4xMi0zLjA4OC0yLjEyLTUuMDIyYzAtMS45MzUsMC43MDctMy42MDksMi4xMi01LjAyMiBDMTMyLjEwNSwwLjcwNywxMzMuNzc5LDAsMTM1LjcxNSwwaDU3LjE0M2MxLjkzNCwwLDMuNjA4LDAuNzA3LDUuMDIxLDIuMTIxQzE5OS4yOTMsMy41MzQsMjAwLDUuMjA4LDIwMCw3LjE0M3oiLz48L3N2Zz4=) diff --git a/client/main.js b/client/main.js index 8ce8aedc49..e8614eeb8a 100644 --- a/client/main.js +++ b/client/main.js @@ -262,6 +262,12 @@ $(document).ready(function() { // map $('#nav-map-btn').on('click', () => { + if (!main.isMapAsideLoad) { + var mapAside = $('