+
{ company }
@@ -123,6 +124,7 @@ export default React.createClass({
{ locale ? locale : `${city}, ${state}` }
+
{ this.renderHowToApply(showApply, preview, message, howToApply) }
-
+
diff --git a/common/app/routes/Jobs/components/TwitterBtn.jsx b/common/app/routes/Jobs/components/TwitterBtn.jsx
deleted file mode 100644
index 7998353ffc..0000000000
--- a/common/app/routes/Jobs/components/TwitterBtn.jsx
+++ /dev/null
@@ -1,33 +0,0 @@
-import React, { PropTypes } from 'react';
-import { Button } from 'react-bootstrap';
-
-const followLink = 'https://twitter.com/intent/follow?' +
- 'ref_src=twsrc%5Etfw®ion=follow_link&screen_name=CamperJobs&' +
- 'amp;tw_p=followbutton';
-
-function commify(count) {
- return Number(count).toLocaleString('en');
-}
-
-export default React.createClass({
-
- displayName: 'FollowButton',
-
- propTypes: {
- count: PropTypes.number
- },
-
- render() {
- const { count } = this.props;
- return (
-
- );
- }
-});
diff --git a/common/models/challenge.json b/common/models/challenge.json
index 67e8ee197a..9785a0d9cb 100644
--- a/common/models/challenge.json
+++ b/common/models/challenge.json
@@ -70,6 +70,11 @@
"default": [],
"description": "prepended to user code"
},
+ "helpRoom": {
+ "type": "string",
+ "default": "Help",
+ "description": "Gitter help chatroom this challenge belongs too. Must be PascalCase"
+ },
"fileName": {
"type": "string",
"description": "filename challenge comes from. Used in dev mode"
diff --git a/gulpfile.js b/gulpfile.js
index a73cab824b..902f142ce3 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -131,7 +131,7 @@ var paths = {
],
less: './client/less/main.less',
- lessFiles: './client/less/*.less',
+ lessFiles: './client/less/**/*.less',
manifest: 'server/manifests/',
@@ -191,7 +191,7 @@ gulp.task('serve', ['build-manifest'], function(cb) {
ignore: paths.serverIgnore,
exec: path.join(__dirname, 'node_modules/.bin/babel-node'),
env: {
- 'NODE_ENV': 'development',
+ 'NODE_ENV': process.env.NODE_ENV || 'development',
'DEBUG': process.env.DEBUG || 'freecc:*'
}
})
@@ -357,10 +357,15 @@ gulp.task('less', function() {
var dest = paths.css;
return gulp.src(paths.less)
.pipe(plumber({ errorHandler: errorHandler }))
+ .pipe(__DEV__ ? sourcemaps.init() : gutil.noop())
// compile
.pipe(less({
paths: [ path.join(__dirname, 'less', 'includes') ]
}))
+ .pipe(__DEV__ ?
+ sourcemaps.write({ sourceRoot: '/less' }) :
+ gutil.noop()
+ )
.pipe(gulp.dest(dest))
// add revision
.pipe(rev())
diff --git a/package.json b/package.json
index d5d4f1f3d8..b82351af60 100644
--- a/package.json
+++ b/package.json
@@ -6,7 +6,7 @@
"url": "https://github.com/freecodecamp/freecodecamp.git"
},
"scripts": {
- "only-once": "npm run create-rev && echo '\n\nseeding database\n\n' && node seed && node seed/nonprofits && echo",
+ "only-once": "npm run create-rev && echo '\n\nseeding database\n\n' && node seed && echo '\n\nSeeding Completed\n\n'",
"create-rev": "node -e \"console.log('\\n\\ncreating manifest\\n\\n'); require('fs').writeFileSync('server/rev-manifest.json', '{}');\"",
"build": "NODE_ENV=production gulp build -p",
"start": "babel-node server/server.js",
@@ -14,12 +14,11 @@
"start-production": "node pm2Start",
"lint": "npm run lint-js && npm run lint-json",
"lint-challenges": "jsonlint -q seed/challenges/**/*.json",
- "lint-nonprofits": "jsonlint -q seed/nonprofits.json",
"lint-server": "jsonlint -q server/*.json",
"lint-resources": "jsonlint -q server/resources/*.json",
"lint-utils": "jsonlint -q server/utils/*.json",
"lint-js": "eslint --ext=.js,.jsx server/ common/ config/ client/",
- "lint-json": "npm run lint-server && npm run lint-nonprofits && npm run lint-challenges && npm run lint-resources && npm run lint-utils",
+ "lint-json": "npm run lint-server && npm run && npm run lint-challenges && npm run lint-resources && npm run lint-utils",
"test-challenges": "babel-node seed/test-challenges.js | tap-spec",
"pretest": "npm run lint",
"test": "npm run test-challenges"
diff --git a/seed/challenges/00-getting-started/getting-started.json b/seed/challenges/00-getting-started/getting-started.json
index d105874619..17820d4ba1 100644
--- a/seed/challenges/00-getting-started/getting-started.json
+++ b/seed/challenges/00-getting-started/getting-started.json
@@ -1,7 +1,8 @@
{
"name": "Getting Started",
"order": 1,
- "time": "15m",
+ "time": "15 minutes",
+ "helpRoom": "Help",
"challenges": [
{
"id": "560add10cb82ac38a17513be",
@@ -9,7 +10,7 @@
"challengeSeed": [],
"description": [
[
- "http://i.imgur.com/RlEk2IF.jpg",
+ "http://i.imgur.com/4HK5ZFP.jpg",
"A picture of Free Code Camp's 4 benefits: Get connected, Learn JavaScript, Build your Portfolio, Help nonprofits",
"Welcome to Free Code Camp. We're an open source community of busy people who learn to code and help nonprofits.",
""
@@ -33,27 +34,51 @@
""
],
[
- "http://i.imgur.com/dLx8nrg.jpg",
- "An illustration showing that you will learn HTML5, CSS3, JavaScript, Databases, Git, Node.js, Angular.js and Agile.",
- "During the first half of Free Code Camp, you'll learn technologies like HTML5, Node.js and databases.",
+ "http://i.imgur.com/pR5le2g.jpg",
+ "An illustration showing that you will learn HTML5, CSS3, JavaScript, Databases, Git, Node.js, React and D3.",
+ "We have hundreds of optional coding challenges that will teach you fundamental web development technologies like HTML5, Node.js and databases.",
""
],
[
- "http://i.imgur.com/syJxavV.jpg",
+ "http://i.imgur.com/fQCeZjk.jpg",
+ "An image of a camper at a cafe building projects on Free Code Camp.",
+ "We believe humans learn best by doing. So you'll spend most of your time actually building projects. We'll give you a list of specifications (agile user stories), and you'll figure out how to build apps that fulfill those specifications.",
+ ""
+ ],
+ [
+ "http://i.imgur.com/hTyj4f8.jpg",
+ "An image of showing our front end, back end, and data visualization certifications (400 hours each), our nonprofit projects (800 hours), and interview prep (80 hours) for a total of 2,080 hours of coding experience.",
+ "Our curriculum is divided into 4 certifications. These certifications are standardized, and instantly verifiable by your freelance clients and future employers. Like everything else at Free Code Camp, these certifications are free. We recommend doing them in order, but you are free to jump around. The first three certifications take 400 hours each, and the final certification takes 800 hours, and involves building real-life projects for nonprofits.",
+ ""
+ ],
+ [
+ "http://i.imgur.com/D0NI1mz.jpg",
"A screenshot of our Front End Development Certificate",
- "About 400 hours into Free Code Camp, you'll earn your verified Front End Development Certification.",
+ "To earn our verified Front End Development Certification, you'll build 10 projects using HTML, CSS, jQuery, and JavaScript.",
""
],
[
- "http://i.imgur.com/sKYQhdG.jpg",
- "A screenshot of our Full Stack Development Certificate",
- "About 800 hours into Free Code Camp, you'll earn your verified Full Stack Development Certification.",
+ "http://i.imgur.com/V64y2Na.jpg",
+ "A screenshot of our Data Visualization Certificate",
+ "To earn our Data Visualization Certification, you'll build 10 projects using React, Sass and D3.js.",
+ ""
+ ],
+ [
+ "http://i.imgur.com/NeHZ02J.jpg",
+ "A screenshot of our Back End Development Certificate",
+ "To earn our Back End Development Certification, you'll build 10 projects using Node.js, Express, and MongoDB. You'll use Git and Heroku to deploy them to the cloud.",
""
],
[
"http://i.imgur.com/yXyxbDd.jpg",
"A screen shot of our nonprofit project directory.",
- "Then you'll build several real-life projects for nonprofits. By the time you finish, you'll have a portfolio of real apps that people use every day.",
+ "After you complete all three of these certificates, you'll team up with another camper and use agile software development methodologies to build two real-life projects for nonprofits. You'll also add functionality to two legacy code nonprofit projects. By the time you finish, you'll have a portfolio of real apps that people use every day.",
+ ""
+ ],
+ [
+ "http://i.imgur.com/BQYCcLW.jpg",
+ "An image of campers building projects together in a cafe in Seoul.",
+ "If you complete all 2,080 hours worth of challenges and projects, you'll earn our Full Stack Development Certification. We'll offer you free coding interview practice. We have a even offer a job board where employers specifically hire campers who've earned Free Code Camp certifications.",
""
]
],
@@ -140,7 +165,7 @@
[
"http://i.imgur.com/ALN6zPK.gif",
"A gif showing you how to click the profile image in the upper right hand corner of GitHub. Upload a photo of yourself or you will continue to use the automatically generated pixel art. Then fill in the remaining form fields and click submit.",
- "Click the pixel art in the upper right hand corner of GitHub, then choose settings.
Upload a picture of yourself. A picture of your face works best. This is how your fellow campers will see you in our chat rooms, so put your best foot forward.
You can add your city and your name if you want.",
+ "Click the pixel art in the upper right hand corner of GitHub, then choose settings. Upload a picture of yourself. A picture of your face works best. This is how your fellow campers will see you in our chat rooms, so put your best foot forward. You can add your city and your name if you want.",
"https://github.com/settings/profile"
],
[
@@ -152,7 +177,7 @@
[
"http://i.imgur.com/zwYPeQT.gif",
"A gif showing you how to click the link below to go to our chat room and click the \"sign in with GitHub\" button. Then you can click into the text input field and type a message to your fellow campers.",
- "Now that you have a GitHub account, you can join our main chat room by logging in with GitHub. Introduce yourself by saying \"Hello world!\".
Tell your fellow campers how you found Free Code Camp. Also tell us why you want to learn to code.",
+ "Now that you have a GitHub account, you can join our main chat room by logging in with GitHub. Introduce yourself by saying \"Hello world!\". Tell your fellow campers how you found Free Code Camp. Also tell us why you want to learn to code.",
"https://gitter.im/FreeCodeCamp/FreeCodeCamp"
],
[
@@ -206,7 +231,7 @@
[
"http://i.imgur.com/ALN6zPK.gif",
"Un gif mostrandote como pulsar en la imagen de perfil en la esquina superior derecha de GitHub. Sube una foto tuya o continuaras usando la imagen de pixeles generada automáticamente. Entonces llena los campos restantes y haz clic en envíar.",
- "En la esquina superior derecha pulsa sobre la imagen de pixeles, entonces selecciona configuraciones.
Sube una imagen tuya. Una foto de tu cara es mejor. Así es como tus compañeros campistas te verán en nuestras salas de chat, así que toma tu mejor ángulo.
Puedes añadir tu ciudad y tu nombre si lo deseas.",
+ "En la esquina superior derecha pulsa sobre la imagen de pixeles, entonces selecciona configuraciones. Sube una imagen tuya. Una foto de tu cara es mejor. Así es como tus compañeros campistas te verán en nuestras salas de chat, así que toma tu mejor ángulo. Puedes añadir tu ciudad y tu nombre si lo deseas.",
"https://github.com/settings/profile"
],
[
@@ -218,7 +243,7 @@
[
"http://i.imgur.com/zwYPeQT.gif",
"Un gif mostrandote como pulsar en el enlace inferior para ir a nuestra sala de chat y pulsar en el botón de \"iniciar sesión con GitHub\". Entonces puedes pulsar en el próximo campo de texto y escribir un mensaje a tus compañeros campistas.",
- "Ahora que tienes una cuenta de GitHub, puedes unirte a nuestro chat principal al iniciar sesión con GitHub. Presentate diciendo \"Hello world!\".
Cuéntales a los tus compañeros campistas como encontraste Free Code Camp. Además cuéntanos porque deseas aprender a programar.",
+ "Ahora que tienes una cuenta de GitHub, puedes unirte a nuestro chat principal al iniciar sesión con GitHub. Presentate diciendo \"Hello world!\". Cuéntales a los tus compañeros campistas como encontraste Free Code Camp. Además cuéntanos porque deseas aprender a programar.",
"https://gitter.im/FreeCodeCamp/FreeCodeCamp"
],
[
@@ -257,7 +282,7 @@
[
"http://i.imgur.com/tP2ccTE.gif",
"A gif showing how you can click your profile image in your upper right hand corner to your code portfolio and connect GitHub.",
- "Check out your code portfolio. Click your picture in your upper right hand corner. To activate your code portfolio, you'll need to link your GitHub account with Free Code Camp.
Your code portfolio shows your progress and how many Brownie Points you have. You can get Brownie Points by completing challenges and by helping other campers in our chat rooms. If you get Brownie Points on several days in a row, you'll get a streak.",
+ "Check out your code portfolio. Click your picture in your upper right hand corner. To activate your code portfolio, you'll need to link your GitHub account with Free Code Camp. Your code portfolio shows your progress and how many Brownie Points you have. You can get Brownie Points by completing challenges and by helping other campers in our chat rooms. If you get Brownie Points on several days in a row, you'll get a streak.",
""
]
],
@@ -275,7 +300,7 @@
[
"http://i.imgur.com/tP2ccTE.gif",
"Un gif mostrandore como puedes pulsar en tu imagen de perfil en la esquina superior derecha conectar tu portafolio y GitHub.",
- "Dale un vistazo de tu portafolio de código. Da click en tu imagen en la esquina superior derecha. Para activar tu portafolio de código, necesitaras conectar tu cuenta de GitHub con Free Code Camp.
Tu portafolio de código muestra tu progreso y cuantos Brownie Points tienes. Puedes obtener Brownie Points completando desafíos y ayudando a otros campistas en nuestras salas de chat. Si obtienes Brownie Points varios días consecutivos, obtendrás una racha.",
+ "Dale un vistazo de tu portafolio de código. Da click en tu imagen en la esquina superior derecha. Para activar tu portafolio de código, necesitaras conectar tu cuenta de GitHub con Free Code Camp. Tu portafolio de código muestra tu progreso y cuantos Brownie Points tienes. Puedes obtener Brownie Points completando desafíos y ayudando a otros campistas en nuestras salas de chat. Si obtienes Brownie Points varios días consecutivos, obtendrás una racha.",
""
]
],
@@ -296,7 +321,7 @@
[
"http://i.imgur.com/fTFMjwf.gif",
"A gif showing how you can click the link below, find your city on the list of Campsites, then click on the Facebook link for your city and join your city's Facebook group.",
- "Find your city on this list and click it. This will take you to your city's Campsite's Facebook group.
Click the \"Join group\" button to apply to join your city's Facebook group. Someone from the campsite should approve you shortly.
If your city isn't on this list, scroll to the bottom of the wiki article for instructions for how you can create your city's Campsite.",
+ "Find your city on this list and click it. This will take you to your city's Campsite's Facebook group. Click the \"Join group\" button to apply to join your city's Facebook group. Someone from the campsite should approve you shortly. If your city isn't on this list, scroll to the bottom of the wiki article for instructions for how you can create your city's Campsite.",
"https://github.com/FreeCodeCamp/freecodecamp/wiki/List-of-Free-Code-Camp-city-based-Campsites"
]
],
@@ -320,7 +345,7 @@
[
"http://i.imgur.com/fTFMjwf.gif",
"Un gif mostrandote como puedes pulsar en el enlace inferior, encontrar tu ciudad en la lista de Campamentos, entonces haz clic en el enlace de Facebook para tu ciudad y unirte al grupo de Facebook de tu ciudad.",
- "Encuentra tu ciudad en esta lista y haz clic en esta. Esto te llevara al grupo de Facebook del Campamento de tu ciudad.
Da clic en el botón de \"Unirse al grupo\" para unirte a el grupo. Alguien del mismo campamento debería aprobarte en breve.
Si tu ciudad no esta en esta lista, ve al final del articulo de la wiki para ver instrucciones de como crear un campamento para tu ciudad.",
+ "Encuentra tu ciudad en esta lista y haz clic en esta. Esto te llevara al grupo de Facebook del Campamento de tu ciudad. Da clic en el botón de \"Unirse al grupo\" para unirte a el grupo. Alguien del mismo campamento debería aprobarte en breve. Si tu ciudad no esta en esta lista, ve al final del articulo de la wiki para ver instrucciones de como crear un campamento para tu ciudad.",
"https://github.com/FreeCodeCamp/freecodecamp/wiki/List-of-Free-Code-Camp-city-based-Campsites"
]
],
@@ -377,7 +402,7 @@
[
"http://i.imgur.com/ZRgXraT.gif",
"A gif showing us scrolling through our challenge map.",
- "Now you're ready to start coding.
The \"Map\" button in your upper right hand corner will show you our challenge map.
We recommend that you complete these from top to bottom, at a sustainable pace.
Our open source community is constantly improving our challenges, so don't be surprised if they change or move around. Don't worry about going back - just keep moving forward.
You can always go to your most recent challenge by clicking the \"Learn\" button.",
+ "Now you're ready to start coding. The \"Map\" button in your upper right hand corner will show you our challenge map. We recommend that you complete these from top to bottom, at a sustainable pace. Our open source community is constantly improving our challenges, so don't be surprised if they change or move around. Don't worry about going back - just keep moving forward. You can always go to your most recent challenge by clicking the \"Learn\" button.",
""
]
],
@@ -437,7 +462,7 @@
[
"http://i.imgur.com/ZRgXraT.gif",
"Un gif mostrandonos nuestro mapa de desafíos.",
- "Ahora estas listo para empezar a programar.
El botón de \"Mapa\" en tu esquina superior derecha te mostrará nuestro mapa de desafíos.
Te recomendaos que completes los desafíos de arriba hacía abajo, a un ritmo sostenible.
Nuestra comunidad de código abierto esta constantemente mejorando nuestros desafíos, así que no te sorprendas si cambian o se mueven alrededor. No te preocupes por volver hacia atrás - solo continúa avanzando.
Siempre puedes ir a tu desafío más reciente pulsando el botón de \"Aprender\".",
+ "Ahora estas listo para empezar a programar. El botón de \"Mapa\" en tu esquina superior derecha te mostrará nuestro mapa de desafíos. Te recomendaos que completes los desafíos de arriba hacía abajo, a un ritmo sostenible. Nuestra comunidad de código abierto esta constantemente mejorando nuestros desafíos, así que no te sorprendas si cambian o se mueven alrededor. No te preocupes por volver hacia atrás - solo continúa avanzando. Siempre puedes ir a tu desafío más reciente pulsando el botón de \"Aprender\".",
""
]
],
diff --git a/seed/challenges/01-front-end-development-certification/advanced-bonfires.json b/seed/challenges/01-front-end-development-certification/advanced-bonfires.json
index 3a49435492..4e1e507f86 100644
--- a/seed/challenges/01-front-end-development-certification/advanced-bonfires.json
+++ b/seed/challenges/01-front-end-development-certification/advanced-bonfires.json
@@ -1,7 +1,8 @@
{
"name": "Advanced Algorithm Scripting",
"order": 12,
- "time": "50h",
+ "time": "50 hours",
+ "helpRoom": "HelpJavaScript",
"challenges": [
{
"id": "aff0395860f5d3034dc0bfc9",
diff --git a/seed/challenges/01-front-end-development-certification/basic-bonfires.json b/seed/challenges/01-front-end-development-certification/basic-bonfires.json
index 66146ca022..18dea610a9 100644
--- a/seed/challenges/01-front-end-development-certification/basic-bonfires.json
+++ b/seed/challenges/01-front-end-development-certification/basic-bonfires.json
@@ -1,7 +1,8 @@
{
"name": "Basic Algorithm Scripting",
"order": 8,
- "time": "50h",
+ "time": "50 hours",
+ "helpRoom": "HelpJavaScript",
"challenges": [
{
"id": "bd7158d2c442eddfbeb5bd1f",
diff --git a/seed/challenges/01-front-end-development-certification/basic-javascript.json b/seed/challenges/01-front-end-development-certification/basic-javascript.json
index a3ab766538..b256190dc5 100644
--- a/seed/challenges/01-front-end-development-certification/basic-javascript.json
+++ b/seed/challenges/01-front-end-development-certification/basic-javascript.json
@@ -1,7 +1,8 @@
{
"name": "Basic JavaScript",
- "time": "10h",
+ "time": "10 hours",
"order": 6,
+ "helpRoom": "HelpJavaScript",
"challenges": [
{
"id": "bd7123c9c441eddfaeb4bdef",
diff --git a/seed/challenges/01-front-end-development-certification/basic-ziplines.json b/seed/challenges/01-front-end-development-certification/basic-ziplines.json
index 57ae6c21b9..c191d4f01b 100644
--- a/seed/challenges/01-front-end-development-certification/basic-ziplines.json
+++ b/seed/challenges/01-front-end-development-certification/basic-ziplines.json
@@ -1,7 +1,8 @@
{
"name": "Basic Front End Development Projects",
"order": 9,
- "time": "100h",
+ "time": "100 hours",
+ "helpRoom": "HelpFrontEnd",
"challenges": [
{
"id": "bd7158d8c442eddfbeb5bd1f",
@@ -110,13 +111,13 @@
"133315782"
],
"description": [
- "Objective: Build a CodePen.io app that is functionally similar to this: http://codepen.io/FreeCodeCamp/full/VemmoX/.",
- "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
- "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.",
- "User Story: I can access all of the portfolio webpage's content just by scrolling.",
- "User Story: I can click different buttons that will take me to the portfolio creator's different social media pages.",
- "User Story: I can see thumbnail images of different projects the portfolio creator has built (if you haven't built any websites before, use placeholders.)",
- "User Story: I navigate to different sections of the webpage by clicking buttons in the navigation.",
+ "Objective: Build a CodePen.io app that is functionally similar to this: http://codepen.io/FreeCodeCamp/full/VemmoX/.",
+ "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
+ "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.",
+ "User Story: I can access all of the portfolio webpage's content just by scrolling.",
+ "User Story: I can click different buttons that will take me to the portfolio creator's different social media pages.",
+ "User Story: I can see thumbnail images of different projects the portfolio creator has built (if you haven't built any websites before, use placeholders.)",
+ "User Story: I navigate to different sections of the webpage by clicking buttons in the navigation.",
"Don't worry if you don't have anything to showcase on your portfolio yet - you will build several apps on the next few CodePen challenges, and can come back and update your portfolio later.",
"There are many great portfolio templates out there, but for this challenge, you'll need to build a portfolio page yourself. Using Bootstrap will make this much easier for you.",
"Note that CodePen.io overrides the Window.open() function, so if you want to open windows using jQuery, you will need to target invisible anchor elements like this one: <a target='_blank'>
.",
@@ -180,11 +181,11 @@
"126415122"
],
"description": [
- "Objective: Build a CodePen.io app that is functionally similar to this: http://codepen.io/FreeCodeCamp/full/yeVgBY.",
- "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
- "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.",
- "User Story: I can click a button to show me a new random quote.",
- "User Story: I can press a button to tweet out a quote.",
+ "Objective: Build a CodePen.io app that is functionally similar to this: http://codepen.io/FreeCodeCamp/full/yeVgBY.",
+ "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
+ "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.",
+ "User Story: I can click a button to show me a new random quote.",
+ "User Story: I can press a button to tweet out a quote.",
"Remember to use Read-Search-Ask if you get stuck.",
"When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen. ",
"You can get feedback on your project from fellow campers by sharing it in our Code Review Chatroom. You can also share it on Twitter and your city's Campsite (on Facebook)."
@@ -234,12 +235,12 @@
"126411565"
],
"description": [
- "Objective: Build a CodePen.io app that is functionally similar to this: http://codepen.io/FreeCodeCamp/full/EPNZYW.",
- "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
- "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.",
- "User Story: I can add, subtract, multiply and divide two numbers.",
- "User Story: I can clear the input field with a clear button.",
- "User Story: I can keep chaining mathematical operations together until I hit the equal button, and the calculator will tell me the correct output.",
+ "Objective: Build a CodePen.io app that is functionally similar to this: http://codepen.io/FreeCodeCamp/full/EPNZYW.",
+ "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
+ "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.",
+ "User Story: I can add, subtract, multiply and divide two numbers.",
+ "User Story: I can clear the input field with a clear button.",
+ "User Story: I can keep chaining mathematical operations together until I hit the equal button, and the calculator will tell me the correct output.",
"Remember to use Read-Search-Ask if you get stuck.",
"When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen. ",
"You can get feedback on your project from fellow campers by sharing it in our Code Review Chatroom. You can also share it on Twitter and your city's Campsite (on Facebook)."
@@ -278,12 +279,12 @@
"126411567"
],
"description": [
- "Objective: Build a CodePen.io app that is functionally similar to this: http://codepen.io/FreeCodeCamp/full/VemPZX.",
- "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
- "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.",
- "User Story: I can start a 25 minute pomodoro, and the timer will go off once 25 minutes has elapsed.",
- "User Story: I can reset the clock for my next pomodoro.",
- "User Story: I can customize the length of each pomodoro.",
+ "Objective: Build a CodePen.io app that is functionally similar to this: http://codepen.io/FreeCodeCamp/full/VemPZX.",
+ "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
+ "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.",
+ "User Story: I can start a 25 minute pomodoro, and the timer will go off once 25 minutes has elapsed.",
+ "User Story: I can reset the clock for my next pomodoro.",
+ "User Story: I can customize the length of each pomodoro.",
"Remember to use Read-Search-Ask if you get stuck.",
"When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen. ",
"You can get feedback on your project from fellow campers by sharing it in our Code Review Chatroom. You can also share it on Twitter and your city's Campsite (on Facebook)."
diff --git a/seed/challenges/01-front-end-development-certification/bootstrap.json b/seed/challenges/01-front-end-development-certification/bootstrap.json
index 8fc4b9be3d..b68b2663b2 100644
--- a/seed/challenges/01-front-end-development-certification/bootstrap.json
+++ b/seed/challenges/01-front-end-development-certification/bootstrap.json
@@ -1,7 +1,8 @@
{
"name": "Responsive Design with Bootstrap",
"order": 3,
- "time": "5h",
+ "time": "5 hours",
+ "helpRoom": "Help",
"challenges": [
{
"id": "bad87fee1348bd9acde08712",
diff --git a/seed/challenges/01-front-end-development-certification/front-end-development-certificate.json b/seed/challenges/01-front-end-development-certification/front-end-development-certificate.json
index cc6eee87f6..95cda02d25 100644
--- a/seed/challenges/01-front-end-development-certification/front-end-development-certificate.json
+++ b/seed/challenges/01-front-end-development-certification/front-end-development-certificate.json
@@ -1,7 +1,7 @@
{
"name": "Claim Your Front End Development Certificate",
"order": 13,
- "time": "5m",
+ "time": "5 minutes",
"challenges": [
{
"id": "561add10cb82ac38a17513be",
@@ -42,10 +42,6 @@
"type": "Waypoint",
"challengeType": 7,
"tests": [
- {
- "id": "ad7123c8c441eddfaeb5bdef",
- "title": "Meet Bonfire"
- },
{
"id": "a202eed8fc186c8434cb6d61",
"title": "Reverse a String"
diff --git a/seed/challenges/01-front-end-development-certification/gear-up-for-success.json b/seed/challenges/01-front-end-development-certification/gear-up-for-success.json
index c39f10fda2..e824370e11 100644
--- a/seed/challenges/01-front-end-development-certification/gear-up-for-success.json
+++ b/seed/challenges/01-front-end-development-certification/gear-up-for-success.json
@@ -1,7 +1,7 @@
{
"name": "Gear up for Success",
"order": 4,
- "time": "20m",
+ "time": "20 minutes",
"challenges": [
{
"id": "560add65cb82ac38a17513c2",
diff --git a/seed/challenges/01-front-end-development-certification/html5-and-css.json b/seed/challenges/01-front-end-development-certification/html5-and-css.json
index 01c565765e..f4a4c537c0 100644
--- a/seed/challenges/01-front-end-development-certification/html5-and-css.json
+++ b/seed/challenges/01-front-end-development-certification/html5-and-css.json
@@ -1,7 +1,8 @@
{
"name": "HTML5 and CSS",
"order": 2,
- "time": "5h",
+ "time": "5 hours",
+ "helpRoom": "Help",
"challenges": [
{
"id": "bd7123c8c441eddfaeb5bdef",
diff --git a/seed/challenges/01-front-end-development-certification/intermediate-bonfires.json b/seed/challenges/01-front-end-development-certification/intermediate-bonfires.json
index b2a5e419fa..bcc88e5f24 100644
--- a/seed/challenges/01-front-end-development-certification/intermediate-bonfires.json
+++ b/seed/challenges/01-front-end-development-certification/intermediate-bonfires.json
@@ -1,7 +1,8 @@
{
"name": "Intermediate Algorithm Scripting",
"order": 10,
- "time": "50h",
+ "time": "50 hours",
+ "helpRoom": "HelpJavaScript",
"challenges": [
{
"id": "a3566b1109230028080c9345",
diff --git a/seed/challenges/01-front-end-development-certification/intermediate-ziplines.json b/seed/challenges/01-front-end-development-certification/intermediate-ziplines.json
index 651214dc46..896d93ce7f 100644
--- a/seed/challenges/01-front-end-development-certification/intermediate-ziplines.json
+++ b/seed/challenges/01-front-end-development-certification/intermediate-ziplines.json
@@ -1,7 +1,8 @@
{
"name": "Intermediate Front End Development Projects",
"order": 11,
- "time": "200h",
+ "time": "200 hours",
+ "helpRoom": "HelpFrontEnd",
"challenges": [
{
"id": "bd7158d8c442eddfaeb5bd10",
@@ -10,12 +11,12 @@
"126415127"
],
"description": [
- "Objective: Build a CodePen.io app that is functionally similar to this: http://codepen.io/FreeCodeCamp/full/avqvgJ.",
- "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
- "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.",
- "User Story: I can see the weather in my current location.",
- "User Story: I can see a different icon or background image (e.g. snowy mountain, hot desert) depending on the weather.",
- "User Story: I can push a button to toggle between Fahrenheit and Celsius.",
+ "Objective: Build a CodePen.io app that is functionally similar to this: http://codepen.io/FreeCodeCamp/full/avqvgJ.",
+ "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
+ "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.",
+ "User Story: I can see the weather in my current location.",
+ "User Story: I can see a different icon or background image (e.g. snowy mountain, hot desert) depending on the weather.",
+ "User Story: I can push a button to toggle between Fahrenheit and Celsius.",
"We recommend using the Open Weather API. This will require creating a free API key. Normally you want to avoid exposing API keys on CodePen, but we haven't been able to find a keyless API for weather.",
"Remember to use Read-Search-Ask if you get stuck.",
"When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen.",
@@ -70,13 +71,13 @@
"126415129"
],
"description": [
- "Objective: Build a CodePen.io app that is functionally similar to this: http://codepen.io/FreeCodeCamp/full/pgNRoJ.",
- "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
- "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.",
- "User Story: I can browse recent posts from Camper News.",
- "User Story: I can click on a post to be taken to the story's original URL.",
- "User Story: I can see how many upvotes each story has.",
- "Hint: Here's the Camper News Hot Stories API endpoint: http://www.freecodecamp.com/news/hot
.",
+ "Objective: Build a CodePen.io app that is functionally similar to this: http://codepen.io/FreeCodeCamp/full/pgNRoJ.",
+ "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
+ "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.",
+ "User Story: I can browse recent posts from Camper News.",
+ "User Story: I can click on a post to be taken to the story's original URL.",
+ "User Story: I can see how many upvotes each story has.",
+ "Hint: Here's the Camper News Hot Stories API endpoint: http://www.freecodecamp.com/news/hot
.",
"Remember to use Read-Search-Ask if you get stuck.",
"When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen.",
"You can get feedback on your project from fellow campers by sharing it in our Code Review Chatroom. You can also share it on Twitter and your city's Campsite (on Facebook)."
@@ -116,14 +117,14 @@
"126415131"
],
"description": [
- "Objective: Build a CodePen.io app that is functionally similar to this: http://codepen.io/FreeCodeCamp/full/pgNRvJ.",
- "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
- "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.",
- "User Story: I can search Wikipedia entries in a search box and see the resulting Wikipedia entries.",
- "User Story: I can click a button to see a random Wikipedia entry.",
- "User Story: When I type in the search box, I can see a dropdown menu with autocomplete options for matching Wikipedia entries.",
- "Hint #1: Here's an entry on using Wikipedia's API: http://www.mediawiki.org/wiki/API:Main_page
.",
- "Hint #2: Use this link to experiment with Wikipedia's API.",
+ "Objective: Build a CodePen.io app that is functionally similar to this: http://codepen.io/FreeCodeCamp/full/pgNRvJ.",
+ "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
+ "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.",
+ "User Story: I can search Wikipedia entries in a search box and see the resulting Wikipedia entries.",
+ "User Story: I can click a button to see a random Wikipedia entry.",
+ "Hint #1: Here's a URL you can use to get a random Wikipedia article: http://en.wikipedia.org/wiki/Special:Random
.",
+ "Hint #2: Here's an entry on using Wikipedia's API: http://www.mediawiki.org/wiki/API:Main_page
.",
+ "Hint #3: Use this link to experiment with Wikipedia's API.",
"Remember to use Read-Search-Ask if you get stuck.",
"When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen.",
"You can get feedback on your project from fellow campers by sharing it in our Code Review Chatroom. You can also share it on Twitter and your city's Campsite (on Facebook)."
@@ -163,16 +164,16 @@
"126411564"
],
"description": [
- "Objective: Build a CodePen.io app that is functionally similar to this: http://codepen.io/FreeCodeCamp/full/adBpOw.",
- "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
- "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.",
- "User Story: I can see whether Free Code Camp is currently streaming on Twitch.tv.",
- "User Story: I can click the status output and be sent directly to the Free Code Camp's Twitch.tv channel.",
- "User Story: if a Twitch user is currently streaming, I can see additional details about what they are streaming.",
- "User Story: I will see a placeholder notification if a streamer has closed their Twitch account (or the account never existed). You can verify this works by adding brunofin and comster404 to your array of Twitch streamers.",
- "Hint: See an example call to Twitch.tv's JSONP API at https://github.com/FreeCodeCamp/FreeCodeCamp/wiki/Zipline-Use-the-Twitchtv-JSON-API
.",
- "Hint: The relevant documentation about this API call is here: https://github.com/justintv/Twitch-API/blob/master/v3_resources/streams.md#get-streamschannel.",
- "Hint: Here's an array of the Twitch.tv usernames of people who regularly stream coding: [\"freecodecamp\", \"storbeck\", \"terakilobyte\", \"habathcx\",\"RobotCaleb\",\"thomasballinger\",\"noobs2ninjas\",\"beohoff\"]
",
+ "Objective: Build a CodePen.io app that is functionally similar to this: http://codepen.io/FreeCodeCamp/full/adBpOw.",
+ "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
+ "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.",
+ "User Story: I can see whether Free Code Camp is currently streaming on Twitch.tv.",
+ "User Story: I can click the status output and be sent directly to the Free Code Camp's Twitch.tv channel.",
+ "User Story: if a Twitch user is currently streaming, I can see additional details about what they are streaming.",
+ "User Story: I will see a placeholder notification if a streamer has closed their Twitch account (or the account never existed). You can verify this works by adding brunofin and comster404 to your array of Twitch streamers.",
+ "Hint: See an example call to Twitch.tv's JSONP API at https://github.com/FreeCodeCamp/FreeCodeCamp/wiki/Zipline-Use-the-Twitchtv-JSON-API
.",
+ "Hint: The relevant documentation about this API call is here: https://github.com/justintv/Twitch-API/blob/master/v3_resources/streams.md#get-streamschannel.",
+ "Hint: Here's an array of the Twitch.tv usernames of people who regularly stream coding: [\"freecodecamp\", \"storbeck\", \"terakilobyte\", \"habathcx\",\"RobotCaleb\",\"thomasballinger\",\"noobs2ninjas\",\"beohoff\"]
",
"Remember to use Read-Search-Ask if you get stuck.",
"When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen.",
"You can get feedback on your project from fellow campers by sharing it in our Code Review Chatroom. You can also share it on Twitter and your city's Campsite (on Facebook)."
@@ -233,13 +234,13 @@
"126415123"
],
"description": [
- "Objective: Build a CodePen.io app that is functionally similar to this: http://codepen.io/FreeCodeCamp/full/adBpvw.",
- "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
- "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.",
- "User Story: I can play a game of Tic Tac Toe with the computer.",
- "User Story: I can never actually win against the computer - at best I can tie.",
- "User Story: My game will reset as soon as it's over so I can play again.",
- "User Story: I can choose whether I want to play as X or O.",
+ "Objective: Build a CodePen.io app that is functionally similar to this: http://codepen.io/FreeCodeCamp/full/adBpvw.",
+ "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
+ "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.",
+ "User Story: I can play a game of Tic Tac Toe with the computer.",
+ "User Story: I can never actually win against the computer - at best I can tie.",
+ "User Story: My game will reset as soon as it's over so I can play again.",
+ "User Story: I can choose whether I want to play as X or O.",
"Remember to use Read-Search-Ask if you get stuck.",
"When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen.",
"You can get feedback on your project from fellow campers by sharing it in our Code Review Chatroom. You can also share it on Twitter and your city's Campsite (on Facebook)."
@@ -279,19 +280,18 @@
"137213633"
],
"description": [
- "Objective: Build a CodePen.io app that is functionally similar to this: http://codepen.io/FreeCodeCamp/full/obYBjE.",
- "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
- "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.",
- "User Story: I am presented with a random series of button presses.",
- "User Story: each time I input a series of button presses correctly, I see the same series of button presses but with an additional step.",
- "User Story: I hear a sound that corresponds to each button both when the series of button presses plays, and when I personally press a button.",
- "User Story: If I press the wrong button, I am notified that I have done so, and that series of button presses starts again to remind me of the pattern so I can try again.",
- "User Story: I can see how many steps are in the current series of button presses.",
- "User Story: If I want to restart, I can hit a button to do so, and the game will return to a single step.",
- "User Story: I can play in strict mode where if I get a button press wrong, it notifies me that I have done so, and the game restarts at a new random series of button presses.",
- "User Story: The tempo of the game speeds up incrementally on the 5th, 9th and 13th step.",
- "User Story: I can win the game by getting a series of 20 steps correct. I am notified of my victory, then the game starts over.",
- "Hint: Here are mp3s you can use for each button: https://s3.amazonaws.com/freecodecamp/simonSound1.mp3
, https://s3.amazonaws.com/freecodecamp/simonSound2.mp3
, https://s3.amazonaws.com/freecodecamp/simonSound3.mp3
, https://s3.amazonaws.com/freecodecamp/simonSound4.mp3
.",
+ "Objective: Build a CodePen.io app that is functionally similar to this: http://codepen.io/FreeCodeCamp/full/obYBjE.",
+ "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
+ "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.",
+ "User Story: I am presented with a random series of button presses.",
+ "User Story: Each time I input a series of button presses correctly, I see the same series of button presses but with an additional step.",
+ "User Story: I hear a sound that corresponds to each button both when the series of button presses plays, and when I personally press a button.",
+ "User Story: If I press the wrong button, I am notified that I have done so, and that series of button presses starts again to remind me of the pattern so I can try again.",
+ "User Story: I can see how many steps are in the current series of button presses.",
+ "User Story: If I want to restart, I can hit a button to do so, and the game will return to a single step.",
+ "User Story: I can play in strict mode where if I get a button press wrong, it notifies me that I have done so, and the game restarts at a new random series of button presses.",
+ "User Story: I can win the game by getting a series of 20 steps correct. I am notified of my victory, then the game starts over.",
+ "Hint: Here are mp3s you can use for each button: https://s3.amazonaws.com/freecodecamp/simonSound1.mp3
, https://s3.amazonaws.com/freecodecamp/simonSound2.mp3
, https://s3.amazonaws.com/freecodecamp/simonSound3.mp3
, https://s3.amazonaws.com/freecodecamp/simonSound4.mp3
.",
"Remember to use Read-Search-Ask if you get stuck.",
"When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen.",
"You can get feedback on your project from fellow campers by sharing it in our Code Review Chatroom. You can also share it on Twitter and your city's Campsite (on Facebook)."
diff --git a/seed/challenges/01-front-end-development-certification/jquery.json b/seed/challenges/01-front-end-development-certification/jquery.json
index 977281f904..6e6aa444e5 100644
--- a/seed/challenges/01-front-end-development-certification/jquery.json
+++ b/seed/challenges/01-front-end-development-certification/jquery.json
@@ -1,7 +1,8 @@
{
"name": "jQuery",
"order": 5,
- "time": "3h",
+ "time": "3 hours",
+ "helpRoom": "Help",
"challenges": [
{
"id": "bad87fee1348bd9acdd08826",
diff --git a/seed/challenges/01-front-end-development-certification/json-apis-and-ajax.json b/seed/challenges/01-front-end-development-certification/json-apis-and-ajax.json
index 90d75630f5..22b6361493 100644
--- a/seed/challenges/01-front-end-development-certification/json-apis-and-ajax.json
+++ b/seed/challenges/01-front-end-development-certification/json-apis-and-ajax.json
@@ -1,7 +1,8 @@
{
"name": "JSON APIs and Ajax",
"order": 10.5,
- "time": "2h",
+ "time": "2 hours",
+ "helpRoom": "Help",
"challenges": [
{
"id": "bb000000000000000000001",
diff --git a/seed/challenges/01-front-end-development-certification/object-oriented-and-functional-programming.json b/seed/challenges/01-front-end-development-certification/object-oriented-and-functional-programming.json
index f9d0c91340..8a442592f0 100644
--- a/seed/challenges/01-front-end-development-certification/object-oriented-and-functional-programming.json
+++ b/seed/challenges/01-front-end-development-certification/object-oriented-and-functional-programming.json
@@ -1,7 +1,8 @@
{
"name": "Object Oriented and Functional Programming",
"order": 7,
- "time": "2h",
+ "time": "2 hours",
+ "helpRoom": "HelpJavaScript",
"note": [
"Methods",
"Closures",
diff --git a/seed/challenges/02-data-visualization-certification/d3.json b/seed/challenges/02-data-visualization-certification/d3.json
index 0128b92c05..75172df8b3 100644
--- a/seed/challenges/02-data-visualization-certification/d3.json
+++ b/seed/challenges/02-data-visualization-certification/d3.json
@@ -2,7 +2,8 @@
"name": "D3",
"order": 16,
"isComingSoon": true,
- "time": "5h",
+ "time": "5 hours",
+ "helpRoom": "HelpDataViz",
"challenges": [
{
"id": "bd7158d8c423ede2aab5bdee",
diff --git a/seed/challenges/02-data-visualization-certification/data-visualization-certificate.json b/seed/challenges/02-data-visualization-certification/data-visualization-certificate.json
index 75a77bbd9e..6e46922f32 100644
--- a/seed/challenges/02-data-visualization-certification/data-visualization-certificate.json
+++ b/seed/challenges/02-data-visualization-certification/data-visualization-certificate.json
@@ -1,7 +1,7 @@
{
"name": "Claim Your Data Visualization Certificate",
"order": 18,
- "time": "5m",
+ "time": "5 minutes",
"challenges": [
{
"id": "561add10cb82ac38a17513b3",
@@ -129,4 +129,4 @@
"descriptionPt": []
}
]
-}
\ No newline at end of file
+}
diff --git a/seed/challenges/02-data-visualization-certification/data-visualization-projects.json b/seed/challenges/02-data-visualization-certification/data-visualization-projects.json
index 822062680c..b4861ab031 100644
--- a/seed/challenges/02-data-visualization-certification/data-visualization-projects.json
+++ b/seed/challenges/02-data-visualization-certification/data-visualization-projects.json
@@ -1,7 +1,8 @@
{
"name": "Data Visualization Projects",
"order": 17,
- "time": "200h",
+ "time": "200 hours",
+ "helpRoom": "HelpDataViz",
"challenges": [
{
"id": "bd7168d8c242eddfaeb5bd13",
@@ -10,13 +11,13 @@
"150324699"
],
"description": [
- "Objective: Build a CodePen.io app that is functionally similar to this: http://codepen.io/FreeCodeCamp/full/adBBWd.",
- "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
- "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.",
- "Rule #3: You must use D3.js to build this project.",
- "User Story: I can see US Gross Domestic Product by quarter, over time.",
- "User Story: I can mouse over a bar and see a tooltip with the GDP amount and exact year and month that bar represents.",
- "Hint: Here's a dataset you can use to build this: https://raw.githubusercontent.com/FreeCodeCamp/ProjectReferenceData/master/GDP-data.json",
+ "Objective: Build a CodePen.io app that is functionally similar to this: http://codepen.io/FreeCodeCamp/full/adBBWd.",
+ "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
+ "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.",
+ "Rule #3: You must use D3.js to build this project.",
+ "User Story: I can see US Gross Domestic Product by quarter, over time.",
+ "User Story: I can mouse over a bar and see a tooltip with the GDP amount and exact year and month that bar represents.",
+ "Hint: Here's a dataset you can use to build this: https://raw.githubusercontent.com/FreeCodeCamp/ProjectReferenceData/master/GDP-data.json",
"Remember to use Read-Search-Ask if you get stuck.",
"When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen. ",
"You can get feedback on your project from fellow campers by sharing it in our Code Review Chatroom. You can also share it on Twitter and your city's Campsite (on Facebook)."
@@ -44,13 +45,13 @@
"150324700"
],
"description": [
- "Objective: Build a CodePen.io app that is functionally similar to this: http://codepen.io/FreeCodeCamp/full/GoNNEy.",
- "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
- "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.",
- "Rule #3: You must use D3.js to build this project.",
- "User Story: I can see performance time visualized in a scatterplot graph.",
- "User Story: I can mouse over a plot to see a tooltip with additional details.",
- "Hint: Here's a dataset you can use to build this: https://raw.githubusercontent.com/FreeCodeCamp/ProjectReferenceData/master/cyclist-data.json",
+ "Objective: Build a CodePen.io app that is functionally similar to this: http://codepen.io/FreeCodeCamp/full/GoNNEy.",
+ "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
+ "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.",
+ "Rule #3: You must use D3.js to build this project.",
+ "User Story: I can see performance time visualized in a scatterplot graph.",
+ "User Story: I can mouse over a plot to see a tooltip with additional details.",
+ "Hint: Here's a dataset you can use to build this: https://raw.githubusercontent.com/FreeCodeCamp/ProjectReferenceData/master/cyclist-data.json",
"Remember to use Read-Search-Ask if you get stuck.",
"When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen. ",
"You can get feedback on your project from fellow campers by sharing it in our Code Review Chatroom. You can also share it on Twitter and your city's Campsite (on Facebook)."
@@ -78,14 +79,14 @@
"150324701"
],
"description": [
- "Objective: Build a CodePen.io app that is functionally similar to this: http://codepen.io/FreeCodeCamp/full/rxWWGa.",
- "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
- "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.",
- "Rule #3: You must use D3.js to build this project.",
- "User Story: I can view a heat map with data represented both on the Y and X axis.",
- "User Story: Each cell is colored based its relationship to other data.",
- "User Story: I can mouse over a cell in the heat map to get more exact information.",
- "Hint: Here's a dataset you can use to build this: https://raw.githubusercontent.com/FreeCodeCamp/ProjectReferenceData/master/global-temperature.json",
+ "Objective: Build a CodePen.io app that is functionally similar to this: http://codepen.io/FreeCodeCamp/full/rxWWGa.",
+ "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
+ "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.",
+ "Rule #3: You must use D3.js to build this project.",
+ "User Story: I can view a heat map with data represented both on the Y and X axis.",
+ "User Story: Each cell is colored based its relationship to other data.",
+ "User Story: I can mouse over a cell in the heat map to get more exact information.",
+ "Hint: Here's a dataset you can use to build this: https://raw.githubusercontent.com/FreeCodeCamp/ProjectReferenceData/master/global-temperature.json",
"Remember to use Read-Search-Ask if you get stuck.",
"When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen. ",
"You can get feedback on your project from fellow campers by sharing it in our Code Review Chatroom. You can also share it on Twitter and your city's Campsite (on Facebook)."
@@ -113,16 +114,16 @@
"150324458"
],
"description": [
- "Objective: Build a CodePen.io app that is functionally similar to this: http://codepen.io/FreeCodeCamp/full/KVNNXY.",
- "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
- "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.",
- "Rule #3: You must use D3.js to build this project.",
- "User Story: I can see a Force-directed Graph that shows which campers are posting links on Camper News to which domains.",
- "User Story: I can see each camper's icon on their node.",
- "User Story: I can see the relationship between the campers and the domains they're posting.",
- "User Story: I can tell approximately many times campers have linked to a specific domain from it's node size.",
- "User Story: I can tell approximately how many times a specific camper has posted a link from their node's size.",
- "Hint: Here's the Camper News Hot Stories API endpoint: http://www.freecodecamp.com/news/hot
.",
+ "Objective: Build a CodePen.io app that is functionally similar to this: http://codepen.io/FreeCodeCamp/full/KVNNXY.",
+ "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
+ "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.",
+ "Rule #3: You must use D3.js to build this project.",
+ "User Story: I can see a Force-directed Graph that shows which campers are posting links on Camper News to which domains.",
+ "User Story: I can see each camper's icon on their node.",
+ "User Story: I can see the relationship between the campers and the domains they're posting.",
+ "User Story: I can tell approximately many times campers have linked to a specific domain from it's node size.",
+ "User Story: I can tell approximately how many times a specific camper has posted a link from their node's size.",
+ "Hint: Here's the Camper News Hot Stories API endpoint: http://www.freecodecamp.com/news/hot
.",
"Remember to use Read-Search-Ask if you get stuck.",
"When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen. ",
"You can get feedback on your project from fellow campers by sharing it in our Code Review Chatroom. You can also share it on Twitter and your city's Campsite (on Facebook)."
@@ -150,14 +151,14 @@
"150324698"
],
"description": [
- "Objective: Build a CodePen.io app that is functionally similar to this: http://codepen.io/FreeCodeCamp/full/mVEJag.",
- "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
- "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.",
- "Rule #3: You must use D3.js to build this project.",
- "User Story: I can see where all Meteorites landed on a world map.",
- "User Story: I can tell the relative size of the meteorite, just by looking at the way it's represented on the map.",
- "User Story: I can mouse over the meteorite's data point for additional data.",
- "Hint: Here's a dataset you can use to build this: https://raw.githubusercontent.com/FreeCodeCamp/ProjectReferenceData/master/meteorite-strike-data.json",
+ "Objective: Build a CodePen.io app that is functionally similar to this: http://codepen.io/FreeCodeCamp/full/mVEJag.",
+ "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
+ "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.",
+ "Rule #3: You must use D3.js to build this project.",
+ "User Story: I can see where all Meteorites landed on a world map.",
+ "User Story: I can tell the relative size of the meteorite, just by looking at the way it's represented on the map.",
+ "User Story: I can mouse over the meteorite's data point for additional data.",
+ "Hint: Here's a dataset you can use to build this: https://raw.githubusercontent.com/FreeCodeCamp/ProjectReferenceData/master/meteorite-strike-data.json",
"Remember to use Read-Search-Ask if you get stuck.",
"When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen. ",
"You can get feedback on your project from fellow campers by sharing it in our Code Review Chatroom. You can also share it on Twitter and your city's Campsite (on Facebook)."
diff --git a/seed/challenges/02-data-visualization-certification/react-projects.json b/seed/challenges/02-data-visualization-certification/react-projects.json
index 0df0abbbb3..e1fbbe6dc5 100644
--- a/seed/challenges/02-data-visualization-certification/react-projects.json
+++ b/seed/challenges/02-data-visualization-certification/react-projects.json
@@ -1,7 +1,8 @@
{
"name": "React Projects",
"order": 15,
- "time": "200h",
+ "time": "200 hours",
+ "helpRoom": "HelpDataViz",
"challenges": [
{
"id": "bd7157d8c242eddfaeb5bd13",
@@ -10,14 +11,14 @@
"150324697"
],
"description": [
- "Objective: Build a CodePen.io app that is functionally similar to this: http://codepen.io/FreeCodeCamp/full/obYYqW.",
- "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
- "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.",
- "Rule #3: You must use both Sass and React to build this project.",
- "User Story: I can type GitHub-flavored Markdown into a text area.",
- "User Story: I can see a preview of the output of my markdown that is updated as I type.",
- "Hint: You don't need to interperate Markdown yourself - you can import the Marked library for this: https://cdnjs.com/libraries/marked",
- "Note: If you want to use the React JSX syntax, you need to enable 'Babel' as a preprocessor",
+ "Objective: Build a CodePen.io app that is functionally similar to this: http://codepen.io/FreeCodeCamp/full/obYYqW.",
+ "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
+ "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.",
+ "Rule #3: You must use both Sass and React to build this project.",
+ "User Story: I can type GitHub-flavored Markdown into a text area.",
+ "User Story: I can see a preview of the output of my markdown that is updated as I type.",
+ "Hint: You don't need to interperate Markdown yourself - you can import the Marked library for this: https://cdnjs.com/libraries/marked",
+ "Note: If you want to use the React JSX syntax, you need to enable 'Babel' as a preprocessor",
"Remember to use Read-Search-Ask if you get stuck.",
"When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen. ",
"You can get feedback on your project from fellow campers by sharing it in our Code Review Chatroom. You can also share it on Twitter and your city's Campsite (on Facebook)."
@@ -45,15 +46,15 @@
"150324694"
],
"description": [
- "Objective: Build a CodePen.io app that is functionally similar to this: http://codepen.io/FreeCodeCamp/full/qbqqJm/.",
- "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
- "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.",
- "Rule #3: You must use both Sass and React to build this project.",
- "User Story: I can see a table of the Free Code Camp campers who've earned the most brownie points in the past 30 days.",
- "User Story: I can see how many brownie points they've earned in the past 30 days, and how many they've earned total.",
- "User Story: I can toggle between sorting the list by how many bronwie points they've earned in the past 30 days and by how many brownie points they've earned total.",
- "Hint: To get the top 100 campers for the last 30 days: http://fcctop100.herokuapp.com/api/fccusers/top/recent.",
- "Hint: To get the top 100 campers of all time: http://fcctop100.herokuapp.com/api/fccusers/top/alltime.",
+ "Objective: Build a CodePen.io app that is functionally similar to this: http://codepen.io/FreeCodeCamp/full/qbqqJm/.",
+ "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
+ "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.",
+ "Rule #3: You must use both Sass and React to build this project.",
+ "User Story: I can see a table of the Free Code Camp campers who've earned the most brownie points in the past 30 days.",
+ "User Story: I can see how many brownie points they've earned in the past 30 days, and how many they've earned total.",
+ "User Story: I can toggle between sorting the list by how many bronwie points they've earned in the past 30 days and by how many brownie points they've earned total.",
+ "Hint: To get the top 100 campers for the last 30 days: http://fcctop100.herokuapp.com/api/fccusers/top/recent.",
+ "Hint: To get the top 100 campers of all time: http://fcctop100.herokuapp.com/api/fccusers/top/alltime.",
"Remember to use Read-Search-Ask if you get stuck.",
"When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen. ",
"You can get feedback on your project from fellow campers by sharing it in our Code Review Chatroom. You can also share it on Twitter and your city's Campsite (on Facebook)."
@@ -81,16 +82,16 @@
"150324695"
],
"description": [
- "Objective: Build a CodePen.io app that is functionally similar to this: http://codepen.io/FreeCodeCamp/full/LGbbqj.",
- "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
- "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.",
- "Rule #3: You must use both Sass and React to build this project.",
- "User Story: I can create recipes that have names and ingredients.",
- "User Story: I can see an index view where the names of all the recipes are visible.",
- "User Story: I can click into any of those recipes to view it.",
- "User Story: I can edit these recipes.",
- "User Story: I can delete these recipes.",
- "User Story: All new recipes I add are saved in my browser's local storage. If I refresh the page, these recipes will still be there.",
+ "Objective: Build a CodePen.io app that is functionally similar to this: http://codepen.io/FreeCodeCamp/full/LGbbqj.",
+ "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
+ "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.",
+ "Rule #3: You must use both Sass and React to build this project.",
+ "User Story: I can create recipes that have names and ingredients.",
+ "User Story: I can see an index view where the names of all the recipes are visible.",
+ "User Story: I can click into any of those recipes to view it.",
+ "User Story: I can edit these recipes.",
+ "User Story: I can delete these recipes.",
+ "User Story: All new recipes I add are saved in my browser's local storage. If I refresh the page, these recipes will still be there.",
"Remember to use Read-Search-Ask if you get stuck.",
"When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen.",
"You can get feedback on your project from fellow campers by sharing it in our Code Review Chatroom. You can also share it on Twitter and your city's Campsite (on Facebook)."
@@ -118,18 +119,18 @@
"150324459"
],
"description": [
- "Objective: Build a CodePen.io app that is functionally similar to this: http://codepen.io/FreeCodeCamp/full/dGOOrZ.",
- "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
- "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.",
- "Rule #3: You must use both Sass and React to build this project.",
- "User Story: When I first arrive at the game, it will randomly generate a board and start playing.",
- "User Story: I can start and stop the board.",
- "User Story: I can set up the board.",
- "User Story: I can clear the board.",
- "User Story: When I press start, the game will play out.",
- "User Story: Each time the board changes, I can see how many generations have gone by.",
- "Hint: Here's an explanation of Conway's Game of Life from John Conway himself: https://www.youtube.com/watch?v=E8kUJL04ELA",
- "Hint: Here's an overview of Conway's Game of Life with rules for your reference: https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life",
+ "Objective: Build a CodePen.io app that is functionally similar to this: http://codepen.io/FreeCodeCamp/full/dGOOrZ.",
+ "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
+ "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.",
+ "Rule #3: You must use both Sass and React to build this project.",
+ "User Story: When I first arrive at the game, it will randomly generate a board and start playing.",
+ "User Story: I can start and stop the board.",
+ "User Story: I can set up the board.",
+ "User Story: I can clear the board.",
+ "User Story: When I press start, the game will play out.",
+ "User Story: Each time the board changes, I can see how many generations have gone by.",
+ "Hint: Here's an explanation of Conway's Game of Life from John Conway himself: https://www.youtube.com/watch?v=E8kUJL04ELA",
+ "Hint: Here's an overview of Conway's Game of Life with rules for your reference: https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life",
"Remember to use Read-Search-Ask if you get stuck.",
"When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen. ",
"You can get feedback on your project from fellow campers by sharing it in our Code Review Chatroom. You can also share it on Twitter and your city's Campsite (on Facebook)."
@@ -157,19 +158,19 @@
"150324693"
],
"description": [
- "Objective: Build a CodePen.io app that is functionally similar to this: http://codepen.io/FreeCodeCamp/full/dGOOEJ/.",
- "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
- "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.",
- "Rule #3: You must use both Sass and React to build this project.",
- "User Story: I have health, a level, and a weapon. I can pick up a better weapon. I can pick up health items.",
- "User Story: All the items and enemies on the map are arranged at random.",
- "User Story: I can move throughout a map, discovering items.",
- "User Story: I can move anywhere within the map's boundaries, but I can't move through an enemy until I've beaten it.",
- "User Story: Much of the map is hidden. When I take a step, all spaces that are within a certain number of spaces from me are revealed.",
- "User Story: When I beat an enemy, the enemy goes away and I get XP, which eventually increases my level.",
- "User Story: When I fight an enemy, we take turns damaging each other until one of us loses. I do damage based off of my level and my weapon. The enemy does damage based off of its level. Damage is somewhat random within a range.",
- "User Story: When I find and beat the boss, I win.",
- "User Story: The game should be challenging, but theoretically winnable.",
+ "Objective: Build a CodePen.io app that is functionally similar to this: http://codepen.io/FreeCodeCamp/full/dGOOEJ/.",
+ "Rule #1: Don't look at the example project's code. Figure it out for yourself.",
+ "Rule #2: Fulfill the below user stories. Use whichever libraries or APIs you need. Give it your own personal style.",
+ "Rule #3: You must use both Sass and React to build this project.",
+ "User Story: I have health, a level, and a weapon. I can pick up a better weapon. I can pick up health items.",
+ "User Story: All the items and enemies on the map are arranged at random.",
+ "User Story: I can move throughout a map, discovering items.",
+ "User Story: I can move anywhere within the map's boundaries, but I can't move through an enemy until I've beaten it.",
+ "User Story: Much of the map is hidden. When I take a step, all spaces that are within a certain number of spaces from me are revealed.",
+ "User Story: When I beat an enemy, the enemy goes away and I get XP, which eventually increases my level.",
+ "User Story: When I fight an enemy, we take turns damaging each other until one of us loses. I do damage based off of my level and my weapon. The enemy does damage based off of its level. Damage is somewhat random within a range.",
+ "User Story: When I find and beat the boss, I win.",
+ "User Story: The game should be challenging, but theoretically winnable.",
"Remember to use Read-Search-Ask if you get stuck.",
"When you are finished, click the \"I've completed this challenge\" button and include a link to your CodePen. ",
"You can get feedback on your project from fellow campers by sharing it in our Code Review Chatroom. You can also share it on Twitter and your city's Campsite (on Facebook)."
diff --git a/seed/challenges/02-data-visualization-certification/react.json b/seed/challenges/02-data-visualization-certification/react.json
index 482ab4e62d..60f29a5b3b 100644
--- a/seed/challenges/02-data-visualization-certification/react.json
+++ b/seed/challenges/02-data-visualization-certification/react.json
@@ -2,7 +2,8 @@
"name": "React",
"order": 14,
"isComingSoon": true,
- "time": "5h",
+ "time": "5 hours",
+ "helpRoom": "HelpDataViz",
"challenges": [
{
"id": "bd7158d8c423ede3aeb5bdee",
diff --git a/seed/challenges/02-data-visualization-certification/sass.json b/seed/challenges/02-data-visualization-certification/sass.json
index 54e0126eba..e45b5726ba 100644
--- a/seed/challenges/02-data-visualization-certification/sass.json
+++ b/seed/challenges/02-data-visualization-certification/sass.json
@@ -2,7 +2,8 @@
"name": "Sass",
"order": 13.5,
"isComingSoon": true,
- "time": "5h",
+ "time": "5 hours",
+ "helpRoom": "HelpDataViz",
"challenges": [
{
"id": "bd7158d8c423ede2aeb5bdee",
diff --git a/seed/challenges/03-back-end-development-certification/api-projects.json b/seed/challenges/03-back-end-development-certification/api-projects.json
index 98c52b7a9f..d26697e802 100644
--- a/seed/challenges/03-back-end-development-certification/api-projects.json
+++ b/seed/challenges/03-back-end-development-certification/api-projects.json
@@ -1,7 +1,8 @@
{
"name": "API Projects",
"order": 26,
- "time": "150h",
+ "time": "150 hours",
+ "helpRoom": "HelpBackEnd",
"challenges": [
{
"id": "bd7158d8c443eddfaeb5bcef",
@@ -199,12 +200,12 @@
"150324691"
],
"description": [
- "Objective: Build a full stack JavaScript app that is functionally similar to this: https://timestamp-ms.herokuapp.com/ and deploy it to Heroku.",
+ "Objective: Build a full stack JavaScript app that is functionally similar to this: https://timestamp-ms.herokuapp.com/ and deploy it to Heroku.",
"Note that for each project, you should create a new GitHub repository and a new Heroku project. If you can't remember how to do this, revisit http://freecodecamp.com//challenges/get-set-for-our-back-end-development-projects.",
"Here are the specific user stories you should implement for this project:",
- "User Story: I can pass a string as a parameter, and it will check to see whether that string contains either a unix timestamp or a natural language date (example: January 1, 2016).",
- "User Story: If it does, it returns both the Unix timestamp and the natural language form of that date.",
- "User Story: If it does not contain a date or Unix timestamp, it returns null for those properties.",
+ "User Story: I can pass a string as a parameter, and it will check to see whether that string contains either a unix timestamp or a natural language date (example: January 1, 2016).",
+ "User Story: If it does, it returns both the Unix timestamp and the natural language form of that date.",
+ "User Story: If it does not contain a date or Unix timestamp, it returns null for those properties.",
"Once you've finished implementing these user stories, click the \"I've completed this challenge\" button and enter the URLs for both your GitHub repository and your live app running on Heroku.",
"You can get feedback on your project from fellow campers by sharing it in our Code Review Chatroom. You can also share it on Twitter and your city's Campsite (on Facebook)."
],
@@ -231,10 +232,10 @@
"150324460"
],
"description": [
- "Objective: Build a full stack JavaScript app that is functionally similar to this: https://cryptic-ridge-9197.herokuapp.com/api/whoami/ and deploy it to Heroku.",
+ "Objective: Build a full stack JavaScript app that is functionally similar to this: https://cryptic-ridge-9197.herokuapp.com/api/whoami/ and deploy it to Heroku.",
"Note that for each project, you should create a new GitHub repository and a new Heroku project. If you can't remember how to do this, revisit http://freecodecamp.com//challenges/get-set-for-our-back-end-development-projects.",
"Here's the specific user story you should implement for this project:",
- "User Story: I can get the IP address, language and operating system for my browser.",
+ "User Story: I can get the IP address, language and operating system for my browser.",
"Once you've finished implementing these user stories, click the \"I've completed this challenge\" button and enter the URLs for both your GitHub repository and your live app running on Heroku.",
"You can get feedback on your project from fellow campers by sharing it in our Code Review Chatroom. You can also share it on Twitter and your city's Campsite (on Facebook)."
],
@@ -261,12 +262,12 @@
"150324692"
],
"description": [
- "Objective: Build a full stack JavaScript app that is functionally similar to this: https://shurli.herokuapp.com/ and deploy it to Heroku.",
+ "Objective: Build a full stack JavaScript app that is functionally similar to this: https://shurli.herokuapp.com/ and deploy it to Heroku.",
"Note that for each project, you should create a new GitHub repository and a new Heroku project. If you can't remember how to do this, revisit http://freecodecamp.com//challenges/get-set-for-our-back-end-development-projects.",
"Here are the specific user stories you should implement for this project:",
- "User Story: I can pass a URL as a parameter and I will receive a shortened URL in the JSON response.",
- "User Story: If I pass an invalid URL that doesn't follow the valid http://www.example.com format, the JSON response will contain an error instead.",
- "User Story: When I visit that shortened URL, it will redirect me to my original link.",
+ "User Story: I can pass a URL as a parameter and I will receive a shortened URL in the JSON response.",
+ "User Story: If I pass an invalid URL that doesn't follow the valid http://www.example.com format, the JSON response will contain an error instead.",
+ "User Story: When I visit that shortened URL, it will redirect me to my original link.",
"Once you've finished implementing these user stories, click the \"I've completed this challenge\" button and enter the URLs for both your GitHub repository and your live app running on Heroku.",
"You can get feedback on your project from fellow campers by sharing it in our Code Review Chatroom. You can also share it on Twitter and your city's Campsite (on Facebook)."
],
@@ -293,12 +294,12 @@
"150324461"
],
"description": [
- "Objective: Build a full stack JavaScript app that allows you to search for images like this: https://cryptic-ridge-9197.herokuapp.com/api/imagesearch/lolcats%20funny?offset=10 and browse recent search queries like this: https://cryptic-ridge-9197.herokuapp.com/api/latest/imagesearch/. Then deploy it to Heroku.",
+ "Objective: Build a full stack JavaScript app that allows you to search for images like this: https://cryptic-ridge-9197.herokuapp.com/api/imagesearch/lolcats%20funny?offset=10 and browse recent search queries like this: https://cryptic-ridge-9197.herokuapp.com/api/latest/imagesearch/. Then deploy it to Heroku.",
"Note that for each project, you should create a new GitHub repository and a new Heroku project. If you can't remember how to do this, revisit http://freecodecamp.com//challenges/get-set-for-our-back-end-development-projects.",
"Here are the specific user stories you should implement for this project:",
- "User Story: I can get the image URLs, alt text and page urls for a set of images relating to a given search string.",
- "User Story: I can paginate through the responses by adding a ?offset=2 parameter to the URL.",
- "User Story: I can get a list of the most recently submitted search strings.",
+ "User Story: I can get the image URLs, alt text and page urls for a set of images relating to a given search string.",
+ "User Story: I can paginate through the responses by adding a ?offset=2 parameter to the URL.",
+ "User Story: I can get a list of the most recently submitted search strings.",
"Once you've finished implementing these user stories, click the \"I've completed this challenge\" button and enter the URLs for both your GitHub repository and your live app running on Heroku.",
"You can get feedback on your project from fellow campers by sharing it in our Code Review Chatroom. You can also share it on Twitter and your city's Campsite (on Facebook)."
],
@@ -325,12 +326,12 @@
"150324457"
],
"description": [
- "Objective: Build a full stack JavaScript app that is functionally similar to this: https://cryptic-ridge-9197.herokuapp.com/ and deploy it to Heroku.",
+ "Objective: Build a full stack JavaScript app that is functionally similar to this: https://cryptic-ridge-9197.herokuapp.com/ and deploy it to Heroku.",
"Note that for each project, you should create a new GitHub repository and a new Heroku project. If you can't remember how to do this, revisit http://freecodecamp.com//challenges/get-set-for-our-back-end-development-projects.",
"Here are the specific user stories you should implement for this project:",
- "User Story: I can submit a FormData object that includes a file upload.",
- "User Story: When I submit something, I will receive the file size in bytes within the JSON response",
- "Hint: You may want to use this package: https://www.npmjs.com/package/multer",
+ "User Story: I can submit a FormData object that includes a file upload.",
+ "User Story: When I submit something, I will receive the file size in bytes within the JSON response",
+ "Hint: You may want to use this package: https://www.npmjs.com/package/multer",
"Once you've finished implementing these user stories, click the \"I've completed this challenge\" button and enter the URLs for both your GitHub repository and your live app running on Heroku.",
"You can get feedback on your project from fellow campers by sharing it in our Code Review Chatroom. You can also share it on Twitter and your city's Campsite (on Facebook)."
],
diff --git a/seed/challenges/03-back-end-development-certification/automated-testing-and-debugging.json b/seed/challenges/03-back-end-development-certification/automated-testing-and-debugging.json
index 90e38c5139..d5505c96a3 100644
--- a/seed/challenges/03-back-end-development-certification/automated-testing-and-debugging.json
+++ b/seed/challenges/03-back-end-development-certification/automated-testing-and-debugging.json
@@ -1,7 +1,8 @@
{
"name": "Automated Testing and Debugging",
"order": 20,
- "time": "15m",
+ "time": "15 minutes",
+ "helpRoom": "HelpBackEnd",
"challenges": [
{
"id":"cf1111c1c16feddfaeb6bdef",
diff --git a/seed/challenges/03-back-end-development-certification/back-end-development-certificate.json b/seed/challenges/03-back-end-development-certification/back-end-development-certificate.json
index 8321f443ec..a087e00982 100644
--- a/seed/challenges/03-back-end-development-certification/back-end-development-certificate.json
+++ b/seed/challenges/03-back-end-development-certification/back-end-development-certificate.json
@@ -1,7 +1,7 @@
{
"name": "Claim Your Back End Development Certificate",
"order": 29,
- "time": "5m",
+ "time": "5 minutes",
"challenges": [
{
"id": "660add10cb82ac38a17513be",
diff --git a/seed/challenges/03-back-end-development-certification/dynamic-web-applications.json b/seed/challenges/03-back-end-development-certification/dynamic-web-applications.json
index b49ac3c868..c96987addf 100644
--- a/seed/challenges/03-back-end-development-certification/dynamic-web-applications.json
+++ b/seed/challenges/03-back-end-development-certification/dynamic-web-applications.json
@@ -1,24 +1,25 @@
{
"name": "Dynamic Web Application Projects",
"order": 27,
- "time": "250h",
+ "time": "250 hours",
+ "helpRoom": "HelpBackEnd",
"challenges": [
{
"id": "bd7158d8c443eddfaeb5bdef",
"title": "Build a Voting App",
"challengeSeed": ["133315786"],
"description": [
- "Objective: Build a full stack JavaScript app that is functionally similar to this: http://votingapp.herokuapp.com/ and deploy it to Heroku.",
+ "Objective: Build a full stack JavaScript app that is functionally similar to this: http://votingapp.herokuapp.com/ and deploy it to Heroku.",
"Note that for each project, you should create a new GitHub repository and a new Heroku project. If you can't remember how to do this, revisit http://freecodecamp.com/challenges/get-set-for-our-back-end-development-projects.",
"Here are the specific user stories you should implement for this project:",
- "User Story: As an authenticated user, I can keep my polls and come back later to access them.",
- "User Story: As an authenticated user, I can share my polls with my friends.",
- "User Story: As an authenticated user, I can see the aggregate results of my polls.",
- "User Story: As an authenticated user, I can delete polls that I decide I don't want anymore.",
- "User Story: As an authenticated user, I can create a poll with any number of possible items.",
- "User Story: As an unauthenticated or authenticated user, I can see and vote on everyone's polls.",
- "User Story: As an unauthenticated or authenticated user, I can see the results of polls in chart form. (This could be implemented using Chart.js or Google Charts.)",
- "User Story: As an authenticated user, if I don't like the options on a poll, I can create a new option.",
+ "User Story: As an authenticated user, I can keep my polls and come back later to access them.",
+ "User Story: As an authenticated user, I can share my polls with my friends.",
+ "User Story: As an authenticated user, I can see the aggregate results of my polls.",
+ "User Story: As an authenticated user, I can delete polls that I decide I don't want anymore.",
+ "User Story: As an authenticated user, I can create a poll with any number of possible items.",
+ "User Story: As an unauthenticated or authenticated user, I can see and vote on everyone's polls.",
+ "User Story: As an unauthenticated or authenticated user, I can see the results of polls in chart form. (This could be implemented using Chart.js or Google Charts.)",
+ "User Story: As an authenticated user, if I don't like the options on a poll, I can create a new option.",
"Once you've finished implementing these user stories, click the \"I've completed this challenge\" button and enter the URLs for both your GitHub repository and your live app running on Heroku.",
"You can get feedback on your project from fellow campers by sharing it in our Code Review Chatroom. You can also share it on Twitter and your city's Campsite (on Facebook)."
],
@@ -58,14 +59,14 @@
"title": "Build a Nightlife Coordination App",
"challengeSeed": ["133315781"],
"description": [
- "Objective: Build a full stack JavaScript app that is functionally similar to this: http://whatsgoinontonight.herokuapp.com/ and deploy it to Heroku.",
+ "Objective: Build a full stack JavaScript app that is functionally similar to this: http://whatsgoinontonight.herokuapp.com/ and deploy it to Heroku.",
"Note that for each project, you should create a new GitHub repository and a new Heroku project. If you can't remember how to do this, revisit http://freecodecamp.com/challenges/get-set-for-our-back-end-development-projects.",
"Here are the specific user stories you should implement for this project:",
- "User Story: As an unauthenticated user, I can view all bars in my area.",
- "User Story: As an authenticated user, I can add myself to a bar to indicate I am going there tonight.",
- "User Story: As an authenticated user, I can remove myself from a bar if I no longer want to go there.",
- "User Story: As an unauthenticated user, when I login I should not have to search again.",
- "Hint: Try using the Yelp API to find venues in the cities your users search for. If you use Yelp's API, be sure to mention so in your app.",
+ "User Story: As an unauthenticated user, I can view all bars in my area.",
+ "User Story: As an authenticated user, I can add myself to a bar to indicate I am going there tonight.",
+ "User Story: As an authenticated user, I can remove myself from a bar if I no longer want to go there.",
+ "User Story: As an unauthenticated user, when I login I should not have to search again.",
+ "Hint: Try using the Yelp API to find venues in the cities your users search for. If you use Yelp's API, be sure to mention so in your app.",
"Once you've finished implementing these user stories, click the \"I've completed this challenge\" button and enter the URLs for both your GitHub repository and your live app running on Heroku.",
"You can get feedback on your project from fellow campers by sharing it in our Code Review Chatroom. You can also share it on Twitter and your city's Campsite (on Facebook)."
],
@@ -102,13 +103,13 @@
"title": "Chart the Stock Market",
"challengeSeed": ["133315787"],
"description": [
- "Objective: Build a full stack JavaScript app that is functionally similar to this: http://stockstream.herokuapp.com/ and deploy it to Heroku.",
+ "Objective: Build a full stack JavaScript app that is functionally similar to this: http://stockstream.herokuapp.com/ and deploy it to Heroku.",
"Note that for each project, you should create a new GitHub repository and a new Heroku project. If you can't remember how to do this, revisit http://freecodecamp.com/challenges/get-set-for-our-back-end-development-projects.",
"Here are the specific user stories you should implement for this project:",
- "User Story: I can view a graph displaying the recent trend lines for each added stock.",
- "User Story: I can add new stocks by their symbol name.",
- "User Story: I can remove stocks.",
- "User Story: I can see changes in real-time when any other user adds or removes a stock. For this you will need to use Web Sockets.",
+ "User Story: I can view a graph displaying the recent trend lines for each added stock.",
+ "User Story: I can add new stocks by their symbol name.",
+ "User Story: I can remove stocks.",
+ "User Story: I can see changes in real-time when any other user adds or removes a stock. For this you will need to use Web Sockets.",
"Once you've finished implementing these user stories, click the \"I've completed this challenge\" button and enter the URLs for both your GitHub repository and your live app running on Heroku.",
"You can get feedback on your project from fellow campers by sharing it in our Code Review Chatroom. You can also share it on Twitter and your city's Campsite (on Facebook)."
],
@@ -144,13 +145,13 @@
"title": "Manage a Book Trading Club",
"challengeSeed": ["133316032"],
"description": [
- "Objective: Build a full stack JavaScript app that is functionally similar to this: http://bookjump.herokuapp.com/ and deploy it to Heroku.",
+ "Objective: Build a full stack JavaScript app that is functionally similar to this: http://bookjump.herokuapp.com/ and deploy it to Heroku.",
"Note that for each project, you should create a new GitHub repository and a new Heroku project. If you can't remember how to do this, revisit http://freecodecamp.com/challenges/get-set-for-our-back-end-development-projects.",
"Here are the specific user stories you should implement for this project:",
- "User Story: I can view all books posted by every user.",
- "User Story: I can add a new book.",
- "User Story: I can update my settings to store my full name, city, and state.",
- "User Story: I can propose a trade and wait for the other user to accept the trade.",
+ "User Story: I can view all books posted by every user.",
+ "User Story: I can add a new book.",
+ "User Story: I can update my settings to store my full name, city, and state.",
+ "User Story: I can propose a trade and wait for the other user to accept the trade.",
"Once you've finished implementing these user stories, click the \"I've completed this challenge\" button and enter the URLs for both your GitHub repository and your live app running on Heroku.",
"You can get feedback on your project from fellow campers by sharing it in our Code Review Chatroom. You can also share it on Twitter and your city's Campsite (on Facebook)."
],
@@ -186,16 +187,16 @@
"title": "Build a Pinterest Clone",
"challengeSeed": ["133315784"],
"description": [
- "Objective: Build a full stack JavaScript app that is functionally similar to this: http://stark-lowlands-3680.herokuapp.com/ and deploy it to Heroku.",
+ "Objective: Build a full stack JavaScript app that is functionally similar to this: http://stark-lowlands-3680.herokuapp.com/ and deploy it to Heroku.",
"Note that for each project, you should create a new GitHub repository and a new Heroku project. If you can't remember how to do this, revisit http://freecodecamp.com/challenges/get-set-for-our-back-end-development-projects.",
"Here are the specific user stories you should implement for this project:",
- "User Story: As an unauthenticated user, I can login with Twitter.",
- "User Story: As an authenticated user, I can link to images.",
- "User Story: As an authenticated user, I can delete images that I've linked to.",
- "User Story: As an authenticated user, I can see a Pinterest-style wall of all the images I've linked to.",
- "User Story: As an unauthenticated user, I can browse other users' walls of images.",
- "User Story: As an authenticated user, if I upload an image that is broken, it will be replaced by a placeholder image. (can use jQuery broken image detection)",
- "Hint: Masonry.js is a library that allows for Pinterest-style image grids.",
+ "User Story: As an unauthenticated user, I can login with Twitter.",
+ "User Story: As an authenticated user, I can link to images.",
+ "User Story: As an authenticated user, I can delete images that I've linked to.",
+ "User Story: As an authenticated user, I can see a Pinterest-style wall of all the images I've linked to.",
+ "User Story: As an unauthenticated user, I can browse other users' walls of images.",
+ "User Story: As an authenticated user, if I upload an image that is broken, it will be replaced by a placeholder image. (can use jQuery broken image detection)",
+ "Hint: Masonry.js is a library that allows for Pinterest-style image grids.",
"Once you've finished implementing these user stories, click the \"I've completed this challenge\" button and enter the URLs for both your GitHub repository and your live app running on Heroku.",
"You can get feedback on your project from fellow campers by sharing it in our Code Review Chatroom. You can also share it on Twitter and your city's Campsite (on Facebook)."
],
diff --git a/seed/challenges/03-back-end-development-certification/git.json b/seed/challenges/03-back-end-development-certification/git.json
index d268d507dc..63eaade3b5 100644
--- a/seed/challenges/03-back-end-development-certification/git.json
+++ b/seed/challenges/03-back-end-development-certification/git.json
@@ -1,7 +1,8 @@
{
"name": "Git",
"order" : 24,
- "time": "3h",
+ "time": "3 hours",
+ "helpRoom": "HelpBackEnd",
"challenges": [
{
"id": "bd7353d8c341eddeaeb5bd0f",
diff --git a/seed/challenges/03-back-end-development-certification/mongodb.json b/seed/challenges/03-back-end-development-certification/mongodb.json
index e7cfec10cb..6d433195c2 100644
--- a/seed/challenges/03-back-end-development-certification/mongodb.json
+++ b/seed/challenges/03-back-end-development-certification/mongodb.json
@@ -1,7 +1,8 @@
{
"name": "MongoDB",
"order" : 25,
- "time": "3h",
+ "time": "3 hours",
+ "helpRoom": "HelpBackEnd",
"challenges": [
{
"id": "bd7243d8c341eddeaeb5bd0f",
diff --git a/seed/challenges/03-back-end-development-certification/nodejs-and-expressjs.json b/seed/challenges/03-back-end-development-certification/nodejs-and-expressjs.json
index 781f4e7a5d..e6e8398b79 100644
--- a/seed/challenges/03-back-end-development-certification/nodejs-and-expressjs.json
+++ b/seed/challenges/03-back-end-development-certification/nodejs-and-expressjs.json
@@ -1,7 +1,8 @@
{
"name": "Node.js and Express.js",
"order" : 24,
- "time": "20h",
+ "time": "20 hours",
+ "helpRoom": "HelpBackEnd",
"challenges": [
{
"id": "bd7153d8c441eddfaeb5bd0f",
diff --git a/seed/challenges/hikes/computer-basics.json b/seed/challenges/hikes/computer-basics.json
index dd7aaf11ef..de97a6f725 100644
--- a/seed/challenges/hikes/computer-basics.json
+++ b/seed/challenges/hikes/computer-basics.json
@@ -1,7 +1,7 @@
{
"name": "Computer Basics",
"order": 0,
- "time": "3h",
+ "time": "3 hours",
"challenges": [
{
"id": "bd7128d8c441eddfbeb5bddf",
diff --git a/seed/challenges/hikes/programming.json b/seed/challenges/hikes/programming.json
index eb424b3283..7f99857c91 100644
--- a/seed/challenges/hikes/programming.json
+++ b/seed/challenges/hikes/programming.json
@@ -1,7 +1,7 @@
{
"name": "Programming",
"order": 0.050,
- "time": "3h",
+ "time": "3 hours",
"challenges": [
{
"id": "bd712bd8c441eddfbeb5bddf",
diff --git a/seed/index.js b/seed/index.js
index 121a9ba953..2b76db411e 100644
--- a/seed/index.js
+++ b/seed/index.js
@@ -22,6 +22,8 @@ destroy()
var isBeta = !!challengeSpec.isBeta;
var isComingSoon = !!challengeSpec.isComingSoon;
var fileName = challengeSpec.fileName;
+ var helpRoom = challengeSpec.helpRoom || 'Help';
+
console.log('parsed %s successfully', block);
// challenge file has no challenges...
@@ -31,11 +33,7 @@ destroy()
var challenges = challengeSpec.challenges
.map(function(challenge, index) {
- // NOTE(berks): add title for displaying in views
- challenge.name =
- _.capitalize(challenge.type) +
- ': ' +
- challenge.title.replace(/[^a-zA-Z0-9\s]/g, '');
+ challenge.name = challenge.title.replace(/[^a-zA-Z0-9\s]/g, '');
challenge.dashedName = challenge.name
.toLowerCase()
@@ -43,6 +41,7 @@ destroy()
.replace(/\s/g, '-');
challenge.fileName = fileName;
+ challenge.helpRoom = helpRoom;
challenge.order = order;
challenge.suborder = index + 1;
challenge.block = block;
diff --git a/seed/nonprofits.js b/seed/nonprofits.js
deleted file mode 100644
index 96ed0ba5c9..0000000000
--- a/seed/nonprofits.js
+++ /dev/null
@@ -1,29 +0,0 @@
-/* eslint-disable no-process-exit */
-require('babel/register');
-require('dotenv').load();
-
-var Rx = require('rx');
-var app = require('../server/server');
-
-var Nonprofits = app.models.Nonprofit;
-var nonprofits = require('./nonprofits.json');
-var destroy = Rx.Observable.fromNodeCallback(Nonprofits.destroyAll, Nonprofits);
-var create = Rx.Observable.fromNodeCallback(Nonprofits.create, Nonprofits);
-
-destroy()
- .flatMap(function() {
- if (!nonprofits) {
- return Rx.Observable.throw(new Error('No nonprofits found'));
- }
- return create(nonprofits);
- })
- .subscribe(
- function(nonprofits) {
- console.log('successfully saved %d nonprofits', nonprofits.length);
- },
- function(err) { throw err; },
- function() {
- console.log('nonprofit seed completed');
- process.exit(0);
- }
- );
diff --git a/seed/nonprofits.json b/seed/nonprofits.json
deleted file mode 100644
index 2f6ee0b77d..0000000000
--- a/seed/nonprofits.json
+++ /dev/null
@@ -1,329 +0,0 @@
-[
- {
- "whatDoesNonprofitDo": "We help the many less-fortunate Jewish families in our community, by providing them with nutritious food and energy to grow, learn, work, and give them hope for a better and brighter future.",
- "websiteLink": "http://chasdeikaduri.org/",
- "name": "Chasdei Kaduri",
- "endUser": "Clients, donors, and admin.",
- "approvedDeliverables": [
- "website",
- "donor",
- "inventory",
- "volunteer",
- "form"
- ],
- "projectDescription": "Campers will create a system will integrate the food inventory, donor and delivery driver management systems as well as replace the current application system with a custom form solution. System will include a more streamlined operations management, with user printable lists of inventory, drivers, and deliveries.",
- "logoUrl": "http://i.imgur.com/zQiM0P8.png",
- "imageUrl": "http://i.imgur.com/xeRdA87.jpg",
- "estimatedHours": 300,
- "currentStatus": "completed",
- "moneySaved": 60000
- },
- {
- "whatDoesNonprofitDo": "We connect simple technology with last mile communities to reduce poverty.",
- "websiteLink": "http://kopernik.info/",
- "name": "Kopernik",
- "endUser": "Women in rural Indonesia.",
- "approvedDeliverables": [
- "other"
- ],
- "projectDescription": "Campers will create a Chrome browser extension to preserve sales data from a form, and upload in batches as the internet connection allows.",
- "logoUrl": "http://i.imgur.com/xTqjIkC.png",
- "imageUrl": "http://i.imgur.com/xBAUJSa.jpg",
- "estimatedHours": 100,
- "currentStatus": "completed",
- "moneySaved": 20000
- },
- {
- "whatDoesNonprofitDo": "We distribute biodegradable toothbrushes globally to children in need.",
- "websiteLink": "http://www.operationbrush.org/",
- "name": "Operation Brush",
- "endUser": "Donors",
- "approvedDeliverables": [
- "website"
- ],
- "projectDescription": "Campers will create a mobile responsive website for the organization, with donation capabilities.",
- "logoUrl": "http://i.imgur.com/DEDhImE.png",
- "imageUrl": "http://i.imgur.com/RuA9Rgy.jpg",
- "estimatedHours": 100,
- "currentStatus": "completed",
- "moneySaved": 20000
- },
- {
- "whatDoesNonprofitDo": "We are the largest roller derby league in the world with around 250 adults and 150 junior skater members plus 500+ volunteers.",
- "websiteLink": "http://www.rosecityrollers.com/about/our-charities/",
- "name": "Rose City Rollers",
- "endUser": "Roller derby administrators, coaches, and volunteers",
- "approvedDeliverables": [
- "community"
- ],
- "projectDescription": "Campers will create a volunteer management system with multi-user access and reporting capabilities.",
- "logoUrl": "http://i.imgur.com/ZZAZSs4.jpg",
- "imageUrl": "http://i.imgur.com/WKS4cZ8.jpg",
- "estimatedHours": 200,
- "currentStatus": "completed",
- "moneySaved": 40000
- },
- {
- "whatDoesNonprofitDo": "We provide urgently needed pediatric heart surgery and follow-up care for indigent children from developing countries",
- "websiteLink": "http://www.saveachildsheart.com/global/young-leadership-program/",
- "name": "Save a Child's Heart",
- "endUser": "Donors",
- "approvedDeliverables": [
- "website"
- ],
- "projectDescription": "Campers will create a single page fundraising website. In exchange for a donation, a user can customize a graphical 'heart' in someone's name or anonymously. The page will display all of the hearts on a 'wall of hearts.'",
- "logoUrl": "http://i.imgur.com/t6tpiEW.jpg",
- "imageUrl": "http://i.imgur.com/xqhvdn2.jpg",
- "estimatedHours": 200,
- "currentStatus": "completed",
- "moneySaved": 40000
- },
- {
- "whatDoesNonprofitDo": "We empower youth with technology by providing age appropriate resources and education.",
- "websiteLink": "http://savvycyberkids.org/",
- "name": "Savvy Cyber Kids",
- "endUser": "Donors",
- "approvedDeliverables": [
- "website"
- ],
- "projectDescription": "Campers will create a website where potential donors can view which schools already have the Savvy Cyber Kids books, and donate books to those schools that do not.",
- "logoUrl": "http://i.imgur.com/JgxYVJ5.png",
- "imageUrl": "http://i.imgur.com/ZTg12ao.jpg",
- "estimatedHours": 200,
- "currentStatus": "completed",
- "moneySaved": 40000
- },
- {
- "whatDoesNonprofitDo": "We bring a new edge to arts and medicine in the Bay Area through powerful live performances of new music to those who feel marginalized by their affliction.",
- "websiteLink": "http://transcendentpathways.org/",
- "name": "Transcendent Pathways",
- "endUser": "Medical Facilities, Musicians",
- "approvedDeliverables": [
- "other"
- ],
- "projectDescription": "Campers will build a website where medical facilities can list music therapy time slots, and musicians can sign up to fill these slots.",
- "logoUrl": "http://i.imgur.com/JV4rcKX.png",
- "imageUrl": "http://i.imgur.com/gyhrPee.jpg",
- "estimatedHours": 200,
- "currentStatus": "completed",
- "moneySaved": 40000
- },
- {
- "whatDoesNonprofitDo": "We have provide volunteer matching fairs and silent art auctions at events across Canada. Rather than bid money on artwork, participants bid volunteer hours.",
- "websiteLink": "http://www.timeraiser.ca/",
- "name": "Timeraiser",
- "endUser": "Working professionals who want to donate their time and expertise",
- "approvedDeliverables": [
- "other"
- ],
- "projectDescription": "Campers will build a mobile responsive web form to allow Timeraiser eventgoers to select which nonprofit organizations they're interested in volunteering with. System will have Salesforce integration and reporting capabilities.",
- "logoUrl": "http://i.imgur.com/USK8ld7.png",
- "imageUrl": "http://i.imgur.com/7apWppe.jpg",
- "estimatedHours": 200,
- "currentStatus": "completed",
- "moneySaved": 40000
- },
- {
- "whatDoesNonprofitDo": "We focus on raising funds to assist injured homeless animals.",
- "websiteLink": "http://www.peoplesavinganimals.org/",
- "name": "People Saving Animals",
- "endUser": "Animal shelters in Central America and people adopting pets",
- "approvedDeliverables": [
- "website",
- "inventory",
- "form"
- ],
- "projectDescription": "Campers will build an adoption database and all related web interfaces and forms to allow animal shelters to easily post animals, photos, and relevant medical information. They'll make it easy for locals to browse these animals and adopt them. Once completed, this project will be translated into Spanish.",
- "logoUrl": "http://i.imgur.com/iKcKcpg.jpg",
- "imageUrl": "http://i.imgur.com/b9ZeU7R.jpg",
- "estimatedHours": 300,
- "currentStatus": "completed",
- "moneySaved": 60000
- },
- {
- "whatDoesNonprofitDo": "We preserve Florida's health by regulating septic contractors and reviewing logs of sewage collection and disposal.",
- "websiteLink": "http://www.floridahealth.gov/",
- "name": "Florida Department of Health",
- "endUser": "Government workers and independent contractors who must comply with regulations.",
- "approvedDeliverables": [
- "inventory",
- "form",
- "other"
- ],
- "projectDescription": "Campers will build mobile responsive web forms to allow contractors to seamlessly log the chain of custody for potentially hazardous sewage. They'll also build a government-facing database that allows for easy monitoring and reporting of activity.",
- "logoUrl": "http://i.imgur.com/J3Scbsp.png",
- "imageUrl": "http://i.imgur.com/8LEFrKy.jpg",
- "estimatedHours": 200,
- "currentStatus": "completed",
- "moneySaved": 40000
- },
- {
- "whatDoesNonprofitDo": "We strengthen the value of songwriting and independent music in Columbus, Ohio.",
- "websiteLink": "http://columbussongwritersassociation.com",
- "name": "Columbus Songwriters Association",
- "endUser": "Songwriters and their audiences in the Columbus, Ohio community.",
- "approvedDeliverables": [
- "website"
- ],
- "projectDescription": "Build mobile responsive website that allows users to see browse our partners, their photos and information, and connect with them.",
- "logoUrl": "http://i.imgur.com/UN85TI4.jpg",
- "imageUrl": "http://i.imgur.com/NFxL1oS.jpg",
- "estimatedHours": 100,
- "currentStatus": "completed",
- "moneySaved": 20000
- },
- {
- "whatDoesNonprofitDo": "We leverage all the benefits of cycling to support and improve the lives of youth and teens in the Triangle region.",
- "websiteLink": "http://www.trianglebikeworks.org",
- "name": "Triangle Bike Works",
- "endUser": "Youth and teens in the Triangle region.",
- "approvedDeliverables": [
- "website"
- ],
- "projectDescription": "Campers will build a website with donation integration.",
- "logoUrl": "http://i.imgur.com/T5OkXuT.png",
- "imageUrl": "http://i.imgur.com/7bOaMPq.jpg",
- "estimatedHours": 100,
- "currentStatus": "open",
- "moneySaved": 0
- },
- {
- "whatDoesNonprofitDo": "We work to eradicate female genital mutilation in the US and Gambia. We work with survivors and communities.",
- "websiteLink": "http://safehandsforgirls.org/",
- "name": "Safe Hands for Girls",
- "endUser": "Supporters",
- "approvedDeliverables": [
- "website"
- ],
- "projectDescription": "Campers will build a website with donation management.",
- "logoUrl": "http://i.imgur.com/QnAY6Ji.png",
- "imageUrl": "http://i.imgur.com/s9E4oa9.jpg",
- "estimatedHours": 100,
- "currentStatus": "open",
- "moneySaved": 0
- },
- {
- "whatDoesNonprofitDo": "We're a part of the Department of Psychiatry at Mass General Hospital. We teach an innovative way for helping people that have challenging behaviors.",
- "websiteLink": "http://www.thinkkids.org/",
- "name": "Think Kids at Massachusetts General Hospital",
- "endUser": "Volunteers, Administrators",
- "approvedDeliverables": [
- "volunteer"
- ],
- "projectDescription": "We would like help developing a simple online based portal for both our trainees and trainers where we can store and share documents, track their progress, and incorporate a blackboard/chat forum.",
- "logoUrl": "http://i.imgur.com/fu6dTmH.png",
- "imageUrl": "http://i.imgur.com/hiGJms5.png",
- "estimatedHours": 300,
- "currentStatus": "started",
- "moneySaved": 0
- },
- {
- "whatDoesNonprofitDo": "We enable, educate, and empower students from rural backgrounds in Uttar Pradesh, India.",
- "websiteLink": "http://www.milaan.in/",
- "name": "Milaan",
- "endUser": "Supporters",
- "approvedDeliverables": [
- "website"
- ],
- "projectDescription": "Campers will build a basic website for the US operations of Milaan. ",
- "logoUrl": "http://i.imgur.com/GLq1qqD.png",
- "imageUrl": "http://i.imgur.com/PkMHQ8N.jpg",
- "estimatedHours": 100,
- "currentStatus": "open",
- "moneySaved": 0
- },
- {
- "whatDoesNonprofitDo": "We're committed to closing the opportunity gap for children in Baltimore City by providing high quality after school and in-school programs.",
- "websiteLink": "http://childfirstauthority.org/",
- "name": "Child First Authority",
- "endUser": "School Coordinators",
- "approvedDeliverables": [
- "volunteer"
- ],
- "projectDescription": "Campers will build a dynamic database that will allow 7 community school coordinators to (1) input student-level absenteeism data, (2) code and track outreach efforts, (3) code root causes for absenteeism, and (4) track trends in each area. Currently, Child First uses an unwieldy excel spreadsheet to do this.",
- "logoUrl": "http://i.imgur.com/YlPsQmN.jpg",
- "imageUrl": "http://i.imgur.com/Z2RfQku.gifv",
- "estimatedHours": 200,
- "currentStatus": "started",
- "moneySaved": 0
- },
- {
- "whatDoesNonprofitDo": "We are an interdisciplinary team that works towards harmony among humans and nature through three distinct branches: sustainable agriculture, environmental education and applied and appropriate technology; focused in Líbano, Tolima, Colombia.",
- "websiteLink": "",
- "name": "QET America",
- "endUser": "Donors",
- "approvedDeliverables": ["Website"],
- "projectDescription": "Campers will build a multiple language website (English, Spanish) that accepts donations.",
- "logoUrl": "http://i.imgur.com/jPuiPOy.jpg",
- "imageUrl": "http://i.imgur.com/zaaL2pj.jpg",
- "estimatedHours": 100,
- "currentStatus": "open",
- "moneySaved": 0
- },
- {
- "whatDoesNonprofitDo": "1to1 Movement provides free environmental education in schools",
- "websiteLink": "http://1to1movement.org/",
- "name": "1 to 1 Movement",
- "endUser": "Pledgers",
- "approvedDeliverables": ["Web App"],
- "projectDescription": "Campers will build a simple, social, data-driven application that allows people to see the impact of their actions. User can make a pledge and track the outcome. Will make use of the D3.js visualization library.",
- "logoUrl": "http://i.imgur.com/jaqxg0O.png",
- "imageUrl": "http://i.imgur.com/GXSWTZw.jpg",
- "estimatedHours": 300,
- "currentStatus": "open",
- "moneySaved": 0
- },
-
- {
- "whatDoesNonprofitDo": "Our missions is to elevate the national dialogue and engage the American people around climate change policy and the promotion of real clean energy solutions in the United States.",
- "websiteLink": "http://www.usclimateplan.org/",
- "name": "US Climate Plan",
- "endUser": "Donors",
- "approvedDeliverables": ["Website"],
- "projectDescription": "Campers will build a basic website for sharing information, feeds from different campaign’s websites.",
- "logoUrl": "http://i.imgur.com/uAyUiMN.png",
- "imageUrl": "http://i.imgur.com/2Og5tqy.jpg",
- "estimatedHours": 100,
- "currentStatus": "open",
- "moneySaved": 0
- },
- {
- "whatDoesNonprofitDo": "We empower the community through improved literacy.",
- "websiteLink": "http://www.tleliteracy.com/",
- "name": "The Learning Exchange",
- "endUser": "Community members",
- "approvedDeliverables": ["Website"],
- "projectDescription": "Campers will build a simple website to replace essentialskillsquebec.com. Site will host many documents related to the Nine Essential Skills.",
- "logoUrl": "http://i.imgur.com/jXQY01H.png",
- "imageUrl": "http://i.imgur.com/iUXBpeL.jpg",
- "estimatedHours": 100,
- "currentStatus": "started",
- "moneySaved": 0
- },
- {
- "whatDoesNonprofitDo": "Options Inc. is an organization that was founded in 1979 to assist adults with disabilities in living and working in the community. We provide transportation to approximately 230 individuals.",
- "websiteLink": "www.options-inc.org",
- "name": "Options Inc.",
- "endUser": "Administrators and Persons with Disabilities",
- "approvedDeliverables": ["Web App"],
- "projectDescription": "Campers will build a system to store all of Options Inc.'s clients addresses, optimize routes for our 23 vehicles, and schedule their staff for these routes.",
- "logoUrl": "http://i.imgur.com/jGWRMuF.jpg",
- "imageUrl": "http://i.imgur.com/VUuJJlM.jpg",
- "estimatedHours": 300,
- "currentStatus": "open",
- "moneySaved": 0
- },
- {
- "whatDoesNonprofitDo": "Our goal is to improve addiction treatment and recovery services through targeted outreach, policy development, and direct support services for addicts, their families and health professionals.",
- "websiteLink": "http://www.taadas.org/",
- "name": "Tennessee Association of Alcohol Drug and other Addiction Services",
- "endUser": "Administrators and Persons with Disabilities",
- "approvedDeliverables": ["Website"],
- "projectDescription": "Campers will build a modern, mobile-responsive website.",
- "logoUrl": "http://i.imgur.com/kYHgY0F.jpg",
- "imageUrl": "http://i.imgur.com/W6L1sGV.jpg",
- "estimatedHours": 100,
- "currentStatus": "open",
- "moneySaved": 0
- }
-]
diff --git a/server/boot/about.js b/server/boot/about.js
new file mode 100644
index 0000000000..852b5e2bf8
--- /dev/null
+++ b/server/boot/about.js
@@ -0,0 +1,37 @@
+import dedent from 'dedent';
+import moment from 'moment';
+
+import { observeMethod } from '../utils/rx';
+
+function numberWithCommas(x) {
+ return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
+}
+
+export default function about(app) {
+ const router = app.loopback.Router();
+ const User = app.models.User;
+ const userCount$ = observeMethod(User, 'count');
+
+ function showAbout(req, res, next) {
+ const daysRunning = moment().diff(new Date('10/15/2014'), 'days');
+
+ userCount$()
+ .map(camperCount => numberWithCommas(camperCount))
+ .doOnNext(camperCount => {
+ res.render('resources/about', {
+ camperCount,
+ daysRunning,
+ title: dedent`
+ About our Open Source Community, our social media presence,
+ and how to contact us`.split('\n').join(' '),
+ globalCompletedCount: numberWithCommas(
+ 5612952 + (Math.floor((Date.now() - 1446268581061) / 2000))
+ )
+ });
+ })
+ .subscribe(() => {}, next);
+ }
+
+ router.get('/about', showAbout);
+ app.use(router);
+}
diff --git a/server/boot/challenge.js b/server/boot/challenge.js
index c88e377b04..18c0469aeb 100644
--- a/server/boot/challenge.js
+++ b/server/boot/challenge.js
@@ -31,15 +31,14 @@ const isDev = process.env.NODE_ENV !== 'production';
const isBeta = !!process.env.BETA;
const debug = debugFactory('freecc:challenges');
const challengesRegex = /^(bonfire|waypoint|zipline|basejump|checkpoint)/i;
-const firstChallenge = 'waypoint-learn-how-free-code-camp-works';
const challengeView = {
- 0: 'coursewares/showHTML',
- 1: 'coursewares/showJS',
- 2: 'coursewares/showVideo',
- 3: 'coursewares/showZiplineOrBasejump',
- 4: 'coursewares/showZiplineOrBasejump',
- 5: 'coursewares/showBonfire',
- 7: 'coursewares/showStep'
+ 0: 'challenges/showHTML',
+ 1: 'challenges/showJS',
+ 2: 'challenges/showVideo',
+ 3: 'challenges/showZiplineOrBasejump',
+ 4: 'challenges/showZiplineOrBasejump',
+ 5: 'challenges/showBonfire',
+ 7: 'challenges/showStep'
};
function isChallengeCompleted(user, challengeId) {
@@ -50,9 +49,11 @@ function isChallengeCompleted(user, challengeId) {
challenge.id === challengeId );
}
+/*
function numberWithCommas(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}
+*/
function updateUserProgress(user, challengeId, completedChallenge) {
let { completedChallenges } = user;
@@ -116,6 +117,213 @@ function shouldNotFilterComingSoon({ isComingSoon, isBeta: challengeIsBeta }) {
(isBeta && challengeIsBeta);
}
+function getRenderData$(user, challenge$, origChallengeName, solution) {
+ const challengeName = unDasherize(origChallengeName)
+ .replace(challengesRegex, '');
+
+ const testChallengeName = new RegExp(challengeName, 'i');
+ debug('looking for %s', testChallengeName);
+
+ return challenge$
+ .map(challenge => challenge.toJSON())
+ .filter((challenge) => {
+ return testChallengeName.test(challenge.name) &&
+ shouldNotFilterComingSoon(challenge);
+ })
+ .last({ defaultValue: null })
+ .flatMap(challenge => {
+ if (challenge && isDev) {
+ return getFromDisk$(challenge);
+ }
+ return Observable.just(challenge);
+ })
+ .flatMap(challenge => {
+
+ // Handle not found
+ if (!challenge) {
+ debug('did not find challenge for ' + origChallengeName);
+ return Observable.just({
+ type: 'redirect',
+ redirectUrl: '/map',
+ message: dedent`
+ 404: We couldn\'t find a challenge with the name ${origChallengeName}.
+ Please double check the name.
+ `
+ });
+ }
+
+ if (dasherize(challenge.name) !== origChallengeName) {
+ let redirectUrl = `/challenges/${dasherize(challenge.name)}`;
+
+ if (solution) {
+ redirectUrl += `?solution=${encodeURIComponent(solution)}`;
+ }
+
+ return Observable.just({
+ type: 'redirect',
+ redirectUrl
+ });
+ }
+
+ // save user does nothing if user does not exist
+ return Observable.just({
+ data: {
+ ...challenge,
+ // identifies if a challenge is completed
+ isCompleted: isChallengeCompleted(user, challenge.id),
+
+ // video challenges
+ video: challenge.challengeSeed[0],
+
+ // bonfires specific
+ bonfires: challenge,
+ MDNkeys: challenge.MDNlinks,
+ MDNlinks: getMDNLinks(challenge.MDNlinks),
+
+ // htmls specific
+ verb: randomVerb(),
+ phrase: randomPhrase(),
+ compliment: randomCompliment()
+ }
+ });
+ });
+}
+
+function getCompletedChallengeIds(user = {}) {
+ // if user
+ // get the id's of all the users completed challenges
+ return !user.completedChallenges ?
+ [] :
+ _.uniq(user.completedChallenges)
+ .map(({ id, _id }) => id || _id);
+}
+
+// create a stream of an array of all the challenge blocks
+function getSuperBlocks$(challenge$, completedChallenges) {
+ return challenge$
+ // mark challenge completed
+ .map(challengeModel => {
+ const challenge = challengeModel.toJSON();
+ if (completedChallenges.indexOf(challenge.id) !== -1) {
+ challenge.completed = true;
+ }
+ challenge.markNew = shouldShowNew(challenge);
+ return challenge;
+ })
+ // group challenges by block | returns a stream of observables
+ .groupBy(challenge => challenge.block)
+ // turn block group stream into an array
+ .flatMap(block$ => block$.toArray())
+ .map(blockArray => {
+ const completedCount = blockArray.reduce((sum, { completed }) => {
+ if (completed) {
+ return sum + 1;
+ }
+ return sum;
+ }, 0);
+ const isBeta = _.every(blockArray, 'isBeta');
+ const isComingSoon = _.every(blockArray, 'isComingSoon');
+ const isRequired = _.every(blockArray, 'isRequired');
+
+ return {
+ isBeta,
+ isComingSoon,
+ isRequired,
+ name: blockArray[0].block,
+ superBlock: blockArray[0].superBlock,
+ dashedName: dasherize(blockArray[0].block),
+ markNew: shouldShowNew(null, blockArray),
+ challenges: blockArray,
+ completed: completedCount / blockArray.length * 100,
+ time: blockArray[0] && blockArray[0].time || '???'
+ };
+ })
+ // filter out hikes
+ .filter(({ superBlock }) => {
+ return !(/hikes/i).test(superBlock);
+ })
+ // turn stream of blocks into a stream of an array
+ .toArray()
+ .flatMap(blocks => Observable.from(blocks, null, null, Scheduler.default))
+ .groupBy(block => block.superBlock)
+ .flatMap(blocks$ => blocks$.toArray())
+ .map(superBlockArray => ({
+ name: superBlockArray[0].superBlock,
+ blocks: superBlockArray
+ }))
+ .toArray();
+}
+
+function getChallengeById$(challenge$, challengeId) {
+ // return first challenge if no id is given
+ if (!challengeId) {
+ return challenge$
+ .map(challenge => challenge.toJSON())
+ .filter(shouldNotFilterComingSoon)
+ // filter out hikes
+ .filter(({ superBlock }) => !(/hikes/gi).test(superBlock))
+ .first();
+ }
+ return challenge$
+ .map(challenge => challenge.toJSON())
+ // filter out challenges coming soon
+ .filter(shouldNotFilterComingSoon)
+ // filter out hikes
+ .filter(({ superBlock }) => !(/hikes/gi).test(superBlock))
+ .filter(({ id }) => id === challengeId);
+}
+
+function getNextChallenge$(challenge$, blocks$, challengeId) {
+ return getChallengeById$(challenge$, challengeId)
+ // now lets find the block it belongs to
+ .flatMap(challenge => {
+ // find the index of the block this challenge resides in
+ const blockIndex$ = blocks$
+ .findIndex(({ name }) => name === challenge.block);
+
+
+ return blockIndex$
+ .flatMap(blockIndex => {
+ // could not find block?
+ if (blockIndex === -1) {
+ return Observable.throw(
+ 'could not find challenge block for ' + challenge.block
+ );
+ }
+ const firstChallengeOfNextBlock$ = blocks$
+ .elementAt(blockIndex + 1, {})
+ .map(({ challenges = [] }) => challenges[0]);
+
+ return blocks$
+ .filter(shouldNotFilterComingSoon)
+ .elementAt(blockIndex)
+ .flatMap(block => {
+ // find where our challenge lies in the block
+ const challengeIndex$ = Observable.from(
+ block.challenges,
+ null,
+ null,
+ Scheduler.default
+ )
+ .findIndex(({ id }) => id === challengeId);
+
+ // grab next challenge in this block
+ return challengeIndex$
+ .map(index => {
+ return block.challenges[index + 1];
+ })
+ .flatMap(nextChallenge => {
+ if (!nextChallenge) {
+ return firstChallengeOfNextBlock$;
+ }
+ return Observable.just(nextChallenge);
+ });
+ });
+ });
+ })
+ .first();
+}
+
module.exports = function(app) {
const router = app.loopback.Router();
@@ -166,9 +374,17 @@ module.exports = function(app) {
})
.shareReplay();
- const User = app.models.User;
- const userCount$ = observeMethod(User, 'count');
+ const firstChallenge$ = challenge$
+ .first()
+ .map(challenge => challenge.toJSON())
+ .shareReplay();
+ const lastChallenge$ = challenge$
+ .last()
+ .map(challenge => challenge.toJSON())
+ .shareReplay();
+
+ const User = app.models.User;
const send200toNonUser = ifNoUserSend(true);
router.post(
@@ -182,191 +398,103 @@ module.exports = function(app) {
completedZiplineOrBasejump
);
- router.get('/map', challengeMap);
+ router.get('/map', showMap.bind(null, false));
+ router.get('/map-aside', showMap.bind(null, true));
+ router.get(
+ '/challenges/current-challenge',
+ redirectToCurrentChallenge
+ );
router.get(
'/challenges/next-challenge',
- returnNextChallenge
+ redirectToNextChallenge
);
- router.get('/challenges/:challengeName', returnIndividualChallenge);
+ router.get('/challenges/:challengeName', showChallenge);
app.use(router);
- function returnNextChallenge(req, res, next) {
- let nextChallengeName = firstChallenge;
-
- const challengeId = req.query.id;
-
- // find challenge
- return challenge$
- .map(challenge => challenge.toJSON())
- // filter out challenges coming soon
- .filter(shouldNotFilterComingSoon)
- // filter out hikes
- .filter(({ superBlock }) => !(/hikes/gi).test(superBlock))
- .filter(({ id }) => id === challengeId)
- // now lets find the block it belongs to
- .flatMap(challenge => {
- // find the index of the block this challenge resides in
- const blockIndex$ = blocks$
- .findIndex(({ name }) => name === challenge.block);
-
-
- return blockIndex$
- .flatMap(blockIndex => {
- // could not find block?
- if (blockIndex === -1) {
- return Observable.throw(
- 'could not find challenge block for ' + challenge.block
- );
- }
- const firstChallengeOfNextBlock$ = blocks$
- .elementAt(blockIndex + 1, {})
- .map(({ challenges = [] }) => challenges[0]);
-
- return blocks$
- .filter(shouldNotFilterComingSoon)
- .elementAt(blockIndex)
- .flatMap(block => {
- // find where our challenge lies in the block
- const challengeIndex$ = Observable.from(
- block.challenges,
- null,
- null,
- Scheduler.default
- )
- .findIndex(({ id }) => id === challengeId);
-
- // grab next challenge in this block
- return challengeIndex$
- .map(index => {
- return block.challenges[index + 1];
- })
- .flatMap(nextChallenge => {
- if (!nextChallenge) {
- return firstChallengeOfNextBlock$;
- }
- return Observable.just(nextChallenge);
- });
- });
+ function redirectToCurrentChallenge(req, res, next) {
+ let challengeId = req.query.id || req.cookies.currentChallengeId;
+ // prevent serialized null/undefined from breaking things
+ if (challengeId === 'undefined' || challengeId === 'null') {
+ challengeId = null;
+ }
+ getChallengeById$(challenge$, challengeId)
+ .doOnNext(({ dashedName })=> {
+ if (!dashedName) {
+ debug('no challenge found for %s', challengeId);
+ req.flash('info', {
+ msg: `We coudn't find a challenge with the id ${challengeId}`
});
- })
- .map(nextChallenge => {
- if (!nextChallenge) {
- return null;
+ res.redirect('/map');
}
- nextChallengeName = nextChallenge.dashedName;
- return nextChallengeName;
+ res.redirect('/challenges/' + dashedName);
})
- .subscribe(
- function() {},
- next,
- function() {
- debug('next challengeName', nextChallengeName);
- if (!nextChallengeName || nextChallengeName === firstChallenge) {
- req.flash('info', {
- msg: dedent`
- Once you have completed all of our challenges, you should
- join our Half Way Club and start getting
- ready for our nonprofit projects.
- `.split('\n').join(' ')
- });
- return res.redirect('/map');
- }
- res.redirect('/challenges/' + nextChallengeName);
- }
- );
+ .subscribe(() => {}, next);
}
- function returnIndividualChallenge(req, res, next) {
- const origChallengeName = req.params.challengeName;
- const solutionCode = req.query.solution;
- const unDashedName = unDasherize(origChallengeName);
+ function redirectToNextChallenge(req, res, next) {
+ let challengeId = req.query.id || req.cookies.currentChallengeId;
+ if (challengeId === 'undefined' || challengeId === 'null') {
+ challengeId = null;
+ }
- const challengeName = challengesRegex.test(unDashedName) ?
- // remove first word if matches
- unDashedName.split(' ').slice(1).join(' ') :
- unDashedName;
-
- const testChallengeName = new RegExp(challengeName, 'i');
- debug('looking for %s', testChallengeName);
- challenge$
- .filter((challenge) => {
- return testChallengeName.test(challenge.name) &&
- shouldNotFilterComingSoon(challenge);
- })
- .last({ defaultValue: null })
- .flatMap(challenge => {
- if (challenge && isDev) {
- return getFromDisk$(challenge);
+ Observable.combineLatest(
+ firstChallenge$,
+ lastChallenge$
+ )
+ .flatMap(([firstChallenge, { id: lastChallengeId } ]) => {
+ // no id supplied, load first challenge
+ if (!challengeId) {
+ return Observable.just(firstChallenge);
+ }
+ // camper just completed last challenge
+ if (challengeId === lastChallengeId) {
+ return Observable.just()
+ .doOnCompleted(() => {
+ req.flash('info', {
+ msg: dedent`
+ Once you have completed all of our challenges, you should
+ join our Half Way Club and start getting
+ ready for our nonprofit projects.
+ `.split('\n').join(' ')
+ });
+ return res.redirect('/map');
+ });
}
- return Observable.just(challenge);
- })
- .flatMap(challenge => {
- // Handle not found
- if (!challenge) {
- debug('did not find challenge for ' + origChallengeName);
- req.flash('errors', {
- msg:
- '404: We couldn\'t find a challenge with the name `' +
- origChallengeName +
- '` Please double check the name.'
+ return getNextChallenge$(challenge$, blocks$, challengeId)
+ .doOnNext(({ dashedName } = {}) => {
+ if (!dashedName) {
+ debug('no challenge found for %s', challengeId);
+ res.redirect('/map');
+ }
+ res.redirect('/challenges/' + dashedName);
});
- return Observable.just('/map');
- }
-
- if (dasherize(challenge.name) !== origChallengeName) {
- let redirectUrl = `/challenges/${dasherize(challenge.name)}`;
-
- if (solutionCode) {
- redirectUrl += `?solution=${encodeURIComponent(solutionCode)}`;
- }
-
- return Observable.just(redirectUrl);
- }
-
- // save user does nothing if user does not exist
- return Observable.just({
-
- title: challenge.name,
- name: challenge.name,
- details: challenge.description,
- description: challenge.description,
- challengeId: challenge.id,
- challengeType: challenge.challengeType,
- dashedName: origChallengeName,
-
- challengeSeed: challenge.challengeSeed,
- head: challenge.head,
- tail: challenge.tail,
- tests: challenge.tests,
-
- // identifies if a challenge is completed
- isCompleted: isChallengeCompleted(req.user, challenge.id),
-
- // video challenges
- video: challenge.challengeSeed[0],
-
- // bonfires specific
- bonfires: challenge,
- MDNkeys: challenge.MDNlinks,
- MDNlinks: getMDNLinks(challenge.MDNlinks),
-
- // htmls specific
- verb: randomVerb(),
- phrase: randomPhrase(),
- compliment: randomCompliment()
- });
})
+ .subscribe(() => {}, next);
+ }
+
+ function showChallenge(req, res, next) {
+ const solution = req.query.solution;
+
+ getRenderData$(req.user, challenge$, req.params.challengeName, solution)
.subscribe(
- function(data) {
- if (typeof data === 'string') {
- debug('redirecting to %s', data);
- return res.redirect(data);
+ ({ type, redirectUrl, message, data }) => {
+ if (message) {
+ req.flash('info', {
+ msg: message
+ });
+ }
+ if (type === 'redirect') {
+ debug('redirecting to %s', redirectUrl);
+ return res.redirect(redirectUrl);
}
var view = challengeView[data.challengeType];
+ if (data.id) {
+ res.cookie('currentChallengeId', data.id);
+ }
res.render(view, data);
},
next,
@@ -500,94 +628,15 @@ module.exports = function(app) {
);
}
- function challengeMap({ user = {} }, res, next) {
+ function showMap(showAside, { user }, res, next) {
- let lastCompleted;
- const daysRunning = moment().diff(new Date('10/15/2014'), 'days');
-
- // if user
- // get the id's of all the users completed challenges
- const completedChallenges = !user.completedChallenges ?
- [] :
- _.uniq(user.completedChallenges).map(({ id, _id }) => id || _id);
-
- const camperCount$ = userCount$()
- .map(camperCount => numberWithCommas(camperCount));
-
- // create a stream of an array of all the challenge blocks
- const superBlocks$ = challenge$
- // mark challenge completed
- .map(challengeModel => {
- const challenge = challengeModel.toJSON();
- if (completedChallenges.indexOf(challenge.id) !== -1) {
- challenge.completed = true;
- }
- challenge.markNew = shouldShowNew(challenge);
- return challenge;
- })
- // group challenges by block | returns a stream of observables
- .groupBy(challenge => challenge.block)
- // turn block group stream into an array
- .flatMap(block$ => block$.toArray())
- .map(blockArray => {
- const completedCount = blockArray.reduce((sum, { completed }) => {
- if (completed) {
- return sum + 1;
- }
- return sum;
- }, 0);
- const isBeta = _.every(blockArray, 'isBeta');
- const isComingSoon = _.every(blockArray, 'isComingSoon');
-
- return {
- isBeta,
- isComingSoon,
- name: blockArray[0].block,
- superBlock: blockArray[0].superBlock,
- dashedName: dasherize(blockArray[0].block),
- markNew: shouldShowNew(null, blockArray),
- challenges: blockArray,
- completed: completedCount / blockArray.length * 100,
- time: blockArray[0] && blockArray[0].time || '???'
- };
- })
- // filter out hikes
- .filter(({ superBlock }) => {
- return !(/hikes/i).test(superBlock);
- })
- // turn stream of blocks into a stream of an array
- .toArray()
- .doOnNext(blocks => {
- const lastCompletedBlock = _.findLast(blocks, (block) => {
- return block.completed === 100;
- });
- lastCompleted = lastCompletedBlock && lastCompletedBlock.name || null;
- })
- .flatMap(blocks => Observable.from(blocks, null, null, Scheduler.default))
- .groupBy(block => block.superBlock)
- .flatMap(blocks$ => blocks$.toArray())
- .map(superBlockArray => ({
- name: superBlockArray[0].superBlock,
- blocks: superBlockArray
- }))
- .toArray();
-
- Observable.combineLatest(
- camperCount$,
- superBlocks$,
- (camperCount, superBlocks) => ({ camperCount, superBlocks })
- )
+ getSuperBlocks$(challenge$, getCompletedChallengeIds(user))
.subscribe(
- ({ camperCount, superBlocks }) => {
- res.render('challengeMap/show', {
+ superBlocks => {
+ res.render('map/show', {
superBlocks,
- daysRunning,
- globalCompletedCount: numberWithCommas(
- 5612952 + (Math.floor((Date.now() - 1446268581061) / 2000))
- ),
- camperCount,
- lastCompleted,
- title: 'A Map to Learn to Code and Become a Software Engineer'
+ title: 'A Map to Learn to Code and Become a Software Engineer',
+ showAside
});
},
next
diff --git a/server/boot/home.js b/server/boot/home.js
index 0177fa1edc..8d8a2be441 100644
--- a/server/boot/home.js
+++ b/server/boot/home.js
@@ -22,7 +22,7 @@ module.exports = function(app) {
function index(req, res) {
if (req.user) {
- return res.redirect('/map');
+ return res.redirect('/challenges/current-challenge');
}
res.render('home', { title: message });
}
diff --git a/server/boot/nonprofits.js b/server/boot/nonprofits.js
deleted file mode 100644
index f042f34354..0000000000
--- a/server/boot/nonprofits.js
+++ /dev/null
@@ -1,107 +0,0 @@
-var Rx = require('rx');
-var debug = require('debug')('freecc:nonprofits');
-var observeMethod = require('../utils/rx').observeMethod;
-var unDasherize = require('../utils').unDasherize;
-var dasherize = require('../utils').dasherize;
-
-module.exports = function(app) {
- var router = app.loopback.Router();
- var Nonprofit = app.models.Nonprofit;
- var findNonprofits = observeMethod(Nonprofit, 'find');
- var findOneNonprofit = observeMethod(Nonprofit, 'findOne');
-
- router.get('/nonprofits/directory', nonprofitsDirectory);
- router.get('/nonprofits/:nonprofitName', returnIndividualNonprofit);
-
- app.use(router);
-
- function nonprofitsDirectory(req, res, next) {
- findNonprofits({
- order: 'moneySaved DESC'
- })
- .flatMap(
- (nonprofits = []) => {
- // turn array of nonprofits into observable array
- return Rx.Observable.from(nonprofits)
- .pluck('moneySaved')
- .reduce((sum, moneySaved = 0) => sum + moneySaved, 0);
- },
- (nonprofits = [], totalSavings) => ({ nonprofits, totalSavings })
- )
- .subscribe(({ nonprofits, totalSavings }) => {
- res.render('nonprofits/directory', {
- title: 'Nonprofits we help',
- nonprofits: nonprofits,
- totalSavings: totalSavings.toString().replace(/000$/, ',000')
- });
- },
- next
- );
- }
-
- function returnIndividualNonprofit(req, res, next) {
- var dashedName = req.params.nonprofitName;
- var nonprofitName = unDasherize(dashedName);
- var query = { where: { name: {
- like: nonprofitName,
- options: 'i'
- } } };
-
- debug('looking for %s', nonprofitName);
- debug('query', query);
- findOneNonprofit(query).subscribe(
- function(nonprofit) {
- if (!nonprofit) {
- req.flash('errors', {
- msg: "404: We couldn't find a nonprofit with that name. " +
- 'Please double check the name.'
- });
- return res.redirect('/nonprofits');
- }
-
- var dashedNameFull = dasherize(nonprofit.name);
- if (dashedNameFull !== dashedName) {
- return res.redirect('../nonprofit/' + dashedNameFull);
- }
-
- res.render('nonprofits/show', {
- dashedName: dashedNameFull,
- title: nonprofit.name,
- logoUrl: nonprofit.logoUrl,
- estimatedHours: nonprofit.estimatedHours,
- projectDescription: nonprofit.projectDescription,
-
- approvedOther:
- nonprofit.approvedDeliverables.indexOf('other') > -1,
- approvedWebsite:
- nonprofit.approvedDeliverables.indexOf('website') > -1,
-
- approvedDonor:
- nonprofit.approvedDeliverables.indexOf('donor') > -1,
- approvedInventory:
- nonprofit.approvedDeliverables.indexOf('inventory') > -1,
-
- approvedVolunteer:
- nonprofit.approvedDeliverables.indexOf('volunteer') > -1,
- approvedForm:
- nonprofit.approvedDeliverables.indexOf('form') > -1,
-
- approvedCommunity:
- nonprofit.approvedDeliverables.indexOf('community') > -1,
- approvedELearning:
- nonprofit.approvedDeliverables.indexOf('eLearning') > -1,
-
- websiteLink: nonprofit.websiteLink,
- imageUrl: nonprofit.imageUrl,
- whatDoesNonprofitDo: nonprofit.whatDoesNonprofitDo,
- interestedCampers: nonprofit.interestedCampers,
- assignedCampers: nonprofit.assignedCampers,
- buttonActive: false,
- moneySaved: nonprofit.moneySaved,
- currentStatus: nonprofit.currentStatus
- });
- },
- next
- );
- }
-};
diff --git a/server/boot/randomAPIs.js b/server/boot/randomAPIs.js
index 95b6997aee..f19686eacc 100644
--- a/server/boot/randomAPIs.js
+++ b/server/boot/randomAPIs.js
@@ -35,8 +35,9 @@ module.exports = function(app) {
router.get('/labs', showLabs);
router.get('/stories', showTestimonials);
router.get('/all-stories', showAllTestimonials);
- router.get('/about', showAbout);
- router.get('/terms-and-privacy', termsAndPrivacy);
+ router.get('/terms', terms);
+ router.get('/privacy', privacy);
+ router.get('/code-of-conduct', codeOfConduct);
router.get(
'/the-fastest-web-page-on-the-internet',
theFastestWebPageOnTheInternet
@@ -196,18 +197,23 @@ module.exports = function(app) {
});
}
- function showAbout(req, res) {
- res.render('resources/about', {
- title: 'About our Open Source Community, our social media presence, ' +
- 'and how to contact us'
- });
+ function terms(req, res) {
+ res.render('resources/terms-of-service', {
+ title: 'Terms of Service'
+ });
}
- function termsAndPrivacy(req, res) {
- res.render('resources/terms-and-privacy', {
- title: 'Terms of Service, Privacy Policy, and Code of Conduct'
- });
- }
+ function privacy(req, res) {
+ res.render('resources/privacy', {
+ title: 'Privacy'
+ });
+ }
+
+ function codeOfConduct(req, res) {
+ res.render('resources/code-of-conduct', {
+ title: 'Code of Conduct'
+ });
+ }
function theFastestWebPageOnTheInternet(req, res) {
res.render('resources/the-fastest-web-page-on-the-internet', {
diff --git a/server/boot/user.js b/server/boot/user.js
index 563c10302d..69cb81eaae 100644
--- a/server/boot/user.js
+++ b/server/boot/user.js
@@ -178,6 +178,7 @@ module.exports = function(app) {
req.flash('errors', {
msg: `404: We couldn't find path ${ path }`
});
+ console.log('404');
return res.redirect('/');
}
profileUser = profileUser.toJSON();
@@ -290,7 +291,7 @@ module.exports = function(app) {
(user) => {
if (!user) {
req.flash('errors', {
- msg: `404: We couldn't find the user with the username ${username}`
+ msg: `We couldn't find the user with the username ${username}`
});
return res.redirect('/');
}
diff --git a/server/middlewares/error-handlers.js b/server/middlewares/error-handlers.js
index 359d713272..ddabe06a38 100644
--- a/server/middlewares/error-handlers.js
+++ b/server/middlewares/error-handlers.js
@@ -29,7 +29,7 @@ export default function prodErrorHandler() {
msg: message
});
}
- return res.redirect('/');
+ return res.redirect('/map');
// json
} else if (type === 'json') {
res.setHeader('Content-Type', 'application/json');
diff --git a/server/utils/getFromDisk$.js b/server/utils/getFromDisk$.js
index b6e24fe3ca..1f64f0551b 100644
--- a/server/utils/getFromDisk$.js
+++ b/server/utils/getFromDisk$.js
@@ -1,4 +1,3 @@
-import _ from 'lodash';
import path from 'path';
import { Observable } from 'rx';
@@ -16,16 +15,17 @@ export default function getFromDisk$(challenge) {
)];
return Observable.just(require(path.join(basePath, challenge.fileName)))
- .map(challengeSpec => challengeSpec.challenges[challenge.suborder - 1])
+ .map(challengeSpec => {
+ const _challenge = challengeSpec.challenges[challenge.suborder - 1];
+ _challenge.helpRoom = challengeSpec.helpRoom || 'Help';
+ return _challenge;
+ })
.map(challenge => {
challenge.head = challenge.head || [];
challenge.tail = challenge.tail || [];
challenge.challengeType = '' + challenge.challengeType;
- challenge.name =
- _.capitalize(challenge.type) +
- ': ' +
- challenge.title.replace(/[^a-zA-Z0-9\s]/g, '');
+ challenge.name = challenge.title.replace(/[^a-zA-Z0-9\s]/g, '');
challenge.dashedName = challenge.name
.toLowerCase()
diff --git a/server/utils/index.js b/server/utils/index.js
index 0975ee3662..d830b55850 100644
--- a/server/utils/index.js
+++ b/server/utils/index.js
@@ -1,13 +1,11 @@
var cheerio = require('cheerio'),
request = require('request'),
MDNlinks = require('../../seed/bonfireMDNlinks'),
- resources = require('./resources.json'),
- nonprofits = require('../../seed/nonprofits.json');
+ resources = require('./resources.json');
/**
* Cached values
*/
-var allNonprofitNames;
module.exports = {
dasherize: function dasherize(name) {
@@ -44,17 +42,6 @@ module.exports = {
];
},
- allNonprofitNames: function() {
- if (allNonprofitNames) {
- return allNonprofitNames;
- } else {
- allNonprofitNames = nonprofits.map(function(elem) {
- return {name: elem.name};
- });
- return allNonprofitNames;
- }
- },
-
whichEnvironment: function() {
return process.env.NODE_ENV;
},
diff --git a/server/views/account/email-signin.jade b/server/views/account/email-signin.jade
index e36d19b97b..fed5792311 100644
--- a/server/views/account/email-signin.jade
+++ b/server/views/account/email-signin.jade
@@ -1,19 +1,18 @@
extends ../layout
block content
- .jumbotron.text-center
- .row
- .col-xs-12
- h2 Sign in with an email address here:
- .col-sm-6.col-sm-offset-3
- form(method='POST', action='/api/users/login')
- input(type='hidden', name='_csrf', value=_csrf)
- .form-group
- input.input-lg.form-control(type='email', name='email', id='email', placeholder='Email', autofocus=true)
- .form-group
- input.input-lg.form-control(type='password', name='password', id='password', placeholder='Password')
- button.btn.btn-primary.btn-lg.btn-block(type='submit')
- span.ion-android-hand
- | Login
- .button-spacer
- .button-spacer
- a.btn.btn-info.btn-lg.btn-block(href='/forgot') Forgot your password?
+ .row
+ .col-xs-12
+ h2.text-center Sign in with an email address here:
+ .col-sm-6.col-sm-offset-3
+ form(method='POST', action='/api/users/login')
+ input(type='hidden', name='_csrf', value=_csrf)
+ .form-group
+ input.input-lg.form-control(type='email', name='email', id='email', placeholder='Email', autofocus=true)
+ .form-group
+ input.input-lg.form-control(type='password', name='password', id='password', placeholder='Password')
+ button.btn.btn-primary.btn-lg.btn-block(type='submit')
+ span.ion-android-hand
+ | Login
+ .button-spacer
+ .button-spacer
+ a.btn.btn-info.btn-lg.btn-block(href='/forgot') Forgot your password?
diff --git a/server/views/account/email-signup.jade b/server/views/account/email-signup.jade
index 15ab666565..e8a2ce9b23 100644
--- a/server/views/account/email-signup.jade
+++ b/server/views/account/email-signup.jade
@@ -1,9 +1,8 @@
extends ../layout
block content
- script.
- var challengeName = 'Email Signup'
- .jumbotron.text-center
- h2 Sign up with an email address here:
+ script.
+ var challengeName = 'Email Signup'
+ h2.text-center Sign up with an email address here:
form.form-horizontal(method='POST', action='/api/users', name="signupForm")
.row
.col-sm-6.col-sm-offset-3
@@ -13,6 +12,6 @@ block content
.form-group
input.input-lg.form-control(type='password', name='password', id='password', placeholder='password', required, pattern=".{8,50}", title="Must be at least 8 characters and no longer than 50 characters.")
.form-group
- button.btn.btn-lg.btn-success.btn-block(type='submit')
+ button.btn.btn-lg.btn-primary.btn-block(type='submit')
span.ion-person-add
| Signup
diff --git a/server/views/account/forgot.jade b/server/views/account/forgot.jade
index c5da16558c..4b1e94c606 100644
--- a/server/views/account/forgot.jade
+++ b/server/views/account/forgot.jade
@@ -1,12 +1,11 @@
extends ../layout
-
block content
- .col-sm-8.col-sm-offset-2.jumbotron
+ .col-sm-6.col-sm-offset-3
form(method='POST', action="/forgot")
h2.text-center Forgot Password Reset
input(type='hidden', name='_csrf', value=_csrf)
.form-group
- p Enter your email address. We'll send you password reset instructions.
+ p.large-p Enter your email address. We'll send you password reset instructions.
input.form-control.input-lg(type='email', name='email', id='email', placeholder='Email', autofocus=true required)
.form-group
button.btn.btn-primary.btn-lg.btn-block(type='submit')
diff --git a/server/views/account/show.jade b/server/views/account/show.jade
index 545d2341e4..a38f6fd050 100644
--- a/server/views/account/show.jade
+++ b/server/views/account/show.jade
@@ -4,241 +4,228 @@ block content
script.
var challengeName = 'Profile View';
if (user && user.username === username)
- .panel.panel-info
- .panel-heading.text-center Update your code portfolio
- .panel-body
- .row
- .col-xs-12
- if (!user.isGithubCool)
- a.btn.btn-lg.btn-block.btn-github.btn-link-social(href='/link/github')
- i.fa.fa-github
- | Link my GitHub to unlock my portfolio
- else
- a.btn.btn-lg.btn-block.btn-github.btn-link-social(href='/link/github')
- i.fa.fa-github
- | Update my name, username, and location with data from my GitHub account
- if (!user.twitter)
- a.btn.btn-lg.btn-block.btn-twitter.btn-link-social(href='/link/twitter')
- i.fa.fa-twitter
- | Add my Twitter to my portfolio
- if (!user.facebook)
- a.btn.btn-lg.btn-block.btn-facebook.btn-link-social(href='/link/facebook')
- i.fa.fa-facebook
- | Add my Facebook to my portfolio
- if (!user.linkedin)
- a.btn.btn-lg.btn-block.btn-linkedin.btn-link-social(href='/link/linkedin')
- i.fa.fa-linkedin
- | Add my LinkedIn to my portfolio
- if (!user.google)
- a.btn.btn-lg.btn-block.btn-google-plus.btn-link-social(href='/link/google')
- i.fa.fa-google-plus
- | Add my Google+ to my portfolio
-
- .panel.panel-info
- .panel-heading.text-center
- h1 #{username}'s code portfolio
- .panel-body
- .row
- .col-xs-12.col-sm-10.col-sm-offset-1.col-md-8.col-md-offset-2.text-center
- if picture
- img.img-center.img-responsive.public-profile-img(src=picture)
- else
- img.img-center.img-responsive.public-profile-img(src='https://s3.amazonaws.com/freecodecamp/camper-image-placeholder.png')
- h1.text-center.negative-5.profile-social-icons
- if (twitter)
- a.fa.fa-twitter-square.text-primary(title="@#{username}'s Twitter Profile", href='https://twitter.com/' + twitter, target='_blank')
- if (github)
- a.fa.fa-github-square.text-primary(title="@#{username}'s GitHub Profile", href=github, target='_blank')
- if (linkedin)
- a.fa.fa-linkedin-square.text-primary(title="@#{username}'s LinkedIn Profile", href=linkedin, target='_blank')
- if (facebook)
- a.fa.fa-facebook-square.text-primary(title="@#{username}'s Facebook Profile", href='https://facebook.com/' + facebook, target='_blank')
- if (google)
- a.fa.fa-google-plus-square.text-primary(title="@#{username}'s Google Profile", href='https://plus.google.com/' + google, target='_blank')
- h1.flat-top.wrappable= name
- h1.flat-top.wrappable= location
- h1.flat-top.text-primary= "[ " + (progressTimestamps.length) + " ]"
- if pledge
- .spacer
- h4
- | This camper has committed to giving $#{pledge.amount} to
- a(href='#{pledge.donateUrl}?ref=freecodecamp.com' target='_blank') #{pledge.displayName}
- | each month until they have completed their #{pledge.goal}.
- .spacer
- if isFrontEndCert
- a.btn.btn-primary(href='/' + username + '/front-end-certification') View My Front End Development Certification
- if isDataVisCert
- .button-spacer
- a.btn.btn-success(href='/' + username + '/data-visualization-certification') View My Data Visualization Certification
- if isBackEndCert
- .button-spacer
- a.btn.btn-success(href='/' + username + '/back-end-certification') View My Back End Development Certification
- //if (user && user.username !== username)
- // a.btn.btn-lg.btn-block.btn-twitter.btn-link-social(href='/leaderboard/add?username=#{username}')
- // i.fa.fa-plus-square
- // | Add them to my personal leaderboard
-
- .spacer
- .col-md-12
- #cal-heatmap.hidden-xs.hidden-sm.d3-centered
- script.
- $(document).ready(function () {
- var cal = new CalHeatMap();
- var calendar = !{JSON.stringify(calender)};
- /*
- var estUTCOffset = -5;
- // moment returns the utc offset in minutes
- var userUTCOffset = moment().utcOffset() / 60;
- var secondsToOffset =
- (estUTCOffset - userUTCOffset) * 3600;
- var offsetCalendar = {};
- for (var prop in calendar) {
- if (calendar.hasOwnProperty(prop)) {
- var offsetProp = prop + secondsToOffset;
- offsetCalendar[offsetProp] = calendar[prop];
- }
- }
- */
- cal.init({
- itemSelector: "#cal-heatmap",
- domain: "month",
- subDomain: "x_day",
- domainGutter: 10,
- data: calendar,
- cellSize: 15,
- align: 'center',
- cellRadius: 3,
- cellPadding: 2,
- tooltip: true,
- range: 6,
- start: new Date().setDate(new Date().getDate() - 150),
- legendColors: ["#cccccc", "#215f1e"],
- legend: [1, 2, 3],
- label: {
- position: "top"
- }
- });
- });
- .row
- .hidden-xs.col-sm-12.text-center
- .row.text-primary
- h4.col-sm-6.text-right Longest Streak: #{longestStreak} #{longestStreak === 1 ? ' day' : ' days'}
- h4.col-sm-6.text-left Current Streak: #{currentStreak} #{currentStreak === 1 ? ' day' : ' days'}
-
-
- if (user && user.username == username || !isLocked)
- if (baseAndZip.length > 0)
- .col-sm-12
- table.table.table-striped
- thead
- tr
- th.col-xs-6 Projects
- th.col-xs-3.hidden-xs Completed
- th.col-xs-3.hidden-xs Link
- for challenge in baseAndZip
- tr
- td.col-xs-4.hidden-xs
- a(href='/challenges/' + challenge.name, target='_blank')= challenge.name
- td.col-xs-2.hidden-xs= challenge.completedDate ? moment(challenge.completedDate, 'x').format("MMM DD, YYYY") : 'Not Available'
- td.col-xs-6.hidden-xs
- a(href=challenge.solution, target='_blank') View my project
- td.col-xs-12.visible-xs
- a(href=challenge.solution, target='_blank')=challenge.name
- if (bonfires.length > 0)
- .col-sm-12
- table.table.table-striped
- thead
- tr
- th.col-xs-6 Bonfires
- th.col-xs-3.hidden-xs Completed
- th.col-xs-3.hidden-xs Solution
- for bonfire in bonfires
- tr
- td.col-xs-6.hidden-xs= bonfire.name
- td.col-xs-3.hidden-xs= bonfire.completedDate ? moment(bonfire.completedDate, 'x').format("MMM DD, YYYY") : 'Not Available'
- td.col-xs-3.hidden-xs
- a(href='/challenges/' + bonfire.name + '?solution=' + encodeURIComponent(encodeFcc(bonfire.solution)), target='_blank') View my solution
- td.col-xs-12.visible-xs
- a(href='/challenges/' + bonfire.name + '?solution=' + encodeURIComponent(encodeFcc(bonfire.solution)), target='_blank')= bonfire.name
- if (waypoints.length > 0)
- .col-sm-12
- table.table.table-striped
- thead
- tr
- th.col-xs-6 Waypoints
- th.col-xs-3.hidden-xs Completed
- th.col-xs-3.hidden-xs Solution
- for challenge in waypoints
- tr
- td.col-xs-6.hidden-xs= challenge.name
- td.col-xs-3.hidden-xs= challenge.completedDate ?moment(challenge.completedDate, 'x').format("MMM DD, YYYY") : 'Not Available'
- td.col-xs-3.hidden-xs
- if (challenge.solution)
- a(href='/challenges/' + challenge.name + '?solution=' + encodeURIComponent(encodeFcc(challenge.solution)), target='_blank') View my solution
- else
- a(href='/challenges/' + challenge.name) View this challenge
- td.col-xs-12.visible-xs
- if (challenge.solution)
- a(href='/challenges/' + challenge.name + '?solution=' + encodeURIComponent(encodeFcc(challenge.solution)), target='_blank')= challenge.name
- else
- a(href='/challenges/' + challenge.name)= challenge.name
- if (user && user.username === username)
- .panel.panel-info
- .panel-heading.text-center Manage your account
- .panel-body
- .col-xs-12
- a.btn.btn-lg.btn-block.btn-warning.btn-link-social(href='/logout')
- span.ion-android-exit
- | Sign me out of Free Code Camp
- .col-xs-12
- a.btn.btn-lg.btn-block.btn-primary.btn-link-social(href='mailto:team@freecodecamp.com')
- span.ion-email
- | Email us at team@freecodecamp.com
- if (!user.isLocked)
- .col-xs-12
- a.btn.btn-lg.btn-block.btn-info.btn-link-social(href='/toggle-lockdown-mode')
- span.ion-locked
- | Hide all my solutions from other people
- br
- | (this will disable your certificates)
+ h1.text-center Update your code portfolio
+ .row
+ .col-xs-12
+ if (!user.isGithubCool)
+ a.btn.btn-lg.btn-block.btn-github.btn-link-social(href='/link/github')
+ i.fa.fa-github
+ | Link my GitHub to unlock my portfolio
else
- .col-xs-12
- a.btn.btn-lg.btn-block.btn-info.btn-link-social(href='/toggle-lockdown-mode')
- span.ion-unlocked
- | Let other people see all my solutions
- br
- | (this will enable your certificates)
- .col-xs-12
- a.btn.btn-lg.btn-block.btn-success.btn-link-social(href='/commit')
- span.ion-edit
- | Edit my pledge
- .col-xs-12
- a.btn.btn-lg.btn-block.btn-danger.btn-link-social.confirm-deletion
- span.ion-trash-b
- | Delete my Free Code Camp account
- script.
- $('.confirm-deletion').on("click", function () {
- $('#modal-dialog').modal('show');
+ a.btn.btn-lg.btn-block.btn-github.btn-link-social(href='/link/github')
+ i.fa.fa-github
+ | Update my portfolio from GitHub
+ if (!user.twitter)
+ a.btn.btn-lg.btn-block.btn-twitter.btn-link-social(href='/link/twitter')
+ i.fa.fa-twitter
+ | Add my Twitter to my portfolio
+ if (!user.facebook)
+ a.btn.btn-lg.btn-block.btn-facebook.btn-link-social(href='/link/facebook')
+ i.fa.fa-facebook
+ | Add my Facebook to my portfolio
+ if (!user.linkedin)
+ a.btn.btn-lg.btn-block.btn-linkedin.btn-link-social(href='/link/linkedin')
+ i.fa.fa-linkedin
+ | Add my LinkedIn to my portfolio
+ if (!user.google)
+ a.btn.btn-lg.btn-block.btn-google-plus.btn-link-social(href='/link/google')
+ i.fa.fa-google-plus
+ | Add my Google+ to my portfolio
+ .spacer
+ h1.text-center #{username}'s code portfolio
+ hr
+ .row
+ .col-xs-12.col-sm-10.col-sm-offset-1.col-md-8.col-md-offset-2.text-center
+ if picture
+ img.img-center.img-responsive.public-profile-img(src=picture)
+ else
+ img.img-center.img-responsive.public-profile-img(src='https://s3.amazonaws.com/freecodecamp/camper-image-placeholder.png')
+ h1.text-center.negative-5.profile-social-icons
+ if (twitter)
+ a.fa.fa-twitter-square.text-primary(title="@#{username}'s Twitter Profile", href='https://twitter.com/' + twitter, target='_blank')
+ if (github)
+ a.fa.fa-github-square.text-primary(title="@#{username}'s GitHub Profile", href=github, target='_blank')
+ if (linkedin)
+ a.fa.fa-linkedin-square.text-primary(title="@#{username}'s LinkedIn Profile", href=linkedin, target='_blank')
+ if (facebook)
+ a.fa.fa-facebook-square.text-primary(title="@#{username}'s Facebook Profile", href='https://facebook.com/' + facebook, target='_blank')
+ if (google)
+ a.fa.fa-google-plus-square.text-primary(title="@#{username}'s Google Profile", href='https://plus.google.com/' + google, target='_blank')
+ h1.flat-top.wrappable= name
+ h1.flat-top.wrappable= location
+ h1.flat-top.text-primary= "[ " + (progressTimestamps.length) + " ]"
+ if pledge
+ .spacer
+ h4
+ | This camper has committed to giving $#{pledge.amount} to
+ a(href='#{pledge.donateUrl}?ref=freecodecamp.com' target='_blank') #{pledge.displayName}
+ | each month until they have completed their #{pledge.goal}.
+ .spacer
+ .row
+ .col-xs-12.col-sm-10.col-sm-offset-1.col-md-8.col-md-offset-2
+ if isFrontEndCert
+ a.btn.btn-primary.btn-block(href='/' + username + '/front-end-certification') View My Front End Development Certification
+ if isDataVisCert
+ .button-spacer
+ a.btn.btn-primary.btn-block(href='/' + username + '/data-visualization-certification') View My Data Visualization Certification
+ if isBackEndCert
+ .button-spacer
+ a.btn.btn-primary.btn-block(href='/' + username + '/back-end-certification') View My Back End Development Certification
+
+ .spacer
+ .col-md-12
+ #cal-heatmap.hidden-xs.hidden-sm.d3-centered
+ script.
+ $(document).ready(function () {
+ var cal = new CalHeatMap();
+ var calendar = !{JSON.stringify(calender)};
+ /*
+ var estUTCOffset = -5;
+ // moment returns the utc offset in minutes
+ var userUTCOffset = moment().utcOffset() / 60;
+ var secondsToOffset =
+ (estUTCOffset - userUTCOffset) * 3600;
+ var offsetCalendar = {};
+ for (var prop in calendar) {
+ if (calendar.hasOwnProperty(prop)) {
+ var offsetProp = prop + secondsToOffset;
+ offsetCalendar[offsetProp] = calendar[prop];
+ }
+ }
+ */
+ cal.init({
+ itemSelector: "#cal-heatmap",
+ domain: "month",
+ subDomain: "x_day",
+ domainGutter: 10,
+ data: calendar,
+ cellSize: 15,
+ align: 'center',
+ cellRadius: 3,
+ cellPadding: 2,
+ tooltip: true,
+ range: 6,
+ start: new Date().setDate(new Date().getDate() - 150),
+ legendColors: ["#cccccc", "#215f1e"],
+ legend: [1, 2, 3],
+ label: {
+ position: "top"
+ }
});
- #modal-dialog.modal.animated.wobble
- .modal-dialog
- .modal-content
- .modal-header
- a.close(href='#', data-dismiss='modal', aria-hidden='true') ×
- h3 You don't really want to delete your account, do you?
- .modal-body
- p This will really delete all your data, including all your progress, news stories and brownie points.
- p We won't be able to recover any of it for you later, even if you change your mind.
- p If there's something we could do better, send us an email instead and we'll do our best:
- a(href="mailto:team@freecodecamp.com") team@freecodecamp.com
- | .
- .modal-footer
- a.btn.btn-success.btn-block(href='#', data-dismiss='modal', aria-hidden='true')
- span.ion-happy
- | Nevermind, I don't want to delete all of my progress
- .spacer
- form(action='/account/delete', method='POST')
- input(type='hidden', name='_csrf', value=_csrf)
- button.btn.btn-danger.btn-block(type='submit')
- span.ion-trash-b
- | I am 100% sure I want to delete my account and all of my progress
+ });
+ .row
+ .hidden-xs.col-sm-12.text-center
+ .row.text-primary
+ h4.col-sm-6.text-right Longest Streak: #{longestStreak} #{longestStreak === 1 ? ' day' : ' days'}
+ h4.col-sm-6.text-left Current Streak: #{currentStreak} #{currentStreak === 1 ? ' day' : ' days'}
+
+
+ if (user && user.username == username || !isLocked)
+ if (baseAndZip.length > 0)
+ .col-sm-12
+ table.table.table-striped
+ thead
+ tr
+ th.col-xs-6 Projects
+ th.col-xs-3.hidden-xs Completed
+ th.col-xs-3.hidden-xs Link
+ for challenge in baseAndZip
+ tr
+ td.col-xs-4.hidden-xs
+ a(href='/challenges/' + challenge.name, target='_blank')= challenge.name
+ td.col-xs-2.hidden-xs= challenge.completedDate ? moment(challenge.completedDate, 'x').format("MMM DD, YYYY") : 'Not Available'
+ td.col-xs-6.hidden-xs
+ a(href=challenge.solution, target='_blank') View my project
+ td.col-xs-12.visible-xs
+ a(href=challenge.solution, target='_blank')=challenge.name
+ if (bonfires.length > 0)
+ .col-sm-12
+ table.table.table-striped
+ thead
+ tr
+ th.col-xs-6 Bonfires
+ th.col-xs-3.hidden-xs Completed
+ th.col-xs-3.hidden-xs Solution
+ for bonfire in bonfires
+ tr
+ td.col-xs-6.hidden-xs= bonfire.name
+ td.col-xs-3.hidden-xs= bonfire.completedDate ? moment(bonfire.completedDate, 'x').format("MMM DD, YYYY") : 'Not Available'
+ td.col-xs-3.hidden-xs
+ a(href='/challenges/' + bonfire.name + '?solution=' + encodeURIComponent(encodeFcc(bonfire.solution)), target='_blank') View my solution
+ td.col-xs-12.visible-xs
+ a(href='/challenges/' + bonfire.name + '?solution=' + encodeURIComponent(encodeFcc(bonfire.solution)), target='_blank')= bonfire.name
+ if (waypoints.length > 0)
+ .col-sm-12
+ table.table.table-striped
+ thead
+ tr
+ th.col-xs-6 Waypoints
+ th.col-xs-3.hidden-xs Completed
+ th.col-xs-3.hidden-xs Solution
+ for challenge in waypoints
+ tr
+ td.col-xs-6.hidden-xs= challenge.name
+ td.col-xs-3.hidden-xs= challenge.completedDate ?moment(challenge.completedDate, 'x').format("MMM DD, YYYY") : 'Not Available'
+ td.col-xs-3.hidden-xs
+ if (challenge.solution)
+ a(href='/challenges/' + challenge.name + '?solution=' + encodeURIComponent(encodeFcc(challenge.solution)), target='_blank') View my solution
+ else
+ a(href='/challenges/' + challenge.name) View this challenge
+ td.col-xs-12.visible-xs
+ if (challenge.solution)
+ a(href='/challenges/' + challenge.name + '?solution=' + encodeURIComponent(encodeFcc(challenge.solution)), target='_blank')= challenge.name
+ else
+ a(href='/challenges/' + challenge.name)= challenge.name
+
+ if (user && user.username === username)
+ h1.text-center Manage your account
+ hr
+ .col-xs-12
+ a.btn.btn-lg.btn-block.btn-primary.btn-link-social(href='/logout')
+ | Sign me out of Free Code Camp
+ .col-xs-12
+ a.btn.btn-lg.btn-block.btn-primary.btn-link-social(href='mailto:team@freecodecamp.com')
+ | Email us at team@freecodecamp.com
+ if (!user.isLocked)
+ .col-xs-12
+ a.btn.btn-lg.btn-block.btn-primary.btn-link-social(href='/toggle-lockdown-mode')
+ | Hide all my solutions from other people
+ br
+ | (this will disable your certificates)
+ else
+ .col-xs-12
+ a.btn.btn-lg.btn-block.btn-primary.btn-link-social(href='/toggle-lockdown-mode')
+ | Let other people see all my solutions
+ br
+ | (this will enable your certificates)
+ .col-xs-12
+ a.btn.btn-lg.btn-block.btn-primary.btn-link-social(href='/commit')
+ | Edit my pledge
+ .col-xs-12
+ a.btn.btn-lg.btn-block.btn-danger.btn-link-social.confirm-deletion
+ | Delete my Free Code Camp account
+ script.
+ $('.confirm-deletion').on("click", function () {
+ $('#modal-dialog').modal('show');
+ });
+ #modal-dialog.modal.animated.wobble
+ .modal-dialog
+ .modal-content
+ .modal-header
+ a.close(href='#', data-dismiss='modal', aria-hidden='true') ×
+ h3 You don't really want to delete your account, do you?
+ .modal-body
+ p This will really delete all your data, including all your progress, news stories and brownie points.
+ p We won't be able to recover any of it for you later, even if you change your mind.
+ p If there's something we could do better, send us an email instead and we'll do our best:
+ a(href="mailto:team@freecodecamp.com") team@freecodecamp.com
+ | .
+ .modal-footer
+ a.btn.btn-success.btn-block(href='#', data-dismiss='modal', aria-hidden='true')
+ | Nevermind, I don't want to delete all of my progress
+ .spacer
+ form(action='/account/delete', method='POST')
+ input(type='hidden', name='_csrf', value=_csrf)
+ button.btn.btn-danger.btn-block(type='submit')
+ | I am 100% sure I want to delete my account and all of my progress
+>>>>>>> refactor map view and make buttons and text bigger
diff --git a/server/views/account/signin.jade b/server/views/account/signin.jade
index e6a01f3cee..eba1c665a9 100644
--- a/server/views/account/signin.jade
+++ b/server/views/account/signin.jade
@@ -1,6 +1,6 @@
extends ../layout
block content
- .jumbotron.text-center
+ .text-center
h2 Sign in with one of these options:
a.btn.btn-lg.btn-block.btn-github.btn-social(href='/auth/github')
i.fa.fa-github
diff --git a/server/views/challengeMap/show.jade b/server/views/challengeMap/show.jade
deleted file mode 100644
index fc5f39d629..0000000000
--- a/server/views/challengeMap/show.jade
+++ /dev/null
@@ -1,215 +0,0 @@
-extends ../layout
-block content
- .panel.panel-info
- .panel-heading.text-center
- h1 Challenge Map
- .panel-body
- if (Math.random() > 0.999)
- img.img-responsive.img-center.border-radius-5(src='https://s3.amazonaws.com/freecodecamp/wide-social-banner-dino.png')
- audio(autoplay src='https://s3.amazonaws.com/freecodecamp/t-rex-roar.mp3')
- else
- img.img-responsive.img-center.border-radius-5(src='https://s3.amazonaws.com/freecodecamp/wide-social-banner.png')
- .col-xs-12.col-md-8.col-md-offset-2
- h2
- table.population-table.img-center
- tr
- td Established:
- td
- span.text-primary #{daysRunning}
- | days ago
- tr
- td Population:
- td
- span.text-primary #{camperCount}
- | campers
- tr
- td Completed:
- td
- span.text-primary #{globalCompletedCount}
- | challenges
-
-
-
- .spacer
- if (user && user.progressTimestamps.length > 100)
- .row
- #map-notice.col-xs-12.col-md-8.col-md-offset-2.hidden
- h2.text-center Reddit or not, here we come
- img.thumbnail.img-center.img-responsive(src="http://i.imgur.com/lyd0bfM.jpg")
- h4.text-center Come ask questions and share your thoughts with our entire open source community on our subreddit.
- a.button.btn.btn-block.btn-primary(href="https://reddit.com/r/freecodecamp" target="_blank") Check it out
- .button-spacer
- .text-center
- a#hide-map-notice-button(href='#') Hide this forever
- .spacer
-
- ul
- for superBlock in superBlocks
- h2= superBlock.name
- - var i = 0
- for challengeBlock in superBlock.blocks
- - i++
- .row
- if (user)
- if (challengeBlock.completed === 100)
- .hidden-xs.col-sm-3.col-md-2.text-primary.ion-checkmark-circled.padded-ionic-icon.text-center.map-p.negative-10
- .col-xs-1.col-sm-1.col-md-1.map-row-numbers.negative-5
- span.map-p.negative-10 #{i}.
- .col-xs-11.col-sm-8.col-md-9
- li.map-p.faded.negative-10
- a(href='#' + challengeBlock.dashedName)= challengeBlock.name
- if challengeBlock.markNew
- span.text-info.small
- strong
- em NEW
- if challengeBlock.isComingSoon
- span.text-info.small
- strong
- em Coming Soon
- else
- .hidden-xs.col-sm-3.col-md-2
- .progress.progress-bar-padding.text-center.thin-progress-bar
- .progress-bar(role='progressbar', aria-valuenow=(challengeBlock.completed), aria-valuemin='0', aria-valuemax='100', style='width: ' + challengeBlock.completed + '%;')
- .col-xs-1.col-sm-1.col-md-1.map-row-numbers.negative-5
- span.map-p #{i}.
- .col-xs-11.col-sm-8.col-md-9
- li.map-p.negative-10
- a(href='#' + challengeBlock.dashedName)= challengeBlock.name
- if challengeBlock.markNew
- span.text-info.small
- strong
- em NEW
- if challengeBlock.isComingSoon
- span.text-info.small
- strong
- em Coming Soon
- else
- .hidden-xs.col-sm-3.col-md-2
- .col-xs-1.col-sm-1.col-md-1.map-row-numbers
- span.map-p.negative-10 #{i}.
- .col-xs-10.col-sm-8.col-md-9
- span.map-p.negative-10
- a(href='#' + challengeBlock.dashedName)= challengeBlock.name
- if challengeBlock.markNew
- span.text-info.small
- strong
- em NEW
- if challengeBlock.isComingSoon
- span.text-info.small
- strong
- em Coming Soon
- h2 Full Stack Development Certification
- .row
- .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10
- .col-xs-12.col-sm-9.col-md-10
- li.map-p.negative-10 Greenfield Nonprofit Project 1
- .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10
- .col-xs-12.col-sm-9.col-md-10
- li.map-p.negative-10 Greenfield Nonprofit Project 2
- .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10
- .col-xs-12.col-sm-9.col-md-10
- li.map-p.negative-10 Legacy Nonprofit Project 1
- .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10
- .col-xs-12.col-sm-9.col-md-10
- li.map-p.negative-10 Legacy Nonprofit Project 2
- .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10
- .col-xs-12.col-sm-9.col-md-10
- li.map-p.negative-10 Claim your Full Stack Development Certification
-
- h2 Coding Interview Preparation
- .row
- .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10
- .col-xs-12.col-sm-9.col-md-10
- li.map-p.negative-10 Whiteboard Coding Interview Training
- .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10
- .col-xs-12.col-sm-9.col-md-10
- li.map-p.negative-10 Critical Thinking Interview Training
- .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10
- .col-xs-12.col-sm-9.col-md-10
- li.map-p.negative-10 Mock Interview 1
- .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10
- .col-xs-12.col-sm-9.col-md-10
- li.map-p.negative-10 Mock Interview 2
- .hidden-xs.col-sm-3.col-md-2.ion-locked.padded-ionic-icon.text-center.map-p.negative-10
- .col-xs-12.col-sm-9.col-md-10
- li.map-p.negative-10 Mock Interview 3
-
- hr
-
- for superBlock, index in superBlocks
- for challengeBlock in superBlock.blocks
- .row
- a(href='#' name=challengeBlock.dashedName)
- .spacer.negative-55
-
- .row
- .hidden-xs.col-sm-3.col-md-2
- h3.text-primary.text-right.nowrap
- i.fa.fa-clock-o
- = challengeBlock.time
- .col-xs-12.col-sm-9.col-md-10
- h3 #{challengeBlock.name}
-
- - var i = 0
- for challenge in challengeBlock.challenges
- - i++
- .row
- if challenge.completed
- .hidden-xs.col-sm-3.col-md-2.text-primary.ion-checkmark-circled.padded-ionic-icon.text-center.map-p.negative-10
- .col-xs-1.col-sm-1.col-md-1.map-row-numbers
- span.map-p.negative-10 #{i}.
- .col-xs-10.col-sm-8.col-md-9
- span.faded.map-p.negative-10
- a(href="/challenges/#{challenge.dashedName}")
- span.capitalize= challenge.type + ': '
- span= challenge.title
- span.sr-only= " Complete"
-
- else
- .hidden-xs.col-sm-3.col-md-2
- span.negative-10
- .col-xs-1.col-sm-1.col-md-1.map-row-numbers
- span.map-p.negative-10 #{i}.
- .col-xs-10.col-sm-8.col-md-9
- span.map-p.negative-10
- a(href="/challenges/#{challenge.dashedName}" class=challenge.isComingSoon ? 'disabled' : '')
- span.capitalize= challenge.type + ': '
- span= challenge.title
- span.sr-only= " Incomplete"
- if challenge.markNew
- span.text-info.small
- strong
- em NEW
- if challengeBlock.isComingSoon
- span.text-info.small
- strong
- em Coming Soon
-
- if (challengeBlock.completed === 100)
- .button-spacer
- .row
- .col-xs-12.col-sm-8.col-md-6.col-sm-offset-3.col-md-offset-2.hidden
- a.btn.btn-lg.btn-block.signup-btn.map-challenge-block-share Section complete. Share your code portfolio with your friends.
- .hidden(id="#{challengeBlock.name}")
-
- if (index < superBlocks.length - 1)
- .spacer
- hr
- .spacer
-
- script.
- var username = !{JSON.stringify(user && user.username || '')};
- var lastCompleted = !{JSON.stringify(lastCompleted || false)}
- $(document).ready(function () {
- if (!localStorage || !localStorage.hideRedditNotice) {
- $("#map-notice").removeClass("hidden");
- }
- $("#hide-map-notice-button").on("click", function(e) {
- e.preventDefault();
- $("#map-notice").addClass('animated fadeOut');
- setTimeout(function() {
- $("#map-notice").hide();
- }, 1000);
- localStorage.hideRedditNotice = "true";
- });
- });
diff --git a/server/views/coursewares/showBonfire.jade b/server/views/challenges/showBonfire.jade
similarity index 72%
rename from server/views/coursewares/showBonfire.jade
rename to server/views/challenges/showBonfire.jade
index a3a584d876..1ced7be390 100644
--- a/server/views/coursewares/showBonfire.jade
+++ b/server/views/challenges/showBonfire.jade
@@ -4,46 +4,40 @@ block content
link(rel='stylesheet', href='/bower_components/CodeMirror/addon/lint/lint.css')
link(rel='stylesheet', href='/bower_components/CodeMirror/theme/monokai.css')
link(rel='stylesheet', href='/css/ubuntu.css')
-
.row
.col-md-4.col-lg-3
.scroll-locker(id = "scroll-locker")
.innerMarginFix(style=' width: 99%')
- #testCreatePanel.well
- h3.text-center.negative-10= name
+ #testCreatePanel
+ h4.text-center= name
if (isCompleted)
|
i.ion-checkmark-circled.text-primary(title="Completed")
+ hr
.row
.col-xs-12
.bonfire-instructions
- for sentence in details
+ for sentence in description
if (/blockquote|h4|table/.test(sentence))
!=sentence
else
- p.wrappable.negative-10!= sentence
+ p.wrappable!= sentence
if (MDNlinks.length)
- .negative-30-bottom
- #MDN-links
- p.negative-10 Here are some helpful links:
- for link, index in MDNlinks
- .negative-10
- ul: li: a(href=""+link, target="_blank") !{MDNkeys[index]}
-
+ #MDN-links
+ p Here are some helpful links:
+ for link, index in MDNlinks
+ ul: li: a(href=""+link, target="_blank") !{MDNkeys[index]}
+ .button-spacer
if (user)
- label.negative-10.btn.btn-primary.btn-block.btn-lg#submitButton
- i.fa.fa-play
- | Run tests (ctrl + enter)
+ label.btn.btn-primary.btn-block.btn-lg#submitButton
+ | Run tests (ctrl + enter)
.button-spacer
.btn-group.input-group.btn-group-justified
- label.btn.btn-success#trigger-reset-modal
- i.fa.fa-refresh
+ label.btn.btn-primary.btn-primary-ghost.btn-lg#trigger-reset-modal
| Reset
- label.btn.btn-success#challenge-help-btn
- i.fa.fa-medkit
+ label.btn.btn-primary.btn-primary-ghost.btn-lg#challenge-help-btn
| Help
- label.btn.btn-success#trigger-issue-modal
- i.fa.fa-bug
+ label.btn.btn-primary.btn-primary-ghost.btn-lg#trigger-issue-modal
| Bug
if (!user)
.button-spacer
@@ -55,7 +49,7 @@ block content
.form-group.codeMirrorView
textarea#codeOutput(style='display: none;')
br
- #testSuite.negative-10
+ #testSuite
br
.col-md-8.col-lg-9
@@ -84,7 +78,7 @@ block content
i.fa.fa-twitter
= phrase
else
- a#next-challenge.btn.btn-lg.btn-primary.btn-block(href="/challenges/next-challenge?id="+challengeId) Go to my next challenge (ctrl + enter)
+ a#next-challenge.btn.btn-lg.btn-primary.btn-block(href="/challenges/next-challenge?id="+id) Go to my next challenge (ctrl + enter)
include ../partials/challenge-modals
script(type="text/javascript").
var common = window.common = window.common || { init: [] };
@@ -93,7 +87,7 @@ block content
common.head = !{JSON.stringify(head)};
common.tail = !{JSON.stringify(tail)};
- common.challengeId = !{JSON.stringify(challengeId)};
+ common.challengeId = !{JSON.stringify(id)};
common.challengeName = !{JSON.stringify(name)};
common.challengeSeed = !{JSON.stringify(challengeSeed)};
common.challengeType = !{JSON.stringify(challengeType)};
@@ -104,8 +98,6 @@ block content
include ../partials/challenge-footer
script.
- document.addEventListener('gitter-sidecar-ready', function(e) {
- if (window.main) {
- window.main.chat.createHelpChat('freecodecamp/helpbonfires', '#challenge-help-btn', 'Bonfires Help');
- }
- });
+ if (!!{JSON.stringify(MDNlinks.length)}) {
+ $('#MDN-links').addClass('collapse');
+ }
diff --git a/server/views/coursewares/showHTML.jade b/server/views/challenges/showHTML.jade
similarity index 64%
rename from server/views/coursewares/showHTML.jade
rename to server/views/challenges/showHTML.jade
index 163c813689..8320c9e1be 100644
--- a/server/views/coursewares/showHTML.jade
+++ b/server/views/challenges/showHTML.jade
@@ -4,39 +4,31 @@ block content
link(rel='stylesheet', href='/bower_components/CodeMirror/addon/lint/lint.css')
link(rel='stylesheet', href='/bower_components/CodeMirror/theme/monokai.css')
link(rel='stylesheet', href='/css/ubuntu.css')
- .row.courseware-height
+ .row
.col-md-3.col-lg-3
.scroll-locker(id = "scroll-locker")
.innerMarginFix(style = "width: 99%;")
- .well
- .row
- .col-xs-12
- h3.text-center.negative-10= name
- if (isCompleted)
- |
- i.ion-checkmark-circled.text-primary(title="Completed")
- .bonfire-instructions
- for sentence in details
- p.wrappable.negative-10!= sentence
- .negative-bottom-margin-30
- label.negative-10.btn.btn-primary.btn-lg.btn-block#submitButton
- i.fa.fa-play
- | Run tests (ctrl + enter)
+ .row
+ .col-xs-12
+ h4.text-center= name
+ if (isCompleted)
+ |
+ i.ion-checkmark-circled.text-primary(title="Completed")
+ hr
+ .bonfire-instructions
+ for sentence in description
+ p.wrappable!= sentence
+ .negative-bottom-margin-30
+ .button-spacer
+ .btn-big.btn.btn-primary.btn-block#submitButton
+ | Run tests (ctrl + enter)
.button-spacer
.btn-group.input-group.btn-group-justified
- label.btn.btn-success#trigger-reset-modal
- i.fa.fa-refresh
- | Reset
- label.btn.btn-success.hidden-sm.hidden-md.hidden-lg
- a(href='//gitter.im/freecodecamp/help')
- i.fa.fa-medkit
- | Help
- label.btn.btn-success.hidden-xs#challenge-help-btn
- i.fa.fa-medkit
- | Help
- label.btn.btn-success#trigger-issue-modal
- i.fa.fa-bug
- | Bug
+ label.btn.btn-primary.btn-primary-ghost.btn-lg#trigger-reset-modal Reset
+ label.btn.btn-primary.btn-primary-ghost.hidden-sm.hidden-md.hidden-lg
+ a(href='//gitter.im/freecodecamp/help') Help
+ label.btn.btn-primary.btn-primary-ghost.hidden-xs.btn-lg#challenge-help-btn Help
+ label.btn.btn-primary.btn-primary-ghost.btn-lg#trigger-issue-modal Bug
script.
var userLoggedIn = true;
if (!user)
@@ -73,7 +65,7 @@ block content
if(user)
#submit-challenge.animated.fadeIn.btn.btn-lg.btn-primary.btn-block Submit and go to my next challenge (ctrl + enter)
else
- a#next-challenge.btn.btn-lg.btn-primary.btn-block(href="/challenges/next-challenge?id="+challengeId) Go to my next challenge (ctrl + enter)
+ a#next-challenge.btn.btn-lg.btn-primary.btn-block(href="/challenges/next-challenge?id="+id) Go to my next challenge (ctrl + enter)
include ../partials/challenge-modals
script(type="text/javascript").
$('#next-courseware-button').attr('disabled', 'disabled');
@@ -83,7 +75,7 @@ block content
common.head = !{JSON.stringify(head)};
common.tail = !{JSON.stringify(tail)};
- common.challengeId = !{JSON.stringify(challengeId)};
+ common.challengeId = !{JSON.stringify(id)};
common.challengeName = !{JSON.stringify(name)};
common.challengeSeed = !{JSON.stringify(challengeSeed)};
common.challengeType = !{JSON.stringify(challengeType)};
@@ -96,9 +88,3 @@ block content
});
include ../partials/challenge-footer
- script.
- document.addEventListener('gitter-sidecar-ready', function(e) {
- if (window.main) {
- window.main.chat.createHelpChat('freecodecamp/help', '#challenge-help-btn');
- }
- });
diff --git a/server/views/coursewares/showJS.jade b/server/views/challenges/showJS.jade
similarity index 72%
rename from server/views/coursewares/showJS.jade
rename to server/views/challenges/showJS.jade
index c4b2aa5386..5d353ef2a6 100644
--- a/server/views/coursewares/showJS.jade
+++ b/server/views/challenges/showJS.jade
@@ -8,45 +8,38 @@ block content
.col-md-4.col-lg-3
.scroll-locker(id = "scroll-locker")
.innerMarginFix(style = "width: 99%;")
- #testCreatePanel.well
- h3.text-center.negative-10= name
+ #testCreatePanel
+ h4.text-center= name
if (isCompleted)
|
i.ion-checkmark-circled.text-primary(title="Completed")
+ hr
.row
.col-xs-12
.bonfire-instructions
- for sentence in details
+ for sentence in description
if (/blockquote|h4|table/.test(sentence))
!=sentence
else
- p.wrappable.negative-10!= sentence
+ p.wrappable!= sentence
if (MDNlinks.length)
.negative-bottom-margin-30
#MDN-links
- p.negative-10 Here are some helpful links:
+ p Here are some helpful links:
for link, index in MDNlinks
- .negative-10
- ul: li: a(href="" + link, target="_blank") !{MDNkeys[index]}
+ ul: li: a(href="" + link, target="_blank") !{MDNkeys[index]}
+ .button-spacer
if (user)
form.form-horizontal(novalidate='novalidate', name='completedWithForm')
- .form-group.text-center.negative-10
+ .form-group.text-center
.col-xs-12
// extra field to distract password tools like lastpass from injecting css into our username field
- label.negative-10.btn.btn-primary.btn-lg.btn-block#submitButton
- i.fa.fa-play
- | Run tests (ctrl + enter)
+ label.btn.btn-primary.btn-big.btn-block#submitButton Run tests (ctrl + enter)
.button-spacer
.btn-group.input-group.btn-group-justified
- label.btn.btn-success#trigger-reset-modal
- i.fa.fa-refresh
- | Reset
- label.btn.btn-success#challenge-help-btn
- i.fa.fa-medkit
- | Help
- label.btn.btn-success#trigger-issue-modal
- i.fa.fa-bug
- | Bug
+ label.btn.btn-primary.btn-lg#trigger-reset-modal Reset
+ label.btn.btn-primary.btn-lg#challenge-help-btn Help
+ label.btn.btn-primary.btn-lg#trigger-issue-modal Bug
if (!user)
.button-spacer
a.btn.signup-btn.btn-block.btn-block(href='/login') Sign in so you can save your progress
@@ -57,7 +50,7 @@ block content
.form-group.codeMirrorView
textarea#codeOutput(style='display: none;')
br
- #testSuite.negative-10
+ #testSuite
br
.col-md-8.col-lg-9
.editorScrollDiv(style = "overflow-y: auto; overflow-x: hidden;")
@@ -80,7 +73,7 @@ block content
if (user)
#submit-challenge.animated.fadeIn.btn.btn-lg.btn-primary.btn-block Submit and go to my next challenge (ctrl + enter)
else
- a#next-challenge.animated.fadeIn.btn.btn-lg.btn-primary.btn-block(href="/challenges/next-challenge?id="+challengeId) Go to my next challenge (ctrl + enter)
+ a#next-challenge.animated.fadeIn.btn.btn-lg.btn-primary.btn-block(href="/challenges/next-challenge?id="+id) Go to my next challenge (ctrl + enter)
include ../partials/challenge-modals
script(type="text/javascript").
var common = window.common = { init: [] };
@@ -89,7 +82,7 @@ block content
common.head = !{JSON.stringify(head)};
common.tail = !{JSON.stringify(tail)};
- common.challengeId = !{JSON.stringify(challengeId)};
+ common.challengeId = !{JSON.stringify(id)};
common.challengeName = !{JSON.stringify(name)};
common.challengeSeed = !{JSON.stringify(challengeSeed)};
common.challengeType = !{JSON.stringify(challengeType)};
@@ -98,11 +91,9 @@ block content
include ../partials/challenge-footer
script.
- document.addEventListener('gitter-sidecar-ready', function(e) {
- if (window.main) {
- window.main.chat.createHelpChat('freecodecamp/help', '#challenge-help-btn');
- }
- });
+ if (!!{JSON.stringify(MDNlinks.length)}) {
+ $('#MDN-links').addClass('collapse');
+ }
common.init.push(function() {
common.editor.setOption('mode', 'javascript');
diff --git a/server/views/coursewares/showStep.jade b/server/views/challenges/showStep.jade
similarity index 72%
rename from server/views/coursewares/showStep.jade
rename to server/views/challenges/showStep.jade
index 53a120143e..fbbd614dc1 100644
--- a/server/views/coursewares/showStep.jade
+++ b/server/views/challenges/showStep.jade
@@ -3,25 +3,27 @@ block content
.row
.col-md-8.col-md-offset-2
for step, index in description
- .thumbnail.challenge-step(class=index !== 0 ? 'hidden': '')
+ .challenge-step(class=index !== 0 ? 'hidden': '')
a(href=step[0] data-lightbox='img-enlarge')
- img.gif-block.img-center.img-responsive.thumbnail(src='#{step[0]}' alt='#{step[1]}')
- .caption
- p.large-p!= step[2]
+ img.gif-block.img-center.img-responsive(src='#{step[0]}' alt='#{step[1]}')
+ .row
+ .col-xs-12.col-sm-10.col-sm-offset-1.col-md-8.col-md-offset-2
+ p!= step[2]
.challenge-button-block
if step[3]
- a.btn.btn-block.btn-primary.challenge-step-btn-action(id='#{index}' href='#{step[3]}' target='_blank') Open link in new tab (this unlocks the next step)
+ a.btn.btn-block.btn-primary.challenge-step-btn-action.btn-lg(id='#{index}' href='#{step[3]}' target='_blank') Open link in new tab (this unlocks the next step)
.button-spacer
if index === 0
.col-sm-5.hidden-xs
else
- .btn.btn-warning.col-sm-5.col-xs-12.challenge-step-btn-prev(id='#{index - 1}') Go to my previous step
+ .btn.btn-primary.btn-primary-ghost.col-sm-5.col-xs-12.challenge-step-btn-prev.btn-lg(id='#{index - 1}') Go to my previous step
.challenge-step-counter.large-p.col-sm-2.col-xs-12.text-center (#{index + 1} / #{description.length})
if index + 1 === description.length
- .btn.btn-primary.col-sm-5.col-xs-12.challenge-step-btn-finish(id='last' class=step[3] && !isCompleted ? 'disabled' : '') Finish challenge
+ .btn.btn-primary.col-sm-5.col-xs-12.challenge-step-btn-finish.btn-lg(id='last' class=step[3] && !isCompleted ? 'disabled' : '') Finish challenge
else
- .btn.btn-primary.col-sm-5.col-xs-12.challenge-step-btn-next(id='#{index}' class=step[3] && !isCompleted ? 'disabled' : '') Go to my next step
+ .btn.btn-primary.col-sm-5.col-xs-12.challenge-step-btn-next.btn-lg(id='#{index}' class=step[3] && !isCompleted ? 'disabled' : '') Go to my next step
.clearfix
+ .spacer
#challenge-step-modal.modal(tabindex='-1')
.modal-dialog.animated.fadeIn.fast-animation
.modal-content
@@ -37,11 +39,11 @@ block content
if (user)
#challenge-step-btn-submit.animated.fadeIn.btn.btn-lg.btn-primary.btn-block Submit and go to my next challenge
else
- a.btn.btn-lg.btn-primary.btn-block(href='/challenges/next-challenge?id=' + challengeId) Go to my next challenge
+ a.btn.btn-lg.btn-primary.btn-block(href='/challenges/next-challenge?id=' + id) Go to my next challenge
script.
var common = window.common || { init: [] };
- common.challengeId = !{JSON.stringify(challengeId)};
+ common.challengeId = !{JSON.stringify(id)};
common.challengeName = !{JSON.stringify(name)};
common.challengeType = !{JSON.stringify(challengeType)};
common.dashedName = !{JSON.stringify(dashedName || '')};
diff --git a/server/views/coursewares/showVideo.jade b/server/views/challenges/showVideo.jade
similarity index 70%
rename from server/views/coursewares/showVideo.jade
rename to server/views/challenges/showVideo.jade
index df8d00dc92..62a0de1aa9 100644
--- a/server/views/coursewares/showVideo.jade
+++ b/server/views/challenges/showVideo.jade
@@ -2,16 +2,15 @@ extends ../layout-wide
block content
.row
.col-xs-12.col-sm-12.col-md-4.bonfire-top
- h1.text-center= name
- .well
- h4
- ol
- for step, index in details
- .row.checklist-element(id="#{dashedName + index}")
- .col-xs-3.col-sm-1.col-md-2.padded-ionic-icon.text-center
- input(type='checkbox' class='challenge-list-checkbox')
- .col-xs-9.col-sm-11.col-md-10
- li.step-text.wrappable!= step
+ h4.text-center= name
+ hr
+ ol
+ for step, index in description
+ .row.checklist-element(id="#{dashedName + index}")
+ .col-xs-3.col-sm-1.col-md-2.padded-ionic-icon.text-center
+ input(type='checkbox' class='challenge-list-checkbox')
+ .col-xs-9.col-sm-11.col-md-10
+ li.step-text.wrappable!= step
.col-xs-12.col-sm-12.col-md-8
.embed-responsive.embed-responsive-16by9
iframe.embed-responsive-item(src='//player.vimeo.com/video/#{video}')
@@ -19,17 +18,13 @@ block content
if (user)
a.btn.btn-primary.btn-big.btn-block#completed-courseware-editorless I've completed this challenge (ctrl + enter)
else
- a.btn.btn-big.btn-primary.btn-block(href='/challenges/next-challenge?id=' + challengeId) I've completed this challenge (ctrl + enter)
+ a.btn.btn-big.btn-primary.btn-block(href='/challenges/next-challenge?id=' + id) I've completed this challenge (ctrl + enter)
script.
var userLoggedIn = true;
.button-spacer
.btn-group.input-group.btn-group-justified
- .btn.btn-success.btn-big#challenge-help-btn
- i.fa.fa-medkit
- | Get help
- .btn.btn-success.btn-big#trigger-issue-modal
- i.fa.fa-bug
- | Report a bug
+ .btn.btn-primary.btn-big#challenge-help-btn Get help
+ .btn.btn-primary.btn-big#trigger-issue-modal Report a bug
if (!user)
.button-spacer
a.btn.btn-big.signup-btn.btn-block(href='/login') Sign in so you can save your progress
@@ -51,13 +46,13 @@ block content
if (user)
a.btn.btn-lg.btn-primary.btn-block#next-courseware-button(name='_csrf', value=_csrf) I've completed this challenge (ctrl + enter)
else
- a.animated.fadeIn.btn.btn-lg.btn-primary.btn-block(href='/challenges/next-challenge?id=' + challengeId) I've completed this challenge (ctrl + enter)
+ a.animated.fadeIn.btn.btn-lg.btn-primary.btn-block(href='/challenges/next-challenge?id=' + id) I've completed this challenge (ctrl + enter)
include ../partials/challenge-modals
script.
var common = window.common || { init: [] };
- common.challengeId = !{JSON.stringify(challengeId)};
+ common.challengeId = !{JSON.stringify(id)};
common.challengeName = !{JSON.stringify(name)};
common.challengeType = !{JSON.stringify(challengeType)};
common.dashedName = !{JSON.stringify(dashedName)};
@@ -91,9 +86,4 @@ block content
});
});
- document.addEventListener('gitter-sidecar-ready', function(e) {
- if (window.main) {
- window.main.chat.createHelpChat('freecodecamp/help', '#challenge-help-btn');
- }
- });
include ../partials/challenge-footer
diff --git a/server/views/coursewares/showZiplineOrBasejump.jade b/server/views/challenges/showZiplineOrBasejump.jade
similarity index 75%
rename from server/views/coursewares/showZiplineOrBasejump.jade
rename to server/views/challenges/showZiplineOrBasejump.jade
index 03c1ebb19e..e2a0db3783 100644
--- a/server/views/coursewares/showZiplineOrBasejump.jade
+++ b/server/views/challenges/showZiplineOrBasejump.jade
@@ -2,17 +2,16 @@ extends ../layout-wide
block content
.row
.col-md-4.bonfire-top
- h1.text-center= name
- .well
- h4
- ol
- for step, index in details
- .row.checklist-element(id="#{dashedName + index}")
- .col-xs-3.col-sm-1.col-md-2.padded-ionic-icon.text-center
- input(type='checkbox' class='challenge-list-checkbox')
- .col-xs-9.col-sm-11.col-md-10
- li.step-text.wrappable!= step
- .col-md-8
+ h4.text-center= name
+ hr
+ ol
+ for step, index in description
+ .row.checklist-element(id="#{dashedName + index}")
+ .col-xs-3.col-sm-1.col-md-2.padded-ionic-icon.text-center
+ input(type='checkbox' class='challenge-list-checkbox')
+ .col-xs-9.col-sm-11.col-md-10
+ li.step-text.wrappable!= step
+ .col-xs-12.col-sm-12.col-md-8
.embed-responsive.embed-responsive-16by9
iframe.embed-responsive-item(src='//player.vimeo.com/video/#{video}')
br
@@ -21,15 +20,11 @@ block content
script.
var userLoggedIn = true;
else
- a.btn.btn-big.btn-primary.btn-block(href='/challenges/next-challenge?id=' + challengeId) Go to my next challenge (ctrl + enter)
+ a.btn.btn-big.btn-primary.btn-block(href='/challenges/next-challenge?id=' + id) Go to my next challenge (ctrl + enter)
.button-spacer
.btn-group.input-group.btn-group-justified
- .btn.btn-success.btn-big#challenge-help-btn
- i.fa.fa-medkit
- | Help
- .btn.btn-success.btn-big#trigger-issue-modal
- i.fa.fa-bug
- | Bug
+ .btn.btn-primary.btn-primary-ghost.btn-big#challenge-help-btn Help
+ .btn.btn-primary.btn-primary-ghost.btn-big#trigger-issue-modal Bug
if (!user)
.button-spacer
a.btn.btn-big.signup-btn.btn-block(href='/login') Sign in so you can save your progress
@@ -65,12 +60,12 @@ block content
a.btn.btn-lg.btn-block.btn-twitter(target="_blank", href="https://twitter.com/intent/tweet?text=Check%20out%20the%20project%20I%20just%20built%20with%20%40FreeCodeCamp:%20PASTE_YOUR_CODEPEN_URL_HERE_USING_FULL_INSTEAD_OF_PEN%20%0A%20%23LearnToCode%20%23JavaScript", onclick="ga('send', 'event', 'twitter', 'share', 'challenge completion share');")
i.fa.fa-twitter Tweet this project
else
- a.btn.btn-lg.btn-primary.btn-block(href='/challenges/next-challenge?id=' + challengeId) Go to my next challenge
+ a.btn.btn-lg.btn-primary.btn-block(href='/challenges/next-challenge?id=' + id) Go to my next challenge
include ../partials/challenge-modals
script.
var common = window.common || { init: [] };
- common.challengeId = !{JSON.stringify(challengeId)};
+ common.challengeId = !{JSON.stringify(id)};
common.challengeName = !{JSON.stringify(name)};
common.dashedName = !{JSON.stringify(dashedName)};
common.challengeType = !{JSON.stringify(challengeType)};
@@ -110,25 +105,4 @@ block content
$('#complete-zipline-or-basejump-dialog').modal('show');
});
});
-
-
-
- document.addEventListener('gitter-sidecar-ready', function(e) {
- var room = 'freecodecamp/help';
- var title;
-
- if (common.challengeType === '4') {
- room = 'freecodecamp/helpBasejumps';
- title = 'Basejump Help';
- }
-
- if (common.challengeType === '3') {
- room = 'freecodecamp/helpZiplines';
- title = 'Zipline Help';
- }
-
- if (window.main) {
- window.main.chat.createHelpChat(room, '#challenge-help-btn', title);
- }
- });
include ../partials/challenge-footer
diff --git a/server/views/commit/directory.jade b/server/views/commit/directory.jade
index e27ba5f1cd..d2e86ef426 100644
--- a/server/views/commit/directory.jade
+++ b/server/views/commit/directory.jade
@@ -1,15 +1,14 @@
extends ../layout
block content
- .panel.panel-info
- .panel-heading.text-center Commit to one of these nonprofits
- .panel-body
- .row
- .col-xs-12.col-sm-10.col-sm-offset-1
- for nonprofit in nonprofits
- .col-xs-12.col-sm-6.col-md-4.height-400
- .text-center
- h2= nonprofit.displayName
- img.testimonial-image.img-responsive.img-center(src=nonprofit.imgUrl)
- .button-spacer
- a.text-center(href='/commit?nonprofit=#{nonprofit.name}') Commit to #{nonprofit.displayName}
- p= nonprofit.description
+ h1.text-center Commit to one of these nonprofits
+ hr
+ .row
+ .col-xs-12.col-sm-10.col-sm-offset-1
+ for nonprofit in nonprofits
+ .col-xs-12.col-sm-6.col-md-4.height-400
+ .text-center
+ h2= nonprofit.displayName
+ img.testimonial-image.img-responsive.img-center(src=nonprofit.imgUrl)
+ .button-spacer
+ a.text-center(href='/commit?nonprofit=#{nonprofit.name}') Commit to #{nonprofit.displayName}
+ p= nonprofit.description
diff --git a/server/views/commit/index.jade b/server/views/commit/index.jade
index e9a919fd5a..722654e64c 100644
--- a/server/views/commit/index.jade
+++ b/server/views/commit/index.jade
@@ -1,86 +1,84 @@
extends ../layout
block content
- .panel.panel-info
- .panel-body
- h2.text-center Commit to yourself. Commit to a nonprofit.
- .row
- .col-xs-12.col-sm-6.col-sm-offset-3
- p Give yourself external motivation and help nonprofits right away. Pledge a monthly donation to a nonprofit until you’ve earned either your Front End or Full Stack Development Certification.
+ h2.text-center Commit to yourself. Commit to a nonprofit.
+ .row
+ .col-xs-12.col-sm-6.col-sm-offset-3
+ p Give yourself external motivation and help nonprofits right away. Pledge a monthly donation to a nonprofit until you’ve earned either your Front End or Full Stack Development Certification.
- .row
- .col-xs-12.col-sm-6.col-sm-offset-3.text-center
- h3 Pledge to #{displayName}
- .button-spacer
- a(href='#{imgUrl}' data-lightbox='img-enlarge' alt='#{imgAlt}')
- img.img-responsive(src='#{imgUrl}' alt='#{imgAlt}')
- p.large-p
- = description
- a(href='/commit/directory') ...or see other nonprofits
- .spacer
- form.form(name='commit')
- .hidden
- input(type='text' value='#{name}' name='nonprofit')
- .row
- .col-xs-12.col-sm-6.col-sm-offset-3
- h3 Step 1: Which certification do you pledge to complete?
- .btn-group.btn-group-justified(data-toggle='buttons' role='group')
- label.btn.btn-primary.btn-lg.active
- input(type='radio' id=frontEndCert value=frontEndCert name='goal' checked="checked")
- | Front End
- label.btn.btn-primary.btn-lg
- input(type='radio' id=dataVisCert value=dataVisCert name='goal')
- | Data
- label.btn.btn-primary.btn-lg
- input(type='radio' id=backEndCert value=backEndCert name='goal')
- | Back End
- label.btn.btn-primary.btn-lg
- input(type='radio' id=fullStackCert value=fullStackCert name='goal')
- | Full Stack
- .spacer
- .row
- .col-xs-12.col-sm-6.col-sm-offset-3
- h3 Step 2: How much do you want to pledge monthly until you earn that certification?
- .btn-group.btn-group-justified(data-toggle='buttons' role='group')
- label.btn.btn-success
- input(type='radio' id='5-dollar-pledge' value='5' name='amount')
- | $5 per month
- label.btn.btn-success.active
- input(type='radio' id='10-dollar-pledge' value='10' name='amount' checked="checked")
- | $10 per month
- label.btn.btn-success
- input(type='radio' id='25-dollar-pledge' value='25' name='amount')
- | $25 per month
- label.btn.btn-success
- input(type='radio' id='50-dollar-pledge' value='50' name='amount')
- | $50 per month
- .spacer
- .col-xs-12.col-sm-6.col-sm-offset-3
- h3 Step 3: Set up your monthly donation
- .row
- .col-xs-12.col-sm-6.col-sm-offset-3.text-center
- a#commit-btn-donate.btn.btn-block.btn-lg.btn-primary(href=donateUrl target='_blank') Open the #{displayName} donation page
+ .row
+ .col-xs-12.col-sm-6.col-sm-offset-3.text-center
+ h3 Pledge to #{displayName}
+ .button-spacer
+ a(href='#{imgUrl}' data-lightbox='img-enlarge' alt='#{imgAlt}')
+ img.img-responsive(src='#{imgUrl}' alt='#{imgAlt}')
+ p.large-p
+ = description
+ p
+ a(href='/commit/directory') ...or see other nonprofits
+ .spacer
+ form.form(name='commit')
+ .hidden
+ input(type='text' value='#{name}' name='nonprofit')
+ .row
+ .col-xs-12.col-sm-6.col-sm-offset-3
+ h3 Step 1: Which certification do you pledge to complete?
+ .btn-group.btn-group-justified(data-toggle='buttons' role='group')
+ label.btn.btn-primary.btn-lg.active
+ input(type='radio' id=frontEndCert value=frontEndCert name='goal' checked="checked")
+ | Front End
+ label.btn.btn-primary.btn-lg
+ input(type='radio' id=dataVisCert value=dataVisCert name='goal')
+ | Data
+ label.btn.btn-primary.btn-lg
+ input(type='radio' id=backEndCert value=backEndCert name='goal')
+ | Back End
+ label.btn.btn-primary.btn-lg
+ input(type='radio' id=fullStackCert value=fullStackCert name='goal')
+ | Full Stack
+ .spacer
+ .row
+ .col-xs-12.col-sm-6.col-sm-offset-3
+ h3 Step 2: How much do you want to pledge monthly until you earn that certification?
+ .btn-group.btn-group-justified(data-toggle='buttons' role='group')
+ label.btn.btn-primary
+ input(type='radio' id='5-dollar-pledge' value='5' name='amount')
+ | $5 per month
+ label.btn.btn-primary.active
+ input(type='radio' id='10-dollar-pledge' value='10' name='amount' checked="checked")
+ | $10 per month
+ label.btn.btn-primary
+ input(type='radio' id='25-dollar-pledge' value='25' name='amount')
+ | $25 per month
+ label.btn.btn-primary
+ input(type='radio' id='50-dollar-pledge' value='50' name='amount')
+ | $50 per month
+ .spacer
+ .col-xs-12.col-sm-6.col-sm-offset-3
+ h3 Step 3: Set up your monthly donation
+ .row
+ .col-xs-12.col-sm-6.col-sm-offset-3.text-center
+ a#commit-btn-donate.btn.btn-block.btn-lg.btn-primary(href=donateUrl target='_blank') Open the #{displayName} donation page
- .spacer
- .col-xs-12.col-sm-6.col-sm-offset-3
- h3#commit-step4-text.disabled
- Step 4: Confirm
- span#commit-step4-hidden.disabled (Do step 3 first)
- span#commit-step4-show.hidden your commitment to your goal
- .row
- .col-xs-12.col-sm-6.col-sm-offset-3.text-center
- button#commit-btn-submit.btn.btn-block.btn-lg.btn-primary.disabled Commit
+ .spacer
+ .col-xs-12.col-sm-6.col-sm-offset-3
+ h3#commit-step4-text.disabled
+ Step 4: Confirm
+ span#commit-step4-hidden.disabled (Do step 3 first)
+ span#commit-step4-show.hidden your commitment to your goal
+ .row
+ .col-xs-12.col-sm-6.col-sm-offset-3.text-center
+ button#commit-btn-submit.btn.btn-block.btn-lg.btn-primary.disabled Commit
- if pledge
- form.row(name='stop-pledge' action='/commit/stop-commitment' method='post')
- .col-xs-12.col-sm-6.col-sm-offset-3.text-center
- .button-spacer
- button.btn.btn-block.btn-lg.btn-default(name='submit' type='submit') Stop my current pledge
- else
- .row
- .col-xs-12.col-sm-6.col-sm-offset-3.text-center
- .button-spacer
- a.btn.btn-block.btn-lg.btn-default(href='/map') Maybe later
- .spacer
+ if pledge
+ form.row(name='stop-pledge' action='/commit/stop-commitment' method='post')
+ .col-xs-12.col-sm-6.col-sm-offset-3.text-center
+ .button-spacer
+ button.btn.btn-block.btn-lg.btn-default(name='submit' type='submit') Stop my current pledge
+ else
+ .row
+ .col-xs-12.col-sm-6.col-sm-offset-3.text-center
+ .button-spacer
+ a.btn.btn-block.btn-lg.btn-default(href='/map') Maybe later
script.
$(function() {
$('#commit-btn-donate').click(function() {
diff --git a/server/views/coursewares/showVideo.html b/server/views/coursewares/showVideo.html
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/server/views/coursewares/showZiplineOrBasejump.html b/server/views/coursewares/showZiplineOrBasejump.html
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/server/views/home.jade b/server/views/home.jade
index 68b69c5c03..61a99b102e 100644
--- a/server/views/home.jade
+++ b/server/views/home.jade
@@ -1,107 +1,109 @@
extends layout
block content
- .jumbotron
- .text-center
- h1.landing-heading Learn to code and help nonprofits.
- .spacer
- .row
- .col-xs-12.col-sm-12.col-md-3
- h3.nowrap Get connected
- img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_connect.svg.gz', alt='Get great references and connections to start your software engineer career')
- p.landing-p Join a community of 100,000+ motivated people.
- .col-xs-12.col-sm-12.col-md-3
- h3.nowrap Learn JavaScript
- img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_learn.svg.gz', alt='Learn to code and learn full stack JavaScript')
- 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.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_portfolio.svg.gz', alt='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.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_nonprofits.svg.gz', alt='Help empower nonprofits with code')
- p.landing-p Give nonprofits a boost by empowering them with code.
+ .text-center
+ h1.landing-heading Learn to code and help nonprofits.
+ .spacer
+ .row
.big-break
- .row
- .col-xs-12.col-sm-8.col-sm-offset-2
- a.btn.btn-cta.signup-btn.btn-block(href="/signin") Start learning to code (it's free)
- .button-spacer
- a.btn.btn-lg.btn-primary.btn-primary-ghost.btn-block(href="/nonprofits") My nonprofit needs coding help
- .spacer
- h2 As featured in:
- img.img-center.img-responsive(src='https://s3.amazonaws.com/freecodecamp/as-seen-on.png')
- .spacer
- hr
- .spacer
- h2 Launch your career as a software engineer:
- .spacer
- .row
- .col-xs-12.col-sm-12.col-md-4
- img.img-responsive.testimonial-image.img-center(src="http://i.imgur.com/nsvNixW.jpg", alt="Meta's testimonial image")
- p.testimonial-copy Through Free Code Camp, I built a robust and highly functional web app for a nonprofit. This led me to getting a fantastic job.
- h3 - Meta Hirschl
- .col-xs-12.col-sm-12.col-md-4
- img.img-responsive.testimonial-image.img-center(src="http://i.imgur.com/QPpjPac.jpg", alt="Brian's testimonial image")
- p.testimonial-copy Free Code Camp's a great way for disabled veterans like me to retrain. I'm receiving engineering job offers, and I haven't even finished yet.
- h3 - Brian Grant
- .col-xs-12.col-sm-12.col-md-4
- img.img-responsive.testimonial-image.img-center(src="http://i.imgur.com/wjlDigg.jpg", alt="Maxim Orlov's testimonial image")
- p.testimonial-copy I started Free Code Camp with zero knowledge of web development. 6 months later, I landed my first job as a back end engineer.
- h3 - Maxim Orlov
- .spacer
- .row
- .col-xs-12.col-sm-8.col-sm-offset-2
- a.btn.btn-lg.btn-primary.btn-primary-ghost.btn-block(href='/stories') Hear from more of our campers
- .spacer
- .spacer
- hr
- .spacer
- h2 Skills you'll learn:
- .spacer
- .row
- .text-center.negative-35
- .col-xs-12.col-sm-12.col-md-3
- .landing-skill-icon.ion-social-html5
- h2.black-text HTML5
- .col-xs-12.col-sm-12.col-md-3
- .landing-skill-icon.ion-social-css3
- h2.black-text CSS3
- .col-xs-12.col-sm-12.col-md-3
- .landing-skill-icon.ion-social-javascript
- h2.black-text JavaScript
- .col-xs-12.col-sm-12.col-md-3
- .landing-skill-icon.fa.fa-database.font-awesome-padding
- h2.black-text Databases
- .col-xs-12.col-sm-12.col-md-3
- .landing-skill-icon.ion-social-github
- h2.black-text Git & GitHub
- .col-xs-12.col-sm-12.col-md-3
- .landing-skill-icon.ion-social-nodejs
- h2.black-text Node.js
- .col-xs-12.col-sm-12.col-md-3
- .landing-skill-icon.custom-landing-skill-icon
- img(src='https://s3.amazonaws.com/freecodecamp/react.svg')
- h2.black-text React.js
- .col-xs-12.col-sm-12.col-md-3
- .landing-skill-icon.custom-landing-skill-icon
- img(src='https://s3.amazonaws.com/freecodecamp/d3-logo.svg')
- h2.black-text D3.js
- .spacer
- hr
- .spacer
- .col-xs-offset-0.col-sm-offset-1.text-left
- h2 Here's why you should join our open source community right now:
- ul.large-li
- li.ion-code You'll get help in real time from our community chat rooms.
- li.ion-code You'll meet up with other coders in your city.
- li.ion-code You'll learn to code at your own pace, in your browser or on your phone.
- li.ion-code You'll work through our focused, interactive courses and tutorials.
- li.ion-code You'll learn state-of-the-art full stack JavaScript technologies.
- li.ion-code You'll build projects that help nonprofits carry out their missions more effectively.
- li.ion-code You'll assemble a portfolio of real apps used by real people.
.big-break
- .row
- .col-xs-12.col-sm-8.col-sm-offset-2
- a.btn.btn-cta.signup-btn.btn-block(href="/signin") Learn to code today (it's free)
- script.
- challengeName = 'Home'
+ .big-break
+ .col-xs-12.col-sm-12.col-md-3
+ img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_connect.svg', alt='Get great references and connections to start your software engineer career')
+ p.large-p Join a community of 100,000+ developers.
+ .col-xs-12.col-sm-12.col-md-3
+ img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_learn.svg', alt='Learn to code and learn full stack JavaScript')
+ p.large-p Work together on coding challenges.
+ .col-xs-12.col-sm-12.col-md-3
+ img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_portfolio.svg', alt='Build a portfolio of apps for nonprofits')
+ p.large-p Build a portfolio of apps that solve real problems.
+ .col-xs-12.col-sm-12.col-md-3
+ img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_nonprofits.svg', alt='Help empower nonprofits with code')
+ p.large-p Empowering nonprofits with code.
+ .big-break
+ .big-break
+ .big-break
+ .big-break
+ .row
+ .col-xs-12.col-sm-8.col-sm-offset-2
+ a.btn.btn-cta.signup-btn.btn-block(href="/signin") Start learning to code (it's free)
+ .button-spacer
+ a.btn.btn-lg.btn-primary.btn-primary-ghost.btn-block(href="/nonprofits") My nonprofit needs coding help
+ .spacer
+ h2 As featured in:
+ img.img-center.img-responsive(src='https://s3.amazonaws.com/freecodecamp/as-seen-on.png')
+ .spacer
+ hr
+ .spacer
+ h2 Launch your career as a software engineer:
+ .spacer
+ .row
+ .col-xs-12.col-sm-12.col-md-4
+ img.img-responsive.testimonial-image.img-center(src="http://i.imgur.com/nsvNixW.jpg", alt="Meta's testimonial image")
+ p.testimonial-copy Through Free Code Camp, I built a robust and highly functional web app for a nonprofit. This led me to getting a fantastic job.
+ h3 - Meta Hirschl
+ .col-xs-12.col-sm-12.col-md-4
+ img.img-responsive.testimonial-image.img-center(src="http://i.imgur.com/QPpjPac.jpg", alt="Brian's testimonial image")
+ p.testimonial-copy Free Code Camp's a great way for disabled veterans like me to retrain. I'm receiving engineering job offers, and I haven't even finished yet.
+ h3 - Brian Grant
+ .col-xs-12.col-sm-12.col-md-4
+ img.img-responsive.testimonial-image.img-center(src="http://i.imgur.com/wjlDigg.jpg", alt="Maxim Orlov's testimonial image")
+ p.testimonial-copy I started Free Code Camp with zero knowledge of web development. 6 months later, I landed my first job as a back end engineer.
+ h3 - Maxim Orlov
+ .spacer
+ .row
+ .col-xs-12.col-sm-8.col-sm-offset-2
+ a.btn.btn-lg.btn-primary.btn-primary-ghost.btn-block(href='/stories') Hear from more of our campers
+ .spacer
+ .spacer
+ hr
+ .spacer
+ h2 Skills you'll learn:
+ .spacer
+ .row
+ .text-center.negative-35
+ .col-xs-12.col-sm-12.col-md-3
+ .landing-skill-icon.ion-social-html5
+ h2.black-text HTML5
+ .col-xs-12.col-sm-12.col-md-3
+ .landing-skill-icon.ion-social-css3
+ h2.black-text CSS3
+ .col-xs-12.col-sm-12.col-md-3
+ .landing-skill-icon.ion-social-javascript
+ h2.black-text JavaScript
+ .col-xs-12.col-sm-12.col-md-3
+ .landing-skill-icon.fa.fa-database.font-awesome-padding
+ h2.black-text Databases
+ .col-xs-12.col-sm-12.col-md-3
+ .landing-skill-icon.ion-social-github
+ h2.black-text Git & GitHub
+ .col-xs-12.col-sm-12.col-md-3
+ .landing-skill-icon.ion-social-nodejs
+ h2.black-text Node.js
+ .col-xs-12.col-sm-12.col-md-3
+ .landing-skill-icon.custom-landing-skill-icon
+ img(src='https://s3.amazonaws.com/freecodecamp/react.svg')
+ h2.black-text React.js
+ .col-xs-12.col-sm-12.col-md-3
+ .landing-skill-icon.custom-landing-skill-icon
+ img(src='https://s3.amazonaws.com/freecodecamp/d3-logo.svg')
+ h2.black-text D3.js
+ .spacer
+ hr
+ .spacer
+ .col-xs-offset-0.col-sm-offset-1.text-left.large-p
+ h2 Here's why you should join our open source community right now:
+ .spacer
+ ul.large-li
+ li.ion-code You'll get help in real time from our community chat rooms.
+ li.ion-code You'll meet up with other coders in your city.
+ li.ion-code You'll learn to code at your own pace, in your browser or on your phone.
+ li.ion-code You'll work through our focused, interactive courses and tutorials.
+ li.ion-code You'll learn state-of-the-art full stack JavaScript technologies.
+ li.ion-code You'll build projects that help nonprofits carry out their missions more effectively.
+ li.ion-code You'll assemble a portfolio of real apps used by real people.
+ .big-break
+ .row
+ .col-xs-12.col-sm-8.col-sm-offset-2
+ a.btn.btn-cta.signup-btn.btn-block(href="/signin") Learn to code today (it's free)
+ script.
+ challengeName = 'Home'
diff --git a/server/views/layout-wide.jade b/server/views/layout-wide.jade
index df33c7b4aa..f9ada9ed56 100644
--- a/server/views/layout-wide.jade
+++ b/server/views/layout-wide.jade
@@ -3,9 +3,14 @@ html(lang='en')
head
include partials/meta
include partials/stylesheets
- body.no-top-and-bottom-margins.full-screen-body-background
- include partials/scripts
- include partials/navbar
- include partials/flash
- block content
- include partials/footer
+ if showAside
+ body.map-aside-body
+ include partials/scripts
+ block content
+ else
+ body.no-top-and-bottom-margins.full-screen-body-background
+ include partials/scripts
+ include partials/navbar
+ include partials/flash
+ block content
+ include partials/footer
diff --git a/server/views/map/show.jade b/server/views/map/show.jade
new file mode 100644
index 0000000000..477c6777f4
--- /dev/null
+++ b/server/views/map/show.jade
@@ -0,0 +1,69 @@
+extends ../layout-wide
+block content
+ .row
+ .col-xs-12.col-md-6.col-md-offset-3
+ for superBlock, index in superBlocks
+ if index > 0
+ .row
+ h2.text-center #{superBlock.name}
+ .text-center.small Requires completion of the below challenges marked with a *
+ hr
+ for challengeBlock in superBlock.blocks
+ .row
+ a(href='#' name=challengeBlock.dashedName)
+ .spacer.negative-55
+ .row
+ h3.bold #{challengeBlock.name} (#{challengeBlock.time})
+ for challenge in challengeBlock.challenges
+ .col-xs-12.col-sm-9.col-md-10
+ if challenge.completed
+ p.text-primary.ion-checkmark-circled.padded-ionic-icon.negative-15(name="#{challenge.dashedName}")
+ a(href="/challenges/#{challenge.dashedName}" target='_parent')
+ = challenge.title
+ span.sr-only= " Complete"
+ else if challenge.isRequired
+ p.ion-ios-circle-outline.padded-ionic-icon.negative-15(name="#{challenge.dashedName}")
+ a(name="#{challenge.dashedName}" target='_parent' href="/challenges/#{challenge.dashedName}" class=challenge.isComingSoon ? 'disabled' : '')
+ span= challenge.title
+ span.sr-only= " Incomplete"
+ if challenge.markNew
+ span.text-success.small
+ strong
+ em New
+ if challengeBlock.isComingSoon
+ span.text-success.small
+ strong
+ em Coming Soon
+ span.text-primary
+ strong *
+ else
+ p.ion-ios-circle-outline.padded-ionic-icon.negative-15(name="#{challenge.dashedName}")
+ a(name="#{challenge.dashedName}" target='_parent' href="/challenges/#{challenge.dashedName}" class=challenge.isComingSoon ? 'disabled' : '')
+ span= challenge.title
+ span.sr-only= " Incomplete"
+ if challenge.markNew
+ span.text-success.small
+ strong
+ em New
+ if challengeBlock.isComingSoon
+ span.text-success.small
+ strong
+ em Coming Soon
+ .row
+ h2.text-center Full Stack Development Certification
+ hr
+ p.ion-locked.padded-ionic-icon.negative-15 Greenfield Nonprofit Project 1
+ p.ion-locked.padded-ionic-icon.negative-15 Greenfield Nonprofit Project 2
+ p.ion-locked.padded-ionic-icon.negative-15 Legacy Nonprofit Project 1
+ p.ion-locked.padded-ionic-icon.negative-15 Legacy Nonprofit Project 2
+ p.ion-locked.padded-ionic-icon.negative-15 Claim your Full Stack Development Certification
+
+ .row
+ h2.text-center Coding Interview Preparation
+ hr
+ p.ion-locked.padded-ionic-icon.negative-15 Whiteboard Coding Interview Training
+ p.ion-locked.padded-ionic-icon.negative-15 Critical Thinking Interview Training
+ p.ion-locked.padded-ionic-icon.negative-15 Mock Interview 1
+ p.ion-locked.padded-ionic-icon.negative-15 Mock Interview 2
+ p.ion-locked.padded-ionic-icon.negative-15 Mock Interview 3
+ .spacer
diff --git a/server/views/nonprofits/directory.jade b/server/views/nonprofits/directory.jade
deleted file mode 100644
index e30a6671fd..0000000000
--- a/server/views/nonprofits/directory.jade
+++ /dev/null
@@ -1,27 +0,0 @@
-extends ../layout
-block content
- script.
- var challengeName = 'Nonprofits View';
- .col-xs-12.col-sm-12.col-md-12
- .panel.panel-info
- .panel-heading.text-center Nonprofits We Help
- .panel-body
- .col-xs-12.col-sm-12.col-md-10.col-md-offset-1
- h1.text-primary.text-center Our campers have saved nonprofits $#{totalSavings}.
- .spacer
- for nonprofit in nonprofits
- .spacer
- .row
- .col-xs-12.col-sm-3
- img.img-responsive.img-center(src=nonprofit.logoUrl)
- .col-xs-12.col-sm-9
- h2.negative-15= nonprofit.name
- h3.negative-15= nonprofit.whatDoesNonprofitDo
- if (nonprofit.moneySaved > 0)
- h4.negative-15.text-primary Estimated Cost Savings for Nonprofit: $#{nonprofit.moneySaved.toString().replace(/000$/, ',000')}
- a.text-center.btn.btn-primary.btn-lg(href='/nonprofits/' + nonprofit.name.toLowerCase().replace(/\s/g, '-')) Read more
- .spacer
- .col-xs-12.col-sm-8.col-sm-offset-2
- if (!user)
- a.btn.btn-cta.signup-btn.btn-block(href="/nonprofits-form") My nonprofit needs coding help
- .spacer
diff --git a/server/views/nonprofits/show.jade b/server/views/nonprofits/show.jade
deleted file mode 100644
index f408a70aab..0000000000
--- a/server/views/nonprofits/show.jade
+++ /dev/null
@@ -1,78 +0,0 @@
-extends ../layout
-block content
- script.
- var challengeName = 'Nonprofits View';
- .panel.panel-info
- .panel-heading.text-center= title
- .panel-body
- .row
- .col-xs-12.col-sm-10.col-sm-offset-1
- .row
- .col-xs-12
- img.img-center.img-responsive(src=imageUrl)
- .spacer
- .row
- .col-xs-12.col-sm-4
- img.img-responsive(src=logoUrl)
- .col-xs-12.col-sm-8
- .col-xs-12
- h4= whatDoesNonprofitDo
- h4
- a(href=websiteLink)= websiteLink
- .spacer
- h3 Project Description:
- .col-xs-12
- h4.negative-15 #{projectDescription} (About #{estimatedHours} hours per camper)
- .spacer
- h3 This project involves building:
- h4.negative-15.col-xs-12
- if (approvedWebsite)
- .ion-android-globe Website
- if (approvedDonor)
- .ion-card Donor Management System
- if (approvedInventory)
- .ion-ios-box Inventory Management System
- if (approvedVolunteer)
- .ion-android-calendar Volunteer Management System
- if (approvedForm)
- .ion-ios-list Webform
- if (approvedCommunity)
- .ion-ios-people Community Management System
- if (approvedELearning)
- .ion-university E-learning Platform
- if (approvedOther)
- .ion-settings Other tools
- h3 Project Status: #{currentStatus}
- if (moneySaved > 0)
- h3.text-primary Estimated Cost Savings for Nonprofit: $#{moneySaved.toString().replace(/000$/, ',000')}
-
- if (interestedCampers && interestedCampers.length > 0)
- h3 Interested campers:
- .col-xs-12.text-left
- for interestedCamper in interestedCampers
- a(href='/' + interestedCamper.username class="interested-camper-image")
- img.profile-picture.float-right(src=interestedCamper.picture)
- if (assignedCampers && assignedCampers.length > 0)
- h3 Assigned campers:
- .col-xs-12.text-left
- for assignedCamper in assignedCampers
- a(href='/' + assignedCamper.username class="interested-camper-image")
- img.profile-picture.float-right(src=assignedCamper.picture)
- if (!buttonActive)
- .col-xs-12.col-sm-8.col-sm-offset-2
- .text-center
- if !user
- a.btn.btn-cta.signup-btn.btn-block(href="/login") Start learning to code (it's free)
- .button-spacer
- else
- a.btn.btn-primary.btn-big.btn-block.disabled(href='/nonprofits/interested-in-nonprofit/#{dashedName}') I'm interested in building this project *
- p * Complete all our Bonfires, Ziplines, and Basejumps to unlock this.
- a.btn.btn-info.btn-big.btn-block(href='/nonprofits/directory') Show all Nonprofit Projects
- .spacer
- if (buttonActive)
- .col-xs-12.col-sm-8.col-sm-offset-2
- .text-center
- a.btn.btn-primary.btn-big.btn-block(href='/nonprofits/interested-in-nonprofit/#{dashedName}') I'm interested in building this project
- .button-spacer
- a.btn.btn-info.btn-big.btn-block(href='/nonprofits/directory') Show all Nonprofit Projects
- .spacer
diff --git a/server/views/partials/challenge-footer.jade b/server/views/partials/challenge-footer.jade
index ed6be20a3f..732c9dadb6 100644
--- a/server/views/partials/challenge-footer.jade
+++ b/server/views/partials/challenge-footer.jade
@@ -5,3 +5,10 @@ script.
if (typeof localStorage !== 'undefined') {
localStorage.setItem('currentDashedName', typeof common !== 'undefined' && common.dashedName || '');
}
+ var common = window.common || { init: [] };
+ common.helpRoom = !{JSON.stringify(helpRoom)};
+ document.addEventListener('gitter-sidecar-ready', function(e) {
+ if (window.main) {
+ window.main.chat.createHelpChat(common.helpRoom, '#challenge-help-btn');
+ }
+ });
diff --git a/server/views/partials/challenge-modals.jade b/server/views/partials/challenge-modals.jade
index 128be1c95d..d934881695 100644
--- a/server/views/partials/challenge-modals.jade
+++ b/server/views/partials/challenge-modals.jade
@@ -5,10 +5,10 @@
a.close.closing-x(href='#', data-dismiss='modal', aria-hidden='true') ×
.modal-body.text-center
h3 Before you submit a new issue, read "Help I've Found a Bug" and browse other issues with this challenge.
- a.btn.btn-lg.btn-success.btn-block#help-ive-found-a-bug-wiki-article(name='_csrf', value=_csrf) Read "Help I've Found a Bug"
- a.btn.btn-lg.btn-success.btn-block#search-issue(name='_csrf', value=_csrf) Browse other issues with this challenge
+ a.btn.btn-lg.btn-primary.btn-block#help-ive-found-a-bug-wiki-article(name='_csrf', value=_csrf) Read "Help I've Found a Bug"
+ a.btn.btn-lg.btn-primary.btn-block#search-issue(name='_csrf', value=_csrf) Browse other issues with this challenge
a.btn.btn-lg.btn-primary.btn-block#report-issue(name='_csrf', value=_csrf) Create my GitHub issue
- a.btn.btn-lg.btn-info.btn-block(href='#', data-dismiss='modal', aria-hidden='true') Cancel
+ a.btn.btn-lg.btn-primary.btn-block(href='#', data-dismiss='modal', aria-hidden='true') Cancel
#reset-modal.modal(tabindex='-1')
.modal-dialog.animated.fadeInUp.fast-animation
@@ -17,5 +17,5 @@
a.close.closing-x(href='#', data-dismiss='modal', aria-hidden='true') ×
.modal-body
h3 This will restore your code editor to its original state.
- a.btn.btn-lg.btn-info.btn-block#reset-button(href='#', data-dismiss='modal', aria-hidden='true') Clear my code
+ a.btn.btn-lg.btn-warning.btn-block#reset-button(href='#', data-dismiss='modal', aria-hidden='true') Clear my code
a.btn.btn-lg.btn-primary.btn-block(href='#', data-dismiss='modal', aria-hidden='true') Cancel
diff --git a/server/views/partials/footer.jade b/server/views/partials/footer.jade
index 5bed48bdca..6c7e91cb9c 100644
--- a/server/views/partials/footer.jade
+++ b/server/views/partials/footer.jade
@@ -1,2 +1,6 @@
// scripts should be moved here
script(src="https://sidecar.gitter.im/dist/sidecar.v1.js" async defer)
+aside.map-aside.is-collapsed
+ .map-aside-action-bar
+ a.map-aside-action-item.map-aside-action-pop-out(href='/map' target='_blank' aria-label='open map in new tap')
+ button.map-aside-action-item.map-aside-action-collapse(aria-label='close map aside')
diff --git a/server/views/partials/navbar.jade b/server/views/partials/navbar.jade
index 04a029faf5..6c15aab7f5 100644
--- a/server/views/partials/navbar.jade
+++ b/server/views/partials/navbar.jade
@@ -7,9 +7,9 @@ nav.navbar.navbar-default.navbar-fixed-top.nav-height
img.img-responsive.nav-logo(src='https://s3.amazonaws.com/freecodecamp/freecodecamp_logo.svg', alt='learn to code javascript at Free Code Camp logo')
.collapse.navbar-collapse
ul.nav.navbar-nav.navbar-right.hamburger-dropdown
- li
- a.learn-btn(href='#') Learn
- li
+ li.hidden-xs
+ a#nav-map-btn(href='#' onclick='return false') Map
+ li.visible-xs
a(href='/map') Map
li.hidden-xs
a#nav-chat-btn(href='#' onclick="return false") Chat
@@ -24,28 +24,11 @@ nav.navbar.navbar-default.navbar-fixed-top.nav-height
li
a(href='/about') About
if !user
- li
li
- a.btn.signup-btn.signup-btn-nav.signin-button-nav(href='/login') Sign in
+ a(href='/login') Sign in
else
li.brownie-points-nav
a(href='/' + user.username) [ #{user.progressTimestamps.length} ]
.hidden-xs.hidden-sm
a(href='/' + user.username)
img.profile-picture.float-right(src='#{user.picture}')
-script.
- $(document).ready(function() {
- $('.learn-btn').click(function(e) {
- var challengeDashedName = null;
- e.preventDefault();
- if (typeof dashedName === "string") {
- return location.reload();
- }
- if (typeof localStorage !== 'undefined') {
- challengeDashedName = localStorage.getItem('currentDashedName');
- }
- window.location = challengeDashedName ?
- '/challenges/' + challengeDashedName :
- '/map';
- });
- });
diff --git a/server/views/redirect-https.html b/server/views/redirect-https.html
new file mode 100644
index 0000000000..8c7419ad36
--- /dev/null
+++ b/server/views/redirect-https.html
@@ -0,0 +1,9 @@
+ | Free Code Campredirecting you... please wait...
\ No newline at end of file
diff --git a/server/views/resources/about.jade b/server/views/resources/about.jade
index 1478740876..265a0f8d30 100644
--- a/server/views/resources/about.jade
+++ b/server/views/resources/about.jade
@@ -1,146 +1,174 @@
extends ../layout
block content
.col-xs-12
- .panel.panel-info
- .panel-body
- h2.text-center We're an open source community of people
- br
- | who learn to code and help nonprofits.
- .spacer
- .row
- .col-xs-12.col-sm-10.col-sm-offset-1.col-md-6.col-md-offset-3
- h2 Free Code Camp around the web:
- table.table.link-table
- tr
- td.text-right
- .ion-speakerphone
- td
- a(href='//medium.freecodecamp.com', target='_blank') Medium Publication
- tr
- td.text-right
- .ion-social-github
- td
- a(href="//github.com/freecodecamp", target='_blank') GitHub Repository
- tr
- td.text-right
- .ion-social-reddit
- td
- a(href="//www.reddit.com/r/freecodecamp", target='_blank') Subreddit
- tr
- td.text-right
- .ion-social-linkedin
- td
- a(href="//www.linkedin.com/edu/school?id=166029", target='_blank') LinkedIn University Page
- tr
- td.text-right
- .ion-social-twitter
- td
- a(href="//twitter.com/freecodecamp", target='_blank') Twitter Feed
- tr
- td.text-right
- .ion-social-facebook
- td
- a(href="//facebook.com/freecodecamp") Facebook Page
- tr
- td.text-right
- .ion-social-twitch-outline
- td
- a(href="//twitch.tv/freecodecamp", target='_blank') Twitch.tv Channel
- .spacer
+ h2.text-center We're an open source community of people
+ br
+ | who learn to code and help nonprofits.
+ .spacer
+ .row
+ .col-xs-12.col-sm-10.col-sm-offset-1.col-md-6.col-md-offset-3
+ h2
+ table.population-table.img-center
+ tr
+ td Established:
+ td
+ span.text-primary #{daysRunning}
+ | days ago
+ tr
+ td Population:
+ td
+ span.text-primary #{camperCount}
+ | campers
+ tr
+ td Completed:
+ td
+ span.text-primary #{globalCompletedCount}
+ | challenges
- h2 Other useful links:
- table.table.link-table
- tr
- td.text-right
- .ion-locked
- td
- a(href="/terms-and-privacy") Our Privacy Policy, Terms of Service and Code of Conduct
- tr
- td.text-right
- .ion-erlenmeyer-flask
- td
- a(href="/labs") Extra-curricular Apps Built by Campers
- tr
- td.text-right
- .ion-chatbox
- td
- a(href="/stories") Stories from campers who've become professional developers
- .spacer
- h2 Which camper to contact for:
- table.table.table-stripe
- tr
- td Support (team@freecodecamp.com)
- td
- a(href='https://gitter.im/QuincyLarson' target='_blank') @QuincyLarson
- tr
- td Facebook page
- td
- a(href='https://gitter.im/QuincyLarson' target='_blank') @QuincyLarson
- tr
- td Twitter feed
- td
- a(href='https://gitter.im/QuincyLarson' target='_blank') @QuincyLarson
- tr
- td Medium publication
- td
- a(href='https://gitter.im/QuincyLarson' target='_blank') @QuincyLarson
- tr
- td Media inquiries
- td
- a(href='https://gitter.im/QuincyLarson' target='_blank') @QuincyLarson
- tr
- td Open source codebase contributions
- td
- a(href='https://gitter.im/BerkeleyTrue' target='_blank') @BerkeleyTrue
- tr
- td Server problems
- td
- a(href='https://gitter.im/BerkeleyTrue' target='_blank') @BerkeleyTrue
- tr
- td Nonprofit projects
- td
- a(href='https://gitter.im/CodeNonprofit' target='_blank') @CodeNonprofit
- tr
- td Volunteer agile project managers
- td
- a(href='https://gitter.im/CodeNonprofit' target='_blank') @CodeNonprofit
- tr
- td Commit program
- td
- a(href='https://gitter.im/CodeNonprofit' target='_blank') @CodeNonprofit
- tr
- td Hikes curriculum
- td
- a(href='https://gitter.im/BrianaMarie' target='_blank') @BrianaMarie
- tr
- td JavaScript curriculum
- td
- a(href='https://gitter.im/SaintPeter' target='_blank') @SaintPeter
- tr
- td Data Science and Open Data
- td
- a(href='https://gitter.im/Evaristoc' target='_blank') @Evaristoc
- tr
- td CamperBot
- td
- a(href='https://gitter.im/LTegman' target='_blank') @LTegman
- tr
- td Twitch.tv channel
- td
- a(href='https://gitter.im/Septimus' target='_blank') @Septimus
- tr
- td Youtube channel
- td
- a(href='https://gitter.im/Septimus' target='_blank') @Septimus
- tr
- td Translation and Internationalization
- td
- a(href='https://gitter.im/Vtamara' target='_blank') @Vtamara
- tr
- td Wiki
- td
- a(href='https://gitter.im/Rafase282' target='_blank') @Rafase282
- tr
- td Campsites
- td
- a(href='https://gitter.im/Hallaathrad' target='_blank') @Hallaathrad
+ .row
+ .col-xs-12.col-sm-10.col-sm-offset-1.col-md-6.col-md-offset-3
+ h2 Free Code Camp around the web:
+ table.table.link-table
+ tr
+ td.text-right
+ .ion-speakerphone
+ td
+ a(href='//medium.freecodecamp.com', target='_blank') Medium Publication
+ tr
+ td.text-right
+ .ion-social-github
+ td
+ a(href="//github.com/freecodecamp", target='_blank') GitHub Repository
+ tr
+ td.text-right
+ .ion-social-reddit
+ td
+ a(href="//www.reddit.com/r/freecodecamp", target='_blank') Subreddit
+ tr
+ td.text-right
+ .ion-social-linkedin
+ td
+ a(href="//www.linkedin.com/edu/school?id=166029", target='_blank') LinkedIn University Page
+ tr
+ td.text-right
+ .ion-social-twitter
+ td
+ a(href="//twitter.com/freecodecamp", target='_blank') Twitter Feed
+ tr
+ td.text-right
+ .ion-social-facebook
+ td
+ a(href="//facebook.com/freecodecamp") Facebook Page
+ tr
+ td.text-right
+ .ion-social-twitch-outline
+ td
+ a(href="//twitch.tv/freecodecamp", target='_blank') Twitch.tv Channel
+ .spacer
+
+ h2 Other useful links:
+ table.table.link-table
+ tr
+ td.text-right
+ .ion-erlenmeyer-flask
+ td
+ a(href="/labs") Extra-curricular apps built by campers
+ tr
+ td.text-right
+ .ion-chatbox
+ td
+ a(href="/stories") Stories from campers who've become professional developers
+ tr
+ td.text-right
+ .ion-locked
+ td
+ a(href="/privacy") Our privacy policy
+ tr
+ td.text-right
+ .ion-happy-outline
+ td
+ a(href="/code-of-conduct") Our code of conduct
+ tr
+ td.text-right
+ .ion-document-text
+ td
+ a(href="/terms") Our terms of service
+ .spacer
+ h2 Which camper to contact for:
+ table.table.table-stripe
+ tr
+ td Support (team@freecodecamp.com)
+ td
+ a(href='https://gitter.im/QuincyLarson' target='_blank') @QuincyLarson
+ tr
+ td Facebook page
+ td
+ a(href='https://gitter.im/QuincyLarson' target='_blank') @QuincyLarson
+ tr
+ td Twitter feed
+ td
+ a(href='https://gitter.im/QuincyLarson' target='_blank') @QuincyLarson
+ tr
+ td Medium publication
+ td
+ a(href='https://gitter.im/QuincyLarson' target='_blank') @QuincyLarson
+ tr
+ td Media inquiries
+ td
+ a(href='https://gitter.im/QuincyLarson' target='_blank') @QuincyLarson
+ tr
+ td Open source codebase contributions
+ td
+ a(href='https://gitter.im/BerkeleyTrue' target='_blank') @BerkeleyTrue
+ tr
+ td Server problems
+ td
+ a(href='https://gitter.im/BerkeleyTrue' target='_blank') @BerkeleyTrue
+ tr
+ td Nonprofit projects
+ td
+ a(href='https://gitter.im/CodeNonprofit' target='_blank') @CodeNonprofit
+ tr
+ td Volunteer agile project managers
+ td
+ a(href='https://gitter.im/CodeNonprofit' target='_blank') @CodeNonprofit
+ tr
+ td Commit program
+ td
+ a(href='https://gitter.im/CodeNonprofit' target='_blank') @CodeNonprofit
+ tr
+ td Video challenge curriculum
+ td
+ a(href='https://gitter.im/BrianaMarie' target='_blank') @BrianaMarie
+ tr
+ td Twitch.tv channel
+ td
+ a(href='https://gitter.im/BrianaMarie' target='_blank') @BrianaMarie
+ tr
+ td Youtube channel
+ td
+ a(href='https://gitter.im/BrianaMarie' target='_blank') @BrianaMarie
+ tr
+ td JavaScript curriculum
+ td
+ a(href='https://gitter.im/SaintPeter' target='_blank') @SaintPeter
+ tr
+ td Data Science and Open Data
+ td
+ a(href='https://gitter.im/Evaristoc' target='_blank') @Evaristoc
+ tr
+ td CamperBot
+ td
+ a(href='https://gitter.im/LTegman' target='_blank') @LTegman
+ tr
+ td Translation and Internationalization
+ td
+ a(href='https://gitter.im/Vtamara' target='_blank') @Vtamara
+ tr
+ td Wiki
+ td
+ a(href='https://gitter.im/Rafase282' target='_blank') @Rafase282
+ tr
+ td Campsites
+ td
+ a(href='https://gitter.im/Hallaathrad' target='_blank') @Hallaathrad
diff --git a/server/views/resources/code-of-conduct.jade b/server/views/resources/code-of-conduct.jade
new file mode 100644
index 0000000000..4fd01f03ad
--- /dev/null
+++ b/server/views/resources/code-of-conduct.jade
@@ -0,0 +1,30 @@
+extends ../layout
+block content
+ .col-xs-12.col-sm-8.col-sm-offset-2.col-md-6.col-md-offset-3
+ h1.text-center Code of Conduct
+ hr
+ p
+ | Free Code Camp is friendly place to learn to code. We’re committed to keeping it that way.
+ p
+ | All campers are required to agree with the following code of conduct. We’ll enforce this code. We’re expecting cooperation from all campers in ensuring a friendly environment for everybody.
+ p In short: be nice to your fellow campers.
+ p Remember these 3 things and your fellow campers will like you:
+ ol
+ li Compliment your fellow campers when they do good work. Congratulate them when they accomplish something (like completing one of our certifications or getting a job).
+ li Critique the work, not the camper doing it.
+ li Only argue about something if it’s important to the greater discussion.
+ p
+ | Free Code Camp should be a harassment-free experience for everyone, regardless of gender, gender identity and expression, age, sexual orientation, disability, physical appearance, body size, race, national origin, or religion (or lack thereof).
+ p
+ | We do not tolerate harassment of campers in any form, anywhere on Free Code Camp’s online media (Gitter, Twitch, Facebook, etc.) or during pair programming. Harassment includes sexual language and imagery, deliberate intimidation, stalking, unwelcome sexual attention, libel, and any malicious hacking or social engineering.
+ p
+ | If a camper engages in harassing behavior, our team will take any action we deem appropriate, up to and including banning them from Free Code Camp.
+ p
+ | No bots are allowed in any of the Official Chat Rooms without prior explicit permission from the FCC Core Team.
+ p
+ | We want everyone to feel safe and respected. If you are being harassed or notice that someone else is being harassed, say something! Go to our
+ a(href='https://gitter.im/freecodecamp/admin' target='_blank') Admin room in Gitter
+ | and explain what has happened where (preferably with a screen shot of the offending language) so we can take fast action.
+ p
+ | If you have questions about this code of conduct, email us at
+ a(href='mailto:team@freecodecamp.com') team@freecodecamp.com
diff --git a/server/views/resources/links.jade b/server/views/resources/links.jade
new file mode 100644
index 0000000000..269382fab2
--- /dev/null
+++ b/server/views/resources/links.jade
@@ -0,0 +1,54 @@
+extends ../layout
+block content
+ table.table.link-table
+ tr
+ td.text-right
+ .ion-erlenmeyer-flask
+ td
+ a(href="/labs") Cool Apps Built by Campers
+ tr
+ td.text-right
+ .ion-chatbox
+ td
+ a(href="/stories") Stories from Campers
+ tr
+ td.text-right
+ .ion-speakerphone
+ td
+ a(href='//medium.freecodecamp.com', target='_blank') Medium Publication
+ tr
+ td.text-right
+ .ion-social-github
+ td
+ a(href="//github.com/freecodecamp", target='_blank') GitHub Repository
+ tr
+ td.text-right
+ .ion-social-reddit
+ td
+ a(href="//www.reddit.com/r/freecodecamp", target='_blank') Subreddit
+ tr
+ td.text-right
+ .ion-social-linkedin
+ td
+ a(href="//www.linkedin.com/edu/school?id=166029", target='_blank') LinkedIn University Page
+ tr
+ td.text-right
+ .ion-social-twitter
+ td
+ a(href="//twitter.com/freecodecamp", target='_blank') Twitter Feed
+ tr
+ td.text-right
+ .ion-social-facebook
+ td
+ a(href="//facebook.com/freecodecamp") Facebook Page
+ tr
+ td.text-right
+ .ion-social-twitch-outline
+ td
+ a(href="//twitch.tv/freecodecamp", target='_blank') Twitch.tv Channel
+ tr
+ td.text-right
+ .ion-locked
+ td
+ a(href="//github.com/FreeCodeCamp/freecodecamp/wiki/Free-Code-Camp's-Privacy-Policy") Privacy Policy
+ .spacer
diff --git a/server/views/resources/nonprofits.jade b/server/views/resources/nonprofits.jade
index ea3b7d931a..731c463d3e 100644
--- a/server/views/resources/nonprofits.jade
+++ b/server/views/resources/nonprofits.jade
@@ -1,77 +1,74 @@
extends ../layout
block content
- .jumbotron
- .text-center
- .row
- .col-xs-12
- h1.landing-heading Get pro bono code for your nonprofit.
+ .text-center
+ .row
+ .col-xs-12
+ h1.landing-heading Get pro bono code for your nonprofit.
+ .big-break
+ .col-xs-12.col-sm-12.col-md-12
+ .embed-responsive.embed-responsive-16by9
+ iframe.embed-responsive-item(src='//player.vimeo.com/video/126228100')
.big-break
- .col-xs-12.col-sm-12.col-md-12
- .embed-responsive.embed-responsive-16by9
- iframe.embed-responsive-item(src='//player.vimeo.com/video/126228100')
- .big-break
- h2 As featured in:
- img.img-center.img-responsive(src='https://s3.amazonaws.com/freecodecamp/as-seen-on.png')
- .spacer
- hr
- .spacer
- h2 Our process:
- .row
- .col-xs-12.col-sm-12.col-md-4
- h3.nowrap Your idea
- img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_portfolio.svg.gz', alt='Image of a briefcase')
- p.landing-p You tell us how we can help you.
- .col-xs-12.col-sm-12.col-md-4
- h3.nowrap Our team
- img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_nonprofits.svg.gz', alt='Image of people putting their hands together in a huddle')
- p.landing-p We'll hand pick developers and a project manager.
- .col-xs-12.col-sm-12.col-md-4
- h3.nowrap Your solution
- img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_connect.svg.gz', alt='image of two people high-fiving')
- p.landing-p Together we'll set milestones and complete your project.
- .spacer
- hr
- .spacer
- h2 Solutions we can help you build:
- .text-center.negative-35
- .col-xs-12.col-sm-12.col-md-3
- .landing-skill-icon.ion-android-globe
- h2.black-text Websites
- .col-xs-12.col-sm-12.col-md-3
- .landing-skill-icon.ion-card
- h2.black-text Donation Systems
- .col-xs-12.col-sm-12.col-md-3
- .landing-skill-icon.ion-android-calendar
- h2.black-text Volunteer Systems
- .col-xs-12.col-sm-12.col-md-3
- .landing-skill-icon.ion-ios-box
- h2.black-text Inventory Systems
- .col-xs-12.col-sm-12.col-md-3
- .landing-skill-icon.ion-university
- h2.black-text E-learning Platforms
- .col-xs-12.col-sm-12.col-md-3
- .landing-skill-icon.ion-ios-list
- h2.black-text Paperless Workflows
- .col-xs-12.col-sm-12.col-md-3
- .landing-skill-icon.ion-ios-people
- h2.black-text Community Tools
- .col-xs-12.col-sm-12.col-md-3
- .landing-skill-icon.ion-settings
- h2.black-text ...and other tools
+ h2 As featured in:
+ img.img-center.img-responsive(src='https://s3.amazonaws.com/freecodecamp/as-seen-on.png')
+ .spacer
+ hr
+ .spacer
+ h2 Our process:
+ .spacer
+ .row
+ .col-xs-12.col-sm-12.col-md-4
+ img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_portfolio.svg.gz', alt='Image of a briefcase')
+ p.large-p You tell us how we can help you.
+ .col-xs-12.col-sm-12.col-md-4
+ img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_nonprofits.svg.gz', alt='Image of people putting their hands together in a huddle')
+ p.large-p We'll hand pick developers and a project manager.
+ .col-xs-12.col-sm-12.col-md-4
+ img.img-responsive.landing-icon.img-center(src= 'https://s3.amazonaws.com/freecodecamp/landingIcons_connect.svg.gz', alt='image of two people high-fiving')
+ p.large-p Together we'll set milestones and complete your project.
+ .spacer
+ hr
+ .spacer
+ h2 Solutions we can help you build:
+ .spacer
+ .text-center.negative-35
+ .col-xs-12.col-sm-12.col-md-3
+ .landing-skill-icon.ion-android-globe
+ h2.black-text Websites
+ .col-xs-12.col-sm-12.col-md-3
+ .landing-skill-icon.ion-card
+ h2.black-text Donation Systems
+ .col-xs-12.col-sm-12.col-md-3
+ .landing-skill-icon.ion-android-calendar
+ h2.black-text Volunteer Systems
+ .col-xs-12.col-sm-12.col-md-3
+ .landing-skill-icon.ion-ios-box
+ h2.black-text Inventory Systems
+ .col-xs-12.col-sm-12.col-md-3
+ .landing-skill-icon.ion-university
+ h2.black-text E-learning Platforms
+ .col-xs-12.col-sm-12.col-md-3
+ .landing-skill-icon.ion-ios-list
+ h2.black-text Paperless Workflows
+ .col-xs-12.col-sm-12.col-md-3
+ .landing-skill-icon.ion-ios-people
+ h2.black-text Community Tools
+ .col-xs-12.col-sm-12.col-md-3
+ .landing-skill-icon.ion-settings
+ h2.black-text ...and other tools
+ .spacer
+ hr
+ .spacer
+ .col-xs-offset-0.col-sm-offset-1.text-left.large-p
+ h2 Our developers build projects for nonprofits who:
.spacer
- hr
- .spacer
- .large-p.text-left.col-xs-offset-0.col-sm-offset-1
- h2 Our developers build projects for nonprofits who:
- ul.large-li
- li.ion-code already have people who benefit from their services.
- li.ion-code are registered with their government and have tax-exempt status.
- li.ion-code have a stakeholder who can meet with our developers to direct the project.
- li.ion-code can budget at least $20 per month for their own cloud servers.
- li.ion-code can commit to using and maintaining the solution that our developers build.
- .big-break
- .row
- .col-xs-12.col-sm-8.col-sm-offset-2
- a.btn.btn-cta.signup-btn.btn-block(href="/nonprofits-form") My nonprofit needs coding help
- .button-spacer
- a.btn.btn-lg.btn-primary.btn-primary-ghost.btn-block(href="/nonprofits/directory") Browse our directory of nonprofits we've helped
+ ul.large-li
+ li.ion-code already have people who benefit from their services.
+ li.ion-code are registered with their government and have tax-exempt status.
+ li.ion-code have a stakeholder who can meet with our developers to direct the project.
+ li.ion-code can budget at least $20 per month for their own cloud servers.
+ li.ion-code can commit to using and maintaining the solution that our developers build.
+ .big-break
+ .row
+ .col-xs-12.col-sm-8.col-sm-offset-2
+ a.btn.btn-cta.signup-btn.btn-block(href="/nonprofits-form") My nonprofit needs coding help
diff --git a/server/views/resources/privacy.jade b/server/views/resources/privacy.jade
new file mode 100644
index 0000000000..6f12dc9f38
--- /dev/null
+++ b/server/views/resources/privacy.jade
@@ -0,0 +1,34 @@
+extends ../layout
+block content
+ .col-xs-12.col-sm-8.col-sm-offset-2.col-md-6.col-md-offset-3
+ html.
+ Privacy Policy
+
+ Your privacy is critically important to us. At Free Code Camp we have a few fundamental principles:
+
+ - We don’t ask you for personal information unless we truly need it. (We can’t stand services that ask you for things like your gender or income level for no apparent reason.)
+ - We don’t share your personal information with anyone except to comply with the law, develop our products, or protect our rights.
+ - Unless you ask us not to (by clicking the button that says "hide all my solutions from other people" located on your code portfolio), we will share your solutions and progress with the public as part of our open data initiative. This is intended for academics and researchers to better understand Free Code Camp as an educational model.
+ - We don’t store personal information on our servers unless required for the on-going operation of one of our services.
+ - We aim to make it as simple as possible for you to control what’s visible to the public, seen by search engines, kept private, and permanently deleted. Below is our privacy policy which incorporates these goals
+
+ If you have questions about deleting or correcting your personal data please email us at team@freecodecamp.com
+ Free Code Camp Inc. (“Free Code Camp”) operates several websites including FreeCodeCamp.com. It is Free Code Camp’s policy to respect your privacy regarding any information we may collect while operating our websites.
+ Website Visitors
+ Like most website operators, Free Code Camp collects non-personally-identifying information of the sort that web browsers and servers typically make available, such as the browser type, language preference, referring site, and the date and time of each visitor request. Free Code Camp’s purpose in collecting non-personally identifying information is to better understand how Free Code Camp’s visitors use its website. From time to time, Free Code Camp may release non-personally-identifying information in the aggregate, e.g., by publishing a report on trends in the usage of its website.
+ Free Code Camp also collects potentially personally-identifying information like Internet Protocol (IP) addresses for logged in users and for users leaving comments on FreeCodeCamp.com blogs. Free Code Camp only discloses logged in user and commenter IP addresses under the same circumstances that it uses and discloses personally-identifying information as described below, except that blog commenter IP addresses and email addresses are visible and disclosed to the administrators of the blog where the comment was left.
+ Gathering of Personally-Identifying Information
+ Many visitors to Free Code Camp’s websites choose to interact with Free Code Camp in ways that require Free Code Camp to gather personally-identifying information. The amount and type of information that Free Code Camp gathers depends on the nature of the interaction. For example, we ask visitors who create an account for tracking their progress at FreeCodeCamp.com to provide either an email address or sign in with a social media oauth service like GitHub. Those who engage in transactions with Free Code Camp – by placing job ads, for example – are asked to provide additional information, including as necessary the personal and financial information required to process those transactions. In each case, Free Code Camp collects such information only insofar as is necessary or appropriate to fulfill the purpose of the visitor’s interaction with Free Code Camp. Free Code Camp does not disclose personally-identifying information other than as described below. And visitors can always refuse to supply personally-identifying information, with the caveat that it may prevent them from engaging in certain website-related activities.
+ Aggregated Statistics
+ Free Code Camp may collect statistics about the behavior of visitors to its websites. For instance, Free Code Camp may monitor the accounts to try and identify spammers. Free Code Camp may display this information publicly or provide it to others. However, Free Code Camp does not disclose personally-identifying information other than as described below.
+ Protection of Certain Personally-Identifying Information
+ Free Code Camp discloses potentially personally-identifying and personally-identifying information only to those of its employees, contractors and affiliated organizations that (i) need to know that information in order to process it on Free Code Camp’s behalf or to provide services available at Free Code Camp’s websites, and (ii) that have agreed not to disclose it to others. Some of those employees, contractors and affiliated organizations may be located outside of your home country; by using Free Code Camp’s websites, you consent to the transfer of such information to them. Free Code Camp will not rent or sell potentially personally-identifying and personally-identifying information to anyone. Other than to its employees, contractors and affiliated organizations, as described above, Free Code Camp discloses potentially personally-identifying and personally-identifying information only in response to a subpoena, court order or other governmental request, or when Free Code Camp believes in good faith that disclosure is reasonably necessary to protect the property or rights of Free Code Camp, third parties or the public at large. If you are a registered user of an Free Code Camp website and have supplied your email address, Free Code Camp may occasionally send you an email to tell you about new features, solicit your feedback, or just keep you up to date with what’s going on with Free Code Camp and our products. We primarily use our various product blogs to communicate this type of information, so we expect to keep this type of email to a minimum. If you send us a request (for example via a support email or via one of our feedback mechanisms), we reserve the right to publish it in order to help us clarify or respond to your request or to help us support other users. Free Code Camp takes all measures reasonably necessary to protect against the unauthorized access, use, alteration or destruction of potentially personally-identifying and personally-identifying information.
+ Cookies
+ A cookie is a string of information that a website stores on a visitor’s computer, and that the visitor’s browser provides to the website each time the visitor returns. Free Code Camp uses cookies to help Free Code Camp identify and track visitors, their usage of Free Code Camp website, and their website access preferences. Free Code Camp visitors who do not wish to have cookies placed on their computers should set their browsers to refuse cookies before using Free Code Camp’s websites, with the drawback that certain features of Free Code Camp’s websites may not function properly without the aid of cookies.
+ Business Transfers
+ If Free Code Camp, or substantially all of its assets, were acquired, or in the unlikely event that Free Code Camp goes out of business or enters bankruptcy, user information would be one of the assets that is transferred or acquired by a third party. You acknowledge that such transfers may occur, and that any acquirer of Free Code Camp may continue to use your personal information as set forth in this policy.
+ Ads
+ If in the future we show ads, ads appearing on any of our websites may be delivered to users by advertising partners, who may set cookies. These cookies allow the ad server to recognize your computer each time they send you an online advertisement to compile information about you or others who use your computer. This information allows ad networks to, among other things, deliver targeted advertisements that they believe will be of most interest to you. This Privacy Policy covers the use of cookies by Free Code Camp and does not cover the use of cookies by any advertisers.
+ Privacy Policy Changes
+ Although most changes are likely to be minor, Free Code Camp may change its Privacy Policy from time to time, and in Free Code Camp’s sole discretion. Free Code Camp encourages visitors to frequently check this page for any changes to its Privacy Policy. If you have a FreeCodeCamp.com account, you should also check your blog’s dashboard for alerts to these changes. Your continued use of this site after any change in this Privacy Policy will constitute your acceptance of such change.
+ This privacy policy is adopted from the Automattic (Free Code Camp) open source terms and are subject to the Creative Commons Attribution-ShareAlike 4.0 International license. We thank them for making this available.
diff --git a/server/views/resources/sitemap.jade b/server/views/resources/sitemap.jade
index 6b4907a199..7ce295adb1 100644
--- a/server/views/resources/sitemap.jade
+++ b/server/views/resources/sitemap.jade
@@ -37,12 +37,6 @@ urlset(xmlns="http://www.sitemaps.org/schemas/sitemap/0.9")
lastmod= now
priority= 0.9
- url
- loc http://www.freecodecamp.com/twitch
- changefreq weekly
- lastmod= now
- priority= 0.9
-
url
loc http://www.freecodecamp.com/jobs
changefreq weekly
@@ -76,10 +70,3 @@ urlset(xmlns="http://www.sitemaps.org/schemas/sitemap/0.9")
lastmod= now
changefreq weekly
priority= 0.5
-
- each nonprofit in nonprofits
- url
- loc #{appUrl}/nonprofits/#{nonprofit.replace(/\s/g, '-')}
- lastmod= now
- changefreq weekly
- priority= 0.9
diff --git a/server/views/resources/stories.jade b/server/views/resources/stories.jade
index 794c4badea..79739bdcbb 100644
--- a/server/views/resources/stories.jade
+++ b/server/views/resources/stories.jade
@@ -1,27 +1,25 @@
extends ../layout
block content
- .panel.panel-info
- .panel-heading.text-center Stories from happy campers
- .panel-body.text-left
+ h1.text-center Stories from happy campers
+ hr
+ .row
+ .col-xs-12.col-sm-10.col-sm-offset-1
.row
- .col-xs-12.col-sm-10.col-sm-offset-1
- .row
- for story in stories
- .col-xs-12.col-sm-6.col-md-4
- .height-500
- a(href=story.linkedin target='_blank')
- img.testimonial-image.img-responsive.img-center(src=story.image)
- h3.text-center= story.camper
- |
- a.fa.fa-linkedin-square.text-primary(alt="#{story.camper}'s LinkedIn Profile", href=story.linkedin, target='_blank')
- p.text-justify= story.quote
- .col-xs-12.col-sm-10.col-sm-offset-1
- if moreStories
- .text-center
- a.btn.btn-lg.btn-primary.btn-primary-ghost.btn-block(href="/all-stories") Show more stories
- .spacer
+ for story in stories
+ .col-xs-12.col-sm-6.col-md-4
+ .height-500
+ a(href=story.linkedin target='_blank')
+ img.testimonial-image.img-responsive.img-center(src=story.image)
+ h3.text-center= story.camper
+ |
+ a.fa.fa-linkedin-square.text-primary(alt="#{story.camper}'s LinkedIn Profile", href=story.linkedin, target='_blank')
+ p.small-p.text-justify= story.quote
+ .col-xs-12.col-sm-10.col-sm-offset-1
+ if moreStories
+ .text-center
+ a.btn.btn-lg.btn-primary.btn-primary-ghost.btn-block(href="/all-stories") Show more stories
+ .spacer
- if !user
- .text-center
- a.btn.btn-cta.signup-btn.btn-block(href="/login") Start learning to code (it's free)
- .spacer
+ if !user
+ .text-center
+ a.btn.btn-cta.signup-btn.btn-block(href="/login") Start learning to code (it's free)
diff --git a/server/views/resources/terms-and-privacy.jade b/server/views/resources/terms-and-privacy.jade
deleted file mode 100644
index 3d5453a87e..0000000000
--- a/server/views/resources/terms-and-privacy.jade
+++ /dev/null
@@ -1,143 +0,0 @@
-extends ../layout
-block content
- .col-xs-12
- .panel.panel-info
- .panel-body
- h1 Privacy Policy
- p
- | Free Code Camp is committed to respecting the privacy of visitors to our web sites and web applications. The guidelines below explain how we protect the privacy of visitors to
- a(href='http://FreeCodeCamp.com') FreeCodeCamp.com
- | and its features.
- h3
- a#Personally_Identifiable_Information_2
- | Personally Identifiable Information
- p
- | Free Code Camp protects the identity of visitors to
- a(href='http://FreeCodeCamp.com') FreeCodeCamp.com
- | by limiting the collection of personally identifiable information.
- p
- | Free Code Camp does not knowingly collect or solicit personally identifiable information from or about children under 13, except as permitted by law. If we discover we have received any information from a child under 13 in violation of this policy, we will delete that information immediately. If you believe Free Code Camp has any information from or about anyone under 13, please email us at
- okies and software logs
- a(href='mailto:team@freecodecamp.com') team@freecodecamp.com
- | .
- p
- | All personally identifiable information you provide to us is used by Free Code Camp and its team to process and manage your account, analyze the demographic of our users, or to deliver services through the site.
- p
- | If you choose to provide personally identifiable information to us, you may receive occasional emails from us that are relevant to Free Code Camp, getting a job, or learning to code in general.
- | Free Code Camp may also use other third-party providers to facilitate the delivery of the services described above, and these third-party providers may be supplied with or have access to personally identifiable information for the sole purpose of providing these services, to you on behalf of Free Code Camp.
- p
- | Free Code Camp may also disclose personally identifiable information in special legal circumstances. For instance, such information may be used where it is necessary to protect our copyright or intellectual property rights, or if the law requires us to do so.
- h3
- a#Anonymous_Information_15
- | Anonymous Information
- p
- | Anonymous aggregated data may be provided to other organizations we associate with for statistical purposes. For example, we may report to an organization that a certain percentage of our site’s visitors are adults between the ages of 25 and 35.
- h3
- a#Cookies_and_BeaconsUse_by_Free_Code_Camp_Opting_Out_18
- | Cookies and Beacons—Use by Free Code Camp; Opting Out
- p
- | We use cookies and software logs to monitor the use of
- a(href='http://FreeCodeCamp.com') FreeCodeCamp.com
- | and to gather non-personal information about visitors to the site. Cookies are small files that Free Code Camp transfers to the hard drives of visitors for record-keeping purposes. These monitoring systems allow us to track general information about our visitors, such as the type of browsers (for example, Firefox or Internet Explorer), the operating systems (for instance, Windows or Macintosh), or the Internet providers (for instance, Comcast) they use. This information is used for statistical and market research purposes to tailor content to usage patterns and to provide services requested by our customers. To delete these cookies, please see your browser’s privacy settings.
- p
- | A beacon is an electronic file object (typically a transparent image) placed in the code of a Web page. We use third party beacons to monitor the traffic patterns of visitors from one
- a(href='http://FreeCodeCamp.com') Free Code Camp.com
- | page to another and to improve site performance.
- | None of the information we gather in this way can be used to identify any individual who visits our site.
- h3
- a#Security_24
- | Security
- p
- | Any personally identifiable information collected through this site is stored on limited-access servers. We will maintain safeguards to protect these servers and the information they store.
- h3
- a#Surveys_28
- | Surveys
- p
- | We may occasionally conduct on-line surveys. All surveys are voluntary and you may decline to participate.
- h3
- a#Copyright_31
- | Copyright
- p
- | All of the content on
- a(href='http://FreeCodeCamp.com') FreeCodeCamp.com
- | is copyrighted by Free Code Camp. If you’d like to redistribute it beyond simply sharing it through social media, please contact us at
- a(href='mailto:team@freecodecamp.com') team@freecodecamp.com
- | .
- h3
- a#Contacting_Us_34
- | Contacting Us
- p
- | If you have questions about Free Code Camp, or to correct, update, or remove personally identifiable information, please email us at
- a(href='mailto:team@freecodecamp.com') team@freecodecamp.com
- | .
- h3
- a#Links_to_Other_Web_sites_37
- | Links to Other Web sites
- p
- | Free Code Camp’s sites each contain links to other Web sites. Free Code Camp is not responsible for the privacy practices or content of these third-party Web sites. We urge all
- a(href='http://FreeCodeCamp.com') FreeCodeCamp.com
- | visitors to follow safe Internet practices: Do not supply Personally Identifiable Information to these Web sites unless you have verified their security and privacy policies.
- h3
- a#Data_Retention_40
- | Data Retention
- p
- | We retain your information for as long as necessary to permit us to use it for the purposes that we have communicated to you and comply with applicable law or regulations.
- h3
- a#Business_Transfers_43
- | Business Transfers
- p
- | As we continue to develop our business, we might sell or buy subsidiaries, or business units. In such transactions, customer information generally is one of the transferred business assets but remains subject to the promises made in any pre-existing Privacy Policy (unless, of course, the customer consents otherwise). Also, in the unlikely event that Free Code Camp, or substantially all of its assets are acquired, customer information will be one of the transferred assets, and will remain subject to our Privacy Policy.
- h3
- a#Your_California_Privacy_Rights_46
- | Your California Privacy Rights
- p
- | If you are a California resident, you are entitled to prevent sharing of your personal information with third parties for their own marketing purposes through a cost-free means. If you send a request to the address above, Free Code Camp will provide you with a California Customer Choice Notice that you may use to opt-out of such information sharing. To receive this notice, submit a written request to
- a(target='_blank' href='mailto:href=%22mailto:team@freecodecamp.com') team@freecodecamp.com,
- | specifying that you seek your “California Customer Choice Notice.” Please allow at least thirty (30) days for a response.
- h3
- a#Acceptance_of_Privacy_Policy_Terms_and_Conditions_49
- | Acceptance of Privacy Policy Terms and Conditions
- p
- | By using this site, you signify your agreement to the terms and conditions of this
- a(href='http://FreeCodeCamp.com') FreeCodeCamp.com
- | Privacy Policy. If you do not agree to these terms, please do not use this site. We reserve the right, at our sole discretion, to change, modify, add, or remove portions of this policy at any time. All amended terms automatically take effect 30 days after they are initially posted on the site. Please check this page periodically for any modifications. Your continued use of
- a(href='http://FreeCodeCamp.com') FreeCodeCamp.com
- | following the posting of any changes to these terms shall mean that you have accepted those changes.
- p
- | If you have any questions or concerns, please send an email to
- a(href='mailto:team@freecodecamp.com') team@freecodecamp.com
- | .
- .spacer
- hr
- .spacer
- h1 Terms of Service
- p Coming soon
- .spacer
- hr
- .spacer
- h1 Code of Conduct
- p
- | Free Code Camp is friendly place to learn to code. We’re committed to keeping it that way.
- p
- | All campers are required to agree with the following code of conduct. We’ll enforce this code. We’re expecting cooperation from all campers in ensuring a friendly environment for everybody.
- p In short: be nice to your fellow campers.
- p Remember these 3 things and your fellow campers will like you:
- ul
- li
- | Compliment your fellow campers when they do good work. Congratulate them when they accomplish something (like completing one of our certifications or getting a job).
- li Critique the work, not the camper doing it.
- li Only argue about something if it’s important to the greater discussion.
- p
- | Free Code Camp should be a harassment-free experience for everyone, regardless of gender, gender identity and expression, age, sexual orientation, disability, physical appearance, body size, race, national origin, or religion (or lack thereof).
- p
- | We do not tolerate harassment of campers in any form, anywhere on Free Code Camp’s online media (Gitter, Twitch, Facebook, etc.) or during pair programming. Harassment includes sexual language and imagery, deliberate intimidation, stalking, unwelcome sexual attention, libel, and any malicious hacking or social engineering.
- p
- | If a camper engages in harassing behavior, our team will take any action we deem appropriate, up to and including banning them from Free Code Camp.
- p
- | No bots are allowed in any of the Official Chat Rooms without prior explicit permission from the FCC Core Team.
- p
- | We want everyone to feel safe and respected. If you are being harassed or notice that someone else is being harassed, say something! Message @quincylarson, @berkeleytrue, @brianamarie and @codenonprofit in Gitter (preferably with a screen shot of the offending language) so we can take fast action.
- p
- | If you have questions about this code of conduct, email us at
- a(href='mailto:team@freecodecamp.com') team@freecodecamp.com
- | .
diff --git a/server/views/resources/terms-of-service.jade b/server/views/resources/terms-of-service.jade
new file mode 100644
index 0000000000..8097452cd6
--- /dev/null
+++ b/server/views/resources/terms-of-service.jade
@@ -0,0 +1,43 @@
+extends ../layout
+block content
+ .col-xs-12.col-sm-8.col-sm-offset-2.col-md-6.col-md-offset-3
+ html.
+ Terms of Service
+
+ The gist:
+
We (the folks that run Free Code Camp's open source community) would love for you to use it. Our community is free, and our service is designed to give you as much control and ownership over the code you write as possible, and encourage you to express yourself freely. However, be responsible in what you publish. In particular, make sure that none of the prohibited items (like spam, viruses, or serious threats of violence) appear on your website. If you find anything on Free Code Camp that you believe violates these Terms of Service, please email us at team@freecodecamp.com
+ Terms of Service:
+ The following terms and conditions govern all use of the FreeCodeCamp.com website and all content, services, and products available at or through the website - taken together, our Services. Our Services are offered subject to your acceptance without modification of all of the terms and conditions contained herein and all other operating rules, policies (including, without limitation, Free Code Camp's Privacy Policy) and procedures that may be published from time to time by Free Code Camp (collectively, the “Agreement”). You agree that we may automatically upgrade our Services, and these terms will apply to any upgrades. Your agreement is with Free Code Camp Inc. Please read this Agreement carefully before accessing or using our Services. By accessing or using any part of our services, you agree to become bound by the terms and conditions of this agreement. If you do not agree to all the terms and conditions of this agreement, then you may not access or use any of our services. If these terms and conditions are considered an offer by Free Code Camp, acceptance is expressly limited to these terms. Our Services are not directed to children younger than 13, and access and use of our Services is only offered to users 13 years of age or older. If you are under 13 years old, please do not register to use our Services. Any person who registers as a user or provides their personal information to our Services represents that they are 13 years of age or older. Use of some aspects of our Services may require a FreeCodeCamp.com account. You agree to provide us with complete and accurate information when you register for an account. You will be solely responsible and liable for any activity that occurs under your username. You are responsible for keeping your password secure.
+
+
+ - Your FreeCodeCamp.com Account and Website. If you create a website on FreeCodeCamp.com, you are responsible for maintaining the security of your account and website, and you are fully responsible for all activities that occur under the account and any other actions taken in connection with the website. You must immediately notify Free Code Camp of any unauthorized uses of your website, your account, or any other breaches of security. Free Code Camp will not be liable for any acts or omissions by you, including any damages of any kind incurred as a result of such acts or omissions.
+ - Responsibility of Contributors. If you operate a website, comment on a website, post material to FreeCodeCamp.com, post links on FreeCodeCamp.com, or otherwise make (or allow any third party to make) material available (any such material, “Content”), you are entirely responsible for the content of, and any harm resulting from, that Content or your conduct. That is the case regardless of what form the Content takes, which includes, but is not limited to text, photo, video, audio, or code. By using FreeCodeCamp.com, you represent and warrant that your Content and conduct do not violate these terms or the Code of Conduct. By submitting Content to Free Code Camp for inclusion on your website, you grant Free Code Camp a world-wide, royalty-free, and non-exclusive license to reproduce, modify, adapt and publish the Content solely for the purpose of displaying, distributing, and promoting your website. This license allows Free Code Camp to make publicly-posted content available to third parties selected by Free Code Camp (through the Free Code Camp Firehose, for example) so that these third parties can analyze and distribute (but not publicly display) your content through their services. You also give other FreeCodeCamp.com users permission to share your Content on other FreeCodeCamp.com websites and add their own Content to it (aka to reblog your Content), so long as they use only a portion of your post and they give you credit as the original author by linking back to your website (the reblogging function on FreeCodeCamp.com does this automatically!). If you delete Content, Free Code Camp will use reasonable efforts to remove it from FreeCodeCamp.com, but you acknowledge that caching or references to the Content may not be made immediately unavailable. Without limiting any of those representations or warranties, Free Code Camp has the right (though not the obligation) to, in Free Code Camp’s sole discretion, (i) refuse or remove any content that, in Free Code Camp’s reasonable opinion, violates any Free Code Camp policy or is in any way harmful or objectionable, or (ii) terminate or deny access to and use of FreeCodeCamp.com to any individual or entity for any reason. Free Code Camp will have no obligation to provide a refund of any amounts previously paid.
+ - Attribution. Free Code Camp reserves the right to display attribution links such as ‘Website at FreeCodeCamp.com,’ theme author, and font attribution in your website footer or toolbar.
+
+ 4. Responsibility of Visitors.
+ Free Code Camp has not reviewed, and cannot review, all of the material, including computer software, posted to our Services, and cannot therefore be responsible for that material’s content, use or effects. By operating our Services, Free Code Camp does not represent or imply that it endorses the material there posted, or that it believes such material to be accurate, useful, or non-harmful. You are responsible for taking precautions as necessary to protect yourself and your computer systems from viruses, worms, Trojan horses, and other harmful or destructive content. Our Services may contain content that is offensive, indecent, or otherwise objectionable, as well as content containing technical inaccuracies, typographical mistakes, and other errors. Our Services may also contain material that violates the privacy or publicity rights, or infringes the intellectual property and other proprietary rights, of third parties, or the downloading, copying or use of which is subject to additional terms and conditions, stated or unstated. Free Code Camp disclaims any responsibility for any harm resulting from the use by visitors of our Services, or from any downloading by those visitors of content there posted.
+ 5. Content Posted on Other Websites.
+ We have not reviewed, and cannot review, all of the material, including computer software, made available through the websites and webpages to which FreeCodeCamp.com links, and that link to FreeCodeCamp.com. Free Code Camp does not have any control over those non-FreeCodeCamp.com websites, and is not responsible for their contents or their use. By linking to a non-FreeCodeCamp.com website, Free Code Camp does not represent or imply that it endorses such website. You are responsible for taking precautions as necessary to protect yourself and your computer systems from viruses, worms, Trojan horses, and other harmful or destructive content. Free Code Camp disclaims any responsibility for any harm resulting from your use of non-FreeCodeCamp.com websites and webpages.
+ 6. Copyright Infringement and DMCA Policy.
+ As Free Code Camp asks others to respect its intellectual property rights, it respects the intellectual property rights of others. If you believe that material located on or linked to by FreeCodeCamp.com violates your copyright, you are encouraged to notify Free Code Camp in accordance with Free Code Camp’s Digital Millennium Copyright Act (“DMCA”) Policy. Free Code Camp will respond to all such notices, including as required or appropriate by removing the infringing material or disabling all links to the infringing material. Free Code Camp will terminate a visitor’s access to and use of the Website if, under appropriate circumstances, the visitor is determined to be a repeat infringer of the copyrights or other intellectual property rights of Free Code Camp or others.
+ 7. Intellectual Property.
+ This Agreement does not transfer from Free Code Camp to you any Free Code Camp or third party intellectual property, and all right, title, and interest in and to such property will remain (as between the parties) solely with Free Code Camp. Free Code Camp, FreeCodeCamp.com, the FreeCodeCamp.com logo, and all other trademarks, service marks, graphics and logos used in connection with FreeCodeCamp.com or our Services, are trademarks or registered trademarks of Free Code Camp or Free Code Camp’s licensors. Other trademarks, service marks, graphics and logos used in connection with our Services may be the trademarks of other third parties. Your use of our Services grants you no right or license to reproduce or otherwise use any Free Code Camp or third-party trademarks.
+ 10. Changes.
+ We are constantly updating our Services, and that means sometimes we have to change the legal terms under which our Services are offered. If we make changes that are material, we will let you know by posting on one of our websites, or by sending you an email or other communication before the changes take effect. The notice will designate a reasonable period of time after which the new terms will take effect. If you disagree with our changes, then you should stop using our Services within the designated notice period. Your continued use of our Services will be subject to the new terms. However, any dispute that arose before the changes shall be governed by the Terms (including the binding individual arbitration clause) that were in place when the dispute arose.
+ 11. Termination.
+ Free Code Camp may terminate your access to all or any part of our Services at any time, with or without cause, with or without notice, effective immediately. If you wish to terminate this Agreement or your FreeCodeCamp.com account (if you have one), you may simply discontinue using our Services. All provisions of this Agreement which by their nature should survive termination shall survive termination, including, without limitation, ownership provisions, warranty disclaimers, indemnity and limitations of liability.
+ 12. Disclaimer of Warranties.
+ Our Services are provided “as is.” Free Code Camp and its suppliers and licensors hereby disclaim all warranties of any kind, express or implied, including, without limitation, the warranties of merchantability, fitness for a particular purpose and non-infringement. Neither Free Code Camp nor its suppliers and licensors, makes any warranty that our Services will be error free or that access thereto will be continuous or uninterrupted. If you’re actually reading this, we praise your diligence and concern. We'd be better off as a civilization if more people cared like you do. You understand that you download from, or otherwise obtain content or services through, our Services at your own discretion and risk.
+ 13. Limitation of Liability.
+ In no event will Free Code Camp, or its suppliers or licensors, be liable with respect to any subject matter of this Agreement under any contract, negligence, strict liability or other legal or equitable theory for: (i) any special, incidental or consequential damages; (ii) the cost of procurement for substitute products or services; (iii) for interruption of use or loss or corruption of data; or (iv) for any amounts that exceed the fees paid by you to Free Code Camp under this agreement during the twelve (12) month period prior to the cause of action. Free Code Camp shall have no liability for any failure or delay due to matters beyond their reasonable control. The foregoing shall not apply to the extent prohibited by applicable law.
+ 14. General Representation and Warranty.
+ You represent and warrant that (i) your use of our Services will be in strict accordance with the Free Code Camp Privacy Policy, with this Agreement, and with all applicable laws and regulations (including without limitation any local laws or regulations in your country, state, city, or other governmental area, regarding online conduct and acceptable content, and including all applicable laws regarding the transmission of technical data exported from the United States or the country in which you reside) and (ii) your use of our Services will not infringe or misappropriate the intellectual property rights of any third party.
+ 15. US Economic Sanctions.
+ You expressly represent and warrant that your use of our Services and or associated services and products is not contrary to applicable U.S. Sanctions. Such use is prohibited, and Free Code Camp reserve the right to terminate accounts or access of those in the event of a breach of this condition.
+ 16. Indemnification.
+ You agree to indemnify and hold harmless Free Code Camp, its contractors, and its licensors, and their respective directors, officers, employees, and agents from and against any and all claims and expenses, including attorneys’ fees, arising out of your use of our Services, including but not limited to your violation of this Agreement.
+ 17. Translation.
+ These Terms of Service were originally written in English (US). We may translate these terms into other languages. In the event of a conflict between a translated version of these Terms of Service and the English version, the English version will control.
+ 18. Miscellaneous.
+ This Agreement constitutes the entire agreement between Free Code Camp and you concerning the subject matter hereof, and they may only be modified by a written amendment signed by an authorized executive of Free Code Camp, or by the posting by Free Code Camp of a revised version. Except to the extent applicable law, if any, provides otherwise, this Agreement, any access to or use of our Services will be governed by the laws of the state of California, U.S.A., excluding its conflict of law provisions, and the proper venue for any disputes arising out of or relating to any of the same will be the state and federal courts located in San Francisco County, California. Except for claims for injunctive or equitable relief or claims regarding intellectual property rights (which may be brought in any competent court without the posting of a bond), any dispute arising under this Agreement shall be finally settled in accordance with the Comprehensive Arbitration Rules of the Judicial Arbitration and Mediation Service, Inc. (“JAMS”) by three arbitrators appointed in accordance with such Rules. The arbitration shall take place in San Francisco, California, in the English language and the arbitral decision may be enforced in any court. The prevailing party in any action or proceeding to enforce this Agreement shall be entitled to costs and attorneys’ fees. If any part of this Agreement is held invalid or unenforceable, that part will be construed to reflect the parties’ original intent, and the remaining portions will remain in full force and effect. A waiver by either party of any term or condition of this Agreement or any breach thereof, in any one instance, will not waive such term or condition or any subsequent breach thereof. You may assign your rights under this Agreement to any party that consents to, and agrees to be bound by, its terms and conditions; Free Code Camp may assign its rights under this Agreement without condition. This Agreement will be binding upon and will inure to the benefit of the parties, their successors and permitted assigns.
+ These terms are adopted from the Automattic (WordPress) open source terms and are subject to the Creative Commons Attribution-ShareAlike 4.0 International license. We thank them for making this available.
diff --git a/server/views/sponsors/sponsors.html b/server/views/sponsors/sponsors.html
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/server/views/stories/index.jade b/server/views/stories/index.jade
index 196c1bcd3d..56958a7a08 100644
--- a/server/views/stories/index.jade
+++ b/server/views/stories/index.jade
@@ -11,22 +11,22 @@ block content
script.
var challengeName = 'Camper News';
var page = !{JSON.stringify(page)};
- .panel.panel-info
- .panel-heading.text-center Camper News
- .panel-body
- include news-nav
+ h1.text-center Camper News
+ hr
+ .spacer
+ include news-nav
+ .spacer
+ if (page === 'hot')
+ include hot-stories
+ if (page === 'submit')
+ if (user)
+ include preliminary-submit
+ else
.spacer
- if (page === 'hot')
- include hot-stories
- if (page === 'submit')
- if (user)
- include preliminary-submit
- else
- .spacer
- .text-center
- a.btn.btn-cta.signup-btn.btn-primary(href="/login") Sign in to post your story (it's free)
- .spacer
- if (page === 'storySubmission')
- include submit-story
- if (page === 'show')
- include show
+ .text-center
+ a.btn.btn-cta.signup-btn.btn-primary(href="/login") Sign in to post your story (it's free)
+ .spacer
+ if (page === 'storySubmission')
+ include submit-story
+ if (page === 'show')
+ include show
diff --git a/server/views/stories/news-nav.jade b/server/views/stories/news-nav.jade
index c15c30b5d4..bed42d5528 100644
--- a/server/views/stories/news-nav.jade
+++ b/server/views/stories/news-nav.jade
@@ -1,17 +1,17 @@
.row
- .col-xs-12.col-sm-9
- .input-group
- input#searchArea.big-text-field.field-responsive.form-control(type='text', placeholder='search term or @username')
- span.input-group-btn
- button#searchbutton.btn.btn-big.btn-primary.btn-responsive(type='button') Search
- .spacer
.col-xs-12.col-sm-3
span
- a.btn.btn-primary.btn-big.btn-block.btn-responsive(href='/stories/submit' class="#{ page === 'hot' ? '' : 'hidden' }") Submit
+ a.btn.btn-primary.btn-bigger.btn-block.btn-responsive(href='/stories/submit' class="#{ page === 'hot' ? '' : 'hidden' }") Submit a link
span
- a.btn.btn-success.btn-big.btn-block.btn-responsive(href='/news/' class="#{ (page !== 'hot') ? '' : 'hidden' }") All
+ a.btn.btn-success.btn-bigger.btn-block.btn-responsive(href='/news/' class="#{ (page !== 'hot') ? '' : 'hidden' }") All
.visible-xs
.button-spacer
+ .col-xs-12.col-sm-9
+ .input-group
+ input#searchArea.big-text-field.field-responsive.form-control(type='text', placeholder='Search our links')
+ span.input-group-btn
+ button#searchbutton.btn.btn-bigger.btn-primary.btn-responsive(type='button') Search
+ .spacer
#search-results