Merge branch 'master' into courseware

Conflicts:
	controllers/bonfire.js
	controllers/resources.json
	views/bonfire/show.jade
This commit is contained in:
Nathan Leniz
2015-02-06 14:39:16 -05:00
14 changed files with 177 additions and 103 deletions

1
Procfile Normal file
View File

@ -0,0 +1 @@
web: ./node_modules/.bin/forever -m 5 app.js

View File

@ -62,7 +62,7 @@ exports.returnNextBonfire = function(req, res) {
if (bonfire === undefined) { if (bonfire === undefined) {
req.flash('errors', { req.flash('errors', {
msg: "It looks like you've completed all the bonfires we have available. Good job!" msg: "It looks like you've completed all the bonfires we have available. Good job!"
}) });
return res.redirect('../bonfires/meet-bonfire'); return res.redirect('../bonfires/meet-bonfire');
} }
nameString = bonfire.name.toLowerCase().replace(/\s/g, '-'); nameString = bonfire.name.toLowerCase().replace(/\s/g, '-');
@ -79,38 +79,43 @@ exports.returnIndividualBonfire = function(req, res, next) {
if (err) { if (err) {
next(err); next(err);
} }
if (bonfire.length < 1) {
req.flash('errors', {
msg: "404: We couldn't find a bonfire with that name. Please double check the name."
});
return res.redirect('/bonfires');
}
bonfire = bonfire.pop() bonfire = bonfire.pop()
var dashedNameFull = bonfire.name.toLowerCase().replace(/\s/g, '-'); var dashedNameFull = bonfire.name.toLowerCase().replace(/\s/g, '-');
if (dashedNameFull != dashedName) { if (dashedNameFull != dashedName) {
return res.redirect('../bonfires/' + dashedNameFull); return res.redirect('../bonfires/' + dashedNameFull);
} }
if (bonfire.length < 1) {
req.flash('errors', {
msg: "404: We couldn't find a bonfire with that name. Please double check the name."
});
return res.redirect('/bonfires')
} else {
res.render('bonfire/show', {
completedWith: null,
title: bonfire.name,
dashedName: dashedName,
name: bonfire.name,
difficulty: Math.floor(+bonfire.difficulty),
brief: bonfire.description[0],
details: bonfire.description.slice(1),
tests: bonfire.tests,
challengeSeed: bonfire.challengeSeed,
challengeEntryPoint: bonfire.challengeEntryPoint,
cc: !!req.user,
points: req.user ? req.user.points : undefined,
verb: resources.randomVerb(),
phrase: resources.randomPhrase(),
compliment: resources.randomCompliment(),
bonfires: bonfire,
bonfireHash: bonfire._id
}); res.render('bonfire/show', {
} completedWith: null,
title: bonfire.name,
dashedName: dashedName,
name: bonfire.name,
difficulty: Math.floor(+bonfire.difficulty),
brief: bonfire.description[0],
details: bonfire.description.slice(1),
tests: bonfire.tests,
challengeSeed: bonfire.challengeSeed,
challengeEntryPoint: bonfire.challengeEntryPoint,
cc: !!req.user,
points: req.user ? req.user.points : undefined,
verb: resources.randomVerb(),
phrase: resources.randomPhrase(),
compliment: resources.randomCompliment(),
bonfires: bonfire,
bonfireHash: bonfire._id
});
}); });
}; };

View File

