diff --git a/.gitignore b/.gitignore index 760716c..a08237e 100644 --- a/.gitignore +++ b/.gitignore @@ -25,10 +25,11 @@ build/Release node_modules # User environment variables +*.sublime-project +*.sublime-workspace .DS_Store .lock-wscript .service-credentials -.env bower_components diff --git a/.nvmrc b/.nvmrc index fae6e3d..d0439ff 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -4.2.1 +iojs-v2.0.1 diff --git a/LICENSE.md b/LICENSE.md deleted file mode 100644 index d55d63d..0000000 --- a/LICENSE.md +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015 Code School - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/README.md b/README.md index b9db4db..298436f 100644 --- a/README.md +++ b/README.md @@ -1,79 +1,56 @@ # JavaScript.com -With the help of community members contributing content to the site, -JavaScript.com aims to keep developers up to date on news, frameworks, and libraries. -In addition, we aim to be a gateway for those wanting to learn JavaScript. +This is the repo for the JavaScript.com website. -# Roadmap -JavaScript.com was the product of a hack day and there's a lot of room for -improvement. Check out the current [roadmap](https://github.com/codeschool/JavaScript.com/milestones/v2). +## Installing NVM -### Contributions -We'd love for you to contribute! For the time being, we will be placing a strong -emphasis on getting the code base up to standards before adding new features. - -### Deployments -We have two main branches, `master` and `production`. All PR's will be merged -into `master` which is then merged into `production`. The `production` branch is -the code that is currenly deployed. - -At the moment, `master` is ahead of `production` while we streamline our deploy -process. Please bear with us for the timing being! - - -# Getting Started -#### Installing NVM -Install NVM (`brew install nvm` and follow instructions) +Install NVM (`$ brew install nvm` and follow instructions) ```bash -nvm install 4.2.1 +nvm install iojs-v2.0.1 +nvm use iojs-v2.0.1 npm install -g gulp npm install ``` -#### Building Assets +This app authenticates with GitHub, so you'll need to create a GitHub Application and set ENVs for `GH_CLIENT_ID` and `GH_CLIENT_SECRET`. -To build assets locally, you'll need to install Bower dependencies and run these Gulp tasks: +## Running + +Run the application with `$ npm start`. You can also set the environment variables at start time. Here's an example: ```bash -bower install -gulp sass -gulp javascript +$ GH_CLIENT_ID=myid GH_CLIENT_SECRET=mysecret npm start ``` -Remember to re-run these tasks after pulling or changing branches. - -#### Setup Github Application -This app authenticates with GitHub, so you'll need to create a -[GitHub Application](https://github.com/settings/applications/new). - -Set the **Homepage URL** to `http://localhost:3000` and - -the **Authorization callback URL** to `http://localhost:3000/sessions/auth/github/callback/` +For debugging all the things, run `DEBUG=* npm start`. -#### Environment Variables -We use [dotenv](https://github.com/motdotla/dotenv) to keep ourselves sane with -the various environment variables. +## Database +Whenever you do the initial `npm install` a db called `javascriptcom` is created +for you. In the event that you need to drop that database and recreate it, don't +forget to either run `npm install` again or `createdb javascriptcom` -Copy `example.env` to `.env` and then fill in the variables. The only ones -that are critical locally are Github variables for sign in. For everything else, -you can setup test accounts if you'd like. +NPM will run new migrations whenever you `npm start`. In order for it to work, +you'll need to set the `DATABASE_URL` ENV to pg://localhost:5432/javascriptcom. +Migrations are already run for you after the initial `npm install` -#### Database Setup -Download and install [MongoDB](https://www.mongodb.org/downloads) - -When you run `npm start`, mongod will be forked as a background process. No need -to create the database either. You're all set. - -After you're done, make sure you run `npm stop` to shut down mongod. - -## Running the application - -Run the application with `$ npm start`. +To create new migrations see the node-pg-migraton +[documentation](https://github.com/theoephraim/node-pg-migrate). +After setting your database up run `gulp seeds` to seed your database. ## Development If you add any runtime dependencies, you must run `npm shrinkwrap` and commit changes to `npm-shrinkwrap.json`. +### Building Assets + +To build assets locally, you'll need to install Bower dependencies and run these Gulp tasks: +```bash +$ bower install +$ gulp sass +$ gulp javascript +``` + +Remember to re-run these tasks after pulling or changing branches. diff --git a/bower.json b/bower.json index aaf3142..abee7e7 100644 --- a/bower.json +++ b/bower.json @@ -23,7 +23,7 @@ "autosize": "~3.0.6", "bootstrap": "~3.3.4", "codemirror": "~3.16.0", - "cs_console": "https://github.com/renz45/cs_console/archive/master.zip", + "cs_console": "https://github.com/renz45/cs_console.git#8e3d2722e53a8605641e755bb6b71810da145c30", "jquery": "~2.1.3", "lodash": "~3.5.0", "marked": "~0.3.3", diff --git a/client/javascriptcom/directives/console.directive.js b/client/javascriptcom/directives/console.directive.js index 729fc3a..01b03bf 100644 --- a/client/javascriptcom/directives/console.directive.js +++ b/client/javascriptcom/directives/console.directive.js @@ -20,6 +20,8 @@ angular.module('javascriptcom').directive('jsConsole', ['CSConsole', 'jsCommand' jsSuccessCloud.trigger(); jsChallengeProgress.next(); + + ga('send', 'event', 'challenge', 'success', challenge.id) } var onFailure = function onFailure(challenge) { diff --git a/client/javascripts/application.js b/client/javascripts/application.js index f1dd058..bb0b42f 100644 --- a/client/javascripts/application.js +++ b/client/javascripts/application.js @@ -54,7 +54,14 @@ jQuery(function($) { // ----- Global ----- // + // Classes + + new JS.Classes.Newsletter(); + + // Services + JS.injectSvg({ assetPath : '/images/icons/icons.svg' }); + JS.trackAnalyticsEvents(); }); diff --git a/client/javascripts/components/classes/newsletter.js b/client/javascripts/components/classes/newsletter.js new file mode 100644 index 0000000..2d56eba --- /dev/null +++ b/client/javascripts/components/classes/newsletter.js @@ -0,0 +1,111 @@ +// ************************************* +// +// Newsletter +// -> Run JS events based on current page +// Credit: https://github.com/gitlabhq/gitlabhq/blob/master/app/assets/javascripts/dispatcher.js.coffee +// +// ************************************* +// +// @param $element { jQuery object } +// @param dataAttr { string } +// @param events { array (objects) } +// +// ************************************* + +JS.Classes.Newsletter = (function() { + + // ------------------------------------- + // Private Variables + // ------------------------------------- + + Newsletter.prototype._settings = {}; + + // ------------------------------------- + // Constructor + // ------------------------------------- + + function Newsletter(options) { + this.options = options; + this.init(); + } + + // ------------------------------------- + // Initialize + // ------------------------------------- + + Newsletter.prototype.init = function() { + this._settings = $.extend({ + $element : $('.js-newsletter'), + $error : $('.js-newsletter-error'), + $form : $('.js-newsletter-form'), + hiddenClass : 'is-hidden', + newsletterTextClass : 'newsletter-text', + newsletterTextCopy : "Thanks! You're all set to receive the latest JavaScript news.", + submittedClass : 'is-submitted' + }, this.options); + + this._setEventHandlers(); + }; + + // ------------------------------------- + // Set Event Handlers + // ------------------------------------- + + Newsletter.prototype._setEventHandlers = function() { + var self = this; + + this._settings.$form.on('submit', function(event){ + event.preventDefault(); + + self._submitForm(); + }); + }; + + // ------------------------------------- + // Submit Form + // ------------------------------------- + + Newsletter.prototype._submitForm = function() { + var self = this; + + $.post('/subscribe', this._settings.$form.serialize(), function(results) { + if (results.error) { + self._updateInterface('error', results.error.error); + } else { + self._updateInterface('success'); + } + }); + }; + + // ------------------------------------- + // Update Interface + // ------------------------------------- + + Newsletter.prototype._updateInterface = function(type, message) { + var newsletterTextCopy; + + if (message !== undefined) { + newsletterTextCopy = message; + } else { + newsletterTextCopy = this._settings.newsletterTextCopy; + } + + if (type === 'success') { + this._settings.$element.addClass(this._settings.submittedClass); + this._settings.$element.append("

