Merge branch 'master' into angular-images

Conflicts:
	controllers/user.js
	views/account/account.jade
This commit is contained in:
Michael Q Larson
2015-01-31 16:44:56 -08:00
14 changed files with 117 additions and 89 deletions

View File

@ -93,13 +93,12 @@ exports.getEmailSignup = function(req, res) {
*/
exports.postEmailSignup = function(req, res, next) {
var errors = req.validationErrors();
if (errors) {
req.flash('errors', errors);
return res.redirect('/email-signup');
console.log(errors);
debug(errors);
}
var user = new User({
@ -127,6 +126,29 @@ exports.postEmailSignup = function(req, res, next) {
res.redirect('/email-signup');
});
});
var transporter = nodemailer.createTransport({
service: 'Mandrill',
auth: {
user: secrets.mandrill.user,
pass: secrets.mandrill.password
}
});
var mailOptions = {
to: user.email,
from: 'Team@freecodecamp.com',
subject: 'Welcome to Free Code Camp!',
text: [
'Greetings from San Francisco!\n\n',
'Thank you for joining our community.\n',
'Feel free to email us at this address if you have any questions about Free Code Camp.\n',
"And if you have a moment, check out our blog: blog.freecodecamp.com.\n",
'Good luck with the challenges!\n\n',
'- the Volunteer Camp Counselor Team'
].join('')
};
transporter.sendMail(mailOptions, function(err) {
if (err) { return err; }
});
});
};
@ -451,9 +473,6 @@ exports.getReset = function(req, res) {
*/
exports.postReset = function(req, res, next) {
req.assert('password', 'Password must be at least 4 characters long.').len(4);
req.assert('confirm', 'Passwords must match.').equals(req.body.password);
var errors = req.validationErrors();
if (errors) {
@ -542,8 +561,6 @@ exports.getForgot = function(req, res) {
*/
exports.postForgot = function(req, res, next) {
req.assert('email', 'Please enter a valid email address.').isEmail();
var errors = req.validationErrors();
if (errors) {

View File

@ -154,6 +154,11 @@ ul {
}
.landing-icon {
height: 200px;
width: 200px;
}
.completion-icon{
font-size: 150px;
}

View File

@ -420,8 +420,8 @@
"OK, we're finally ready to start pair programming!",
"Pair Programming is where two people code together on the same computer. It is an efficient way to collaborate, and widely practiced at software companies. Pair Programming is one of the core concepts of \"Agile\" Software Development, which you will hear more about later.",
"Many people use Skype or Google Hangouts to pair program, but if you talk with professional software engineers, they will tell you that it's not really pair programming unless both people have the ability to use the keyboard and mouse.",
"The most popular tool for pair programming is Screen Hero. Note that Screen Hero isn't free, and isn't yet available for Linux. Screen Hero does come with a 14 day free trial, is free for students, and you can also use it for free if your pair has a 14-day trial or a paid subscription to it. Download Screen Hero here: <a href='https://screenhero.com/download.html' target='_blank'>https://screenhero.com/download.html</a>.",
"If you are using Linux, or if your 14 day free trial for Screen Hero has expired and you don't want to pay $10 per month for it, go to <a href='http://www.freecodecamp.com/pair-program-with-team-viewer' target='_blank'>http://www.freecodecamp.com/pair-program-with-team-viewer</a> to learn how to use an alternative (but inferior) tool called Team Viewer.",
"The most popular tool for pair programming is Screen Hero. You can download Screen Hero for <a href='http://links.screenhero.com/e/c/eyJlbWFpbF9pZCI6Ik1qQTNNem9XQkNJQ1pBQUNjd0FYQVZrVEdnRkxNamtfX0JWZEdGVEpSZkVCWlRwbFpXRTBNamM0WVMxaE56SmlMVEV4WlRRdE9HUXpZUzFpWXpVNE1HRTJNalkxTldNNk1UUTJNVEEyQUE9PSIsInBvc2l0aW9uIjowLCJocmVmIjoiaHR0cDovL2RsLnNjcmVlbmhlcm8uY29tL3NtYXJ0ZG93bmxvYWQvZklYQU1UUUJBTEtQQkhQTC9TY3JlZW5oZXJvLnppcD9zb3VyY2U9d2ViIn0=' target='_blank'>Mac</a> or <a href='http://links.screenhero.com/e/c/eyJlbWFpbF9pZCI6Ik1qQTNNem9XQkNJQ1pBQUNjd0FYQVZrVEdnRkxNamtfX0JWZEdGVEpSZkVCWlRwbFpXRTBNamM0WVMxaE56SmlMVEV4WlRRdE9HUXpZUzFpWXpVNE1HRTJNalkxTldNNk1UUTJNVEEyQUE9PSIsInBvc2l0aW9uIjoxLCJocmVmIjoiaHR0cDovL2RsLnNjcmVlbmhlcm8uY29tL3NtYXJ0ZG93bmxvYWQvZklYQU1UUUJBTEtQQkhQTC9TY3JlZW5oZXJvLXNldHVwLmV4ZSJ9' target='_blank'>Windows</a>. Create your new user account from within the app.",
"If you are using Linux, go to <a href='http://www.freecodecamp.com/pair-program-with-team-viewer' target='_blank'>http://www.freecodecamp.com/pair-program-with-team-viewer</a> to learn how to use an alternative (but inferior) tool called Team Viewer.",
"We have a special chat room for people ready to pair program. Go to <a href='https://gitter.im/FreeCodeCamp/LetsPair' target='_blank'>https://gitter.im/FreeCodeCamp/LetsPair</a> and type \"Hello Pair Programmers!\"",
"If someone is available, they will be your \"pair\" - the person you pair programming with.",
"Private message your pair and ask for the email address he or she used to register Screen Hero.",

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
@ -90,7 +90,7 @@ block content
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.
@ -110,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.
@ -122,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).
@ -131,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).
@ -140,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).
@ -149,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).
@ -170,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.
@ -179,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).
@ -204,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.
@ -213,7 +213,7 @@ 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).
@ -237,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.
@ -246,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).
@ -254,6 +254,7 @@ block content
.form-group
label.col-sm-3.col-sm-offset-2.control-label(for='website3Image') Image Link (4:3 ratio)
.col-sm-4
<<<<<<< HEAD
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)?$/")
.col-sm-4.col-sm-offset-5(ng-show="profileForm.website3Image.$error.url && !profileForm.website3Image.$pristine")
alert(type='danger')
@ -308,23 +309,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

@ -108,7 +108,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 +116,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')
@ -30,4 +30,3 @@ script.
ga('create', 'UA-55446531-1', 'auto');
ga('require', 'displayfeatures');
ga('send', 'pageview');
script(src="//cdn.optimizely.com/js/999692993.js")

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')
@ -31,4 +31,3 @@ script.
ga('create', 'UA-55446531-1', 'auto');
ga('require', 'displayfeatures');
ga('send', 'pageview');
script(src="//cdn.optimizely.com/js/999692993.js")

View File

@ -37,8 +37,16 @@
a(href='/account') [&nbsp;#{user.points}&nbsp;]
.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