@ -164,6 +164,7 @@
"Down the rabbit hole we go!", "Down the rabbit hole we go!",
"Well, isn't that special!", "Well, isn't that special!",
"Somewhere over the rainbow!", "Somewhere over the rainbow!",
"Follow the white rabbit!",
"Eye of the tiger!", "Eye of the tiger!",
"Run, Forest, run!", "Run, Forest, run!",
"Welcome to the Rock!", "Welcome to the Rock!",
@ -214,6 +215,7 @@
"It's alive. It's alive!", "It's alive. It's alive!",
"Sonic Boom!", "Sonic Boom!",
"Here's looking at you, Code!", "Here's looking at you, Code!",
"Ride like the wind!",
"The more you code!", "The more you code!",
"Legen - wait for it - dary!", "Legen - wait for it - dary!",
"Ludicrous Speed! Go!", "Ludicrous Speed! Go!",
@ -224,7 +226,28 @@
"By the power of Grayskull!", "By the power of Grayskull!",
"You did it!", "You did it!",
"Storm that castle!", "Storm that castle!",
"Face-melting guitar Solo!" "Face-melting guitar Solo!",
"Checkmate!",
"Remember the Alamo!",
"Bodacious!",
"You're the man now, dog!",
"Tubular!",
"You're outta sight!",
"Keep calm and code on!",
"Even sad panda smiles!",
"Even grumpy cat approves!",
"Koolaid Man says oh yeah!",
"Bullseye!",
"You stay classy, San Diego!",
"Loud noises!",
"Me want cookie!",
"Far out!",
"You're heating up!",
"Crash override!",
"This is Sparta!",
"You ARE the law!",
"Hasta la vista, challenge!",
"Huh? It's just a box..."
], ],
"phrases": [ "phrases": [
"Shout it from on top of a mountain", "Shout it from on top of a mountain",

View File

@ -12,7 +12,7 @@
"scripts": { "scripts": {
"start": "node app.js", "start": "node app.js",
"test": "mocha", "test": "mocha",
"prepublish": "node seed_data/seed.js" "postinstall": "node seed_data/seed.js"
}, },
"dependencies": { "dependencies": {
"async": "^0.9.0", "async": "^0.9.0",
@ -33,6 +33,7 @@
"express-flash": "^0.0.2", "express-flash": "^0.0.2",
"express-session": "^1.9.2", "express-session": "^1.9.2",
"express-validator": "^2.8.0", "express-validator": "^2.8.0",
"forever": "^0.14.1",
"github-api": "^0.7.0", "github-api": "^0.7.0",
"helmet": "^0.5.3", "helmet": "^0.5.3",
"jade": "^1.8.0", "jade": "^1.8.0",

View File

@ -136,6 +136,12 @@ ul {
font-size: 25px; font-size: 25px;
} }
.panel-heading > h1 {
font-size: 25px;
padding: 2px;
margin: 2px;
}
.navbar-brand { .navbar-brand {
font-size: 26px; font-size: 26px;
} }

View File

@ -136,7 +136,7 @@
"name": "Sum All Numbers in a Range", "name": "Sum All Numbers in a Range",
"difficulty": "2.00", "difficulty": "2.00",
"description": [ "description": [
"We'll pass you an array of two numbers. Return the sum those two numbers and all numbers between them.", "We'll pass you an array of two numbers. Return the sum of those two numbers and all numbers between them.",
"The lowest number will not always come first." "The lowest number will not always come first."
], ],
"challengeEntryPoint": "sumAll([1, 4]);", "challengeEntryPoint": "sumAll([1, 4]);",
@ -149,9 +149,29 @@
"expect(sumAll([10, 5])).to.equal(45);" "expect(sumAll([10, 5])).to.equal(45);"
] ]
}, },
{
"_id": "d5de63ebea8dbee56860f4f2",
"name": "Diff Two Arrays",
"difficulty": "2.01",
"description": [
"Compare two arrays and return a new array with any items not found in both of the original arrays."
],
"challengeEntryPoint": "diff([1, 2, 3, 5], [1, 2, 3, 4, 5]);",
"challengeSeed": "function diff(arr1, arr2) {\n var newArr = [];\r\n // Same, same; but different.\r\n return newArr;\r\n}",
"tests": [
"expect(diff([1, 2, 3, 5], [1, 2, 3, 4, 5])).to.be.a('array');",
"assert.deepEqual(diff(['diorite', 'andesite', 'grass', 'dirt', 'pink wool', 'dead shrub'], ['diorite', 'andesite', 'grass', 'dirt', 'dead shrub']), ['pink wool'], 'arrays with only one difference');",
"assert.includeMembers(diff(['andesite', 'grass', 'dirt', 'pink wool', 'dead shrub'], ['diorite', 'andesite', 'grass', 'dirt', 'dead shrub']), ['diorite', 'pink wool'], 'arrays with more than one difference');",
"assert.deepEqual(diff(['andesite', 'grass', 'dirt', 'dead shrub'], ['andesite', 'grass', 'dirt', 'dead shrub']), [], 'arrays with no difference');",
"assert.deepEqual(diff([1, 2, 3, 5], [1, 2, 3, 4, 5]), [4], 'arrays with numbers');",
"assert.includeMembers(diff([1, 'calf', 3, 'piglet'], [1, 'calf', 3, 4]), ['piglet', 4], 'arrays with numbers and strings');",
"assert.deepEqual(diff([], ['snuffleupagus', 'cookie monster', 'elmo']), ['snuffleupagus', 'cookie monster', 'elmo'], 'empty array');"
]
},
{ {
"_id": "a5229172f011153519423690", "_id": "a5229172f011153519423690",
"name": "Sum All Odd Fibonacci Numbers", "name": "Sum All Odd Fibonacci Numbers",
"difficulty": "2.09",
"description": [ "description": [
"Return the sum of all odd fibonacci numbers up to and including the passed number if it is a fibonacci number.", "Return the sum of all odd fibonacci numbers up to and including the passed number if it is a fibonacci number.",
"The first few numbers of the Fibonacci sequence are 1, 1, 2, 3, 5 and 8, and each subsequent number is the sum of the previous two numbers.", "The first few numbers of the Fibonacci sequence are 1, 1, 2, 3, 5 and 8, and each subsequent number is the sum of the previous two numbers.",
@ -202,10 +222,38 @@
"(smallestCommons([1,13])).should.equal(360360);" "(smallestCommons([1,13])).should.equal(360360);"
] ]
}, },
{
"_id": "a2f1d72d9b908d0bd72bb9f6",
"name": "Make a Person",
"difficulty": "3.12",
"description": [
"Fill in the object constructor with the methods specified in the tests.",
"Those methods are getFirstName(), getLastName(), getFullName(), setFirstName(), setLastName(), and setFullName().",
"These methods must be the only available means for interacting with the object.",
"There will be some linting errors on the tests, you may safely ignore them. You should see undefined in the console output."
],
"challengeEntryPoint": "var bob = new Person('Bob Ross');",
"challengeSeed": "var Person = function(firstAndLast) {\n return firstAndLast;\r\n};",
"tests": [
"expect(Object.keys(bob).length).to.eql(6);",
"expect(bob instanceof Person).to.be.true;",
"expect(bob.firstName).to.be.undefined();",
"expect(bob.lastName).to.be.undefined();",
"expect(bob.getFirstName()).to.eql('Bob');",
"expect(bob.getLastName()).to.eql('Ross');",
"expect(bob.getFullName()).to.eql('Bob Ross');",
"bob.setFirstName('Happy');",
"expect(bob.getFirstName()).to.eql('Happy');",
"bob.setLastName('Trees');",
"expect(bob.getLastName()).to.eql('Trees');",
"bob.setFullName('George Carlin');",
"expect(bob.getFullName()).to.eql('George Carlin');"
]
},
{ {
"_id" : "aff0395860f5d3034dc0bfc9", "_id" : "aff0395860f5d3034dc0bfc9",
"name": "Validate US Telephone Numbers", "name": "Validate US Telephone Numbers",
"difficulty": "3.10", "difficulty": "4.01",
"description": [ "description": [
"Return true if the passed string is a valid US phone number", "Return true if the passed string is a valid US phone number",
"The user may fill out the form field any way they choose as long as it is a valid US number. The following are all valid formats for US numbers:", "The user may fill out the form field any way they choose as long as it is a valid US number. The following are all valid formats for US numbers:",
@ -239,10 +287,29 @@
"challengeSeed": "function telephoneCheck(str) {\n // Good luck!\n return true;\n}\n\n", "challengeSeed": "function telephoneCheck(str) {\n // Good luck!\n return true;\n}\n\n",
"challengeEntryPoint": "telephoneCheck(\"555-555-5555\");" "challengeEntryPoint": "telephoneCheck(\"555-555-5555\");"
}, },
{
"_id": "ca2e6f85cab2ab736c9a9b24",
"name": "Cash Register",
"difficulty": "4.02",
"description": [
"Design a cash register drawer function that accepts purchase price as the first argument, payment as the second argument, and cash-in-drawer (cid) as the third argument. cid is a 2d array listing available currency. Return the string \"Insufficient Funds\" if change due is less than the cash-in-drawer. Return the string \"Closed\" if cash-in-drawer is equal to the change due. Otherwise, return change in coin and bills, sorted in highest to lowest order."
],
"challengeEntryPoint": "drawer(19.50, 20.00, [['PENNY', 1.01], ['NICKEL', 2.05], ['DIME', 3.10], ['QUARTER', 4.25], ['ONE', 90.00], ['FIVE', 55.00], ['TEN', 20.00], ['TWENTY', 60.00], ['ONE HUNDRED', 100.00]]);",
"challengeSeed": "function drawer(price, cash, cid) {\n var change;\r\n // Here is your change, ma'am.\r\n return change;\r\n}\r\n\r\n// Example cash-in-drawer array:\r\n// [['PENNY', 1.01],\r\n// ['NICKEL', 2.05],\r\n// ['DIME', 3.10],\r\n// ['QUARTER', 4.25],\r\n// ['ONE', 90.00],\r\n// ['FIVE', 55.00],\r\n// ['TEN', 20.00],\r\n// ['TWENTY', 60.00],\r\n// ['ONE HUNDRED', 100.00]]",
"tests": [
"expect(drawer(19.50, 20.00, [['PENNY', 1.01], ['NICKEL', 2.05], ['DIME', 3.10], ['QUARTER', 4.25], ['ONE', 90.00], ['FIVE', 55.00], ['TEN', 20.00], ['TWENTY', 60.00], ['ONE HUNDRED', 100.00]])).to.be.a('array');",
"expect(drawer(19.50, 20.00, [['PENNY', 0.01], ['NICKEL', 0], ['DIME', 0], ['QUARTER', 0], ['ONE', 0], ['FIVE', 0], ['TEN', 0], ['TWENTY', 0], ['ONE HUNDRED', 0]])).to.be.a('string');",
"expect(drawer(19.50, 20.00, [['PENNY', 0.50], ['NICKEL', 0], ['DIME', 0], ['QUARTER', 0], ['ONE', 0], ['FIVE', 0], ['TEN', 0], ['TWENTY', 0], ['ONE HUNDRED', 0]])).to.be.a('string');",
"assert.deepEqual(drawer(19.50, 20.00, [['PENNY', 1.01], ['NICKEL', 2.05], ['DIME', 3.10], ['QUARTER', 4.25], ['ONE', 90.00], ['FIVE', 55.00], ['TEN', 20.00], ['TWENTY', 60.00], ['ONE HUNDRED', 100.00]]), [['QUARTER', 0.50]], 'return correct change');",
"assert.deepEqual(drawer(3.26, 100.00, [['PENNY', 1.01], ['NICKEL', 2.05], ['DIME', 3.10], ['QUARTER', 4.25], ['ONE', 90.00], ['FIVE', 55.00], ['TEN', 20.00], ['TWENTY', 60.00], ['ONE HUNDRED', 100.00]]), [['TWENTY', 80.00], ['TEN', 10.00], ['FIVE', 5], ['ONE', 1], ['QUARTER', 0.50], ['DIME', 0.20], ['PENNY', 0.04] ], 'return correct change with multiple coins and bills');",
"assert.deepEqual(drawer(19.50, 20.00, [['PENNY', 0.01], ['NICKEL', 0], ['DIME', 0], ['QUARTER', 0], ['ONE', 0], ['FIVE', 0], ['TEN', 0], ['TWENTY', 0], ['ONE HUNDRED', 0]]), 'Insufficient Funds', 'insufficient funds');",
"assert.deepEqual(drawer(19.50, 20.00, [['PENNY', 0.50], ['NICKEL', 0], ['DIME', 0], ['QUARTER', 0], ['ONE', 0], ['FIVE', 0], ['TEN', 0], ['TWENTY', 0], ['ONE HUNDRED', 0]]), \"Closed\", 'cash-in-drawer equals change');"
]
},
{ {
"_id": "556138aff60341a09ed6c480", "_id": "556138aff60341a09ed6c480",
"name": "Inventory Update", "name": "Inventory Update",
"difficulty": "3.11", "difficulty": "4.03",
"description": [ "description": [
"Compare and update inventory stored in a 2d array against a second 2d array of a fresh delivery. Update current inventory item quantity, and if an item cannot be found, add the new item and quantity into the inventory array in alphabetical order." "Compare and update inventory stored in a 2d array against a second 2d array of a fresh delivery. Update current inventory item quantity, and if an item cannot be found, add the new item and quantity into the inventory array in alphabetical order."
], ],
@ -256,34 +323,6 @@
"assert.deepEqual(inventory([], [[2, 'Hair Pin'], [3, 'Half-Eaten Apple'], [67, 'Bowling Ball'], [7, 'Toothpaste']]), [[2, 'Hair Pin'], [3, 'Half-Eaten Apple'], [67, 'Bowling Ball'], [7, 'Toothpaste']]);", "assert.deepEqual(inventory([], [[2, 'Hair Pin'], [3, 'Half-Eaten Apple'], [67, 'Bowling Ball'], [7, 'Toothpaste']]), [[2, 'Hair Pin'], [3, 'Half-Eaten Apple'], [67, 'Bowling Ball'], [7, 'Toothpaste']]);",
"assert.deepEqual(inventory([[0, 'Bowling Ball'], [0, 'Dirty Sock'], [0, 'Hair pin'], [0, 'Microphone']], [[1, 'Hair Pin'], [1, 'Half-Eaten Apple'], [1, 'Bowling Ball'], [1, 'Toothpaste']]), [[1, 'Bowling Ball'], [1, 'Dirty Sock'], [1, 'Hair pin'], [1, 'Half-Eaten Apple'], [1, 'Microphone'], [1, 'Toothpaste']]);" "assert.deepEqual(inventory([[0, 'Bowling Ball'], [0, 'Dirty Sock'], [0, 'Hair pin'], [0, 'Microphone']], [[1, 'Hair Pin'], [1, 'Half-Eaten Apple'], [1, 'Bowling Ball'], [1, 'Toothpaste']]), [[1, 'Bowling Ball'], [1, 'Dirty Sock'], [1, 'Hair pin'], [1, 'Half-Eaten Apple'], [1, 'Microphone'], [1, 'Toothpaste']]);"
] ]
},
{
"_id": "a2f1d72d9b908d0bd72bb9f6",
"name": "Make a Person",
"difficulty": "3.12",
"description": [
"Fill in the object constructor with the methods specified in the tests.",
"Those methods are getFirstName(), getLastName(), getFullName(), setFirstName(), setLastName(), and setFullName().",
"These methods must be the only available means for interacting with the object.",
"There will be some linting errors on the tests, you may safely ignore them. You should see undefined in the console output."
],
"challengeEntryPoint": "var bob = new Person('Bob Ross');",
"challengeSeed": "var Person = function(firstAndLast) {\n return firstAndLast;\r\n};",
"tests": [
"expect(Object.keys(bob).length).to.eql(6);",
"expect(bob instanceof Person).to.be.true;",
"expect(bob.firstName).to.be.undefined();",
"expect(bob.lastName).to.be.undefined();",
"expect(bob.getFirstName()).to.eql('Bob');",
"expect(bob.getLastName()).to.eql('Ross');",
"expect(bob.getFullName()).to.eql('Bob Ross');",
"bob.setFirstName('Happy');",
"expect(bob.getFirstName()).to.eql('Happy');",
"bob.setLastName('Trees');",
"expect(bob.getLastName()).to.eql('Trees');",
"bob.setFullName('George Carlin');",
"expect(bob.getFullName()).to.eql('George Carlin');"
]
} }
] ]