" + newsletterTextCopy + "

"); + + this._settings.$form.prop('disabled', true); + } else { + this._settings.$error + .text(newsletterTextCopy) + .removeClass(this._settings.hiddenClass); + } + }; + + // ------------------------------------- + // Namespace + // ------------------------------------- + + return Newsletter; + +})(); diff --git a/client/javascripts/components/dispatcher/home.js b/client/javascripts/components/dispatcher/home.js index b42cfb5..6762f79 100644 --- a/client/javascripts/components/dispatcher/home.js +++ b/client/javascripts/components/dispatcher/home.js @@ -7,13 +7,21 @@ JS.Pages.Home = function() { + // ------------------------------------- + // Classes + // ------------------------------------- + + new JS.Classes.Newsletter({ + $element : $('.js-homeNewsletter'), + $error : $('.js-homeNewsletter-error'), + $form : $('.js-homeNewsletter-form') + }); + // ------------------------------------- // Modules // ------------------------------------- JS.Modules.Console.init(); - JS.Modules.Newsletter.init(); - JS.Modules.Video.init({ vendor: true, ytVideo: true }); // ------------------------------------- // Services diff --git a/client/javascripts/components/dispatcher/news.js b/client/javascripts/components/dispatcher/news.js index 1b3367a..8a4cedf 100644 --- a/client/javascripts/components/dispatcher/news.js +++ b/client/javascripts/components/dispatcher/news.js @@ -18,7 +18,6 @@ JS.Pages.News = function() { // ------------------------------------- JS.Modules.LoadStories.init(); - JS.Modules.Newsletter.init(); JS.Modules.SaveProgress.init(); // ------------------------------------- diff --git a/client/javascripts/components/helpers/cleanUrl.js b/client/javascripts/components/helpers/cleanUrl.js new file mode 100644 index 0000000..8d2c8c6 --- /dev/null +++ b/client/javascripts/components/helpers/cleanUrl.js @@ -0,0 +1,21 @@ +// ************************************* +// +// Clean URL +// -> Strip URL parameters +// +// ************************************* + +JS.Helpers.cleanUrl = function(url) { + var anchor = document.createElement('a'); + + anchor.href = url; + + return anchor.protocol + '//' + anchor.host + anchor.pathname; +} + +// ------------------------------------- +// Usage +// ------------------------------------- +// +// JS.Helpers.cleanUrl('https://example.com/?foo=bar#baz') +// diff --git a/client/javascripts/components/modules/console.js b/client/javascripts/components/modules/console.js index 539bc33..14a77f0 100644 --- a/client/javascripts/components/modules/console.js +++ b/client/javascripts/components/modules/console.js @@ -45,6 +45,8 @@ JS.Modules.Console = (function() { if (value.match(JS.Globals.homepageChallengeAnswer)) { $element.removeClass(_settings.incorrectClass); $element.addClass(_settings.correctClass); + + ga('send', 'event', 'challenge', 'success', 1); } else { $element.removeClass(_settings.correctClass); $element.addClass(_settings.incorrectClass); diff --git a/client/javascripts/components/modules/createComment.js b/client/javascripts/components/modules/createComment.js index 9b21b31..670a932 100644 --- a/client/javascripts/components/modules/createComment.js +++ b/client/javascripts/components/modules/createComment.js @@ -75,17 +75,18 @@ JS.Modules.CreateComment = (function() { var _buildComment = function(data) { var comment = ''; + comment+= - '
  • ' + + '
  • ' + '
    ' + '
    ' + - '' + + '' + '
    ' + '
    ' + - '
    ' + + '
    ' + '
    ' + - '' + data.doc.comments[0].user.name + '' + + '' + data.comment.name + '' + '' + '
    ' + '
    ' + @@ -93,9 +94,9 @@ JS.Modules.CreateComment = (function() { '
    ' + '
    ' + '
    ' + - '

    ' + data.doc.comments[0].body + '

    ' + + '

    ' + data.comment.body + '

    ' + '