diff --git a/client/less/main.less b/client/less/main.less index f9913f653b..f5f123f62d 100644 --- a/client/less/main.less +++ b/client/less/main.less @@ -491,6 +491,12 @@ thead { color: #009900 } +.testimonial-image-jobs { + border-radius: 5px; + color: #009900 +} + + .default-border-radius { border-radius: 5px; } diff --git a/common/app/components/Nav/Nav.jsx b/common/app/components/Nav/Nav.jsx index 874d791e91..b508a16b92 100644 --- a/common/app/components/Nav/Nav.jsx +++ b/common/app/components/Nav/Nav.jsx @@ -42,14 +42,15 @@ export default React.createClass({ }, renderLinks() { - return navLinks.map(({ content, link, react }, index) => { + return navLinks.map(({ content, link, react, target }, index) => { if (react) { return ( - + { content } @@ -59,7 +60,8 @@ export default React.createClass({ + key={ content } + target={ target || null }> { content } ); diff --git a/common/app/components/Nav/links.json b/common/app/components/Nav/links.json index 175e5170cf..79cb418e11 100644 --- a/common/app/components/Nav/links.json +++ b/common/app/components/Nav/links.json @@ -3,10 +3,16 @@ "link": "/map" }, { "content": "Chat", - "link": "//gitter.im/FreeCodeCamp/FreeCodeCamp" + "link": "//gitter.im/FreeCodeCamp/FreeCodeCamp", + "target": "_blank" +},{ + "content": "Wiki", + "link": "https://github.com/freecodecamp/freecodecamp/wiki/", + "target": "_blank" },{ "content": "News", - "link": "/news" + "link": "/news", + "target": "_blank" },{ "content": "Jobs", "link": "/jobs", diff --git a/common/app/routes/Jobs/components/Jobs.jsx b/common/app/routes/Jobs/components/Jobs.jsx index af47b0c2b0..21aa7d40f2 100644 --- a/common/app/routes/Jobs/components/Jobs.jsx +++ b/common/app/routes/Jobs/components/Jobs.jsx @@ -3,7 +3,6 @@ import { contain } from 'thundercats-react'; import { Button, Panel, Row, Col } from 'react-bootstrap'; import ListJobs from './List.jsx'; -import TwitterBtn from './TwitterBtn.jsx'; export default contain( { @@ -61,7 +60,6 @@ export default contain( render() { const { children, - numOfFollowers, jobs, appActions } = this.props; @@ -74,27 +72,55 @@ export default contain( mdOffset= { 1 } xs={ 12 }>

- Hire JavaScript engineers experienced in - HTML5, Node.js, MongoDB, and Agile Development + Hire a JavaScript engineer who's experienced in HTML5, + Node.js, MongoDB, and Agile Development.

+
-
-
+
+ + + {` + + +
+

+ We hired our last developer out of Free Code Camp + and couldn't be happier. Free Code Camp is now + our go-to way to bring on pre-screened candidates + who are enthusiastic about learning quickly and + becoming immediately productive in their new career. +

+
+ Michael Gai, CEO at CoNarrative +
+
+ +
{ this.renderChild(children, jobs) || this.renderList(this.handleJobClick, jobs) } diff --git a/package.json b/package.json index 79e7ad80bf..285a746055 100644 --- a/package.json +++ b/package.json @@ -101,8 +101,8 @@ "react": "~0.14.2", "react-bootstrap": "~0.27.3", "react-motion": "~0.3.1", - "react-router": "^1.0.0-rc4", - "react-router-bootstrap": "~0.19.2", + "react-router": "^1.0.0", + "react-router-bootstrap": "https://github.com/FreeCodeCamp/react-router-bootstrap.git#freecodecamp", "react-vimeo": "~0.0.3", "request": "^2.65.0", "rev-del": "^1.0.5", diff --git a/seed/challenges/basic-bonfires.json b/seed/challenges/basic-bonfires.json index c1327a5c84..97f2577a34 100644 --- a/seed/challenges/basic-bonfires.json +++ b/seed/challenges/basic-bonfires.json @@ -169,6 +169,7 @@ "String.toLowerCase()" ], "solutions": [ + "function palindrome(str) {\n var string = str.toLowerCase().split(/[^A-Za-z0-9]/gi).join('');\n var aux = string.split('');\n if (aux.join('') === aux.reverse().join('')){\n return true;\n }\n\n return false;\n}" ], "type": "bonfire", "challengeType": 5, diff --git a/seed/challenges/basic-javascript.json b/seed/challenges/basic-javascript.json index 7aac971929..5aa5b7549e 100644 --- a/seed/challenges/basic-javascript.json +++ b/seed/challenges/basic-javascript.json @@ -959,7 +959,7 @@ "  ourArray.push(i);", "}", "ourArray will now contain [10,8,6,4,2].", - "Let's change our initialization and final-expression so we can count backward by twos for numbers.", + "Let's change our initialization and final-expression so we can count backward by twos by odd numbers.", "Push the odd numbers from 9 through 1 to myArray using a for loop." ], "tests":[ @@ -978,12 +978,11 @@ "// Only change code below this line.", "", "", - "", - "// Only change code above this line.", - "", - "if(typeof(myArray) !== \"undefined\"){(function(){return myArray;})();}", "" ], + "tail": [ + "if(typeof(myArray) !== \"undefined\"){(function(){return myArray;})();}" + ], "type": "waypoint", "challengeType": 1 }, @@ -1333,12 +1332,13 @@ " ", " // Only change code above this line.", " ", - " $(\".logger\").html(\"\");", - " $(\".logger\").html(\"Not A Win\")", " ", " if (slotOne !== undefined && slotTwo !== undefined && slotThree !== undefined) {", " $(\".logger\").html(slotOne + \" \" + slotTwo + \" \" + slotThree);", " }", + " ", + " ", + " $(\".logger\").append(\" Not A Win\")", " return [slotOne, slotTwo, slotThree];", " }", "", @@ -1460,13 +1460,14 @@ "title": "Add your JavaScript Slot Machine Slots", "description": [ "Now that our slots will each generate random numbers, we need to check whether they've all returned the same number.", - "If they have, we should notify our user that they've won.", - "Otherwise, we should return null, which is a JavaScript data structure that means nothing.", - "If all three numbers match, we should return the number that we have in three of slots or leave it as null.", - "Let's create an if statement with multiple conditions in order to check whether all numbers are equal.", - "if (slotOne !== slotTwo || slotTwo !== slotThree) {", + "If they have, we should notify our user that they've won and we should return null.", + "null is a JavaScript data structure that means nothing.", + "The user wins when all the three numbers match. Let's create an if statement with multiple conditions in order to check whether all numbers are equal.", + "if(slotOne === slotTwo && slotTwo === slotThree){", "  return null;", - "}" + "}", + "Also, we need to show the user that he has won the game when he gets the same number in all the slots.", + "If all three numbers match, we should also set the text \"It's A Win\" to the element with class logger." ], "tests": [ "assert((function(){var data = runSlots();return data === null || data.toString().length === 1;})(), 'If all three of our random numbers are the same we should return that number. Otherwise we should return null.')" @@ -1484,8 +1485,6 @@ " slotTwo = Math.floor(Math.random() * (3 - 1 + 1)) + 1;", " slotThree = Math.floor(Math.random() * (3 - 1 + 1)) + 1;", " ", - " $(\".logger\").html(\"\");", - " $(\".logger\").html(\"Not A Win\");", " ", " // Only change code below this line.", " ", @@ -1493,11 +1492,12 @@ " ", " // Only change code above this line.", " ", - " if (slotOne !== undefined && slotTwo !== undefined && slotThree !== undefined) {", - " $(\".logger\").html(slotOne);", - " $(\".logger\").append(\" \" + slotTwo);", - " $(\".logger\").append(\" \" + slotThree);", + " if(slotOne !== undefined && slotTwo !== undefined && slotThree !== undefined){", + " $(\".logger\").html(slotOne + \" \" + slotTwo + \" \" + slotThree);", " }", + " ", + " $(\".logger\").append(\" Not A Win\");", + " ", " return [slotOne, slotTwo, slotThree];", " }", "", @@ -1622,7 +1622,7 @@ "Let's use the jQuery selector $(\".slot\") to select all of the slots.", "Once they are all selected, we can use bracket notation to access each individual slot:", "$($(\".slot\")[0]).html(slotOne);", - "This jQuery will select the first and update the slot's HTML to display the correct number.", + "This jQuery will select the first slot and update it's HTML to display the correct number.", "Use the above selector to display each number in its corresponding slot." ], "tests": [ @@ -1642,8 +1642,6 @@ " slotTwo = Math.floor(Math.random() * (3 - 1 + 1)) + 1;", " slotThree = Math.floor(Math.random() * (3 - 1 + 1)) + 1;", " ", - " $(\".logger\").html(\"\");", - " $(\".logger\").html(\"Not A Win\")", " ", " // Only change code below this line.", " ", @@ -1652,15 +1650,17 @@ " // Only change code above this line.", " ", " if (slotOne === slotTwo && slotTwo === slotThree) {", - " return slotOne;", + " $(\".logger\").html(\" It's A Win\")", + " return null;", " }", " ", - " if (slotOne !== undefined && slotTwo !== undefined && slotThree !== undefined) {", - " $(\".logger\").html(slotOne);", - " $(\".logger\").append(\" \" + slotTwo);", - " $(\".logger\").append(\" \" + slotThree);", + " if(slotOne !== undefined && slotTwo !== undefined && slotThree !== undefined){", + " $(\".logger\").html(slotOne + \" \" + slotTwo + \" \" + slotThree);", " }", " ", + " $(\".logger\").append(\" Not A Win\");", + " ", + " ", " return [slotOne, slotTwo, slotThree];", " }", "", @@ -1811,8 +1811,6 @@ " slotTwo = Math.floor(Math.random() * (3 - 1 + 1)) + 1;", " slotThree = Math.floor(Math.random() * (3 - 1 + 1)) + 1;", " ", - " $('.logger').html('');", - " $('.logger').html('Not A Win');", " ", " // Only change code below this line.", " ", @@ -1821,15 +1819,16 @@ " // Only change code above this line.", " ", " if (slotOne === slotTwo && slotTwo === slotThree) {", - " return slotOne;", + " $('.logger').html(\"It's A Win\");", + " return null;", " }", " ", - " if (slotOne !== undefined && slotTwo !== undefined && slotThree !== undefined) {", - " $('.logger').html(slotOne);", - " $('.logger').append(' ' + slotTwo);", - " $('.logger').append(' ' + slotThree);", + " if(slotOne !== undefined && slotTwo !== undefined && slotThree !== undefined){", + " $(\".logger\").html(slotOne + \" \" + slotTwo + \" \" + slotThree);", " }", " ", + " $('.logger').append(\" Not A Win\");", + " ", " return [slotOne, slotTwo, slotThree];", " }", "", diff --git a/seed/challenges/object-oriented-and-functional-programming.json b/seed/challenges/object-oriented-and-functional-programming.json index 20dc89a4a9..af1a4ec728 100644 --- a/seed/challenges/object-oriented-and-functional-programming.json +++ b/seed/challenges/object-oriented-and-functional-programming.json @@ -105,7 +105,7 @@ "title":"Make Instances of Objects with a Constructor Function", "description":[ "Now let's put that great constructor function we made in the last lesson to use!", - "To use a constructor function we call it with the new keyword in front if it like:", + "To use a constructor function we call it with the new keyword in front of it like:", "var myCar = new Car();", "myCar is now an instance of the Car constructor that looks like the object it described:", "{", @@ -113,7 +113,7 @@ "  engines: 1,", "  seats: 1", "}", - "Note that it is important to use the new keyword when calling a constructor. This is how javascript knows to create a new object and that all the references to this inside the constructor should be referring to this new object.", + "Note that it is important to use the new keyword when calling a constructor. This is how Javascript knows to create a new object and that all the references to this inside the constructor should be referring to this new object.", "Now, once the myCar instance is created it can be used like any other object and can have its properties accessed and modified the same way you would usually. For example:", "myCar.turboType = \"twin\";", "Our myCar variable now has a property turboType with a value of \"twin\".", @@ -387,7 +387,7 @@ "description": [ "You can use the reverse method to reverse the elements of an array.", "reverse is another array method that alters the array in place, but it also returns the reversed array.", - "Use reverse to reverse the array variable and assign it to myArray." + "Use reverse to reverse the array variable and assign it to newArray." ], "tests": [ "assert.deepEqual(newArray, [7,6,5,4,3,2,1], 'message: You should reverse the array.');", @@ -402,7 +402,9 @@ "var newArray = array;", "", "// Only change code above this line.", - "", + "" + ], + "tail":[ "(function() {return newArray;})();" ], "challengeType": 1, @@ -410,7 +412,7 @@ }, { "id": "cf1111c1c16feddfaeb3bdef", - "title": "Concatenate Strings with .concat", + "title": "Concatenate Arrays with .concat", "description": [ "concat can be used to merge the contents of two arrays into one.", "concat takes an array as an argument and returns a new array with the elements of this array concatenated onto the end.", diff --git a/server/boot/story.js b/server/boot/story.js index ff20a9cd62..6ba36021dc 100755 --- a/server/boot/story.js +++ b/server/boot/story.js @@ -64,6 +64,7 @@ module.exports = function(app) { router.post('/news/userstories', userStories); router.get('/news/hot', hotJSON); + router.get('/news/feed', RSSFeed); router.get('/stories/hotStories', hotJSON); router.get( '/stories/submit', @@ -105,6 +106,26 @@ module.exports = function(app) { ); } + function RSSFeed(req, res, next) { + var query = { + order: 'timePosted DESC', + limit: 1000 + }; + findStory(query).subscribe( + function(stories) { + var sliceVal = stories.length >= 100 ? 100 : stories.length; + var data = stories.sort(sortByRank).slice(0, sliceVal); + res.render('feed', { + title: 'FreeCodeCamp Camper News RSS Feed', + description: 'RSS Feed for FreeCodeCamp Top 100 Hot Camper News', + url: 'http://www.freecodecamp.com/news', + FeedPosts: data + }); + }, + next + ); + } + function hot(req, res) { return res.render('stories/index', { title: 'Top Stories on Camper News', diff --git a/server/resources/labs.json b/server/resources/labs.json index 0d025eeebc..07c50012b3 100644 --- a/server/resources/labs.json +++ b/server/resources/labs.json @@ -20,6 +20,20 @@ "description": "A path to a free education in Computer Science.", "image": "https://camo.githubusercontent.com/c42438055d3fee26b29e6d046fd8d06ebff3db20/687474703a2f2f692e696d6775722e636f6d2f6838786a72726a2e706e67" }, + { + "camper": "akiralaine", + "name": "Musare", + "url": "http://musare.com/", + "description": "Musare is a modern, collaborative, open-source Music App.", + "image": "http://i.imgur.com/Y4D4MPL.png" + }, + { + "camper": "storbeck", + "name": "Free Code Camp Event Zipline: Recipe Box", + "url": "http://codepen.io/GeoffStorbeck/full/bVKyzd/", + "description": "Try to reverse engineer this Recipe Box as an optional Zipline challenge.", + "image": "http://i.imgur.com/5o0bwVQ.png" + }, { "camper": "akiralaine", "name": "Camper News Bot", diff --git a/server/views/feed.jade b/server/views/feed.jade new file mode 100644 index 0000000000..67866c7bf7 --- /dev/null +++ b/server/views/feed.jade @@ -0,0 +1,15 @@ +doctype xml +rss(version="2.0", xmlns:atom="http://www.w3.org/2005/Atom") + channel + title= title + link= url + description= description + atom:link(href="http://www.freecodecamp.com/news/feed", rel="self", type="application/rss+xml") + for post in FeedPosts + if (post.link).match(/https*:\/\/\w+(\.\w+)*/) + item + title #{ post.headline.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"') } + description + pubDate= (new Date(post.timePosted)).toUTCString() + link= post.link + guid(isPermaLink="false")= post.link diff --git a/server/views/partials/meta.jade b/server/views/partials/meta.jade index 8ba19b0ca6..8336afb295 100644 --- a/server/views/partials/meta.jade +++ b/server/views/partials/meta.jade @@ -60,3 +60,4 @@ link(rel="mstile", sizes="310x150", href="https://s3.amazonaws.com/freecodecamp/ link(rel="mstile", sizes="70x70", href="https://s3.amazonaws.com/freecodecamp/favicons/mstile-70x70.png") link(rel="favicon", href="https://s3.amazonaws.com/freecodecamp/favicons/favicon.ico") link(rel='shortcut icon', href='//s3.amazonaws.com/freecodecamp/favicons/favicon.ico') +link(rel="alternate" type="application/rss+xml" title="RSS Feed for FreeCodeCamp Camper News" href="http://www.freecodecamp.com/news/feed")