diff --git a/.gitignore b/.gitignore
index 123ae94..f69aad7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,3 +25,8 @@ build/Release
# Dependency directory
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
node_modules
+
+# Compiled Public Directory
+public/js/
+public/styles/
+public/views/
diff --git a/Gulpfile.js b/Gulpfile.js
new file mode 100644
index 0000000..44f5f45
--- /dev/null
+++ b/Gulpfile.js
@@ -0,0 +1,16 @@
+/*
+ gulpfile.js
+ ===========
+ Rather than manage one giant configuration file responsible
+ for creating multiple tasks, each task has been broken out into
+ its own file in gulp/tasks. Any files in that directory get
+ automatically required below.
+ To add a new task, simply add a new task file that directory.
+ gulp/tasks/default.js specifies the default set of tasks to run
+ when you run `gulp`.
+*/
+
+var requireDir = require('require-dir');
+
+// Require all tasks in gulp/tasks, including subfolders
+requireDir('./gulp/tasks', { recurse: true });
diff --git a/comps/intelly-blog-III@2x.psd b/comps/intelly-blog-III@2x.psd
deleted file mode 100644
index ebfdb1a..0000000
Binary files a/comps/intelly-blog-III@2x.psd and /dev/null differ
diff --git a/comps/intelly-blog-post@2x.psd b/comps/intelly-blog-post@2x.psd
deleted file mode 100644
index 0964434..0000000
Binary files a/comps/intelly-blog-post@2x.psd and /dev/null differ
diff --git a/gulp/config.js b/gulp/config.js
new file mode 100644
index 0000000..84bcda2
--- /dev/null
+++ b/gulp/config.js
@@ -0,0 +1,35 @@
+var dest = "./public";
+var src = './src';
+
+module.exports = {
+ javascript: {
+ src: src + '/app/**/*.js',
+ dest: dest + '/js/',
+ entryPoint: src + '/app/entry.js',
+ packedFile: 'packed.js'
+ },
+ sass: {
+ src: src + "/styles/**/*.{sass,scss}",
+ dest: dest + '/styles/',
+ settings: {
+ indentedSyntax: true, // Enable .sass syntax!
+ }
+ },
+ fonts: {
+ src: src + '/styles/fonts/*',
+ dest: dest + "/styles/fonts/",
+ extensions: ['woff2', 'woff', 'eot', 'ttf', 'svg']
+ },
+ html: {
+ src: src + "/app/**/*.html",
+ dest: dest + "/views/"
+ },
+ server: {
+ serverFile: './server.js'
+ },
+ production: {
+ cssSrc: dest + '/styles/*.css',
+ jsSrc: dest + '/*.js',
+ dest: dest
+ }
+};
diff --git a/gulp/tasks/default.js b/gulp/tasks/default.js
new file mode 100644
index 0000000..8026d44
--- /dev/null
+++ b/gulp/tasks/default.js
@@ -0,0 +1,3 @@
+var gulp = require('gulp');
+
+gulp.task('default', ['sass', 'fonts', 'html', 'webpack', 'watch', 'serve']);
diff --git a/gulp/tasks/fonts.js b/gulp/tasks/fonts.js
new file mode 100644
index 0000000..4347662
--- /dev/null
+++ b/gulp/tasks/fonts.js
@@ -0,0 +1,7 @@
+var gulp = require("gulp");
+var config = require('../config').fonts;
+
+gulp.task('fonts', function() {
+ return gulp.src(config.src)
+ .pipe(gulp.dest(config.dest));
+});
diff --git a/gulp/tasks/html.js b/gulp/tasks/html.js
new file mode 100644
index 0000000..0b29aff
--- /dev/null
+++ b/gulp/tasks/html.js
@@ -0,0 +1,7 @@
+var gulp = require("gulp");
+var config = require('../config').html;
+
+gulp.task('html', function() {
+ return gulp.src(config.src)
+ .pipe(gulp.dest(config.dest));
+});
diff --git a/gulp/tasks/sass.js b/gulp/tasks/sass.js
new file mode 100644
index 0000000..2f24254
--- /dev/null
+++ b/gulp/tasks/sass.js
@@ -0,0 +1,16 @@
+var gulp = require('gulp');
+var sass = require('gulp-sass');
+var autoprefixer = require('gulp-autoprefixer');
+var handleErrors = require('../util/handleErrors');
+var config = require('../config').sass;
+
+gulp.task('sass', function () {
+ return gulp.src(config.src)
+ .pipe(sass(config.settings))
+ .pipe(autoprefixer({
+ browsers: ['last 2 versions'],
+ cascade: false
+ }))
+ .on('error', handleErrors)
+ .pipe(gulp.dest(config.dest));
+});
diff --git a/gulp/tasks/serve.js b/gulp/tasks/serve.js
new file mode 100644
index 0000000..583b9fa
--- /dev/null
+++ b/gulp/tasks/serve.js
@@ -0,0 +1,9 @@
+var gulp = require('gulp');
+var config = require('../config').server;
+var server = require("gulp-express");
+
+gulp.task('serve', ['sass', 'fonts', 'html', 'webpack', 'watch'], function() {
+ server.run([config.serverFile]);
+
+ gulp.watch([config.serverFile], [server.run]);
+});
diff --git a/gulp/tasks/watch.js b/gulp/tasks/watch.js
new file mode 100644
index 0000000..a84ee24
--- /dev/null
+++ b/gulp/tasks/watch.js
@@ -0,0 +1,8 @@
+var gulp = require('gulp');
+var config = require('../config');
+
+gulp.task('watch', function() {
+ gulp.watch(config.javascript.src, ['webpack']);
+ gulp.watch(config.sass.src, ['sass']);
+ gulp.watch(config.html.src, ['html']);
+});
diff --git a/gulp/tasks/webpack.js b/gulp/tasks/webpack.js
new file mode 100644
index 0000000..7dded07
--- /dev/null
+++ b/gulp/tasks/webpack.js
@@ -0,0 +1,13 @@
+var gulp = require('gulp');
+var config = require('../config').javascript;
+var webpack = require('webpack-stream');
+
+gulp.task('webpack', function(callback) {
+ return gulp.src(config.entryPoint)
+ .pipe(webpack({
+ output: {
+ filename: config.packedFile
+ }
+ }))
+ .pipe(gulp.dest(config.dest));
+});
diff --git a/gulp/util/handleErrors.js b/gulp/util/handleErrors.js
new file mode 100644
index 0000000..a6e481d
--- /dev/null
+++ b/gulp/util/handleErrors.js
@@ -0,0 +1,15 @@
+var notify = require("gulp-notify");
+
+module.exports = function() {
+
+ var args = Array.prototype.slice.call(arguments);
+
+ // Send error to notification center with gulp-notify
+ notify.onError({
+ title: "Compile Error",
+ message: "<%= error %>"
+ }).apply(this, args);
+
+ // Keep gulp from hanging on this task
+ this.emit('end');
+};
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..50eeb4d
--- /dev/null
+++ b/package.json
@@ -0,0 +1,39 @@
+{
+ "name": "mean-stack-1",
+ "version": "1.0.0",
+ "description": "Last week we focussed on JavaScript basics. This week we're going to build up a function web application. You'll be expected to build on knowledge you've already learned (semantic HTML, Sass instead of CSS, in addition to all of the Angular work we'll be doing) and produce a \"production-ready\" blog for your assignment this week.",
+ "main": "server.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/pstrum/mean-stack-1.git"
+ },
+ "author": "",
+ "license": "ISC",
+ "bugs": {
+ "url": "https://github.com/pstrum/mean-stack-1/issues"
+ },
+ "homepage": "https://github.com/pstrum/mean-stack-1#readme",
+ "dependencies": {
+ "angular": "^1.4.7",
+ "angular-route": "^1.4.7",
+ "body-parser": "^1.14.1",
+ "connect-livereload": "^0.5.3",
+ "express": "^4.13.3",
+ "gulp": "^3.9.0",
+ "gulp-autoprefixer": "^3.0.2",
+ "gulp-express": "^0.3.5",
+ "gulp-livereload": "^3.8.1",
+ "gulp-notify": "^2.2.0",
+ "gulp-rename": "^1.2.2",
+ "gulp-run": "^1.6.11",
+ "gulp-sass": "^2.0.4",
+ "mongoose": "^4.1.10",
+ "node-bourbon": "^4.2.3",
+ "require-dir": "^0.3.0",
+ "webpack": "^1.12.2",
+ "webpack-stream": "^2.1.1"
+ }
+}
diff --git a/public/index.html b/public/index.html
new file mode 100644
index 0000000..b477b50
--- /dev/null
+++ b/public/index.html
@@ -0,0 +1,80 @@
+
+
+
+
+
+ Intelly
+
+
+
+
+
+
+
+
intelly
+
+
+
+
+
Blog
+
The secular cooling that must someday overtake our planet has already gone far indeed with our neighbour. Its physical condition is still largely a mystery, but we know now that even in its equatorial
Serene in their assurance of their empire over matter
+
No one would have believed in the last years of the nine- teenth century that this world was being watched keenly and closely by intelligences greater than man’s
+ Contact now
+ Learn more
+
+
+
+
+
+
diff --git a/server.js b/server.js
new file mode 100644
index 0000000..30fbf26
--- /dev/null
+++ b/server.js
@@ -0,0 +1,107 @@
+// CALL THE PACKAGES WE NEED TO SET UP THE SERVER
+// ==============================================
+// Require Express Module
+var express = require('express');
+// Declare the variable 'app', create the Express Application
+var app = express();
+// bodyParser to expose various factories to create middlewares
+var bodyParser = require('body-parser');
+// Parses urlencoded bodies; Extend option chooses parsing with qs library
+app.use(bodyParser.urlencoded({ extended: true }));
+// Parses json
+app.use(bodyParser.json());
+// Grab the mongoos package
+var mongoose = require('mongoose');
+// Connect to our local database, named directory auto generated
+mongoose.connect('mongodb://localhost/blogs');
+// Grab the blog post model
+var Blog = require('./src/app/models/blog-post');
+// Environment defined port, OR 8000
+var port = process.env.PORT || 8000;
+// Use built in middleware; pass the directory; use absolute path to directory to serve
+app.use(express.static(__dirname + '/public'));
+// API ROUTES - How our app responds to client requests
+// ==========
+// Get instance of Express Router to handle all our routes
+var router = express.Router();
+// All routes prefixed with /api; add to middleware stack
+app.use('/api', router);
+// Something to happen every time a request is sent to our API
+router.use(function(req, res, next) {
+ console.log('Something is HAPPENING...');
+ // make sure we go to the next routes and don't stop here.
+ next();
+});
+// Define the home route (accessed at GET localhost:8000/api)
+router.get('/', function(req, res) {
+ res.json({ message: 'YOLO! WELCOME to our API!' });
+});
+// app.route('/').get(function(req, res) {
+// res.sendFile('index.html', {root: __dirname + '/public'});
+// });
+// To handle multiple routes for the same URI; all req that end in /blog-post
+router.route('/blog-post')
+ // Create a POST (accessed at POST localhost:8000/api/posts)
+ .post(function(req, res) {
+ // New instance of the Blog model
+ var blog = new Blog();
+ // Set the post title, author, content (comes from request)
+ blog.title = req.body.title;
+ blog.author = req.body.author;
+ blog.content = req.body.content;
+ // Save the post and check for errors
+ blog.save(function(err) {
+ if (err)
+ res.send(err);
+ res.json(blog);
+ });
+ })
+ // Get ALL the posts; chaining routes together...
+ .get(function(req, res) {
+ Blog.find(function(err, blogs) {
+ if (err)
+ res.send(err);
+ res.json(blogs);
+ });
+ });
+// To handle all requests that have a :blog_id--accessed through body-parser
+router.route('/blog-post/:blog_id')
+ // Get a post with that id (accessed at GET localhost:8000/api/blog-post/:blog_id)
+ .get(function(req, res) {
+ Blog.findById(req.params.blog_id, function(err, blog) {
+ if (err)
+ res.send(err);
+ res.json(blog);
+ });
+ })
+ // Update a post (accessed at PUT localhost:8080/api/blog-post/:blog_id)
+ .put(function(req, res) {
+ // Use the blog model to find the post we want
+ Blog.findById(req.params.blog_id, function(err, blog) {
+ if (err)
+ res.send(err);
+ // Update the post info
+ blog.title = req.body.title;
+ blog.author = req.body.author;
+ blog.content = req.body.content;
+ // Save the post!
+ blog.save(function(err) {
+ if (err)
+ res.send(err);
+ res.json(blog);
+ });
+ });
+ })
+ // Delete a post (accessed at DELETE localhost:8080/api/blog-post/:blog_id)
+ .delete(function(req, res) {
+ Blog.remove({
+ _id: req.params.blog_id
+ }, function(err, blog) {
+ if (err)
+ res.send(err);
+ res.json(blog);
+ });
+ });
+// START THE SERVER
+app.listen(port);
+console.log("Fancy stuff on port " + port);
diff --git a/src/app/app.js b/src/app/app.js
new file mode 100644
index 0000000..739c911
--- /dev/null
+++ b/src/app/app.js
@@ -0,0 +1,50 @@
+require('angular');
+require('angular-route');
+
+(function() {
+
+ "use strict";
+
+ // Declare variable app, which equals a new AngularJS module
+ // with the name 'intelly'. ngRoute is a dependency used for
+ // routing and deeplinking services
+ var app = angular.module('intellyApp', ["ngRoute"]);
+
+ // $routeProvider is a provider in the ngRoute module
+ // used for configuring routes.
+ // App routes are declared with $routeProvider.
+ app.config(["$routeProvider", function($routeProvider) {
+ // The $location service parses the URL in the browser address bar (based on the window.location) and makes the URL available to your application
+ // This method is getter / setter.
+
+ // Return path of current url
+ // Add a new route definition to the $route service.
+ // The route path (/blog-post) is (matched against $location.path)
+ // which is a getter/setter that parses the address bar url
+ // and makes it available to our app
+ $routeProvider.when('/blog-post', {
+ // This is the route object:
+ templateUrl: "views/blog/blog-post.html",
+ controller: "BlogsCtrl as vm"
+ }).
+ when('/blog-post/new', {
+ templateUrl: "views/posts/blog-post-form.html",
+ controller: "BlogFormCtrl as vm",
+ }).
+ when('/blog-post/:blog_id', {
+ templateUrl: "views/posts/blog-post-detail.html",
+ controller: "BlogCtrl as vm"
+ }).
+ when('/blog-post/:blog_id/edit', {
+ templateUrl: "views/posts/blog-post-form.html",
+ controller: "BlogFormCtrl as vm"
+ }).
+ when('/blog-post/:blog_id/destroy', {
+ templateUrl: "views/posts/blog-post-detail.html",
+ controller: "BlogFormCtrl as vm"
+ }).
+ otherwise({
+ redirectTo: "/blog-post"
+ });
+ }]);
+})();
diff --git a/src/app/blog/blog-post.html b/src/app/blog/blog-post.html
new file mode 100644
index 0000000..d7811c1
--- /dev/null
+++ b/src/app/blog/blog-post.html
@@ -0,0 +1,23 @@
+
+
+
+
diff --git a/src/app/blog/blog.service.js b/src/app/blog/blog.service.js
new file mode 100644
index 0000000..7ff13ff
--- /dev/null
+++ b/src/app/blog/blog.service.js
@@ -0,0 +1,40 @@
+require('../app.js');
+
+// Organize and share code around out app
+(function () {
+
+ "use strict";
+
+ // Name the service and specify the $http service as a dependency -- inject it to use it
+ angular.module("intellyApp").service("BlogsService", ["$http", function ($http) {
+
+ // Declare urlRoot
+ var urlRoot = "/api/blog-post";
+
+ // Declare blog object with 4 methods
+ var Blog = {
+ // Get function with blog post ID as argument
+ // Function will return a promise
+ get: function (id) {
+ // Determine if a reference (post ID) is defined
+ if (angular.isDefined(id)) {
+ // Send in the URL with ID to the get method
+ return $http.get(urlRoot + "/" + id);
+ } else {
+ // Send in the base URL
+ return $http.get(urlRoot);
+ }
+ },
+ update: function (model) {
+ return $http.put(urlRoot + "/" + model._id, model);
+ },
+ create: function (model) {
+ return $http.post(urlRoot, model);
+ },
+ delete: function (model) {
+ return $http.delete(urlRoot + "/" + model._id);
+ }
+ };
+ return Blog;
+ }]);
+}());
diff --git a/src/app/blog/blogs.ctrl.js b/src/app/blog/blogs.ctrl.js
new file mode 100644
index 0000000..01bd0c4
--- /dev/null
+++ b/src/app/blog/blogs.ctrl.js
@@ -0,0 +1,54 @@
+require('../app.js');
+
+(function() {
+
+ 'use strict';
+
+ angular.module('intellyApp').controller("BlogsCtrl", ["BlogsService", "$anchorScroll", "$location", function(BlogsService, $anchorScroll, $location) {
+
+ var vm = this;
+
+ // Initialize blogs to an empty array
+ // (since our page will render before data returns from get request)
+ vm.blogs = [];
+
+ // Create delete method using deleteBlog function
+ vm.delete = deleteBlog;
+ // Create scroll method using toBreadcrumbs function
+ vm.scroll = toBreadcrumbs;
+
+ // Initialize the controller
+ initialize();
+
+ function initialize () {
+ getBlogs();
+ }
+
+ function getBlogs () {
+ // Run the get method from the BlogsService service
+ // Then (or success) send in a callback with the response (from promise)
+ BlogsService.get().then(function(resp) {
+ // Store the data in the blogs array
+ // Set the property 'blogs' (array) equal to an array of objects
+ vm.blogs = resp.data;
+ console.log(vm.blogs);
+ });
+ }
+
+ function deleteBlog (blog) {
+ BlogsService.delete(blog).then(function () {
+ getBlogs();
+ });
+ }
+
+ function toBreadcrumbs () {
+ // set the location.hash to the id of
+ // the element you wish to scroll to.
+ $location.hash('blog-scroll');
+
+ // call $anchorScroll()
+ $anchorScroll();
+ }
+
+ }]);
+}());
diff --git a/src/app/entry.js b/src/app/entry.js
new file mode 100644
index 0000000..dd23b0d
--- /dev/null
+++ b/src/app/entry.js
@@ -0,0 +1,5 @@
+require('./app.js');
+require('./posts/blog.ctrl.js');
+require('./blog/blogs.ctrl.js');
+require('./posts/blog_form.ctrl.js');
+require('./blog/blog.service.js');
diff --git a/src/app/models/blog-post.js b/src/app/models/blog-post.js
new file mode 100644
index 0000000..73c8712
--- /dev/null
+++ b/src/app/models/blog-post.js
@@ -0,0 +1,18 @@
+// Require mongoose
+var mongoose = require('mongoose');
+
+// Each schema maps to a MongoDB collection
+// and defines the shape of the documents within that collection.
+// Get a reference to Schema and define our blog.
+var Schema = mongoose.Schema;
+
+var blogSchema = new Schema ({
+ title: String,
+ author: String,
+ content: String,
+ comments: [{ body: String, date: Date}],
+ date: { type: Date, default: Date.now}
+});
+
+// Allow access in server.js to use in our app
+module.exports = mongoose.model('Blog', blogSchema);
diff --git a/src/app/posts/blog-post-detail.html b/src/app/posts/blog-post-detail.html
new file mode 100644
index 0000000..f1ffb51
--- /dev/null
+++ b/src/app/posts/blog-post-detail.html
@@ -0,0 +1,13 @@
+
+