Merge branch 'master' into courseware

Conflicts:
	controllers/bonfire.js
	views/layout.jade
This commit is contained in:
Michael Q Larson
2015-02-02 23:32:46 -08:00
27 changed files with 360 additions and 186 deletions

View File

@@ -14,15 +14,15 @@ block content
label.col-sm-3.col-sm-offset-2.control-label(for='name') Name *
.col-sm-4
input.form-control(type='text', placeholder='Name', name='name', autocomplete="off", ng-model='user.profile.name', ng-minlength='3', ng-maxlength='50', required='required', id='name')
.col-sm-4.col-sm-offset-5(ng-show="profileForm.name.$invalid && profileForm.name.$error.required")
.col-sm-4.col-sm-offset-5(ng-cloak, ng-show="profileForm.name.$invalid && profileForm.name.$error.required")
alert(type='danger')
span.ion-close-circled(id='#name-error')
| Your name is required.
.col-sm-4.col-sm-offset-5(ng-show='profileForm.name.$error.minlength && !profileForm.name.$pristine')
.col-sm-4.col-sm-offset-5(ng-cloak, ng-show='profileForm.name.$error.minlength && !profileForm.name.$pristine')
alert(type='danger')
span.ion-close-circled
| Your name must be at least 3 characters.
.col-sm-4.col-sm-offset-5(ng-show='profileForm.name.$error.maxlength && !profileForm.name.$pristine')
.col-sm-4.col-sm-offset-5(ng-cloak, ng-show='profileForm.name.$error.maxlength && !profileForm.name.$pristine')
alert(type='danger')
span.ion-close-circled
| Your name must be fewer than 50 characters.
@@ -31,43 +31,43 @@ block content
label.col-sm-3.col-sm-offset-2.control-label(for='username') Username (path to public profile) *
.col-sm-4
input.form-control(type='text', placeholder='username' name='username', autocomplete="off", id='username', ng-model='user.profile.username', required='required', ng-minlength='5', ng-maxlength='20', ng-keypress='', unique-username='', ng-pattern="/^[A-z0-9_]+$/")
.col-sm-4.col-sm-offset-5(ng-show="profileForm.username.$error.pattern")
.col-sm-4.col-sm-offset-5(ng-cloak, ng-show="profileForm.username.$error.pattern")
alert(type='danger')
span.ion-close-circled
| Your username should only contain letters, numbers and underscores (az10_).
.col-sm-4.col-sm-offset-5(ng-show="profileForm.username.$error.required")
.col-sm-4.col-sm-offset-5(ng-cloak, ng-show="profileForm.username.$error.required")
alert(type='danger')
span.ion-close-circled
| Your username is required.
.col-sm-4.col-sm-offset-5(ng-show="profileForm.username.$error.minlength && !profileForm.username.$pristine")
.col-sm-4.col-sm-offset-5(ng-cloak, ng-show="profileForm.username.$error.minlength && !profileForm.username.$pristine")
alert(type='danger')
span.ion-close-circled
| Your username must be at least 5 characters.
.col-sm-4.col-sm-offset-5(ng-show="profileForm.username.$error.maxlength && !profileForm.username.$pristine")
.col-sm-4.col-sm-offset-5(ng-cloak, ng-show="profileForm.username.$error.maxlength && !profileForm.username.$pristine")
alert(type='danger')
span.ion-close-circled
| Your username must be fewer than 15 characters.
.col-sm-4.col-sm-offset-5(ng-show="profileForm.username.$error.unique && !profileForm.username.$pristine && $scope.storedUsername !== user.profile.username")
.col-sm-4.col-sm-offset-5(ng-cloak, ng-show="profileForm.username.$error.unique && !profileForm.username.$pristine && $scope.storedUsername !== user.profile.username")
alert(type='danger')
span.ion-close-circled
| That username is already taken.
| That username is already in use.
.form-group
label.col-sm-3.col-sm-offset-2.control-label(for='email') Email *
.col-sm-4
input.form-control(type='email', name='email', id='email', autocomplete="off", ng-model='user.email', required='required', ng-keypress='', unique-email='')
.col-sm-4.col-sm-offset-5(ng-show="profileForm.email.$error.required")
.col-sm-4.col-sm-offset-5(ng-cloak, ng-show="profileForm.email.$error.required")
alert(type='danger')
span.ion-close-circled
| Your email address is required.
.col-sm-4.col-sm-offset-5(ng-show="profileForm.$error.email && !profileForm.email.$pristine")
.col-sm-4.col-sm-offset-5(ng-cloak, ng-show="profileForm.$error.email && !profileForm.email.$pristine")
alert(type='danger')
span.ion-close-circled
| Please enter a valid email format.
.col-sm-4.col-sm-offset-5(ng-show="profileForm.email.$error.unique && !profileForm.email.$pristine")
alert(type='danger')
span.ion-close-circled
| That email is already taken.
.col-sm-4.col-sm-offset-5(ng-cloak, ng-show="profileForm.email.$error.unique && !profileForm.email.$pristine")
alert(type='danger')
span.ion-close-circled
| That email is already in use.
.form-group
label.col-sm-3.col-sm-offset-2.control-label(for='location') Location
@@ -77,17 +77,20 @@ block content
.form-group
label.col-sm-3.col-sm-offset-2.control-label(for='email') Link to Profile Photo (1:1 ratio)
.col-sm-4
input.form-control(type='url', name='picture', id='picture', ng-model='user.profile.picture', placeholder='http://')
input.form-control(type='url', name='picture', id='picture', ng-model='user.profile.picture', placeholder='http://www.example.com/image.jpg', ng-pattern="/[\.](jpg|png|jpeg|gif)\s?$/")
.col-sm-4.col-sm-offset-5(ng-show="profileForm.picture.$error.url && !profileForm.picture.$pristine")
alert(type='danger')
span.ion-close-circled
| Please enter a valid URL format (http://www.example.com).
| Please enter a valid URL format (http://www.example.com/image.jpg).
.col-sm-4.col-sm-offset-5(ng-show="profileForm.picture.$error.pattern")
alert(type='danger')
span.ion-close-circled
| The image URL must end in .jpg, .png, .jpeg or .gif.
.form-group
label.col-sm-3.col-sm-offset-2.control-label(for='bio') Bio (140 characters)
.col-sm-4
input.form-control(type='text', name='bio', autocomplete="off", ng-model='user.profile.bio', ng-maxlength='140', id='bio')
.col-sm-4.col-sm-offset-5(ng-show='profileForm.bio.$error.maxlength && !profileForm.bio.$pristine')
.col-sm-4.col-sm-offset-5(ng-cloak, ng-show='profileForm.bio.$error.maxlength && !profileForm.bio.$pristine')
alert(type='danger')
span.ion-close-circled
| Your bio must be fewer than 140 characters.
@@ -107,11 +110,11 @@ block content
.input-group.twitter-input
span.input-group-addon @
input.form-control(type='text', name='twitterHandle', autocomplete="off", id='twitterHandle', ng-model='user.profile.twitterHandle', ng-maxlength='15', ng-pattern="/^[A-z0-9_]+$/")
.col-sm-4.col-sm-offset-5(ng-show="profileForm.twitterHandle.$error.pattern")
.col-sm-4.col-sm-offset-5(ng-cloak, ng-show="profileForm.twitterHandle.$error.pattern")
alert(type='danger')
span.ion-close-circled
| Your Twitter handle should only contain letters, numbers and underscores (az10_).
.col-sm-4.col-sm-offset-5(ng-show='profileForm.twitterHandle.$error.maxlength && !profileForm.twitterHandle.$pristine')
.col-sm-4.col-sm-offset-5(ng-cloak, ng-show='profileForm.twitterHandle.$error.maxlength && !profileForm.twitterHandle.$pristine')
alert(type='danger')
span.ion-close-circled
| Your name must be fewer than 15 characters.
@@ -119,7 +122,7 @@ block content
label.col-sm-3.col-sm-offset-2.control-label(for='email') Github
.col-sm-4
input.form-control(type='url', name='githubProfile', id='githubProfile', autocomplete="off", ng-model='user.profile.githubProfile', placeholder='http://')
.col-sm-4.col-sm-offset-5(ng-show="profileForm.githubProfile.$error.url && !profileForm.githubProfile.$pristine")
.col-sm-4.col-sm-offset-5(ng-cloak, ng-show="profileForm.githubProfile.$error.url && !profileForm.githubProfile.$pristine")
alert(type='danger')
span.ion-close-circled
| Please enter a valid URL format (http://www.example.com).
@@ -128,7 +131,7 @@ block content
label.col-sm-3.col-sm-offset-2.control-label(for='email') CodePen
.col-sm-4
input.form-control(type='url', name='codepenProfile', id='codepenProfile', autocomplete="off", ng-model='user.profile.codepenProfile', placeholder='http://')
.col-sm-4.col-sm-offset-5(ng-show="profileForm.codepenProfile.$error.url && !profileForm.codepenProfile.$pristine")
.col-sm-4.col-sm-offset-5(ng-cloak, ng-show="profileForm.codepenProfile.$error.url && !profileForm.codepenProfile.$pristine")
alert(type='danger')
span.ion-close-circled
| Please enter a valid URL format (http://www.example.com).
@@ -137,7 +140,7 @@ block content
label.col-sm-3.col-sm-offset-2.control-label(for='email') CoderByte
.col-sm-4
input.form-control(type='url', name='coderbyteProfile', id='coderbyteProfile', autocomplete="off", ng-model='user.profile.coderbyteProfile', placeholder='http://')
.col-sm-4.col-sm-offset-5(ng-show="profileForm.coderbyteProfile.$error.url && !profileForm.coderbyteProfile.$pristine")
.col-sm-4.col-sm-offset-5(ng-cloak, ng-show="profileForm.coderbyteProfile.$error.url && !profileForm.coderbyteProfile.$pristine")
alert(type='danger')
span.ion-close-circled
| Please enter a valid URL format (http://www.example.com).
@@ -146,7 +149,7 @@ block content
label.col-sm-3.col-sm-offset-2.control-label(for='email') LinkedIn
.col-sm-4
input.form-control(type='url', name='linkedinProfile', id='linkedinProfile', autocomplete="off", ng-model='user.profile.linkedinProfile', placeholder='http://')
.col-sm-4.col-sm-offset-5(ng-show="profileForm.linkedinProfile.$error.url && !profileForm.linkedinProfile.$pristine")
.col-sm-4.col-sm-offset-5(ng-cloak, ng-show="profileForm.linkedinProfile.$error.url && !profileForm.linkedinProfile.$pristine")
alert(type='danger')
span.ion-close-circled
| Please enter a valid URL format (http://www.example.com).
@@ -167,7 +170,7 @@ block content
label.col-sm-3.col-sm-offset-2.control-label(for='website1Title') Title
.col-sm-4
input.form-control(type='text', name='website1Title', id='website1Title', autocomplete="off", ng-model='user.portfolio.website1Title', ng-maxlength='140')
.col-sm-4.col-sm-offset-5(ng-show="profileForm.website1Title.$error.maxlength && !profileForm.website1Title.$pristine")
.col-sm-4.col-sm-offset-5(ng-cloak, ng-show="profileForm.website1Title.$error.maxlength && !profileForm.website1Title.$pristine")
alert(type='danger')
span.ion-close-circled
| Portfolio project title must be fewer than 140 characters.
@@ -176,7 +179,7 @@ block content
label.col-sm-3.col-sm-offset-2.control-label(for='website1Link') Link
.col-sm-4
input.form-control(type='url', name='website1Link', id='website1Link', autocomplete="off", ng-model='user.portfolio.website1Link', placeholder='http://')
.col-sm-4.col-sm-offset-5(ng-show="profileForm.website1Link.$error.url && !profileForm.website1Link.$pristine")
.col-sm-4.col-sm-offset-5(ng-cloak, ng-show="profileForm.website1Link.$error.url && !profileForm.website1Link.$pristine")
alert(type='danger')
span.ion-close-circled
| Please enter a valid URL format (http://www.example.com).
@@ -184,11 +187,15 @@ block content
.form-group
label.col-sm-3.col-sm-offset-2.control-label(for='website1Image') Image Link (4:3 ratio)
.col-sm-4
input.form-control(type='url', name='website1Image', id='website1Image', autocomplete="off", ng-model='user.portfolio.website1Image', placeholder='http://')
input.form-control(type='url', name='website1Image', id='website1Image', autocomplete="off", ng-model='user.portfolio.website1Image', placeholder='http://www.example.com/image.jpg', ng-pattern="/[\.](jpg|png|jpeg|gif)\s?$/")
.col-sm-4.col-sm-offset-5(ng-show="profileForm.website1Image.$error.url && !profileForm.website1Image.$pristine")
alert(type='danger')
span.ion-close-circled
| Please enter a valid URL format (http://www.example.com).
alert(type='danger')
span.ion-close-circled
| Please enter a valid URL format (http://www.example.com/image.jpg).
.col-sm-4.col-sm-offset-5(ng-show="profileForm.website1Image.$error.pattern")
alert(type='danger')
span.ion-close-circled
| The image URL must end in .jpg, .png, .jpeg or .gif.
.col-sm-4.col-sm-offset-5.flat-top
h3 Second Portfolio Project
@@ -197,7 +204,7 @@ block content
label.col-sm-3.col-sm-offset-2.control-label(for='website2Title') Title
.col-sm-4
input.form-control(type='text', name='website2Title', id='website2Title', autocomplete="off", ng-model='user.portfolio.website2Title', ng-maxlength='140')
.col-sm-4.col-sm-offset-5(ng-show="profileForm.website2Title.$error.maxlength && !profileForm.website2Title.$pristine")
.col-sm-4.col-sm-offset-5(ng-cloak, ng-show="profileForm.website2Title.$error.maxlength && !profileForm.website2Title.$pristine")
alert(type='danger')
span.ion-close-circled
| Portfolio project title must be fewer than 140 characters.
@@ -206,18 +213,22 @@ block content
label.col-sm-3.col-sm-offset-2.control-label(for='website2Link') Link
.col-sm-4
input.form-control(type='url', name='website2Link', id='website2Link', autocomplete="off", ng-model='user.portfolio.website2Link', placeholder='http://')
.col-sm-4.col-sm-offset-5(ng-show="profileForm.website2Link.$error.url && !profileForm.website2Link.$pristine")
.col-sm-4.col-sm-offset-5(ng-cloak, ng-show="profileForm.website2Link.$error.url && !profileForm.website2Link.$pristine")
alert(type='danger')
span.ion-close-circled
| Please enter a valid URL format (http://www.example.com).
.form-group
label.col-sm-3.col-sm-offset-2.control-label(for='website2Image') Image Link (4:3 ratio)
.col-sm-4
input.form-control(type='url', name='website2Image', id='website2Image', autocomplete="off", ng-model='user.portfolio.website2Image', placeholder='http://')
.col-sm-4.col-sm-offset-5(ng-show="profileForm.website2Image.$error.url && !profileForm.website2Image.$pristine")
alert(type='danger')
span.ion-close-circled
| Please enter a valid URL format (http://www.example.com).
input.form-control(type='url', name='website2Image', id='website2Image', autocomplete="off", ng-model='user.portfolio.website2Image', placeholder='http://www.example.com/image.jpg', ng-pattern="/[\.](jpg|png|jpeg|gif)\s?$/")
.col-sm-4.col-sm-offset-5(ng-show="profileForm.website2Image.$error.url && !profileForm.website2Image.$pristine")
alert(type='danger')
span.ion-close-circled
| Please enter a valid URL format (http://www.example.com/image.jpg).
.col-sm-4.col-sm-offset-5(ng-show="profileForm.website2Image.$error.pattern")
alert(type='danger')
span.ion-close-circled
| The image URL must end in .jpg, .png, .jpeg or .gif.
.col-sm-4.col-sm-offset-5.flat-top
h3 Third Portfolio Project
@@ -226,7 +237,7 @@ block content
label.col-sm-3.col-sm-offset-2.control-label(for='website3Title') Title
.col-sm-4
input.form-control(type='text', name='website3Title', id='website3Title', autocomplete="off", ng-model='user.portfolio.website3Title', ng-maxlength='140')
.col-sm-4.col-sm-offset-5(ng-show="profileForm.website3Title.$error.maxlength && !profileForm.website3Title.$pristine")
.col-sm-4.col-sm-offset-5(ng-cloak, ng-show="profileForm.website3Title.$error.maxlength && !profileForm.website3Title.$pristine")
alert(type='danger')
span.ion-close-circled
| Portfolio project title must be fewer than 140 characters.
@@ -235,7 +246,7 @@ block content
label.col-sm-3.col-sm-offset-2.control-label(for='website3Link') Link
.col-sm-4
input.form-control(type='url', name='website3Link', id='website3Link', autocomplete="off", ng-model='user.portfolio.website3Link', placeholder='http://')
.col-sm-4.col-sm-offset-5(ng-show="profileForm.website3Link.$error.url && !profileForm.website3Link.$pristine")
.col-sm-4.col-sm-offset-5(ng-cloak, ng-show="profileForm.website3Link.$error.url && !profileForm.website3Link.$pristine")
alert(type='danger')
span.ion-close-circled
| Please enter a valid URL format (http://www.example.com).
@@ -243,11 +254,15 @@ block content
.form-group
label.col-sm-3.col-sm-offset-2.control-label(for='website3Image') Image Link (4:3 ratio)
.col-sm-4
input.form-control(type='url', name='website3Image', id='website3Image', autocomplete="off", ng-model='user.portfolio.website3Image', placeholder='http://')
.col-sm-4.col-sm-offset-5(ng-show="profileForm.website3Image.$error.url && !profileForm.website3Image.$pristine")
alert(type='danger')
span.ion-close-circled
| Please enter a valid URL format (http://www.example.com).
input.form-control(type='url', name='website3Image', id='website3Image', autocomplete="off", ng-model='user.portfolio.website3Image', placeholder='http://www.example.com/image.jpg', ng-pattern='/[\.](jpg|png|jpeg|gif)(\s+)?$/')
.col-sm-4.col-sm-offset-5(ng-show="profileForm.website3Image.$error.url && !profileForm.website3Image.$pristine")
alert(type='danger')
span.ion-close-circled
| Please enter a valid URL format (http://www.example.com/image.jpg).
.col-sm-4.col-sm-offset-5(ng-show="profileForm.website3Image.$error.pattern")
alert(type='danger')
span.ion-close-circled
| The image URL must end in .jpg, .png, .jpeg or .gif.
.form-group
.col-sm-offset-5.col-sm-4
@@ -293,23 +308,7 @@ block content
a.btn.btn-lg.btn-block.btn-twitter.btn-link-social(href='/auth/twitter')
i.fa.fa-twitter
| Link Twitter with your account
br
- if (ch[0] > 0)
.panel.panel-primary
.panel-heading.text-center Completed Challenges:
.panel-body
.col-xs-12
table.table.table-striped
thead
tr
th Challenge
th Date Finished
for challenge in challenges
if ch[challenge.challengeNumber] > 0
tr
td= challenges[challenge.challengeNumber].name
td= moment(ch[challenge.challengeNumber], 'X').format("MMM DD, YYYY")
br
.panel.panel-danger
.panel-heading.text-center Danger Zone:
.panel-body

View File

@@ -7,46 +7,54 @@ block content
.form-group
.col-sm-6.col-sm-offset-3
input.form-control(type='email', ng-model='email', ng-keypress='', name='email', id='email', placeholder='email', autofocus, required, autocomplete="off", unique-email='')
.col-sm-6.col-sm-offset-3(ng-show="signupForm.email.$error.unique && !signupForm.email.$pristine")
.col-sm-6.col-sm-offset-3(ng-cloak, ng-show="signupForm.email.$error.required && !signupForm.email.$pristine")
alert(type='danger')
span.ion-close-circled
| This email is taken.
| Your email address is required.
.col-sm-6.col-sm-offset-3(ng-cloak, ng-show="signupForm.$error.email && !signupForm.email.$pristine")
alert(type='danger')
span.ion-close-circled
| Please enter a valid email format.
.col-sm-6.col-sm-offset-3(ng-cloak, ng-show="signupForm.email.$error.unique && !signupForm.email.$pristine")
alert(type='danger')
span.ion-close-circled
| That email address is already in use.
.form-group
.col-sm-6.col-sm-offset-3
input.form-control(type='text', name='username', ng-keypress='', autocomplete="off", id='username', placeholder='username', ng-model='username', unique-username='', required, ng-minlength=5, ng-maxlength=20, ng-pattern="/^[A-z0-9_]+$/")
.col-sm-4.col-sm-offset-5(ng-show="profileForm.username.$error.pattern && !signupForm.username.$pristine")
.col-sm-6.col-sm-offset-3(ng-cloak, ng-show="profileForm.username.$error.pattern && !signupForm.username.$pristine")
alert(type='danger')
span.ion-close-circled
| Your username should only contain letters, numbers and underscores (az10_).
.col-sm-6.col-sm-offset-3(ng-show="signupForm.username.$error.unique && !signupForm.username.$pristine")
.col-sm-6.col-sm-offset-3(ng-cloak, ng-show="signupForm.username.$error.unique && !signupForm.username.$pristine")
alert(type='danger')
span.ion-close-circled
| This username is taken.
.col-sm-6.col-sm-offset-3(ng-show="signupForm.username.$error.minlength && !signupForm.username.$pristine")
.col-sm-6.col-sm-offset-3(ng-cloak, ng-show="signupForm.username.$error.minlength && !signupForm.username.$pristine")
alert(type='danger')
span.ion-close-circled
| Your username must be at least 5 characters long.
.col-sm-6.col-sm-offset-3(ng-show="signupForm.username.$error.maxlength && !signupForm.username.$pristine")
.col-sm-6.col-sm-offset-3(ng-cloak, ng-show="signupForm.username.$error.maxlength && !signupForm.username.$pristine")
alert(type='danger')
span.ion-close-circled
| Your usernames must be 20 characters or fewer.
.form-group
.col-sm-6.col-sm-offset-3
input.form-control(type='password', ng-model='password', name='password', id='password', placeholder='password', required, ng-minlength=5)
.col-sm-6.col-sm-offset-3(ng-show="signupForm.password.$error.minlength && !signupForm.password.$pristine")
.col-sm-6.col-sm-offset-3(ng-cloak, ng-show="signupForm.password.$error.minlength && !signupForm.password.$pristine")
alert(type='danger')
span.ion-close-circled
| Your password must be at least 8 characters long.
.form-group
.col-sm-6.col-sm-offset-3
input.form-control(type='password', ng-model='confirmPassword', name='confirmPassword', id='confirmPassword', placeholder='confirm password', required, ng-minlength=5)
.col-sm-6.col-sm-offset-3(ng-show="(confirmPassword !== password) && !signupForm.confirmPassword.$pristine")
alert(type='danger')
span.ion-close-circled
| Passwords must match.
.col-sm-6.col-sm-offset-3(ng-cloak, ng-show="(confirmPassword !== password) && !signupForm.confirmPassword.$pristine")
alert(type='danger')
span.ion-close-circled
| Passwords must match.
.form-group
.col-sm-offset-3.col-sm-6
button.btn.btn-success(type='submit')
.col-sm-6.col-sm-offset-3
button.btn.btn-success(type='submit', ng-disabled='signupForm.$invalid')
span.ion-person-add
| Signup
br

View File

@@ -33,6 +33,9 @@ block content
h3.flat-top.bolded.wrappable= location
h4.flat-top.wrappable= bio
.col-xs-12.col-sm-12.col-md-3.text-center
if (user && user.profile.username === username)
a.btn.btn-warning(href="/account") Edit my Profile
.background-svg.img-center
.points-on-top
= "[ " + points + " ]"

View File

@@ -0,0 +1,45 @@
extends ../layout-wide
block content
script(src='/js/lib/codemirror/lib/codemirror.js')
script(src='/js/lib/codemirror/addon/edit/closebrackets.js')
script(src='/js/lib/codemirror/addon/edit/matchbrackets.js')
script(src='/js/lib/codemirror/addon/lint/lint.js')
script(src='/js/lib/codemirror/addon/lint/javascript-lint.js')
script(src='//ajax.aspnetcdn.com/ajax/jshint/r07/jshint.js')
script(src='/js/lib/chai/chai.js')
link(rel='stylesheet', href='/js/lib/codemirror/lib/codemirror.css')
link(rel='stylesheet', href='/js/lib/codemirror/addon/lint/lint.css')
link(rel='stylesheet', href='/js/lib/codemirror/theme/monokai.css')
link(rel="stylesheet", href="http://fonts.googleapis.com/css?family=Ubuntu+Mono")
script(src='/js/lib/codemirror/mode/javascript/javascript.js')
script(src='/js/lib/jailed/jailed.js')
script(src='/js/lib/bonfire/bonfireInit.js')
.row
script(type="text/javascript").
var tests = !{JSON.stringify(tests)};
var challengeSeed = !{JSON.stringify(challengeSeed)};
var challengeEntryPoint = !{JSON.stringify(challengeEntryPoint)};
var title = !{JSON.stringify(title)};
#mainEditorPanel.col-sm-12.col-md-7.col-xs-12
.panel.panel-primary.panel-bonfire
.panel-heading.text-center Playground
.panel.panel-body
form.code
.form-group.codeMirrorView
textarea#codeEditor(autofocus=true)
#testCreatePanel.col-sm-12.col-md-5.col-xs-12
.panel.panel-primary.panel-bonfire
.panel-heading.text-center Output
.panel.panel-body
#submitButton.btn.btn-primary.btn-big.btn-block Run code (ctrl + enter)
br
form.code
.form-group.codeMirrorView
textarea#codeOutput
br
ul#testSuite.list-group
br
script(src='/js/lib/bonfire/bonfireFramework.js')

View File

@@ -90,6 +90,8 @@ block content
var challengeSeed = !{JSON.stringify(challengeSeed)};
var challengeEntryPoint = !{JSON.stringify(challengeEntryPoint)};
var passedBonfireHash = !{JSON.stringify(bonfireHash)};
var bonfireName = !{JSON.stringify(name)};
var started = Math.floor(Date.now() / 1000);
.col-xs-12.col-sm-12.col-md-8
#mainEditorPanel
form.code
@@ -108,7 +110,7 @@ block content
.text-center
.animated.zoomInDown.delay-half
span.landing-icon.ion-checkmark-circled.text-primary
span.completion-icon.ion-checkmark-circled.text-primary
- if (cc)
form.form-horizontal(novalidate='novalidate', name='completedWithForm')
.form-group.text-center
@@ -116,7 +118,7 @@ block content
// extra field to distract password tools like lastpass from injecting css into our username field
input.form-control(ng-show="false")
input.form-control#completed-with(name="existingUser", placeholder="If you paired, enter your pair's username here", existing-username='', ng-model="existingUser", autofocus)
.col-xs-10.col-xs-offset-1.col-sm-8.col-sm-offset-2.col-md-8.col-md-offset-2(ng-show="completedWithForm.$error.exists && !completedWithForm.existingUser.$pristine && existingUser.length > 0")
.col-xs-10.col-xs-offset-1.col-sm-8.col-sm-offset-2.col-md-8.col-md-offset-2(ng-cloak, ng-show="completedWithForm.$error.exists && !completedWithForm.existingUser.$pristine && existingUser.length > 0")
alert(type='danger')
span.ion-close-circled
| Username not found

View File

@@ -24,7 +24,7 @@ block content
.modal-body
.text-center
.animated.zoomInDown.delay-half
span.landing-icon.ion-checkmark-circled.text-primary
span.completion-icon.ion-checkmark-circled.text-primary
- if (cc)
a.animated.fadeIn.btn.btn-lg.btn-primary.btn-block.next-challenge-button(name='_csrf', value=_csrf, aria-hidden='true') Take me to my next challenge
- if (points && points > 2)

View File

@@ -14,11 +14,11 @@ block content
label(class='col-sm-3 control-label', for='email') Your email *
.col-sm-8
input.form-control(type='text', name='email', id='email', autocomplete="off", ng-model='email', required='required', ng-keypress='')
.col-sm-8.col-sm-offset-3(ng-show="doneWithFirst100HoursForm.$error.email && !doneWithFirst100HoursForm.email.$pristine")
.col-sm-8.col-sm-offset-3(ng-cloak, ng-show="doneWithFirst100HoursForm.$error.email && !doneWithFirst100HoursForm.email.$pristine")
alert(type='danger')
span.ion-close-circled
| Please enter a valid email format.
.col-sm-8.col-sm-offset-3(ng-show="doneWithFirst100HoursForm.email.$invalid && doneWithFirst100HoursForm.email.$error.required && !doneWithFirst100HoursForm.email.$pristine")
.col-sm-8.col-sm-offset-3(ng-cloak, ng-show="doneWithFirst100HoursForm.email.$invalid && doneWithFirst100HoursForm.email.$error.required && !doneWithFirst100HoursForm.email.$pristine")
alert(type='danger')
span.ion-close-circled(id='#email-error').
Your email is required.

View File

@@ -20,7 +20,7 @@ block content
label(class='col-sm-2 control-label', for='name') Your name *
.col-sm-8
input.form-control(type='text', name='name', id='name', autocomplete="off", ng-model='name', required='required')
.col-sm-8.col-sm-offset-2(ng-show="nonprofitForm.name.$invalid && nonprofitForm.name.$error.required && !nonprofitForm.name.$pristine")
.col-sm-8.col-sm-offset-2(ng-cloak, ng-show="nonprofitForm.name.$invalid && nonprofitForm.name.$error.required && !nonprofitForm.name.$pristine")
alert(type='danger')
span.ion-close-circled(id='#name-error')
| Your name is required.
@@ -28,7 +28,7 @@ block content
label(class='col-sm-2 control-label', for='email') Your email *
.col-sm-8
input.form-control(type='text', name='email', id='email', autocomplete="off", ng-model='email', required='required')
.col-sm-8.col-sm-offset-2(ng-show="nonprofitForm.email.$invalid && nonprofitForm.email.$error.required && !nonprofitForm.email.$pristine")
.col-sm-8.col-sm-offset-2(ng-cloak, ng-show="nonprofitForm.email.$invalid && nonprofitForm.email.$error.required && !nonprofitForm.email.$pristine")
alert(type='danger')
span.ion-close-circled(id='#email-error').
Your email is required.
@@ -36,7 +36,7 @@ block content
label(class='col-sm-2 control-label', for='message') Briefly describe what problem you need to solve, and for whom. *
.col-sm-8
textarea.form-control(type='text', name='message', id='message', rows='7', autocomplete="off", ng-model='message', required='required')
.col-sm-8.col-sm-offset-2(ng-show="nonprofitForm.message.$invalid && nonprofitForm.message.$error.required && !nonprofitForm.message.$pristine")
.col-sm-8.col-sm-offset-2(ng-cloak, ng-show="nonprofitForm.message.$invalid && nonprofitForm.message.$error.required && !nonprofitForm.message.$pristine")
alert(type='danger')
span.ion-close-circled(id='#message-error')
| Your message is required.

View File

@@ -7,19 +7,19 @@ block content
.row
.col-xs-12.col-sm-12.col-md-3
h3.nowrap Get Connected
img.img-responsive(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_connect.svg', title='Get great references and connections to help you get a job')
img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_connect.svg', title='Get great references and connections to help you get a job')
p.landing-p Join a community of busy, motivated professionals.
.col-xs-12.col-sm-12.col-md-3
h3.nowrap Learn JavaScript
img.img-responsive(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_learn.svg', title='Learn to code')
img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_learn.svg', title='Learn to code')
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(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_portfolio.svg', title='Build a portfolio of apps for nonprofits')
img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_portfolio.svg', title='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(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_nonprofits.svg', title='Help nonprofits')
img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_nonprofits.svg', title='Help nonprofits')
p.landing-p Give nonprofits a boost by empowering them with code.
.big-break
a.btn.btn-cta.signup-btn(href="/login") Start learning to code (it's free)

View File

@@ -2,7 +2,7 @@ doctype html
html(ng-app='profileValidation', lang='en')
head
script(src="//ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js")
script(src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js")
script(src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.11/angular.min.js")
script(src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.12.0/ui-bootstrap-tpls.min.js")
link(rel='shortcut icon', href='//s3.amazonaws.com/freecodecamp/favicon.ico')
link(rel='stylesheet', href='//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css')
@@ -29,5 +29,4 @@ script.
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-55446531-1', 'auto');
ga('require', 'displayfeatures');
ga('send', 'pageview');
script(src="//cdn.optimizely.com/js/999692993.js")
ga('send', 'pageview');

View File

@@ -2,12 +2,10 @@ doctype html
html(ng-app='profileValidation', lang='en')
head
script(src="//ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js")
script(src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js")
script(src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.min.js")
script(src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.12.0/ui-bootstrap-tpls.min.js")
link(rel='shortcut icon', href='//s3.amazonaws.com/freecodecamp/favicon.ico')
link(rel='stylesheet', href='//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css')
link(rel='stylesheet', href='//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css')
link(rel='stylesheet', href='/css/lib/ionicons/ionicons.min.css')
include partials/meta
title #{title} | Free Code Camp
meta(charset='utf-8')
@@ -30,5 +28,4 @@ script.
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-55446531-1', 'auto');
ga('require', 'displayfeatures');
ga('send', 'pageview');
script(src="//cdn.optimizely.com/js/999692993.js")
ga('send', 'pageview');

View File

@@ -125,4 +125,10 @@
h4.negative-10.text-nowrap JavaScript Engineer
img.profile-image(src='https://s3.amazonaws.com/freecodecamp/kamal-sharif.jpg' alt="Kamal Sharif's picture")
h4.text-nowrap Dhaka, Bangladesh
p.negative-10 "I build applications that help other people improve their own lives."
p.negative-10 "I build applications that help other people improve their own lives."
.col-xs-12.col-sm-4.col-md-3.team-member
h3.negative-10.text-nowrap Patrick Ly
h4.negative-10.text-nowrap Community Builder
img.profile-image(src='https://s3.amazonaws.com/freecodecamp/patrick-ly.jpg' alt="Patrick Ly's picture")
h4.text-nowrap Los Angeles, California
p.negative-10 "I'm a student and self-taught Hip Hop dancer. Just using the web isn't enough for me. I want to create and maintain web apps, too"

View File

@@ -4,24 +4,54 @@ meta(http-equiv='X-UA-Compatible', content='IE=edge')
meta(name='viewport', content='width=device-width, initial-scale=1.0')
meta(name='csrf-token', content=_csrf)
meta(name='keywords', content='learn to code, learn how to code, code, coding, software engineer, software developer, mean stack, pair programming, node.js, angular.js, express.js, mongoDB, coding bootcamp')
meta(content="Free Code Camp is a community of busy people who learn to code by collaborating on projects for nonprofits. Build your full stack JavaScript Portfolio today.", property="og:title")
meta(content="FreeCodeCamp", property="og:site_name")
meta(property="og:title", content="Free Code Camp is a community of busy people who learn to code by collaborating on projects for nonprofits. Build your full stack JavaScript Portfolio today.")
meta(property="og:site_name", content="FreeCodeCamp")
meta(name='twitter:widgets:csp', content='on')
meta(name='p:domain_verify', content='d0bc047a482c03c24f1168004c2a216a')
meta(content="http://www.freecodecamp.com", property="og:url")
meta(content="Free Code Camp is a community of busy people who learn to code by collaborating on projects for nonprofits. Build your full stack JavaScript Portfolio today.", property="og:description")
meta(content="https://pbs.twimg.com/profile_images/522961310212833280/XE6vGAaO.jpeg", property="og:image")
meta(content="article", property="og:type")
meta(content="https://www.facebook.com/freecodecamp", property="article:publisher")
meta(content="Responsive", property="article:section")
link(href="https://plus.google.com/+Freecodecamp", rel="publisher")
link(href="https://plus.google.com/+Freecodecamp", rel="author")
meta(content="Free Code Camp is a community of busy people who learn to code by collaborating on projects for nonprofits. Build your full stack JavaScript Portfolio today.", name="description")
meta(content="@freecodecamp", name="twitter:creator")
meta(content="http://www.freecodecamp.com", name="twitter:url")
meta(content="@freecodecamp", name="twitter:site")
meta(content="summary_large_image", name="twitter:card")
meta(content="https://s3.amazonaws.com/freecodecamp/challenges.png", name="twitter:image:src")
meta(content="Free Code Camp: a community of busy people learning to code", name="twitter:title")
meta(content="We're a community of busy people learning to code by collaborating on projects for nonprofits. Learn Full-stack JavaScript, build a portfolio, and get great references with our online coding bootcamp.", name="twitter:description")
meta(content="a40ee5d5dba3bb091ad783ebd2b1383f", name="p:domain_verify")
meta(property="og:url", content="http://www.freecodecamp.com")
meta(property="og:description", content="Free Code Camp is a community of busy people who learn to code by collaborating on projects for nonprofits. Build your full stack JavaScript Portfolio today.")
meta(property="og:image", content="https://pbs.twimg.com/profile_images/522961310212833280/XE6vGAaO.jpeg")
meta(property="og:type", content="article")
meta(property="article:publisher", content="https://www.facebook.com/freecodecamp")
meta(property="article:section", content="Responsive")
link(rel="publisher", href="https://plus.google.com/+Freecodecamp")
link(rel="author", href="https://plus.google.com/+Freecodecamp")
meta(name="description", content="Free Code Camp is a community of busy people who learn to code by collaborating on projects for nonprofits. Build your full stack JavaScript Portfolio today.")
meta(name="twitter:creator", content="@freecodecamp")
meta(name="twitter:url", content="http://www.freecodecamp.com")
meta(name="twitter:site", content="@freecodecamp")
meta(name="twitter:card", content="summary_large_image")
meta(name="twitter:image:src", content="https://s3.amazonaws.com/freecodecamp/challenges.png")
meta(name="twitter:title", content="Free Code Camp: a community of busy people learning to code")
meta(name="twitter:description", content="We're a community of busy people learning to code by collaborating on projects for nonprofits. Learn Full-stack JavaScript, build a portfolio, and get great references with our online coding bootcamp.")
meta(content="a40ee5d5dba3bb091ad783ebd2b1383f", name="p:domain_verify")
meta(name="msapplication-TileColor", content="#FFFFFF")
meta(name="msapplication-TileImage", content="/")
link(rel="android-chrome", sizes="144x144" href="https://s3.amazonaws.com/freecodecamp/favicons/android-chrome-144x144.png")
link(rel="android-chrome", sizes="192x192" href="https://s3.amazonaws.com/freecodecamp/favicons/android-chrome-192x192.png")
link(rel="android-chrome", sizes="36x36" href="https://s3.amazonaws.com/freecodecamp/favicons/android-chrome-36x36.png")
link(rel="android-chrome", sizes="48x48" href="https://s3.amazonaws.com/freecodecamp/favicons/android-chrome-48x48.png")
link(rel="android-chrome", sizes="72x72" href="https://s3.amazonaws.com/freecodecamp/favicons/android-chrome-72x72.png")
link(rel="android-chrome", sizes="96x96" href="https://s3.amazonaws.com/freecodecamp/favicons/android-chrome-96x96.png")
link(rel="android-chrome-manifest", href="https://s3.amazonaws.com/freecodecamp/favicons/android-chrome-manifest.json")
link(rel="apple-touch-icon", sizes="114x114", href="https://s3.amazonaws.com/freecodecamp/favicons/apple-touch-icon-114x114.png")
link(rel="apple-touch-icon", sizes="120x120", href="https://s3.amazonaws.com/freecodecamp/favicons/apple-touch-icon-120x120.png")
link(rel="apple-touch-icon", sizes="144x144", href="https://s3.amazonaws.com/freecodecamp/favicons/apple-touch-icon-144x144.png")
link(rel="apple-touch-icon", sizes="152x152", href="https://s3.amazonaws.com/freecodecamp/favicons/apple-touch-icon-152x152.png")
link(rel="apple-touch-icon", sizes="180x180", href="https://s3.amazonaws.com/freecodecamp/favicons/apple-touch-icon-180x180.png")
link(rel="apple-touch-icon", sizes="57x57", href="https://s3.amazonaws.com/freecodecamp/favicons/apple-touch-icon-57x57.png")
link(rel="apple-touch-icon", sizes="60x60", href="https://s3.amazonaws.com/freecodecamp/favicons/apple-touch-icon-60x60.png")
link(rel="apple-touch-icon", sizes="72x72", href="https://s3.amazonaws.com/freecodecamp/favicons/apple-touch-icon-72x72.png")
link(rel="apple-touch-icon", sizes="76x76", href="https://s3.amazonaws.com/freecodecamp/favicons/apple-touch-icon-76x76.png")
link(rel="apple-touch-icon-precomposed", href="https://s3.amazonaws.com/freecodecamp/favicons/apple-touch-icon-precomposed.png")
link(rel="apple-touch-icon", href="https://s3.amazonaws.com/freecodecamp/favicons/apple-touch-icon.png")
link(rel="favicon", sizes="16x16", href="https://s3.amazonaws.com/freecodecamp/favicons/favicon-16x16.png")
link(rel="favicon", sizes="32x32", href="https://s3.amazonaws.com/freecodecamp/favicons/favicon-32x32.png")
link(rel="favicon", sizes="96x96", href="https://s3.amazonaws.com/freecodecamp/favicons/favicon-96x96.png")
link(rel="mstile", sizes="144x144", href="https://s3.amazonaws.com/freecodecamp/favicons/mstile-144x144.png")
link(rel="mstile", sizes="150x150", href="https://s3.amazonaws.com/freecodecamp/favicons/mstile-150x150.png")
link(rel="mstile", sizes="310x310", href="https://s3.amazonaws.com/freecodecamp/favicons/mstile-310x310.png")
link(rel="mstile", sizes="310x150", href="https://s3.amazonaws.com/freecodecamp/favicons/mstile-310x150.png")
link(rel="mstile", sizes="70x70", href="https://s3.amazonaws.com/freecodecamp/favicons/mstile-70x70.png")
link(rel="favicon", href="https://s3.amazonaws.com/freecodecamp/favicons/favicon.ico")
link(rel='shortcut icon', href='//s3.amazonaws.com/freecodecamp/favicons/favicon.ico')

View File

@@ -37,8 +37,16 @@
a(href='/account') [ #{user.points} ]
.hidden-xs
if user.profile.picture
a(href='/account')
img.profile-picture.float-right(src='#{user.profile.picture}')
if (user.profile.username)
a(href='/' + user.profile.username)
img.profile-picture.float-right(src='#{user.profile.picture}')
else
a(href='/account')
img.profile-picture.float-right(src='#{user.profile.picture}')
else
a(href='/account')
img.profile-picture.float-right(src='#{user.gravatar(60)}')
if (user.profile.username)
a(href='/' + user.profile.username)
img.profile-picture.float-right(src='#{user.gravatar(60)}')
else
a(href='/account')
img.profile-picture.float-right(src='#{user.gravatar(60)}')

View File

@@ -10,6 +10,13 @@ block content
.col-md-8.col-xs-12
.embed-responsive.embed-responsive-16by9
iframe(src='http://www.twitch.tv/freecodecamp/embed', frameborder='0', scrolling='no')
.col-md-4.col-xs-12
.visible-sm.visible-xs
.embed-responsive.embed-responsive-16by9
iframe(src='http://www.twitch.tv/freecodecamp/chat?popout=', frameborder='0', scrolling='no')
.visible-md.visible-lg
.embed-responsive.embed-responsive-twitch-chat
iframe(src='http://www.twitch.tv/freecodecamp/chat?popout=', frameborder='0', scrolling='no')
h1 Previous Live Pair Programming Sessions
.col-xs-12
.embed-responsive.embed-responsive-16by9.big-break