View File

@ -77,15 +77,11 @@ block content
.form-group .form-group
label.col-sm-3.col-sm-offset-2.control-label(for='email') Link to Profile Photo (1:1 ratio) label.col-sm-3.col-sm-offset-2.control-label(for='email') Link to Profile Photo (1:1 ratio)
.col-sm-4 .col-sm-4
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?$/") input.form-control(type='url', name='picture', id='picture', ng-model='user.profile.picture', placeholder='http://www.example.com/image.jpg')
.col-sm-4.col-sm-offset-5(ng-show="profileForm.picture.$error.url && !profileForm.picture.$pristine") .col-sm-4.col-sm-offset-5(ng-show="profileForm.picture.$error.url && !profileForm.picture.$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/image.jpg). | 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 .form-group
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

View File

@ -2,7 +2,8 @@ extends ../layout
block content block content
.col-xs-12.col-sm-12.col-md-12 .col-xs-12.col-sm-12.col-md-12
.panel.panel-primary .panel.panel-primary
.panel-heading.text-center #{username} .panel-heading.text-center
h1 #{username}'s portfolio
.panel-body .panel-body
.row .row
.col-xs-12 .col-xs-12
@ -10,7 +11,10 @@ block content
if picture if picture
img.img-center.img-responsive.public-profile-img(src=picture) img.img-center.img-responsive.public-profile-img(src=picture)
else else
img.img-center.img-responsive.public-profile-img(src='#{user.gravatar(200)}') if (user)
img.img-center.img-responsive.public-profile-img(src='#{user.gravatar(200)}')
else
img.img-center.img-responsive.public-profile-img(src='https://gravatar.com/avatar/d704cc72a5cd0bfa482ee71f4d557daa?s=200&d=retro')
h1.text-center.negative-5 h1.text-center.negative-5
- if (twitterHandle) - if (twitterHandle)
a.ion-social-twitter.text-primary(title="@#{username}'s Twitter Profile", href="http://twitter.com/#{twitterHandle}", target='_blank') a.ion-social-twitter.text-primary(title="@#{username}'s Twitter Profile", href="http://twitter.com/#{twitterHandle}", target='_blank')

View File

@ -20,8 +20,7 @@ block content
.row .row
.col-xs-12.col-sm-12.col-md-4.bonfire-top .col-xs-12.col-sm-12.col-md-4.bonfire-top
#testCreatePanel #testCreatePanel
h1.text-center= name
h2.text-center= name
h2.text-center.bonfire-flames h2.text-center.bonfire-flames
if (difficulty == "0") if (difficulty == "0")
i.ion-ios-flame-outline i.ion-ios-flame-outline
@ -122,7 +121,7 @@ block content
span.ion-close-circled span.ion-close-circled
| Username not found | Username not found
a.animated.fadeIn.btn.btn-lg.btn-primary.btn-block.next-bonfire-button(name='_csrf', value=_csrf, aria-hidden='true', ng-disabled='completedWithForm.$invalid && existingUser.length > 0') Take me to my next challenge a.animated.fadeIn.btn.btn-lg.btn-primary.btn-block.next-bonfire-button(name='_csrf', value=_csrf, ng-disabled='completedWithForm.$invalid && existingUser.length > 0') Take me to my next challenge
- if (points && points > 2) - if (points && points > 2)
@ -139,3 +138,4 @@ block content
// a.close.closing-x(href='#', data-dismiss='modal', aria-hidden='true') × // a.close.closing-x(href='#', data-dismiss='modal', aria-hidden='true') ×
// .modal-body // .modal-body
// include ../partials/bonfires // include ../partials/bonfires

View File

@ -3,7 +3,8 @@ block content
.row .row
.col-sm-12.col-md-12.col-xs-12 .col-sm-12.col-md-12.col-xs-12
.panel.panel-primary .panel.panel-primary
.panel-heading.text-center #{name} (takes #{time} minutes) .panel-heading.text-center
h1 #{name} (takes #{time} minutes)
script. script.
var bonfireName = null; var bonfireName = null;
.panel.panel-body .panel.panel-body

View File

@ -11,7 +11,7 @@ block content
ul ul
li &#8226 Meet with them regularly to provide direction and answer questions li &#8226 Meet with them regularly to provide direction and answer questions
li &#8226 Clearly communicate your project's goals: what will this project solve, and for whom? li &#8226 Clearly communicate your project's goals: what will this project solve, and for whom?
li &#8226 Understand that they will build your project using JavaScript frameworks (as opposed to older or proprietary tools) li &#8226 Understand that all our projects involve building new sites using modern JavaScript frameworks. We're happy to build a replacement for your old Wordpress or Drupal, but we cannot expand or maintain it.
li &#8226 Keep your expectations high. Our students' goal is to produce work that's up to your standards li &#8226 Keep your expectations high. Our students' goal is to produce work that's up to your standards
h3 If you're OK with these terms, great! We'd love to help you! Fill in this form and we'll get right back to you. h3 If you're OK with these terms, great! We'd love to help you! Fill in this form and we'll get right back to you.
form.form-horizontal(role='form', action="/nonprofits/", method='POST', novalidate='novalidate', name='nonprofitForm') form.form-horizontal(role='form', action="/nonprofits/", method='POST', novalidate='novalidate', name='nonprofitForm')

View File

@ -68,14 +68,20 @@ block content
.col-xs-12.col-sm-12.col-md-3 .col-xs-12.col-sm-12.col-md-3
.landing-skill-icon.ion-ios-loop-strong .landing-skill-icon.ion-ios-loop-strong
h2.black-text Agile h2.black-text Agile
br
br
.big-break .big-break
h2 &nbsp; h2 Why you should join our community right now:
h2 Why you should join our community: h3.col-xs-offset-0.col-sm-offset-1
h3.col-xs-offset-0.col-sm-offset-1.col-md-offset-2
ul.text-left ul.text-left
li.ion-code &nbsp; We're thousands of professionals, all learning to code together li.ion-code &nbsp; We're thousands of professionals, all learning to code together
li.ion-code &nbsp; We're building projects for dozens of nonprofits li.ion-code &nbsp; We're building projects for dozens of nonprofits
li.ion-code &nbsp; Our community is 100% free and open source li.ion-code &nbsp; Our community is 100% free and open source
li.ion-code &nbsp; We all share one goal: to boost our careers with code li.ion-code &nbsp; You'll learn Full Stack JavaScript and become a Software Engineer
li.ion-code &nbsp; You'll work through our focused, interactive courses and tutorials
li.ion-code &nbsp; You'll learn to code at your own pace, in your browser or on your phone
li.ion-code &nbsp; You'll become qualified for thousands of jobs currently going unfilled
li.ion-code &nbsp; You can get help in real time from our community chat rooms and forum
li.ion-code &nbsp; We all share one common goal: to boost our careers with code
.big-break .big-break
a.btn.btn-cta.signup-btn(href="/login") Learn to code today (it's free) a.btn.btn-cta.signup-btn(href="/login") Learn to code today (it's free)

View File

@ -72,10 +72,3 @@
p.landing-p Unlike coding bootcamps, anyone can study at Free Code Camp. We're not going to tell you that you can't become a software engineer. We believe the only person who should be able to tell you that is you. If you persevere, and keep working through our challenges and nonprofit projects, you will become an employable software engineer. p.landing-p Unlike coding bootcamps, anyone can study at Free Code Camp. We're not going to tell you that you can't become a software engineer. We believe the only person who should be able to tell you that is you. If you persevere, and keep working through our challenges and nonprofit projects, you will become an employable software engineer.
br br
br br
.text-center
a.btn.btn-cta.signup-btn.cta(href="/login") Start learning to code (it's free)
br
br
a.btn.nonprofit-cta.btn-success(href="/nonprofits") I'm with a nonprofit and want help coding something
br
br

View File

@ -1,20 +1,19 @@
- if (!landingPage) .fcc-footer
.fcc-footer .col-xs-12
.col-xs-12 a.ion-speakerphone(title="Free Code Camp's Blog", href='http://blog.freecodecamp.com', target='_blank')
a.ion-speakerphone(href='http://blog.freecodecamp.com', target='_blank') | &nbsp;
| &nbsp; a.ion-social-twitch-outline(title="Free Code Camp Live Pair Programming on Twitch.TV", href="http://www.twitch.tv/freecodecamp", target='_blank')
a.ion-social-twitch-outline(title="Free Code Camp Live Pair Programming on Twitch.TV", href="http://www.twitch.tv/freecodecamp", target='_blank') | &nbsp;
| &nbsp; a.ion-social-github(title="Free Code Camp on GitHub", href="http://github.com/freecodecamp", target='_blank')
a.ion-social-github(title="Free Code Camp on GitHub", href="http://github.com/freecodecamp", target='_blank') | &nbsp;
| &nbsp; a.ion-social-twitter(title="Free Code Camp on Twitter", href="http://twitter.com/freecodecamp", target='_blank')
a.ion-social-twitter(title="Free Code Camp on Twitter", href="http://twitter.com/freecodecamp", target='_blank') | &nbsp;
| &nbsp; a.ion-social-facebook(title="Free Code Camp on Facebook", href="http://facebook.com/freecodecamp", target='_blank')
a.ion-social-facebook(title="Free Code Camp on Facebook", href="http://facebook.com/freecodecamp", target='_blank') | &nbsp;
| &nbsp; a.ion-social-linkedin(title="Free Code Camp on LinkedIn", href="http://linkedin.com/company/4831032?free-code-camp", target='_blank')
a.ion-social-linkedin(title="Free Code Camp on LinkedIn", href="http://linkedin.com/company/4831032?free-code-camp", target='_blank') | &nbsp;
| &nbsp; a.ion-information-circled(title="About Free Code Camp", href="/learn-to-code")
a.ion-information-circled(title="About Free Code Camp", href="/learn-to-code") | &nbsp;
| &nbsp; a.ion-locked(title="Free Code Camp's Privacy Policy", href="/privacy")
a.ion-locked(title="Free Code Camp's Privacy Policy", href="/privacy") | &nbsp;
| &nbsp; a.ion-code-working(title="Bonfire Coding Playground", href="/playground")
a.ion-code-working(title="Bonfire Coding Playground", href="/playground")