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) { exports.postEmailSignup = function(req, res, next) {
var errors = req.validationErrors(); var errors = req.validationErrors();
if (errors) { if (errors) {
req.flash('errors', errors); req.flash('errors', errors);
return res.redirect('/email-signup'); return res.redirect('/email-signup');
console.log(errors); debug(errors);
} }
var user = new User({ var user = new User({
@ -127,6 +126,29 @@ exports.postEmailSignup = function(req, res, next) {
res.redirect('/email-signup'); 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) { 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(); var errors = req.validationErrors();
if (errors) { if (errors) {
@ -542,8 +561,6 @@ exports.getForgot = function(req, res) {
*/ */
exports.postForgot = function(req, res, next) { exports.postForgot = function(req, res, next) {
req.assert('email', 'Please enter a valid email address.').isEmail();
var errors = req.validationErrors(); var errors = req.validationErrors();
if (errors) { if (errors) {

View File

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

View File

@ -420,8 +420,8 @@
"OK, we're finally ready to start pair programming!", "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.", "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.", "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>.", "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, 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.", "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!\"", "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.", "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.", "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 * label.col-sm-3.col-sm-offset-2.control-label(for='name') Name *
.col-sm-4 .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') 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') alert(type='danger')
span.ion-close-circled(id='#name-error') span.ion-close-circled(id='#name-error')
| Your name is required. | 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') alert(type='danger')
span.ion-close-circled span.ion-close-circled
| Your name must be at least 3 characters. | 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') alert(type='danger')
span.ion-close-circled span.ion-close-circled
| Your name must be fewer than 50 characters. | 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) * label.col-sm-3.col-sm-offset-2.control-label(for='username') Username (path to public profile) *
.col-sm-4 .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_]+$/") 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') alert(type='danger')
span.ion-close-circled span.ion-close-circled
| Your username should only contain letters, numbers and underscores (az10_). | 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') alert(type='danger')
span.ion-close-circled span.ion-close-circled
| Your username is required. | 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') alert(type='danger')
span.ion-close-circled span.ion-close-circled
| Your username must be at least 5 characters. | 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') alert(type='danger')
span.ion-close-circled span.ion-close-circled
| Your username must be fewer than 15 characters. | 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') alert(type='danger')
span.ion-close-circled span.ion-close-circled
| That username is already taken. | That username is already in use.
.form-group .form-group
label.col-sm-3.col-sm-offset-2.control-label(for='email') Email * label.col-sm-3.col-sm-offset-2.control-label(for='email') Email *
.col-sm-4 .col-sm-4
input.form-control(type='email', name='email', id='email', autocomplete="off", ng-model='user.email', required='required', ng-keypress='', unique-email='') 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') alert(type='danger')
span.ion-close-circled span.ion-close-circled
| Your email address is required. | 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') alert(type='danger')
span.ion-close-circled span.ion-close-circled
| Please enter a valid email format. | Please enter a valid email format.
.col-sm-4.col-sm-offset-5(ng-show="profileForm.email.$error.unique && !profileForm.email.$pristine") .col-sm-4.col-sm-offset-5(ng-cloak, ng-show="profileForm.email.$error.unique && !profileForm.email.$pristine")
alert(type='danger') alert(type='danger')
span.ion-close-circled span.ion-close-circled
| That email is already taken. | That email is already in use.
.form-group .form-group
label.col-sm-3.col-sm-offset-2.control-label(for='location') Location 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) label.col-sm-3.col-sm-offset-2.control-label(for='bio') Bio (140 characters)
.col-sm-4 .col-sm-4
input.form-control(type='text', name='bio', autocomplete="off", ng-model='user.profile.bio', ng-maxlength='140', id='bio') 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') alert(type='danger')
span.ion-close-circled span.ion-close-circled
| Your bio must be fewer than 140 characters. | Your bio must be fewer than 140 characters.
@ -110,11 +110,11 @@ block content
.input-group.twitter-input .input-group.twitter-input
span.input-group-addon @ 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_]+$/") 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') alert(type='danger')
span.ion-close-circled span.ion-close-circled
| Your Twitter handle should only contain letters, numbers and underscores (az10_). | 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') alert(type='danger')
span.ion-close-circled span.ion-close-circled
| Your name must be fewer than 15 characters. | 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 label.col-sm-3.col-sm-offset-2.control-label(for='email') Github
.col-sm-4 .col-sm-4
input.form-control(type='url', name='githubProfile', id='githubProfile', autocomplete="off", ng-model='user.profile.githubProfile', placeholder='http://') 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') alert(type='danger')
span.ion-close-circled span.ion-close-circled
| Please enter a valid URL format (http://www.example.com). | 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 label.col-sm-3.col-sm-offset-2.control-label(for='email') CodePen
.col-sm-4 .col-sm-4
input.form-control(type='url', name='codepenProfile', id='codepenProfile', autocomplete="off", ng-model='user.profile.codepenProfile', placeholder='http://') 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') alert(type='danger')
span.ion-close-circled span.ion-close-circled
| Please enter a valid URL format (http://www.example.com). | 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 label.col-sm-3.col-sm-offset-2.control-label(for='email') CoderByte
.col-sm-4 .col-sm-4
input.form-control(type='url', name='coderbyteProfile', id='coderbyteProfile', autocomplete="off", ng-model='user.profile.coderbyteProfile', placeholder='http://') 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') alert(type='danger')
span.ion-close-circled span.ion-close-circled
| Please enter a valid URL format (http://www.example.com). | 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 label.col-sm-3.col-sm-offset-2.control-label(for='email') LinkedIn
.col-sm-4 .col-sm-4
input.form-control(type='url', name='linkedinProfile', id='linkedinProfile', autocomplete="off", ng-model='user.profile.linkedinProfile', placeholder='http://') 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') alert(type='danger')
span.ion-close-circled span.ion-close-circled
| Please enter a valid URL format (http://www.example.com). | 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 label.col-sm-3.col-sm-offset-2.control-label(for='website1Title') Title
.col-sm-4 .col-sm-4
input.form-control(type='text', name='website1Title', id='website1Title', autocomplete="off", ng-model='user.portfolio.website1Title', ng-maxlength='140') 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') alert(type='danger')
span.ion-close-circled span.ion-close-circled
| Portfolio project title must be fewer than 140 characters. | 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 label.col-sm-3.col-sm-offset-2.control-label(for='website1Link') Link
.col-sm-4 .col-sm-4
input.form-control(type='url', name='website1Link', id='website1Link', autocomplete="off", ng-model='user.portfolio.website1Link', placeholder='http://') 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') alert(type='danger')
span.ion-close-circled span.ion-close-circled
| Please enter a valid URL format (http://www.example.com). | 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 label.col-sm-3.col-sm-offset-2.control-label(for='website2Title') Title
.col-sm-4 .col-sm-4
input.form-control(type='text', name='website2Title', id='website2Title', autocomplete="off", ng-model='user.portfolio.website2Title', ng-maxlength='140') 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') alert(type='danger')
span.ion-close-circled span.ion-close-circled
| Portfolio project title must be fewer than 140 characters. | 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 label.col-sm-3.col-sm-offset-2.control-label(for='website2Link') Link
.col-sm-4 .col-sm-4
input.form-control(type='url', name='website2Link', id='website2Link', autocomplete="off", ng-model='user.portfolio.website2Link', placeholder='http://') 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') alert(type='danger')
span.ion-close-circled span.ion-close-circled
| Please enter a valid URL format (http://www.example.com). | 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 label.col-sm-3.col-sm-offset-2.control-label(for='website3Title') Title
.col-sm-4 .col-sm-4
input.form-control(type='text', name='website3Title', id='website3Title', autocomplete="off", ng-model='user.portfolio.website3Title', ng-maxlength='140') 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') alert(type='danger')
span.ion-close-circled span.ion-close-circled
| Portfolio project title must be fewer than 140 characters. | 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 label.col-sm-3.col-sm-offset-2.control-label(for='website3Link') Link
.col-sm-4 .col-sm-4
input.form-control(type='url', name='website3Link', id='website3Link', autocomplete="off", ng-model='user.portfolio.website3Link', placeholder='http://') 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') alert(type='danger')
span.ion-close-circled span.ion-close-circled
| Please enter a valid URL format (http://www.example.com). | Please enter a valid URL format (http://www.example.com).
@ -254,6 +254,7 @@ block content
.form-group .form-group
label.col-sm-3.col-sm-offset-2.control-label(for='website3Image') Image Link (4:3 ratio) label.col-sm-3.col-sm-offset-2.control-label(for='website3Image') Image Link (4:3 ratio)
.col-sm-4 .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)?$/") 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") .col-sm-4.col-sm-offset-5(ng-show="profileForm.website3Image.$error.url && !profileForm.website3Image.$pristine")
alert(type='danger') alert(type='danger')
@ -308,23 +309,7 @@ block content
a.btn.btn-lg.btn-block.btn-twitter.btn-link-social(href='/auth/twitter') a.btn.btn-lg.btn-block.btn-twitter.btn-link-social(href='/auth/twitter')
i.fa.fa-twitter i.fa.fa-twitter
| Link Twitter with your account | 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.panel-danger
.panel-heading.text-center Danger Zone: .panel-heading.text-center Danger Zone:
.panel-body .panel-body

View File

@ -7,46 +7,54 @@ block content
.form-group .form-group
.col-sm-6.col-sm-offset-3 .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='') 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') alert(type='danger')
span.ion-close-circled 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 .form-group
.col-sm-6.col-sm-offset-3 .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_]+$/") 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') alert(type='danger')
span.ion-close-circled span.ion-close-circled
| Your username should only contain letters, numbers and underscores (az10_). | 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') alert(type='danger')
span.ion-close-circled span.ion-close-circled
| This username is taken. | 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') alert(type='danger')
span.ion-close-circled span.ion-close-circled
| Your username must be at least 5 characters long. | 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') alert(type='danger')
span.ion-close-circled span.ion-close-circled
| Your usernames must be 20 characters or fewer. | Your usernames must be 20 characters or fewer.
.form-group .form-group
.col-sm-6.col-sm-offset-3 .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) 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') alert(type='danger')
span.ion-close-circled span.ion-close-circled
| Your password must be at least 8 characters long. | Your password must be at least 8 characters long.
.form-group .form-group
.col-sm-6.col-sm-offset-3 .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) 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") .col-sm-6.col-sm-offset-3(ng-cloak, ng-show="(confirmPassword !== password) && !signupForm.confirmPassword.$pristine")
alert(type='danger') alert(type='danger')
span.ion-close-circled span.ion-close-circled
| Passwords must match. | Passwords must match.
.form-group .form-group
.col-sm-offset-3.col-sm-6 .col-sm-6.col-sm-offset-3
button.btn.btn-success(type='submit') button.btn.btn-success(type='submit', ng-disabled='signupForm.$invalid')
span.ion-person-add span.ion-person-add
| Signup | Signup
br br

View File

@ -108,7 +108,7 @@ block content
.text-center .text-center
.animated.zoomInDown.delay-half .animated.zoomInDown.delay-half
span.landing-icon.ion-checkmark-circled.text-primary span.completion-icon.ion-checkmark-circled.text-primary
- if (cc) - if (cc)
form.form-horizontal(novalidate='novalidate', name='completedWithForm') form.form-horizontal(novalidate='novalidate', name='completedWithForm')
.form-group.text-center .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 // extra field to distract password tools like lastpass from injecting css into our username field
input.form-control(ng-show="false") 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) 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') alert(type='danger')
span.ion-close-circled span.ion-close-circled
| Username not found | Username not found

View File

@ -24,7 +24,7 @@ block content
.modal-body .modal-body
.text-center .text-center
.animated.zoomInDown.delay-half .animated.zoomInDown.delay-half
span.landing-icon.ion-checkmark-circled.text-primary span.completion-icon.ion-checkmark-circled.text-primary
- if (cc) - 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 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) - if (points && points > 2)

View File

@ -14,11 +14,11 @@ block content
label(class='col-sm-3 control-label', for='email') Your email * label(class='col-sm-3 control-label', for='email') Your email *
.col-sm-8 .col-sm-8
input.form-control(type='text', name='email', id='email', autocomplete="off", ng-model='email', required='required', ng-keypress='') 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') alert(type='danger')
span.ion-close-circled span.ion-close-circled
| Please enter a valid email format. | 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') alert(type='danger')
span.ion-close-circled(id='#email-error'). span.ion-close-circled(id='#email-error').
Your email is required. Your email is required.

View File

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

View File

@ -7,19 +7,19 @@ block content
.row .row
.col-xs-12.col-sm-12.col-md-3 .col-xs-12.col-sm-12.col-md-3
h3.nowrap Get Connected 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. p.landing-p Join a community of busy, motivated professionals.
.col-xs-12.col-sm-12.col-md-3 .col-xs-12.col-sm-12.col-md-3
h3.nowrap Learn JavaScript 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. p.landing-p Work together on Full Stack JavaScript coding challenges.
.col-xs-12.col-sm-12.col-md-3 .col-xs-12.col-sm-12.col-md-3
h3.nowrap Build your Portfolio 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. p.landing-p Build apps that solve real problems for real people.
.col-xs-12.col-sm-12.col-md-3 .col-xs-12.col-sm-12.col-md-3
h3.nowrap Help Nonprofits 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. p.landing-p Give nonprofits a boost by empowering them with code.
.big-break .big-break
a.btn.btn-cta.signup-btn(href="/login") Start learning to code (it's free) 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') html(ng-app='profileValidation', lang='en')
head head
script(src="//ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js") 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") 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='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/bootstrap/3.3.1/css/bootstrap.min.css')
@ -30,4 +30,3 @@ script.
ga('create', 'UA-55446531-1', 'auto'); ga('create', 'UA-55446531-1', 'auto');
ga('require', 'displayfeatures'); ga('require', 'displayfeatures');
ga('send', 'pageview'); 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') html(ng-app='profileValidation', lang='en')
head head
script(src="//ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js") 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") 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='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/bootstrap/3.3.1/css/bootstrap.min.css')
@ -31,4 +31,3 @@ script.
ga('create', 'UA-55446531-1', 'auto'); ga('create', 'UA-55446531-1', 'auto');
ga('require', 'displayfeatures'); ga('require', 'displayfeatures');
ga('send', 'pageview'); ga('send', 'pageview');
script(src="//cdn.optimizely.com/js/999692993.js")

View File

@ -37,8 +37,16 @@
a(href='/account') [&nbsp;#{user.points}&nbsp;] a(href='/account') [&nbsp;#{user.points}&nbsp;]
.hidden-xs .hidden-xs
if user.profile.picture if user.profile.picture
a(href='/account') if (user.profile.username)
img.profile-picture.float-right(src='#{user.profile.picture}') 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 else
a(href='/account') if (user.profile.username)
img.profile-picture.float-right(src='#{user.gravatar(60)}') 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 .col-md-8.col-xs-12
.embed-responsive.embed-responsive-16by9 .embed-responsive.embed-responsive-16by9
iframe(src='http://www.twitch.tv/freecodecamp/embed', frameborder='0', scrolling='no') 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 h1 Previous Live Pair Programming Sessions
.col-xs-12 .col-xs-12
.embed-responsive.embed-responsive-16by9.big-break .embed-responsive.embed-responsive-16by9.big-break