From 5b60c4b07bbbb2bfdf01a2925bf745202af2cd9e Mon Sep 17 00:00:00 2001 From: timcmiller Date: Tue, 1 Dec 2015 15:45:17 -0800 Subject: [PATCH 01/18] adding CRUD to my Mongo DB --- tim_miller/app/index.html | 51 ++++++++++++++++--- tim_miller/app/js/busted/busted.js | 4 ++ .../busted/controllers/busted_controller.js | 14 +++++ tim_miller/app/js/entry.js | 12 ++--- .../js/felons/controllers/felon_controller.js | 25 +++++++++ tim_miller/app/js/felons/felons.js | 4 ++ .../controllers/officer_controller.js | 49 ++++++++++++++++++ tim_miller/app/js/officers/officers.js | 4 ++ tim_miller/routes/felonroutes.js | 6 +-- tim_miller/routes/officerroutes.js | 8 +-- tim_miller/server.js | 34 ++++++++----- 11 files changed, 175 insertions(+), 36 deletions(-) create mode 100644 tim_miller/app/js/busted/busted.js create mode 100644 tim_miller/app/js/busted/controllers/busted_controller.js create mode 100644 tim_miller/app/js/felons/controllers/felon_controller.js create mode 100644 tim_miller/app/js/felons/felons.js create mode 100644 tim_miller/app/js/officers/controllers/officer_controller.js create mode 100644 tim_miller/app/js/officers/officers.js diff --git a/tim_miller/app/index.html b/tim_miller/app/index.html index c6337f3..729ecce 100644 --- a/tim_miller/app/index.html +++ b/tim_miller/app/index.html @@ -2,15 +2,52 @@ - Wow such website! + Cops! - -
-

Bad Boys Bad Boys

-

{{greeting}}

+ +

Bad Boys Bad Boys

+
+
    +
  • {{error}}
  • +
+
+

New Officer:

+ + + +
+
+

New Felon:

+ + + +
+
    +
  • {{officer.name}} + +
    - - +

    Update Officer:

    + + + + + + + +
    + +
  • +
+
+
+
    +
  • {{felon.name}}
  • +
+
+
+ +

{{busted}}

diff --git a/tim_miller/app/js/busted/busted.js b/tim_miller/app/js/busted/busted.js new file mode 100644 index 0000000..843a0d4 --- /dev/null +++ b/tim_miller/app/js/busted/busted.js @@ -0,0 +1,4 @@ +module.exports = function(app) { + require('./controllers/busted_controller')(app); + +}; diff --git a/tim_miller/app/js/busted/controllers/busted_controller.js b/tim_miller/app/js/busted/controllers/busted_controller.js new file mode 100644 index 0000000..2a7f119 --- /dev/null +++ b/tim_miller/app/js/busted/controllers/busted_controller.js @@ -0,0 +1,14 @@ +module.exports = function(app) { + app.controller('BustedController', ['$scope', '$http', function($scope, $http) { + $scope.busted = ''; + + $scope.get = function() { + $http.get('/api/busted') + .then(function(res) { + $scope.busted = res.data.busted; + }, function(err) { + console.log(err.data); + }); + }; + }]); +}; diff --git a/tim_miller/app/js/entry.js b/tim_miller/app/js/entry.js index 45343e2..a660c4b 100644 --- a/tim_miller/app/js/entry.js +++ b/tim_miller/app/js/entry.js @@ -1,11 +1,7 @@ require('angular/angular'); var angular = window.angular; -var officerApp = angular.module('officersAndFelons', []); -officerApp.controller('OfficerController', ['$scope', function($scope) { - $scope.greeting = 'What cha gonna do when the come for you?'; - - $scope.alertGreeting = function() { - alert($scope.greeting); - }; -}]); +var officerAndFelonApp = angular.module('OfficerAndFelonApp', []); +require('./officers/officers.js')(officerAndFelonApp); +require('./felons/felons.js')(officerAndFelonApp); +require('./busted/busted.js')(officerAndFelonApp); diff --git a/tim_miller/app/js/felons/controllers/felon_controller.js b/tim_miller/app/js/felons/controllers/felon_controller.js new file mode 100644 index 0000000..a212996 --- /dev/null +++ b/tim_miller/app/js/felons/controllers/felon_controller.js @@ -0,0 +1,25 @@ +module.exports = function(app) { + app.controller('FelonsController', ['$scope', '$http', function($scope, $http) { + $scope.felons = []; + $scope.newOfficer = null; + + $scope.getAllFelons = function() { + $http.get('/api/felons') + .then(function(res) { + $scope.felons = res.data; + }, function(err) { + console.log(err.data); + }); + }; + + $scope.create = function(felon) { + $http.post('api/felons', felon) + .then(function(res) { + $scope.felons.push(res.data); + $scope.newFelon = null; + }, function(err) { + console.log(err.data); + }); + }; + }]); +}; diff --git a/tim_miller/app/js/felons/felons.js b/tim_miller/app/js/felons/felons.js new file mode 100644 index 0000000..057442c --- /dev/null +++ b/tim_miller/app/js/felons/felons.js @@ -0,0 +1,4 @@ +module.exports = function(app) { + require('./controllers/felon_controller')(app); + +}; diff --git a/tim_miller/app/js/officers/controllers/officer_controller.js b/tim_miller/app/js/officers/controllers/officer_controller.js new file mode 100644 index 0000000..f240a1b --- /dev/null +++ b/tim_miller/app/js/officers/controllers/officer_controller.js @@ -0,0 +1,49 @@ +module.exports = function(app) { + app.controller('OfficersController', ['$scope', '$http', function($scope, $http) { + $scope.officers = []; + $scope.errors = []; + $scope.newOfficer = null; + + $scope.getAllOfficers = function() { + $http.get('/api/officers') + .then(function(res) { + $scope.officers = res.data; + }, function(err) { + console.log(err.data); + }); + }; + + $scope.create = function(officer) { + $http.post('api/officers', officer) + .then(function(res) { + $scope.officers.push(res.data); + $scope.newOfficer = null; + }, function(err) { + console.log(err.data); + }); + }; + + $scope.remove = function(officer) { + $scope.officers.splice($scope.officers.indexOf(officer), 1); + $http.delete('/api/officers/' + officer._id) + .then(function(res) { + console.log('Done'); + }, function(err) { + console.log(err.data); + $scope.errors.push('Could not delete Officer: ' + officer.name); + $scope.getAllOfficers(); + }); + }; + + $scope.update = function(officer) { + officers.editing = false; + $http.put('/api/officers/' + officer._id, officer) + .then(function(res) { + console.log('this officer has a new name'); + }, function(err) { + $scope.errors.push('could not get officer: ' + officer.name); + console.log(err.data); + }); + }; + }]); +}; diff --git a/tim_miller/app/js/officers/officers.js b/tim_miller/app/js/officers/officers.js new file mode 100644 index 0000000..bdfb8a3 --- /dev/null +++ b/tim_miller/app/js/officers/officers.js @@ -0,0 +1,4 @@ +module.exports = function(app) { + require('./controllers/officer_controller')(app); + +}; diff --git a/tim_miller/routes/felonroutes.js b/tim_miller/routes/felonroutes.js index 9924e19..de42c5f 100644 --- a/tim_miller/routes/felonroutes.js +++ b/tim_miller/routes/felonroutes.js @@ -15,7 +15,7 @@ felonRouter.get('/felons', function(req, res) { }); }); -felonRouter.post('/felons', bodyParser.json(), eatAuth, function(req, res) { +felonRouter.post('/felons', bodyParser.json(), /*eatAuth,*/ function(req, res) { var newFelon = new Felon(req.body); newFelon.save(function(err, data) { @@ -25,7 +25,7 @@ felonRouter.post('/felons', bodyParser.json(), eatAuth, function(req, res) { }); }); -felonRouter.put('/felons', bodyParser.json(), eatAuth, function(req, res) { +felonRouter.put('/felons', bodyParser.json(), /*eatAuth,*/ function(req, res) { var felonData = req.body; delete req.body._id; @@ -36,7 +36,7 @@ felonRouter.put('/felons', bodyParser.json(), eatAuth, function(req, res) { }); }); -felonRouter.delete('/felons/:id', bodyParser.json(), eatAuth, function(req, res) { +felonRouter.delete('/felons/:id', bodyParser.json(), /*eatAuth,*/ function(req, res) { Felon.remove({_id: req.params._id}, function(err) { if(err) return error.default(err, res); diff --git a/tim_miller/routes/officerroutes.js b/tim_miller/routes/officerroutes.js index bc86d3c..9d33291 100644 --- a/tim_miller/routes/officerroutes.js +++ b/tim_miller/routes/officerroutes.js @@ -11,11 +11,11 @@ officerRouter.get('/officers', function(req, res) { Officer.find({}, function(err, data) { if(err) return error.default(err, res); - res.json(data); + res.send(data); }); }); -officerRouter.post('/officers', bodyParser.json(), eatAuth, function(req, res) { +officerRouter.post('/officers', bodyParser.json(), /*eatAuth,*/ function(req, res) { var newOfficer = new Officer(req.body); newOfficer.save(function(err, data) { @@ -25,7 +25,7 @@ officerRouter.post('/officers', bodyParser.json(), eatAuth, function(req, res) { }); }); -officerRouter.put('/officers', bodyParser.json(), eatAuth, function(req, res) { +officerRouter.put('/officers', bodyParser.json(), /*eatAuth,*/ function(req, res) { var officerData = req.body; delete officerData._id; @@ -36,7 +36,7 @@ officerRouter.put('/officers', bodyParser.json(), eatAuth, function(req, res) { }); }); -officerRouter.delete('/officers/:id',bodyParser.json(), eatAuth, function(req, res) { +officerRouter.delete('/officers/:id',bodyParser.json(), /*eatAuth,*/ function(req, res) { Officer.remove({_id: req.params._id}, function(err) { if(err) return error.default(err, res); diff --git a/tim_miller/server.js b/tim_miller/server.js index f09d369..884ea67 100644 --- a/tim_miller/server.js +++ b/tim_miller/server.js @@ -11,20 +11,26 @@ var app = express(); process.env.APP_SECRET = process.env.APP_SECRET || '123451234512345'; mongoose.connect(process.env.MONGOLAB_URI || 'mongodb://localhost/officer_dev'); -app.use(officerRouter, felonRouter, bustedRouter, chuckRouter, authRouter); - -app.get('/:filename', function(req, res, next) { - fs.stat(__dirname + '/build/' + req.params.filename, function(err, stats) { - if (err) {console.log(err); - return next(); - } - - if (!stats.isFile()) return next(); - - var file = fs.createReadStream(__dirname + '/build/' + req.params.filename); - file.pipe(res); - }); -}); +app.use('/api', officerRouter, felonRouter, bustedRouter, chuckRouter, authRouter); +app.use('/api', felonRouter); +app.use('/api', bustedRouter); +app.use('/api', chuckRouter); +app.use('/api', authRouter); +app.use(express.static(__dirname + '/build')); + + +// app.get('/:filename', function(req, res, next) { +// fs.stat(__dirname + '/build/' + req.params.filename, function(err, stats) { +// if (err) {console.log(err); +// return next(); +// } + +// if (!stats.isFile()) return next(); + +// var file = fs.createReadStream(__dirname + '/build/' + req.params.filename); +// file.pipe(res); +// }); +// }); app.use(function(req, res) { res.status(404).send('could not find file'); From 053289e9ccf62ca802ade13ad4b0cfeaa6a2bbe2 Mon Sep 17 00:00:00 2001 From: timcmiller Date: Tue, 1 Dec 2015 20:08:09 -0800 Subject: [PATCH 02/18] added CRUD for felons --- tim_miller/.gitignore | 1 + tim_miller/app/index.html | 101 +++++++++++------- .../busted/controllers/busted_controller.js | 8 +- tim_miller/app/js/entry.js | 1 + .../js/felons/controllers/felon_controller.js | 36 ++++++- .../controllers/officer_controller.js | 14 ++- tim_miller/routes/felonroutes.js | 8 +- tim_miller/routes/officerroutes.js | 10 +- 8 files changed, 125 insertions(+), 54 deletions(-) diff --git a/tim_miller/.gitignore b/tim_miller/.gitignore index 6b84670..cfea63f 100644 --- a/tim_miller/.gitignore +++ b/tim_miller/.gitignore @@ -3,3 +3,4 @@ **/db **/tim_miller/db build/** + diff --git a/tim_miller/app/index.html b/tim_miller/app/index.html index 729ecce..ab7d65a 100644 --- a/tim_miller/app/index.html +++ b/tim_miller/app/index.html @@ -6,48 +6,67 @@

Bad Boys Bad Boys

-
-
    -
  • {{error}}
  • -
-
-

New Officer:

- - - -
-
-

New Felon:

- - - -
-
    -
  • {{officer.name}} - -
    - -

    Update Officer:

    - - - - - - - -
    - -
  • -
-
-
-
    -
  • {{felon.name}}
  • -
-
- -

{{busted}}

+ +

{{outcome}}

+ +
+
    +
  • {{error}}
  • +
+
+

New Officer:

+ + + +
+
    +
  • Name: {{officer.name}} Criminals Busted: {{officer.criminalsBusted}} + +
    + +

    Update Officer:

    + + + + + + + +
    + +
  • +
+
+
+ +
+

New Felon:

+ + + +
+ +
    +
  • Name: {{felon.name}} In Jail: {{felon.inJail}} + + +
    + +

    Update felon:

    + + + + + + + +
    + +
  • +
+ +
diff --git a/tim_miller/app/js/busted/controllers/busted_controller.js b/tim_miller/app/js/busted/controllers/busted_controller.js index 2a7f119..29dc17c 100644 --- a/tim_miller/app/js/busted/controllers/busted_controller.js +++ b/tim_miller/app/js/busted/controllers/busted_controller.js @@ -1,11 +1,13 @@ module.exports = function(app) { app.controller('BustedController', ['$scope', '$http', function($scope, $http) { - $scope.busted = ''; - $scope.get = function() { + $scope.busted = function() { $http.get('/api/busted') .then(function(res) { - $scope.busted = res.data.busted; + $scope.outcome = res.data; + $scope.$broadcast(updateOfficers()); + $scope.$broadcast(updateFelons()); + }, function(err) { console.log(err.data); }); diff --git a/tim_miller/app/js/entry.js b/tim_miller/app/js/entry.js index a660c4b..7e78c98 100644 --- a/tim_miller/app/js/entry.js +++ b/tim_miller/app/js/entry.js @@ -5,3 +5,4 @@ var officerAndFelonApp = angular.module('OfficerAndFelonApp', []); require('./officers/officers.js')(officerAndFelonApp); require('./felons/felons.js')(officerAndFelonApp); require('./busted/busted.js')(officerAndFelonApp); + diff --git a/tim_miller/app/js/felons/controllers/felon_controller.js b/tim_miller/app/js/felons/controllers/felon_controller.js index a212996..59e5ac4 100644 --- a/tim_miller/app/js/felons/controllers/felon_controller.js +++ b/tim_miller/app/js/felons/controllers/felon_controller.js @@ -1,7 +1,7 @@ module.exports = function(app) { app.controller('FelonsController', ['$scope', '$http', function($scope, $http) { $scope.felons = []; - $scope.newOfficer = null; + $scope.newFelon = null; $scope.getAllFelons = function() { $http.get('/api/felons') @@ -21,5 +21,39 @@ module.exports = function(app) { console.log(err.data); }); }; + + $scope.remove = function(felon) { + $scope.felons.splice($scope.felons.indexOf(felon), 1); + $http.delete('/api/felons/' + felon._id) + .then(function(res) { + console.log('Done'); + }, function(err) { + console.log(err.data); + $scope.errors.push('Could not delete felon: ' + felon.name); + $scope.getAllfelons(); + }); + }; + + $scope.update = function(felon) { + felon.tempName = ''; + felon.editing = false; + $http.put('/api/felons/' + felon._id, felon) + .then(function(res) { + console.log('this felon has a new name'); + }, function(err) { + $scope.errors.push('could not get felon: ' + felon.name); + console.log(err.data); + }); + }; + + $scope.temp = function(felon) { + felon.editing = true; + felon.tempName = felon.name; + }; + + $scope.cancel = function(felon) { + felon.editing = false; + felon.name = felon.tempName; + }; }]); }; diff --git a/tim_miller/app/js/officers/controllers/officer_controller.js b/tim_miller/app/js/officers/controllers/officer_controller.js index f240a1b..6a23c60 100644 --- a/tim_miller/app/js/officers/controllers/officer_controller.js +++ b/tim_miller/app/js/officers/controllers/officer_controller.js @@ -4,6 +4,7 @@ module.exports = function(app) { $scope.errors = []; $scope.newOfficer = null; + $scope.getAllOfficers = function() { $http.get('/api/officers') .then(function(res) { @@ -36,7 +37,8 @@ module.exports = function(app) { }; $scope.update = function(officer) { - officers.editing = false; + officer.tempName = ''; + officer.editing = false; $http.put('/api/officers/' + officer._id, officer) .then(function(res) { console.log('this officer has a new name'); @@ -45,5 +47,15 @@ module.exports = function(app) { console.log(err.data); }); }; + + $scope.temp = function(officer) { + officer.editing = true; + officer.tempName = officer.name; + }; + + $scope.cancel = function(officer) { + officer.editing = false; + officer.name = officer.tempName; + }; }]); }; diff --git a/tim_miller/routes/felonroutes.js b/tim_miller/routes/felonroutes.js index de42c5f..358871a 100644 --- a/tim_miller/routes/felonroutes.js +++ b/tim_miller/routes/felonroutes.js @@ -25,11 +25,11 @@ felonRouter.post('/felons', bodyParser.json(), /*eatAuth,*/ function(req, res) { }); }); -felonRouter.put('/felons', bodyParser.json(), /*eatAuth,*/ function(req, res) { +felonRouter.put('/felons/:id', bodyParser.json(), /*eatAuth,*/ function(req, res) { var felonData = req.body; - delete req.body._id; - Felon.update({_id: felonData._id}, felonData, function(err) { + delete felonData._id; + Felon.update({_id: req.params.id}, felonData, function(err) { if(err) return error.default(err, res); res.send('updated!'); @@ -38,7 +38,7 @@ felonRouter.put('/felons', bodyParser.json(), /*eatAuth,*/ function(req, res) { felonRouter.delete('/felons/:id', bodyParser.json(), /*eatAuth,*/ function(req, res) { - Felon.remove({_id: req.params._id}, function(err) { + Felon.remove({_id: req.params.id}, function(err) { if(err) return error.default(err, res); res.send('deleted!'); diff --git a/tim_miller/routes/officerroutes.js b/tim_miller/routes/officerroutes.js index 9d33291..c27c4a4 100644 --- a/tim_miller/routes/officerroutes.js +++ b/tim_miller/routes/officerroutes.js @@ -25,20 +25,22 @@ officerRouter.post('/officers', bodyParser.json(), /*eatAuth,*/ function(req, re }); }); -officerRouter.put('/officers', bodyParser.json(), /*eatAuth,*/ function(req, res) { +officerRouter.put('/officers/:id', bodyParser.json(), /*eatAuth,*/ function(req, res) { var officerData = req.body; delete officerData._id; - Officer.update({_id: officerData._id}, officerData, function(err) { + console.log(officerData); + console.log(req.params); + Officer.update({_id: req.params.id}, officerData, function(err) { if(err) return error.default(err, res); res.send('updated!'); }); }); -officerRouter.delete('/officers/:id',bodyParser.json(), /*eatAuth,*/ function(req, res) { +officerRouter.delete('/officers/:id', bodyParser.json(), /*eatAuth,*/ function(req, res) { - Officer.remove({_id: req.params._id}, function(err) { + Officer.remove({_id: req.params.id}, function(err) { if(err) return error.default(err, res); res.send('deleted!'); From 54c551971d66e951f1e6b1c72f3e58aea948b6fb Mon Sep 17 00:00:00 2001 From: timcmiller Date: Wed, 2 Dec 2015 10:49:55 -0800 Subject: [PATCH 03/18] finished CRUD --- tim_miller/app/index.html | 4 ++-- tim_miller/app/js/busted/busted.js | 2 +- tim_miller/app/js/busted/controllers/busted_controller.js | 2 -- tim_miller/app/js/entry.js | 1 - tim_miller/app/js/felons/controllers/felon_controller.js | 1 + tim_miller/app/js/officers/controllers/officer_controller.js | 3 ++- 6 files changed, 6 insertions(+), 7 deletions(-) diff --git a/tim_miller/app/index.html b/tim_miller/app/index.html index ab7d65a..397fbd7 100644 --- a/tim_miller/app/index.html +++ b/tim_miller/app/index.html @@ -49,7 +49,7 @@

New Felon:

  • Name: {{felon.name}} In Jail: {{felon.inJail}} - +
    @@ -59,7 +59,7 @@

    Update felon:

    - +
    diff --git a/tim_miller/app/js/busted/busted.js b/tim_miller/app/js/busted/busted.js index 843a0d4..dacc4e0 100644 --- a/tim_miller/app/js/busted/busted.js +++ b/tim_miller/app/js/busted/busted.js @@ -1,4 +1,4 @@ module.exports = function(app) { - require('./controllers/busted_controller')(app); + require('./controllers/busted_controller.js')(app); }; diff --git a/tim_miller/app/js/busted/controllers/busted_controller.js b/tim_miller/app/js/busted/controllers/busted_controller.js index 29dc17c..328987c 100644 --- a/tim_miller/app/js/busted/controllers/busted_controller.js +++ b/tim_miller/app/js/busted/controllers/busted_controller.js @@ -5,8 +5,6 @@ module.exports = function(app) { $http.get('/api/busted') .then(function(res) { $scope.outcome = res.data; - $scope.$broadcast(updateOfficers()); - $scope.$broadcast(updateFelons()); }, function(err) { console.log(err.data); diff --git a/tim_miller/app/js/entry.js b/tim_miller/app/js/entry.js index 7e78c98..a660c4b 100644 --- a/tim_miller/app/js/entry.js +++ b/tim_miller/app/js/entry.js @@ -5,4 +5,3 @@ var officerAndFelonApp = angular.module('OfficerAndFelonApp', []); require('./officers/officers.js')(officerAndFelonApp); require('./felons/felons.js')(officerAndFelonApp); require('./busted/busted.js')(officerAndFelonApp); - diff --git a/tim_miller/app/js/felons/controllers/felon_controller.js b/tim_miller/app/js/felons/controllers/felon_controller.js index 59e5ac4..bae4609 100644 --- a/tim_miller/app/js/felons/controllers/felon_controller.js +++ b/tim_miller/app/js/felons/controllers/felon_controller.js @@ -55,5 +55,6 @@ module.exports = function(app) { felon.editing = false; felon.name = felon.tempName; }; + }]); }; diff --git a/tim_miller/app/js/officers/controllers/officer_controller.js b/tim_miller/app/js/officers/controllers/officer_controller.js index 6a23c60..25ddb3f 100644 --- a/tim_miller/app/js/officers/controllers/officer_controller.js +++ b/tim_miller/app/js/officers/controllers/officer_controller.js @@ -4,7 +4,6 @@ module.exports = function(app) { $scope.errors = []; $scope.newOfficer = null; - $scope.getAllOfficers = function() { $http.get('/api/officers') .then(function(res) { @@ -51,11 +50,13 @@ module.exports = function(app) { $scope.temp = function(officer) { officer.editing = true; officer.tempName = officer.name; + }; $scope.cancel = function(officer) { officer.editing = false; officer.name = officer.tempName; }; + }]); }; From b3fa767845697a3ac2dcf9356cf3c350b478e056 Mon Sep 17 00:00:00 2001 From: timcmiller Date: Thu, 3 Dec 2015 15:37:57 -0800 Subject: [PATCH 04/18] added get and post tests --- tim_miller/.gitignore | 2 + tim_miller/app/css/base.css | 424 ++++++++++++++++++ tim_miller/app/css/layout.css | 3 + tim_miller/app/css/module.css | 0 tim_miller/app/index.html | 1 + .../controllers/officer_controller.js | 2 +- tim_miller/gulpfile.js | 31 +- tim_miller/karma.conf.js | 69 +++ tim_miller/package.json | 9 + .../test/client/officers_controller_test.js | 61 +++ tim_miller/test/client/test_entry.js | 1 + 11 files changed, 601 insertions(+), 2 deletions(-) create mode 100644 tim_miller/app/css/base.css create mode 100644 tim_miller/app/css/layout.css create mode 100644 tim_miller/app/css/module.css create mode 100644 tim_miller/karma.conf.js create mode 100644 tim_miller/test/client/officers_controller_test.js create mode 100644 tim_miller/test/client/test_entry.js diff --git a/tim_miller/.gitignore b/tim_miller/.gitignore index cfea63f..57a37f9 100644 --- a/tim_miller/.gitignore +++ b/tim_miller/.gitignore @@ -3,4 +3,6 @@ **/db **/tim_miller/db build/** +**/*bundle.js + diff --git a/tim_miller/app/css/base.css b/tim_miller/app/css/base.css new file mode 100644 index 0000000..5e5e3c8 --- /dev/null +++ b/tim_miller/app/css/base.css @@ -0,0 +1,424 @@ +/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */ + +/** + * 1. Set default font family to sans-serif. + * 2. Prevent iOS and IE text size adjust after device orientation change, + * without disabling user zoom. + */ + +html { + font-family: sans-serif; /* 1 */ + -ms-text-size-adjust: 100%; /* 2 */ + -webkit-text-size-adjust: 100%; /* 2 */ +} + +/** + * Remove default margin. + */ + +body { + margin: 0; +} + +/* HTML5 display definitions + ========================================================================== */ + +/** + * Correct `block` display not defined for any HTML5 element in IE 8/9. + * Correct `block` display not defined for `details` or `summary` in IE 10/11 + * and Firefox. + * Correct `block` display not defined for `main` in IE 11. + */ + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +menu, +nav, +section, +summary { + display: block; +} + +/** + * 1. Correct `inline-block` display not defined in IE 8/9. + * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. + */ + +audio, +canvas, +progress, +video { + display: inline-block; /* 1 */ + vertical-align: baseline; /* 2 */ +} + +/** + * Prevent modern browsers from displaying `audio` without controls. + * Remove excess height in iOS 5 devices. + */ + +audio:not([controls]) { + display: none; + height: 0; +} + +/** + * Address `[hidden]` styling not present in IE 8/9/10. + * Hide the `template` element in IE 8/9/10/11, Safari, and Firefox < 22. + */ + +[hidden], +template { + display: none; +} + +/* Links + ========================================================================== */ + +/** + * Remove the gray background color from active links in IE 10. + */ + +a { + background-color: transparent; +} + +/** + * Improve readability of focused elements when they are also in an + * active/hover state. + */ + +a:active, +a:hover { + outline: 0; +} + +/* Text-level semantics + ========================================================================== */ + +/** + * Address styling not present in IE 8/9/10/11, Safari, and Chrome. + */ + +abbr[title] { + border-bottom: 1px dotted; +} + +/** + * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. + */ + +b, +strong { + font-weight: bold; +} + +/** + * Address styling not present in Safari and Chrome. + */ + +dfn { + font-style: italic; +} + +/** + * Address variable `h1` font-size and margin within `section` and `article` + * contexts in Firefox 4+, Safari, and Chrome. + */ + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +/** + * Address styling not present in IE 8/9. + */ + +mark { + background: #ff0; + color: #000; +} + +/** + * Address inconsistent and variable font size in all browsers. + */ + +small { + font-size: 80%; +} + +/** + * Prevent `sub` and `sup` affecting `line-height` in all browsers. + */ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +/* Embedded content + ========================================================================== */ + +/** + * Remove border when inside `a` element in IE 8/9/10. + */ + +img { + border: 0; +} + +/** + * Correct overflow not hidden in IE 9/10/11. + */ + +svg:not(:root) { + overflow: hidden; +} + +/* Grouping content + ========================================================================== */ + +/** + * Address margin not present in IE 8/9 and Safari. + */ + +figure { + margin: 1em 40px; +} + +/** + * Address differences between Firefox and other browsers. + */ + +hr { + box-sizing: content-box; + height: 0; +} + +/** + * Contain overflow in all browsers. + */ + +pre { + overflow: auto; +} + +/** + * Address odd `em`-unit font size rendering in all browsers. + */ + +code, +kbd, +pre, +samp { + font-family: monospace, monospace; + font-size: 1em; +} + +/* Forms + ========================================================================== */ + +/** + * Known limitation: by default, Chrome and Safari on OS X allow very limited + * styling of `select`, unless a `border` property is set. + */ + +/** + * 1. Correct color not being inherited. + * Known issue: affects color of disabled elements. + * 2. Correct font properties not being inherited. + * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. + */ + +button, +input, +optgroup, +select, +textarea { + color: inherit; /* 1 */ + font: inherit; /* 2 */ + margin: 0; /* 3 */ +} + +/** + * Address `overflow` set to `hidden` in IE 8/9/10/11. + */ + +button { + overflow: visible; +} + +/** + * Address inconsistent `text-transform` inheritance for `button` and `select`. + * All other form control elements do not inherit `text-transform` values. + * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. + * Correct `select` style inheritance in Firefox. + */ + +button, +select { + text-transform: none; +} + +/** + * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` + * and `video` controls. + * 2. Correct inability to style clickable `input` types in iOS. + * 3. Improve usability and consistency of cursor style between image-type + * `input` and others. + */ + +button, +html input[type="button"], /* 1 */ +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; /* 2 */ + cursor: pointer; /* 3 */ +} + +/** + * Re-set default cursor for disabled elements. + */ + +button[disabled], +html input[disabled] { + cursor: default; +} + +/** + * Remove inner padding and border in Firefox 4+. + */ + +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; +} + +/** + * Address Firefox 4+ setting `line-height` on `input` using `!important` in + * the UA stylesheet. + */ + +input { + line-height: normal; +} + +/** + * It's recommended that you don't attempt to style these elements. + * Firefox's implementation doesn't respect box-sizing, padding, or width. + * + * 1. Address box sizing set to `content-box` in IE 8/9/10. + * 2. Remove excess padding in IE 8/9/10. + */ + +input[type="checkbox"], +input[type="radio"] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Fix the cursor style for Chrome's increment/decrement buttons. For certain + * `font-size` values of the `input`, it causes the cursor style of the + * decrement button to change from `default` to `text`. + */ + +input[type="number"]::-webkit-inner-spin-button, +input[type="number"]::-webkit-outer-spin-button { + height: auto; +} + +/** + * 1. Address `appearance` set to `searchfield` in Safari and Chrome. + * 2. Address `box-sizing` set to `border-box` in Safari and Chrome. + */ + +input[type="search"] { + -webkit-appearance: textfield; /* 1 */ + box-sizing: content-box; /* 2 */ +} + +/** + * Remove inner padding and search cancel button in Safari and Chrome on OS X. + * Safari (but not Chrome) clips the cancel button when the search input has + * padding (and `textfield` appearance). + */ + +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +/** + * Define consistent border, margin, and padding. + */ + +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; +} + +/** + * 1. Correct `color` not being inherited in IE 8/9/10/11. + * 2. Remove padding so people aren't caught out if they zero out fieldsets. + */ + +legend { + border: 0; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Remove default vertical scrollbar in IE 8/9/10/11. + */ + +textarea { + overflow: auto; +} + +/** + * Don't inherit the `font-weight` (applied by a rule above). + * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. + */ + +optgroup { + font-weight: bold; +} + +/* Tables + ========================================================================== */ + +/** + * Remove most spacing between table cells. + */ + +table { + border-collapse: collapse; + border-spacing: 0; +} + +td, +th { + padding: 0; +} diff --git a/tim_miller/app/css/layout.css b/tim_miller/app/css/layout.css new file mode 100644 index 0000000..aa1634c --- /dev/null +++ b/tim_miller/app/css/layout.css @@ -0,0 +1,3 @@ +body { + background-color: red; +} diff --git a/tim_miller/app/css/module.css b/tim_miller/app/css/module.css new file mode 100644 index 0000000..e69de29 diff --git a/tim_miller/app/index.html b/tim_miller/app/index.html index 397fbd7..dd96286 100644 --- a/tim_miller/app/index.html +++ b/tim_miller/app/index.html @@ -3,6 +3,7 @@ Cops! +

    Bad Boys Bad Boys

    diff --git a/tim_miller/app/js/officers/controllers/officer_controller.js b/tim_miller/app/js/officers/controllers/officer_controller.js index 25ddb3f..9789027 100644 --- a/tim_miller/app/js/officers/controllers/officer_controller.js +++ b/tim_miller/app/js/officers/controllers/officer_controller.js @@ -14,7 +14,7 @@ module.exports = function(app) { }; $scope.create = function(officer) { - $http.post('api/officers', officer) + $http.post('/api/officers', officer) .then(function(res) { $scope.officers.push(res.data); $scope.newOfficer = null; diff --git a/tim_miller/gulpfile.js b/tim_miller/gulpfile.js index 8c9e629..919004a 100644 --- a/tim_miller/gulpfile.js +++ b/tim_miller/gulpfile.js @@ -2,6 +2,9 @@ var gulp = require('gulp'); var mocha = require('gulp-mocha'); var jshint = require('gulp-jshint'); var webpack = require('webpack-stream'); +var minifyCss = require('gulp-minify-css'); +var concatCss = require('gulp-concat-css'); +var gulpWatch = require('gulp-watch'); gulp.task('default', ['jshint', 'test']); @@ -21,6 +24,21 @@ gulp.task('static:dev', function() { .pipe(gulp.dest('build/')); }); +gulp.task('css:dev', function() { + return gulp.src([ + 'app/css/base.css', + 'app/css/layout.css', + 'app/css/module.css' + ]) + .pipe(concatCss('styles.min.css')) + .pipe(minifyCss()) + .pipe(gulp.dest('build/')); +}); + +gulp.task('watch', function() { + gulp.watch('./app/**', ['default']); +}); + gulp.task('webpack:dev', function() { gulp.src('app/js/entry.js') .pipe(webpack({ @@ -31,5 +49,16 @@ gulp.task('webpack:dev', function() { .pipe(gulp.dest('build/')); }); -gulp.task('build:dev', ['webpack:dev', 'static:dev']); +gulp.task('webpack:test', function() { + return gulp.src('test/client/test_entry.js') + .pipe(webpack({ + output: { + filename: 'test_bundle.js' + } + })) + .pipe(gulp.dest('test/client/')); +}); + + +gulp.task('build:dev', ['webpack:dev', 'static:dev', 'css:dev']); gulp.task('default', ['build:dev']); diff --git a/tim_miller/karma.conf.js b/tim_miller/karma.conf.js new file mode 100644 index 0000000..00919be --- /dev/null +++ b/tim_miller/karma.conf.js @@ -0,0 +1,69 @@ +// Karma configuration +// Generated on Wed Dec 02 2015 15:23:37 GMT-0800 (PST) + +module.exports = function(config) { + config.set({ + + // base path that will be used to resolve all patterns (eg. files, exclude) + basePath: '', + + + // frameworks to use + // available frameworks: https://npmjs.org/browse/keyword/karma-adapter + frameworks: ['jasmine'], + + + // list of files / patterns to load in the browser + files: [ + 'test/client/test_bundle.js' + ], + + + // list of files to exclude + exclude: [ + ], + + + // preprocess matching files before serving them to the browser + // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor + preprocessors: { + }, + + + // test results reporter to use + // possible values: 'dots', 'progress' + // available reporters: https://npmjs.org/browse/keyword/karma-reporter + reporters: ['progress'], + + + // web server port + port: 9876, + + + // enable / disable colors in the output (reporters and logs) + colors: true, + + + // level of logging + // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG + logLevel: config.LOG_INFO, + + + // enable / disable watching file and executing tests whenever any file changes + autoWatch: false, + + + // start these browsers + // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher + browsers: ['PhantomJS'], + + + // Continuous Integration mode + // if true, Karma captures browsers, runs the tests and exits + singleRun: true, + + // Concurrency level + // how many browser should be started simultanous + concurrency: Infinity + }) +} diff --git a/tim_miller/package.json b/tim_miller/package.json index 279ed61..c81b728 100644 --- a/tim_miller/package.json +++ b/tim_miller/package.json @@ -25,13 +25,22 @@ }, "devDependencies": { "angular": "^1.4.8", + "angular-mocks": "^1.4.8", "chai": "^3.4.1", "chai-http": "^1.0.0", "gulp": "^3.9.0", + "gulp-concat-css": "^2.2.0", "gulp-jshint": "^1.12.0", + "gulp-minify-css": "^1.2.2", "gulp-mocha": "^2.1.3", + "gulp-watch": "^4.3.5", + "jasmine-core": "^2.3.4", "jshint-stylish": "^2.0.1", + "karma": "^0.13.15", + "karma-jasmine": "^0.3.6", + "karma-phantomjs-launcher": "^0.2.1", "mocha": "^2.3.3", + "phantomjs": "^1.9.19", "webpack-stream": "^2.1.1" } } diff --git a/tim_miller/test/client/officers_controller_test.js b/tim_miller/test/client/officers_controller_test.js new file mode 100644 index 0000000..6885573 --- /dev/null +++ b/tim_miller/test/client/officers_controller_test.js @@ -0,0 +1,61 @@ +require(__dirname + '/../../app/js/entry.js'); +require('angular-mocks'); + +describe('officer controller', function() { + var $httpBackend; + var $ControllerConstructor; + var $scope; + + beforeEach(angular.mock.module('OfficerAndFelonApp')); + + beforeEach(angular.mock.inject(function($rootScope, $controller) { + $scope = $rootScope.$new(); + $ControllerConstructor = $controller; + console.log('outside beforeEach'); + })); + + it('should be able to create a controller', function() { + var controller = $ControllerConstructor('OfficersController', {$scope: $scope}); + expect(typeof $scope).toBe('object'); + expect(typeof controller).toBe('object'); + expect(Array.isArray($scope.officers)).toBe(true); + }); + + describe('REST requests', function() { + + beforeEach(angular.mock.inject(function(_$httpBackend_, $rootScope) { + $httpBackend = _$httpBackend_; + $scope = $rootScope.$new(); + $ControllerConstructor('OfficersController', {$scope: $scope}); + console.log('inside beforeEach'); + + })); + + afterEach(function(){ + $httpBackend.verifyNoOutstandingExpectation(); + $httpBackend.verifyNoOutstandingRequest(); + console.log('inside afterEach'); + }); + + it('should make a get response when getAllOfficers() is called', function() { + $httpBackend.expectGET('/api/officers').respond(200, [{_id: 1, name: 'test name'}]); + $scope.getAllOfficers(); + $httpBackend.flush(); + expect($scope.officers[0]._id).toBe(1); + expect($scope.officers[0].name).toBe('test name'); + + }); + + it('should be able to create a new Officer when create() is called', function() { + $httpBackend.expectPOST('/api/officers', {name: 'test name'}).respond(200, {name: 'a different officer'}); + + expect($scope.officers.length).toBe(0); + $scope.newOfficer = {name: 'test name'}; + $scope.create($scope.newOfficer); + $httpBackend.flush(); + expect($scope.officers[0].name).toBe('a different officer'); + expect($scope.newOfficer).toBe(null); + + }); + }); +}); diff --git a/tim_miller/test/client/test_entry.js b/tim_miller/test/client/test_entry.js new file mode 100644 index 0000000..3665656 --- /dev/null +++ b/tim_miller/test/client/test_entry.js @@ -0,0 +1 @@ +require('./officers_controller_test.js'); From e8f991b71532079f96c47ccfc400be2c8ab9441a Mon Sep 17 00:00:00 2001 From: timcmiller Date: Fri, 4 Dec 2015 09:00:04 -0800 Subject: [PATCH 05/18] added some tests --- tim_miller/app/js/entry.js | 1 + .../controllers/officer_controller.js | 23 +++++----- .../app/js/services/busted_resource/busted.js | 33 ++++++++++++++ tim_miller/app/js/services/services.js | 3 ++ .../test/client/officers_controller_test.js | 44 ++++++++++++++++--- 5 files changed, 86 insertions(+), 18 deletions(-) create mode 100644 tim_miller/app/js/services/busted_resource/busted.js create mode 100644 tim_miller/app/js/services/services.js diff --git a/tim_miller/app/js/entry.js b/tim_miller/app/js/entry.js index a660c4b..1ac769e 100644 --- a/tim_miller/app/js/entry.js +++ b/tim_miller/app/js/entry.js @@ -2,6 +2,7 @@ require('angular/angular'); var angular = window.angular; var officerAndFelonApp = angular.module('OfficerAndFelonApp', []); +require('./services/services.js')(officerAndFelonApp); require('./officers/officers.js')(officerAndFelonApp); require('./felons/felons.js')(officerAndFelonApp); require('./busted/busted.js')(officerAndFelonApp); diff --git a/tim_miller/app/js/officers/controllers/officer_controller.js b/tim_miller/app/js/officers/controllers/officer_controller.js index 9789027..e18c52f 100644 --- a/tim_miller/app/js/officers/controllers/officer_controller.js +++ b/tim_miller/app/js/officers/controllers/officer_controller.js @@ -1,25 +1,24 @@ module.exports = function(app) { - app.controller('OfficersController', ['$scope', '$http', function($scope, $http) { + app.controller('OfficersController', ['$scope', '$http', 'busted', function($scope, $http, busted) { $scope.officers = []; $scope.errors = []; $scope.newOfficer = null; + var officerResource = busted('officers'); $scope.getAllOfficers = function() { - $http.get('/api/officers') - .then(function(res) { - $scope.officers = res.data; - }, function(err) { - console.log(err.data); + officerResource.getAll(function(err, data) { + if (err) return err; + + $scope.officers = data; }); }; $scope.create = function(officer) { - $http.post('/api/officers', officer) - .then(function(res) { - $scope.officers.push(res.data); - $scope.newOfficer = null; - }, function(err) { - console.log(err.data); + + officerResource.create(officer, function(err, data) { + if (err) return err; + $scope.officers.push(data); + $scope.newOfficer = null; }); }; diff --git a/tim_miller/app/js/services/busted_resource/busted.js b/tim_miller/app/js/services/busted_resource/busted.js new file mode 100644 index 0000000..7d8a6db --- /dev/null +++ b/tim_miller/app/js/services/busted_resource/busted.js @@ -0,0 +1,33 @@ +var handleSuccess = function(callback) { + return function(res) { + callback(null, res.data); + }; +}; + +var handleFail = function(callback) { + return function(err) { + console.log(err); + callback(err.data); + }; +}; + +module.exports = function(app) { + + app.factory('busted', ['$http', function($http) { + + return function(resourceName) { + var resource = {}; + resource.getAll = function(callback) { + $http.get('/api/' + resourceName) + .then(handleSuccess(callback), handleFail(callback)); + }; + + resource.create = function(data, callback) { + $http.post('/api/' + resourceName, data) + .then(handleSuccess(callback), handleFail(callback)); + }; + + return resource; + }; + }]); +}; diff --git a/tim_miller/app/js/services/services.js b/tim_miller/app/js/services/services.js new file mode 100644 index 0000000..ce4627e --- /dev/null +++ b/tim_miller/app/js/services/services.js @@ -0,0 +1,3 @@ +module.exports = function(app) { + require('./busted_resource/busted.js')(app); +}; diff --git a/tim_miller/test/client/officers_controller_test.js b/tim_miller/test/client/officers_controller_test.js index 6885573..176c49e 100644 --- a/tim_miller/test/client/officers_controller_test.js +++ b/tim_miller/test/client/officers_controller_test.js @@ -11,7 +11,6 @@ describe('officer controller', function() { beforeEach(angular.mock.inject(function($rootScope, $controller) { $scope = $rootScope.$new(); $ControllerConstructor = $controller; - console.log('outside beforeEach'); })); it('should be able to create a controller', function() { @@ -21,20 +20,17 @@ describe('officer controller', function() { expect(Array.isArray($scope.officers)).toBe(true); }); - describe('REST requests', function() { + describe('officer controller functions', function() { beforeEach(angular.mock.inject(function(_$httpBackend_, $rootScope) { $httpBackend = _$httpBackend_; - $scope = $rootScope.$new(); $ControllerConstructor('OfficersController', {$scope: $scope}); - console.log('inside beforeEach'); - + $scope.officers = []; })); afterEach(function(){ $httpBackend.verifyNoOutstandingExpectation(); $httpBackend.verifyNoOutstandingRequest(); - console.log('inside afterEach'); }); it('should make a get response when getAllOfficers() is called', function() { @@ -57,5 +53,41 @@ describe('officer controller', function() { expect($scope.newOfficer).toBe(null); }); + + it('should be able to respond to a DELETE request when remove() is called', function() { + officer = {_id: 1234, name: 'test name'}; + $scope.officers = [officer]; + $httpBackend.expectDELETE('/api/officers/' + officer._id).respond(200); + + $scope.remove(officer); + $httpBackend.flush(); + expect($scope.officers.length).toBe(0); + }); + + it('should be able to respond to a PUT request when update() is called', function() { + $scope.officers = [{_id: 1234, name: 'a testy name'}]; + $httpBackend.expectPUT('/api/officers/' + $scope.officers[0]._id, {_id: 1234, name: 'a testy name', tempName: '', editing: false}).respond(200); + + $scope.update($scope.officers[0]); + $httpBackend.flush(); + expect($scope.officers[0].tempName).toBe(''); + expect($scope.officers[0].editing).toBe(false); + }); + + it('should be able to change editing to true by calling temp()', function() { + officer = {name: 'a very testy name', tempName: '', editing: false}; + + $scope.temp(officer); + expect(officer.tempName).toBe('a very testy name'); + expect(officer.editing).toBe(true); + }); + + it('should be able to change editing back to false by calling cancel()', function() { + officer = {name: '', tempName: 'an even more testy name', editing: true}; + + $scope.cancel(officer); + expect(officer.name).toBe('an even more testy name'); + expect(officer.editing).toBe(false); + }); }); }); From 3468653edb82c860851da14323730677b73b0cfa Mon Sep 17 00:00:00 2001 From: timcmiller Date: Fri, 4 Dec 2015 09:41:52 -0800 Subject: [PATCH 06/18] added services --- .../controllers/officer_controller.js | 29 +++++++------------ .../app/js/services/busted_resource/busted.js | 23 +++++++++++++++ .../test/client/felon_controller_test.js | 21 ++++++++++++++ tim_miller/test/client/test_entry.js | 1 + 4 files changed, 55 insertions(+), 19 deletions(-) create mode 100644 tim_miller/test/client/felon_controller_test.js diff --git a/tim_miller/app/js/officers/controllers/officer_controller.js b/tim_miller/app/js/officers/controllers/officer_controller.js index e18c52f..7aa7043 100644 --- a/tim_miller/app/js/officers/controllers/officer_controller.js +++ b/tim_miller/app/js/officers/controllers/officer_controller.js @@ -23,38 +23,29 @@ module.exports = function(app) { }; $scope.remove = function(officer) { - $scope.officers.splice($scope.officers.indexOf(officer), 1); - $http.delete('/api/officers/' + officer._id) - .then(function(res) { - console.log('Done'); - }, function(err) { - console.log(err.data); - $scope.errors.push('Could not delete Officer: ' + officer.name); + officerResource.remove($scope.officers, officer, function(err, data) { + if (err) { + $scope.errors.push('Could not delete Officer ' + officer.name); $scope.getAllOfficers(); + } }); }; $scope.update = function(officer) { - officer.tempName = ''; - officer.editing = false; - $http.put('/api/officers/' + officer._id, officer) - .then(function(res) { - console.log('this officer has a new name'); - }, function(err) { + officerResource.update(officer, function(err, data) { + if (err) { $scope.errors.push('could not get officer: ' + officer.name); - console.log(err.data); + } + console.log('this officer has a new name'); }); }; $scope.temp = function(officer) { - officer.editing = true; - officer.tempName = officer.name; - + officerResource.temp(officer); }; $scope.cancel = function(officer) { - officer.editing = false; - officer.name = officer.tempName; + officerResource.cancel(officer); }; }]); diff --git a/tim_miller/app/js/services/busted_resource/busted.js b/tim_miller/app/js/services/busted_resource/busted.js index 7d8a6db..4b09bb1 100644 --- a/tim_miller/app/js/services/busted_resource/busted.js +++ b/tim_miller/app/js/services/busted_resource/busted.js @@ -27,6 +27,29 @@ module.exports = function(app) { .then(handleSuccess(callback), handleFail(callback)); }; + resource.remove = function(collection, data, callback) { + collection.splice(collection.indexOf(data), 1); + $http.delete('/api/' + resourceName + data._id) + .then(handleSuccess(callback), handleFail(callback)); + }; + + resource.update = function(data, callback) { + data.tempName = ''; + data.editing = false; + $http.put('/api/' + resourceName + data._id) + .then(handleSuccess(callback), handleFail(callback)); + }; + + resource.temp = function(data) { + data.editing = true; + data.tempName = data.name; + }; + + resource.cancel = function(data) { + data.editing = false; + data.name = data.tempName; + }; + return resource; }; }]); diff --git a/tim_miller/test/client/felon_controller_test.js b/tim_miller/test/client/felon_controller_test.js new file mode 100644 index 0000000..85fdf7d --- /dev/null +++ b/tim_miller/test/client/felon_controller_test.js @@ -0,0 +1,21 @@ +require(__dirname + '/../../app/js/entry.js'); +require('angular-mocks'); + +describe('felon controller', function() { + + beforeEach(angular.mock.module('OfficerAndFelonApp')); + + beforeEach(angular.mock.inject(function($rootScope, $controller) { + this.scope = $rootScope.$new(); + this.controller = $controller; + })).bind(this); + + it('should be able to create a controller', function() { + this.controller = this.controller('FelonsController', {$scope: this.scope}); + expect(typeof $scope).toBe('object'); + expect(typeof this.controller).toBe('object'); + expect(Array.isArray(this.scope.felons)).toBe(true); + }); + + +}); diff --git a/tim_miller/test/client/test_entry.js b/tim_miller/test/client/test_entry.js index 3665656..93cca29 100644 --- a/tim_miller/test/client/test_entry.js +++ b/tim_miller/test/client/test_entry.js @@ -1 +1,2 @@ require('./officers_controller_test.js'); +require('./felon_controller_test.js'); From f423c071d63e1c8f4c379e4e0230bb0c4947993d Mon Sep 17 00:00:00 2001 From: timcmiller Date: Fri, 4 Dec 2015 09:54:16 -0800 Subject: [PATCH 07/18] stared mock up for felon tests --- .../app/js/services/busted_resource/busted.js | 4 ++-- tim_miller/test/client/felon_controller_test.js | 16 ++++++++++------ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/tim_miller/app/js/services/busted_resource/busted.js b/tim_miller/app/js/services/busted_resource/busted.js index 4b09bb1..8ce40d6 100644 --- a/tim_miller/app/js/services/busted_resource/busted.js +++ b/tim_miller/app/js/services/busted_resource/busted.js @@ -29,14 +29,14 @@ module.exports = function(app) { resource.remove = function(collection, data, callback) { collection.splice(collection.indexOf(data), 1); - $http.delete('/api/' + resourceName + data._id) + $http.delete('/api/' + resourceName + '/' + data._id) .then(handleSuccess(callback), handleFail(callback)); }; resource.update = function(data, callback) { data.tempName = ''; data.editing = false; - $http.put('/api/' + resourceName + data._id) + $http.put('/api/' + resourceName + '/' + data._id, data) .then(handleSuccess(callback), handleFail(callback)); }; diff --git a/tim_miller/test/client/felon_controller_test.js b/tim_miller/test/client/felon_controller_test.js index 85fdf7d..c90c5a6 100644 --- a/tim_miller/test/client/felon_controller_test.js +++ b/tim_miller/test/client/felon_controller_test.js @@ -3,18 +3,22 @@ require('angular-mocks'); describe('felon controller', function() { + var $httpBackend; + var $ControllerConstructor; + var $scope; + beforeEach(angular.mock.module('OfficerAndFelonApp')); beforeEach(angular.mock.inject(function($rootScope, $controller) { - this.scope = $rootScope.$new(); - this.controller = $controller; - })).bind(this); + $scope = $rootScope.$new(); + $ControllerConstructor = $controller; + })); it('should be able to create a controller', function() { - this.controller = this.controller('FelonsController', {$scope: this.scope}); + var controller = $ControllerConstructor('FelonsController', {$scope: $scope}); expect(typeof $scope).toBe('object'); - expect(typeof this.controller).toBe('object'); - expect(Array.isArray(this.scope.felons)).toBe(true); + expect(typeof controller).toBe('object'); + expect(Array.isArray($scope.felons)).toBe(true); }); From 0c38b36041e5d583f521d259380e1ccb0753cd6f Mon Sep 17 00:00:00 2001 From: timcmiller Date: Fri, 4 Dec 2015 18:46:54 -0800 Subject: [PATCH 08/18] added some services and stuff --- tim_miller/server.js | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/tim_miller/server.js b/tim_miller/server.js index 884ea67..efce96d 100644 --- a/tim_miller/server.js +++ b/tim_miller/server.js @@ -1,6 +1,5 @@ var mongoose = require('mongoose'); var express = require('express'); -var fs = require('fs'); var officerRouter = require(__dirname + '/routes/officerroutes.js'); var felonRouter = require(__dirname + '/routes/felonroutes.js'); var bustedRouter = require(__dirname + '/routes/bustedroutes.js'); @@ -11,27 +10,13 @@ var app = express(); process.env.APP_SECRET = process.env.APP_SECRET || '123451234512345'; mongoose.connect(process.env.MONGOLAB_URI || 'mongodb://localhost/officer_dev'); -app.use('/api', officerRouter, felonRouter, bustedRouter, chuckRouter, authRouter); +app.use('/api', officerRouter); app.use('/api', felonRouter); app.use('/api', bustedRouter); app.use('/api', chuckRouter); app.use('/api', authRouter); app.use(express.static(__dirname + '/build')); - -// app.get('/:filename', function(req, res, next) { -// fs.stat(__dirname + '/build/' + req.params.filename, function(err, stats) { -// if (err) {console.log(err); -// return next(); -// } - -// if (!stats.isFile()) return next(); - -// var file = fs.createReadStream(__dirname + '/build/' + req.params.filename); -// file.pipe(res); -// }); -// }); - app.use(function(req, res) { res.status(404).send('could not find file'); }); From 3afc1819828ac7c1d073ef30eed9be65b9345b4d Mon Sep 17 00:00:00 2001 From: timcmiller Date: Fri, 4 Dec 2015 19:15:15 -0800 Subject: [PATCH 09/18] added felon tests --- .../js/felons/controllers/felon_controller.js | 54 +++++++-------- .../controllers/officer_controller.js | 4 +- .../rest_functions.js} | 2 +- tim_miller/app/js/services/services.js | 2 +- .../test/client/felon_controller_test.js | 69 +++++++++++++++++++ 5 files changed, 96 insertions(+), 35 deletions(-) rename tim_miller/app/js/services/{busted_resource/busted.js => rest_resource/rest_functions.js} (96%) diff --git a/tim_miller/app/js/felons/controllers/felon_controller.js b/tim_miller/app/js/felons/controllers/felon_controller.js index bae4609..12f9804 100644 --- a/tim_miller/app/js/felons/controllers/felon_controller.js +++ b/tim_miller/app/js/felons/controllers/felon_controller.js @@ -1,59 +1,51 @@ module.exports = function(app) { - app.controller('FelonsController', ['$scope', '$http', function($scope, $http) { + app.controller('FelonsController', ['$scope', '$http', 'restFunctions', function($scope, $http, restFunctions) { $scope.felons = []; + $scope.errors = []; $scope.newFelon = null; + var felonResource = restFunctions('felons'); $scope.getAllFelons = function() { - $http.get('/api/felons') - .then(function(res) { - $scope.felons = res.data; - }, function(err) { - console.log(err.data); + felonResource.getAll(function(err, data) { + if (err) return err; + + $scope.felons = data; }); }; $scope.create = function(felon) { - $http.post('api/felons', felon) - .then(function(res) { - $scope.felons.push(res.data); - $scope.newFelon = null; - }, function(err) { - console.log(err.data); + + felonResource.create(felon, function(err, data) { + if (err) return err; + $scope.felons.push(data); + $scope.newFelon = null; }); }; $scope.remove = function(felon) { - $scope.felons.splice($scope.felons.indexOf(felon), 1); - $http.delete('/api/felons/' + felon._id) - .then(function(res) { - console.log('Done'); - }, function(err) { - console.log(err.data); - $scope.errors.push('Could not delete felon: ' + felon.name); - $scope.getAllfelons(); + felonResource.remove($scope.felons, felon, function(err, data) { + if (err) { + $scope.erros.push('Could not delete Felon ' + felon.name); + $scope.getAllFelons(); + } }); }; $scope.update = function(felon) { - felon.tempName = ''; - felon.editing = false; - $http.put('/api/felons/' + felon._id, felon) - .then(function(res) { - console.log('this felon has a new name'); - }, function(err) { + felonResource.update(felon, function(err, data) { + if (err) { $scope.errors.push('could not get felon: ' + felon.name); - console.log(err.data); + } + console.log('this felon has a new name'); }); }; $scope.temp = function(felon) { - felon.editing = true; - felon.tempName = felon.name; + felonResource.temp(felon); }; $scope.cancel = function(felon) { - felon.editing = false; - felon.name = felon.tempName; + felonResource.cancel(felon); }; }]); diff --git a/tim_miller/app/js/officers/controllers/officer_controller.js b/tim_miller/app/js/officers/controllers/officer_controller.js index 7aa7043..05768ce 100644 --- a/tim_miller/app/js/officers/controllers/officer_controller.js +++ b/tim_miller/app/js/officers/controllers/officer_controller.js @@ -1,9 +1,9 @@ module.exports = function(app) { - app.controller('OfficersController', ['$scope', '$http', 'busted', function($scope, $http, busted) { + app.controller('OfficersController', ['$scope', '$http', 'restFunctions', function($scope, $http, restFunctions) { $scope.officers = []; $scope.errors = []; $scope.newOfficer = null; - var officerResource = busted('officers'); + var officerResource = restFunctions('officers'); $scope.getAllOfficers = function() { officerResource.getAll(function(err, data) { diff --git a/tim_miller/app/js/services/busted_resource/busted.js b/tim_miller/app/js/services/rest_resource/rest_functions.js similarity index 96% rename from tim_miller/app/js/services/busted_resource/busted.js rename to tim_miller/app/js/services/rest_resource/rest_functions.js index 8ce40d6..14c20fc 100644 --- a/tim_miller/app/js/services/busted_resource/busted.js +++ b/tim_miller/app/js/services/rest_resource/rest_functions.js @@ -13,7 +13,7 @@ var handleFail = function(callback) { module.exports = function(app) { - app.factory('busted', ['$http', function($http) { + app.factory('restFunctions', ['$http', function($http) { return function(resourceName) { var resource = {}; diff --git a/tim_miller/app/js/services/services.js b/tim_miller/app/js/services/services.js index ce4627e..c54ec59 100644 --- a/tim_miller/app/js/services/services.js +++ b/tim_miller/app/js/services/services.js @@ -1,3 +1,3 @@ module.exports = function(app) { - require('./busted_resource/busted.js')(app); + require('./rest_resource/rest_functions.js')(app); }; diff --git a/tim_miller/test/client/felon_controller_test.js b/tim_miller/test/client/felon_controller_test.js index c90c5a6..7d6f777 100644 --- a/tim_miller/test/client/felon_controller_test.js +++ b/tim_miller/test/client/felon_controller_test.js @@ -21,5 +21,74 @@ describe('felon controller', function() { expect(Array.isArray($scope.felons)).toBe(true); }); + describe('felon controller functions', function() { + beforeEach(angular.mock.inject(function(_$httpBackend_, $rootScope) { + $httpBackend = _$httpBackend_; + $ControllerConstructor('FelonsController', {$scope: $scope}); + $scope.felons = []; + })); + + afterEach(function(){ + $httpBackend.verifyNoOutstandingExpectation(); + $httpBackend.verifyNoOutstandingRequest(); + }); + + it('should make a get response when getAllFelons() is called', function() { + $httpBackend.expectGET('/api/felons').respond(200, [{_id: 1, name: 'test name'}]); + $scope.getAllFelons(); + $httpBackend.flush(); + expect($scope.felons[0]._id).toBe(1); + expect($scope.felons[0].name).toBe('test name'); + + }); + + it('should be able to create a new Felon when create() is called', function() { + $httpBackend.expectPOST('/api/felons', {name: 'test name'}).respond(200, {name: 'a different felon'}); + + expect($scope.felons.length).toBe(0); + $scope.newFelon = {name: 'test name'}; + $scope.create($scope.newFelon); + $httpBackend.flush(); + expect($scope.felons[0].name).toBe('a different felon'); + expect($scope.newFelon).toBe(null); + + }); + + it('should be able to respond to a DELETE request when remove() is called', function() { + felon = {_id: 1234, name: 'test name'}; + $scope.felons = [felon]; + $httpBackend.expectDELETE('/api/felons/' + felon._id).respond(200); + + $scope.remove(felon); + $httpBackend.flush(); + expect($scope.felons.length).toBe(0); + }); + + it('should be able to respond to a PUT request when update() is called', function() { + $scope.felons = [{_id: 1234, name: 'a testy name'}]; + $httpBackend.expectPUT('/api/felons/' + $scope.felons[0]._id, {_id: 1234, name: 'a testy name', tempName: '', editing: false}).respond(200); + + $scope.update($scope.felons[0]); + $httpBackend.flush(); + expect($scope.felons[0].tempName).toBe(''); + expect($scope.felons[0].editing).toBe(false); + }); + + it('should be able to change editing to true by calling temp()', function() { + felon = {name: 'a very testy name', tempName: '', editing: false}; + + $scope.temp(felon); + expect(felon.tempName).toBe('a very testy name'); + expect(felon.editing).toBe(true); + }); + + it('should be able to change editing back to false by calling cancel()', function() { + felon = {name: '', tempName: 'an even more testy name', editing: true}; + + $scope.cancel(felon); + expect(felon.name).toBe('an even more testy name'); + expect(felon.editing).toBe(false); + }); + }); }); From 6cadfb5e74b07af23a537b91059d540e4cb28d01 Mon Sep 17 00:00:00 2001 From: timcmiller Date: Fri, 4 Dec 2015 19:29:41 -0800 Subject: [PATCH 10/18] added busted test --- .../test/client/busted_controller_test.js | 42 +++++++++++++++++++ tim_miller/test/client/test_entry.js | 1 + 2 files changed, 43 insertions(+) create mode 100644 tim_miller/test/client/busted_controller_test.js diff --git a/tim_miller/test/client/busted_controller_test.js b/tim_miller/test/client/busted_controller_test.js new file mode 100644 index 0000000..2c97953 --- /dev/null +++ b/tim_miller/test/client/busted_controller_test.js @@ -0,0 +1,42 @@ +require(__dirname + '/../../app/js/entry.js'); +require('angular-mocks'); + +describe('busted controller', function() { + var $httpBackend; + var $ControllerConstructor; + var $scope; + + beforeEach(angular.mock.module('OfficerAndFelonApp')); + + beforeEach(angular.mock.inject(function($rootScope, $controller) { + $scope = $rootScope.$new(); + $ControllerConstructor = $controller; + })); + + it('should be able to create a controller', function() { + var controller = $ControllerConstructor('BustedController', {$scope: $scope}); + expect(typeof $scope).toBe('object'); + expect(typeof controller).toBe('object'); + }); + + describe('busted controller function', function() { + + beforeEach(angular.mock.inject(function(_$httpBackend_, $rootScope) { + $httpBackend = _$httpBackend_; + $ControllerConstructor('BustedController', {$scope: $scope}); + })); + + afterEach(function() { + $httpBackend.verifyNoOutstandingExpectation(); + $httpBackend.verifyNoOutstandingRequest(); + }); + + it('should respond to a $scope.busted()', function() { + $httpBackend.expectGET('/api/busted').respond(200, {name: 'test name'}); + $scope.busted(); + $httpBackend.flush(); + expect($scope.outcome.name).toBe('test name'); + }); + + }); +}); diff --git a/tim_miller/test/client/test_entry.js b/tim_miller/test/client/test_entry.js index 93cca29..d84e6ac 100644 --- a/tim_miller/test/client/test_entry.js +++ b/tim_miller/test/client/test_entry.js @@ -1,2 +1,3 @@ require('./officers_controller_test.js'); require('./felon_controller_test.js'); +require('./busted_controller_test.js'); From e198278c7dde906c4fa549ef65a6abdffd929d17 Mon Sep 17 00:00:00 2001 From: timcmiller Date: Fri, 4 Dec 2015 21:08:19 -0800 Subject: [PATCH 11/18] added broadcast --- .../app/js/busted/controllers/busted_controller.js | 1 + tim_miller/app/js/felons/controllers/felon_controller.js | 9 +++++++++ .../app/js/officers/controllers/officer_controller.js | 8 ++++++++ 3 files changed, 18 insertions(+) diff --git a/tim_miller/app/js/busted/controllers/busted_controller.js b/tim_miller/app/js/busted/controllers/busted_controller.js index 328987c..a7b02b9 100644 --- a/tim_miller/app/js/busted/controllers/busted_controller.js +++ b/tim_miller/app/js/busted/controllers/busted_controller.js @@ -5,6 +5,7 @@ module.exports = function(app) { $http.get('/api/busted') .then(function(res) { $scope.outcome = res.data; + $scope.$broadcast('busted', res); }, function(err) { console.log(err.data); diff --git a/tim_miller/app/js/felons/controllers/felon_controller.js b/tim_miller/app/js/felons/controllers/felon_controller.js index 12f9804..e5a40fb 100644 --- a/tim_miller/app/js/felons/controllers/felon_controller.js +++ b/tim_miller/app/js/felons/controllers/felon_controller.js @@ -13,6 +13,15 @@ module.exports = function(app) { }); }; + $scope.$on('busted', function(e, data) { + felonResource.getAll(function(err, data) { + if (err) return err; + + $scope.felons = data; + }); + }); + + $scope.create = function(felon) { felonResource.create(felon, function(err, data) { diff --git a/tim_miller/app/js/officers/controllers/officer_controller.js b/tim_miller/app/js/officers/controllers/officer_controller.js index 05768ce..0a92bf7 100644 --- a/tim_miller/app/js/officers/controllers/officer_controller.js +++ b/tim_miller/app/js/officers/controllers/officer_controller.js @@ -13,6 +13,14 @@ module.exports = function(app) { }); }; + $scope.$on('busted', function(e, data) { + officerResource.getAll(function(err, data) { + if (err) return err; + + $scope.officers = data; + }); + }); + $scope.create = function(officer) { officerResource.create(officer, function(err, data) { From 24ac33c210c97d4e76e71f401da5c6cbcfb7507d Mon Sep 17 00:00:00 2001 From: timcmiller Date: Fri, 4 Dec 2015 21:11:54 -0800 Subject: [PATCH 12/18] testing broadcast --- tim_miller/test/client/busted_controller_test.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tim_miller/test/client/busted_controller_test.js b/tim_miller/test/client/busted_controller_test.js index 2c97953..89de930 100644 --- a/tim_miller/test/client/busted_controller_test.js +++ b/tim_miller/test/client/busted_controller_test.js @@ -34,8 +34,12 @@ describe('busted controller', function() { it('should respond to a $scope.busted()', function() { $httpBackend.expectGET('/api/busted').respond(200, {name: 'test name'}); $scope.busted(); + $scope.$on('busted', function(e, data) { + $scope.busted = true; + }); $httpBackend.flush(); expect($scope.outcome.name).toBe('test name'); + expect($scope.busted).toBe(true); }); }); From ca88c9fe04b3b78d726d14f9fb1e0bbd6a0860a9 Mon Sep 17 00:00:00 2001 From: timcmiller Date: Sat, 5 Dec 2015 18:14:49 -0800 Subject: [PATCH 13/18] added some sick styles --- tim_miller/app/css/layout.css | 23 ++- tim_miller/app/css/module.css | 30 +++ tim_miller/app/css/skeleton.css | 356 ++++++++++++++++++++++++++++++++ tim_miller/app/css/state.css | 7 + tim_miller/app/index.html | 66 +++--- tim_miller/gulpfile.js | 4 +- 6 files changed, 455 insertions(+), 31 deletions(-) create mode 100644 tim_miller/app/css/skeleton.css create mode 100644 tim_miller/app/css/state.css diff --git a/tim_miller/app/css/layout.css b/tim_miller/app/css/layout.css index aa1634c..db726a4 100644 --- a/tim_miller/app/css/layout.css +++ b/tim_miller/app/css/layout.css @@ -1,3 +1,22 @@ -body { - background-color: red; +.resource { + display: flex; + flex-direction: column; + padding-left: 1em; + margin-bottom: 1em; + border-radius: 25px; } + +.list { + dispaly: flex; + flex-direction: row; +} + +.btn { + justify-content: flex-end; +} + +.list-content { + justify-content: flex-start; +} + + diff --git a/tim_miller/app/css/module.css b/tim_miller/app/css/module.css index e69de29..16eb0a4 100644 --- a/tim_miller/app/css/module.css +++ b/tim_miller/app/css/module.css @@ -0,0 +1,30 @@ +.btn { + background: #3498db; + background-image: -webkit-linear-gradient(top, #3498db, #2980b9); + background-image: -moz-linear-gradient(top, #3498db, #2980b9); + background-image: -ms-linear-gradient(top, #3498db, #2980b9); + background-image: -o-linear-gradient(top, #3498db, #2980b9); + background-image: linear-gradient(to bottom, #3498db, #2980b9); + -webkit-border-radius: 28; + -moz-border-radius: 28; + border-radius: 28px; + font-family: Arial; + color: #ffffff; + font-size: 10px; + padding: 5px 20px 5px 10px; + text-decoration: none; +} + +.btn:hover { + background: #3cb0fd; + background-image: -webkit-linear-gradient(top, #3cb0fd, #3498db); + background-image: -moz-linear-gradient(top, #3cb0fd, #3498db); + background-image: -ms-linear-gradient(top, #3cb0fd, #3498db); + background-image: -o-linear-gradient(top, #3cb0fd, #3498db); + background-image: linear-gradient(to bottom, #3cb0fd, #3498db); + text-decoration: none; +} + +.btn-reverse { + background: #E74C3C; +} diff --git a/tim_miller/app/css/skeleton.css b/tim_miller/app/css/skeleton.css new file mode 100644 index 0000000..8365508 --- /dev/null +++ b/tim_miller/app/css/skeleton.css @@ -0,0 +1,356 @@ +/* +* Skeleton V2.0.4 +* Copyright 2014, Dave Gamache +* www.getskeleton.com +* Free to use under the MIT license. +* http://www.opensource.org/licenses/mit-license.php +* 12/29/2014 +*/ + + +/* Table of contents +–––––––––––––––––––––––––––––––––––––––––––––––––– +- Grid +- Base Styles +- Typography +- Links +- Forms +- Lists +- Code +- Tables +- Spacing +- Utilities +- Clearing +- Media Queries +*/ + + +/* Grid +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +.container { + position: relative; + width: 100%; + max-width: 960px; + margin: 0 auto; + padding: 0 20px; + box-sizing: border-box; } +.column, +.columns { + width: 100%; + float: left; + box-sizing: border-box; } + +/* For devices larger than 400px */ +@media (min-width: 400px) { + .container { + width: 85%; + padding: 0; } +} + +/* For devices larger than 550px */ +@media (min-width: 550px) { + .container { + width: 80%; } + .column, + .columns { + margin-left: 4%; } + .column:first-child, + .columns:first-child { + margin-left: 0; } + + .one.column, + .one.columns { width: 4.66666666667%; } + .two.columns { width: 13.3333333333%; } + .three.columns { width: 22%; } + .four.columns { width: 30.6666666667%; } + .five.columns { width: 39.3333333333%; } + .six.columns { width: 48%; } + .seven.columns { width: 56.6666666667%; } + .eight.columns { width: 65.3333333333%; } + .nine.columns { width: 74.0%; } + .ten.columns { width: 82.6666666667%; } + .eleven.columns { width: 91.3333333333%; } + .twelve.columns { width: 100%; margin-left: 0; } + + .one-third.column { width: 30.6666666667%; } + .two-thirds.column { width: 65.3333333333%; } + + .one-half.column { width: 48%; } + + /* Offsets */ + .offset-by-one.column, + .offset-by-one.columns { margin-left: 8.66666666667%; } + .offset-by-two.column, + .offset-by-two.columns { margin-left: 17.3333333333%; } + .offset-by-three.column, + .offset-by-three.columns { margin-left: 26%; } + .offset-by-four.column, + .offset-by-four.columns { margin-left: 34.6666666667%; } + .offset-by-five.column, + .offset-by-five.columns { margin-left: 43.3333333333%; } + .offset-by-six.column, + .offset-by-six.columns { margin-left: 52%; } + .offset-by-seven.column, + .offset-by-seven.columns { margin-left: 60.6666666667%; } + .offset-by-eight.column, + .offset-by-eight.columns { margin-left: 69.3333333333%; } + .offset-by-nine.column, + .offset-by-nine.columns { margin-left: 78.0%; } + .offset-by-ten.column, + .offset-by-ten.columns { margin-left: 86.6666666667%; } + .offset-by-eleven.column, + .offset-by-eleven.columns { margin-left: 95.3333333333%; } + + .offset-by-one-third.column, + .offset-by-one-third.columns { margin-left: 34.6666666667%; } + .offset-by-two-thirds.column, + .offset-by-two-thirds.columns { margin-left: 69.3333333333%; } + + .offset-by-one-half.column, + .offset-by-one-half.columns { margin-left: 52%; } + +} + + +/* Base Styles +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +/* NOTE +html is set to 62.5% so that all the REM measurements throughout Skeleton +are based on 10px sizing. So basically 1.5rem = 15px :) */ +html { + font-size: 62.5%; } +body { + font-size: 1.5em; /* currently ems cause chrome bug misinterpreting rems on body element */ + line-height: 1.6; + font-weight: 400; + font-family: "Raleway", "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif; + color: #222; } + + +/* Typography +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +h1, h2, h3, h4, h5, h6 { + margin-top: 0; + margin-bottom: 2rem; + font-weight: 300; } +h1 { font-size: 4.0rem; line-height: 1.2; letter-spacing: -.1rem;} +h2 { font-size: 3.6rem; line-height: 1.25; letter-spacing: -.1rem; } +h3 { font-size: 3.0rem; line-height: 1.3; letter-spacing: -.1rem; } +h4 { font-size: 2.4rem; line-height: 1.35; letter-spacing: -.08rem; } +h5 { font-size: 1.8rem; line-height: 1.5; letter-spacing: -.05rem; } +h6 { font-size: 1.5rem; line-height: 1.6; letter-spacing: 0; } + +/* Larger than phablet */ +@media (min-width: 550px) { + h1 { font-size: 5.0rem; } + h2 { font-size: 4.2rem; } + h3 { font-size: 3.6rem; } + h4 { font-size: 3.0rem; } + h5 { font-size: 2.4rem; } + h6 { font-size: 1.5rem; } +} + +p { + margin-top: 0; } + + +/* Links +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +a { + color: #1EAEDB; } +a:hover { + color: #0FA0CE; } + +/* Forms +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +input[type="email"], +input[type="number"], +input[type="search"], +input[type="text"], +input[type="tel"], +input[type="url"], +input[type="password"], +textarea, +select { + height: 38px; + padding: 6px 10px; /* The 6px vertically centers text on FF, ignored by Webkit */ + background-color: #fff; + border: 1px solid #D1D1D1; + border-radius: 4px; + box-shadow: none; + box-sizing: border-box; } +/* Removes awkward default styles on some inputs for iOS */ +input[type="email"], +input[type="number"], +input[type="search"], +input[type="text"], +input[type="tel"], +input[type="url"], +input[type="password"], +textarea { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; } +textarea { + min-height: 65px; + padding-top: 6px; + padding-bottom: 6px; } +input[type="email"]:focus, +input[type="number"]:focus, +input[type="search"]:focus, +input[type="text"]:focus, +input[type="tel"]:focus, +input[type="url"]:focus, +input[type="password"]:focus, +textarea:focus, +select:focus { + border: 1px solid #33C3F0; + outline: 0; } +label, +legend { + display: block; + margin-bottom: .5rem; + font-weight: 600; } +fieldset { + padding: 0; + border-width: 0; } +input[type="checkbox"], +input[type="radio"] { + display: inline; } +label > .label-body { + display: inline-block; + margin-left: .5rem; + font-weight: normal; } + + +/* Lists +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +ul { + list-style: circle inside; } +ol { + list-style: decimal inside; } +ol, ul { + padding-left: 0; + margin-top: 0; } +ul ul, +ul ol, +ol ol, +ol ul { + margin: 1.5rem 0 1.5rem 3rem; + font-size: 90%; } +li { + margin-bottom: 1rem; } + + +/* Code +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +code { + padding: .2rem .5rem; + margin: 0 .2rem; + font-size: 90%; + white-space: nowrap; + background: #F1F1F1; + border: 1px solid #E1E1E1; + border-radius: 4px; } +pre > code { + display: block; + padding: 1rem 1.5rem; + white-space: pre; } + + +/* Tables +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +th, +td { + padding: 12px 15px; + text-align: left; + border-bottom: 1px solid #E1E1E1; } +th:first-child, +td:first-child { + padding-left: 0; } +th:last-child, +td:last-child { + padding-right: 0; } + + +/* Spacing +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +button, +.button { + margin-bottom: 1rem; } +input, +textarea, +select, +fieldset { + margin-bottom: 1.5rem; } +pre, +blockquote, +dl, +figure, +table, +p, +ul, +ol, +form { + margin-bottom: 2.5rem; } + + +/* Utilities +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +.u-full-width { + width: 100%; + box-sizing: border-box; } +.u-max-full-width { + max-width: 100%; + box-sizing: border-box; } +.u-pull-right { + float: right; } +.u-pull-left { + float: left; } + + +/* Misc +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +hr { + margin-top: 3rem; + margin-bottom: 3.5rem; + border-width: 0; + border-top: 1px solid #E1E1E1; } + + +/* Clearing +–––––––––––––––––––––––––––––––––––––––––––––––––– */ + +/* Self Clearing Goodness */ +.container:after, +.row:after, +.u-cf { + content: ""; + display: table; + clear: both; } + + +/* Media Queries +–––––––––––––––––––––––––––––––––––––––––––––––––– */ +/* +Note: The best way to structure the use of media queries is to create the queries +near the relevant code. For example, if you wanted to change the styles for buttons +on small devices, paste the mobile query code up in the buttons section and style it +there. +*/ + + +/* Larger than mobile */ +@media (min-width: 400px) {} + +/* Larger than phablet (also point when grid becomes active) */ +@media (min-width: 550px) {} + +/* Larger than tablet */ +@media (min-width: 750px) {} + +/* Larger than desktop */ +@media (min-width: 1000px) {} + +/* Larger than Desktop HD */ +@media (min-width: 1200px) {} diff --git a/tim_miller/app/css/state.css b/tim_miller/app/css/state.css new file mode 100644 index 0000000..7d96684 --- /dev/null +++ b/tim_miller/app/css/state.css @@ -0,0 +1,7 @@ +.resource { + background-color: #E74C3C; +} + +body { + background-color: #3498DB; +} diff --git a/tim_miller/app/index.html b/tim_miller/app/index.html index dd96286..69e518a 100644 --- a/tim_miller/app/index.html +++ b/tim_miller/app/index.html @@ -6,12 +6,12 @@ -

    Bad Boys Bad Boys

    +

    Bad Boys Bad Boys

    - +

    {{outcome}}

    -
    +
    • {{error}}
    @@ -19,51 +19,61 @@

    Bad Boys Bad Boys

    New Officer:

    - + -
      -
    • Name: {{officer.name}} Criminals Busted: {{officer.criminalsBusted}} - -
      +
        +
      • + + Name: {{officer.name}} Criminals Busted: {{officer.criminalsBusted}} + + + + -

        Update Officer:

        +

        Update Officer:

        - - + + - - + + - - + + +
    -
    +

    New Felon:

    - +
    -
      -
    • Name: {{felon.name}} In Jail: {{felon.inJail}} - +
        +
      • + + Name: {{felon.name}} In Jail: {{felon.inJail}} + + + -
        + -

        Update felon:

        +

        Update felon:

        - - + + - - + + -
        - + + +
      diff --git a/tim_miller/gulpfile.js b/tim_miller/gulpfile.js index 919004a..e61cfb6 100644 --- a/tim_miller/gulpfile.js +++ b/tim_miller/gulpfile.js @@ -27,8 +27,10 @@ gulp.task('static:dev', function() { gulp.task('css:dev', function() { return gulp.src([ 'app/css/base.css', + 'app/css/skeleton.css', + 'app/css/state.css', 'app/css/layout.css', - 'app/css/module.css' + 'app/css/module.css', ]) .pipe(concatCss('styles.min.css')) .pipe(minifyCss()) From ac54a7dcb5cc858828cb5128db19d109e989b428 Mon Sep 17 00:00:00 2001 From: timcmiller Date: Mon, 7 Dec 2015 20:54:16 -0800 Subject: [PATCH 14/18] added some sassyness --- tim_miller/app/css/layout.css | 22 -- tim_miller/app/css/module.css | 30 --- tim_miller/app/css/skeleton.css | 356 --------------------------- tim_miller/app/css/state.css | 7 - tim_miller/app/index.html | 100 ++++---- tim_miller/app/sass/application.scss | 3 + tim_miller/app/sass/layout.scss | 44 ++++ tim_miller/app/sass/state.scss | 20 ++ tim_miller/app/sass/variables.scss | 5 + tim_miller/gulpfile.js | 33 +-- tim_miller/package.json | 9 +- 11 files changed, 147 insertions(+), 482 deletions(-) delete mode 100644 tim_miller/app/css/layout.css delete mode 100644 tim_miller/app/css/module.css delete mode 100644 tim_miller/app/css/skeleton.css delete mode 100644 tim_miller/app/css/state.css create mode 100644 tim_miller/app/sass/application.scss create mode 100644 tim_miller/app/sass/layout.scss create mode 100644 tim_miller/app/sass/state.scss create mode 100644 tim_miller/app/sass/variables.scss diff --git a/tim_miller/app/css/layout.css b/tim_miller/app/css/layout.css deleted file mode 100644 index db726a4..0000000 --- a/tim_miller/app/css/layout.css +++ /dev/null @@ -1,22 +0,0 @@ -.resource { - display: flex; - flex-direction: column; - padding-left: 1em; - margin-bottom: 1em; - border-radius: 25px; -} - -.list { - dispaly: flex; - flex-direction: row; -} - -.btn { - justify-content: flex-end; -} - -.list-content { - justify-content: flex-start; -} - - diff --git a/tim_miller/app/css/module.css b/tim_miller/app/css/module.css deleted file mode 100644 index 16eb0a4..0000000 --- a/tim_miller/app/css/module.css +++ /dev/null @@ -1,30 +0,0 @@ -.btn { - background: #3498db; - background-image: -webkit-linear-gradient(top, #3498db, #2980b9); - background-image: -moz-linear-gradient(top, #3498db, #2980b9); - background-image: -ms-linear-gradient(top, #3498db, #2980b9); - background-image: -o-linear-gradient(top, #3498db, #2980b9); - background-image: linear-gradient(to bottom, #3498db, #2980b9); - -webkit-border-radius: 28; - -moz-border-radius: 28; - border-radius: 28px; - font-family: Arial; - color: #ffffff; - font-size: 10px; - padding: 5px 20px 5px 10px; - text-decoration: none; -} - -.btn:hover { - background: #3cb0fd; - background-image: -webkit-linear-gradient(top, #3cb0fd, #3498db); - background-image: -moz-linear-gradient(top, #3cb0fd, #3498db); - background-image: -ms-linear-gradient(top, #3cb0fd, #3498db); - background-image: -o-linear-gradient(top, #3cb0fd, #3498db); - background-image: linear-gradient(to bottom, #3cb0fd, #3498db); - text-decoration: none; -} - -.btn-reverse { - background: #E74C3C; -} diff --git a/tim_miller/app/css/skeleton.css b/tim_miller/app/css/skeleton.css deleted file mode 100644 index 8365508..0000000 --- a/tim_miller/app/css/skeleton.css +++ /dev/null @@ -1,356 +0,0 @@ -/* -* Skeleton V2.0.4 -* Copyright 2014, Dave Gamache -* www.getskeleton.com -* Free to use under the MIT license. -* http://www.opensource.org/licenses/mit-license.php -* 12/29/2014 -*/ - - -/* Table of contents -–––––––––––––––––––––––––––––––––––––––––––––––––– -- Grid -- Base Styles -- Typography -- Links -- Forms -- Lists -- Code -- Tables -- Spacing -- Utilities -- Clearing -- Media Queries -*/ - - -/* Grid -–––––––––––––––––––––––––––––––––––––––––––––––––– */ -.container { - position: relative; - width: 100%; - max-width: 960px; - margin: 0 auto; - padding: 0 20px; - box-sizing: border-box; } -.column, -.columns { - width: 100%; - float: left; - box-sizing: border-box; } - -/* For devices larger than 400px */ -@media (min-width: 400px) { - .container { - width: 85%; - padding: 0; } -} - -/* For devices larger than 550px */ -@media (min-width: 550px) { - .container { - width: 80%; } - .column, - .columns { - margin-left: 4%; } - .column:first-child, - .columns:first-child { - margin-left: 0; } - - .one.column, - .one.columns { width: 4.66666666667%; } - .two.columns { width: 13.3333333333%; } - .three.columns { width: 22%; } - .four.columns { width: 30.6666666667%; } - .five.columns { width: 39.3333333333%; } - .six.columns { width: 48%; } - .seven.columns { width: 56.6666666667%; } - .eight.columns { width: 65.3333333333%; } - .nine.columns { width: 74.0%; } - .ten.columns { width: 82.6666666667%; } - .eleven.columns { width: 91.3333333333%; } - .twelve.columns { width: 100%; margin-left: 0; } - - .one-third.column { width: 30.6666666667%; } - .two-thirds.column { width: 65.3333333333%; } - - .one-half.column { width: 48%; } - - /* Offsets */ - .offset-by-one.column, - .offset-by-one.columns { margin-left: 8.66666666667%; } - .offset-by-two.column, - .offset-by-two.columns { margin-left: 17.3333333333%; } - .offset-by-three.column, - .offset-by-three.columns { margin-left: 26%; } - .offset-by-four.column, - .offset-by-four.columns { margin-left: 34.6666666667%; } - .offset-by-five.column, - .offset-by-five.columns { margin-left: 43.3333333333%; } - .offset-by-six.column, - .offset-by-six.columns { margin-left: 52%; } - .offset-by-seven.column, - .offset-by-seven.columns { margin-left: 60.6666666667%; } - .offset-by-eight.column, - .offset-by-eight.columns { margin-left: 69.3333333333%; } - .offset-by-nine.column, - .offset-by-nine.columns { margin-left: 78.0%; } - .offset-by-ten.column, - .offset-by-ten.columns { margin-left: 86.6666666667%; } - .offset-by-eleven.column, - .offset-by-eleven.columns { margin-left: 95.3333333333%; } - - .offset-by-one-third.column, - .offset-by-one-third.columns { margin-left: 34.6666666667%; } - .offset-by-two-thirds.column, - .offset-by-two-thirds.columns { margin-left: 69.3333333333%; } - - .offset-by-one-half.column, - .offset-by-one-half.columns { margin-left: 52%; } - -} - - -/* Base Styles -–––––––––––––––––––––––––––––––––––––––––––––––––– */ -/* NOTE -html is set to 62.5% so that all the REM measurements throughout Skeleton -are based on 10px sizing. So basically 1.5rem = 15px :) */ -html { - font-size: 62.5%; } -body { - font-size: 1.5em; /* currently ems cause chrome bug misinterpreting rems on body element */ - line-height: 1.6; - font-weight: 400; - font-family: "Raleway", "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif; - color: #222; } - - -/* Typography -–––––––––––––––––––––––––––––––––––––––––––––––––– */ -h1, h2, h3, h4, h5, h6 { - margin-top: 0; - margin-bottom: 2rem; - font-weight: 300; } -h1 { font-size: 4.0rem; line-height: 1.2; letter-spacing: -.1rem;} -h2 { font-size: 3.6rem; line-height: 1.25; letter-spacing: -.1rem; } -h3 { font-size: 3.0rem; line-height: 1.3; letter-spacing: -.1rem; } -h4 { font-size: 2.4rem; line-height: 1.35; letter-spacing: -.08rem; } -h5 { font-size: 1.8rem; line-height: 1.5; letter-spacing: -.05rem; } -h6 { font-size: 1.5rem; line-height: 1.6; letter-spacing: 0; } - -/* Larger than phablet */ -@media (min-width: 550px) { - h1 { font-size: 5.0rem; } - h2 { font-size: 4.2rem; } - h3 { font-size: 3.6rem; } - h4 { font-size: 3.0rem; } - h5 { font-size: 2.4rem; } - h6 { font-size: 1.5rem; } -} - -p { - margin-top: 0; } - - -/* Links -–––––––––––––––––––––––––––––––––––––––––––––––––– */ -a { - color: #1EAEDB; } -a:hover { - color: #0FA0CE; } - -/* Forms -–––––––––––––––––––––––––––––––––––––––––––––––––– */ -input[type="email"], -input[type="number"], -input[type="search"], -input[type="text"], -input[type="tel"], -input[type="url"], -input[type="password"], -textarea, -select { - height: 38px; - padding: 6px 10px; /* The 6px vertically centers text on FF, ignored by Webkit */ - background-color: #fff; - border: 1px solid #D1D1D1; - border-radius: 4px; - box-shadow: none; - box-sizing: border-box; } -/* Removes awkward default styles on some inputs for iOS */ -input[type="email"], -input[type="number"], -input[type="search"], -input[type="text"], -input[type="tel"], -input[type="url"], -input[type="password"], -textarea { - -webkit-appearance: none; - -moz-appearance: none; - appearance: none; } -textarea { - min-height: 65px; - padding-top: 6px; - padding-bottom: 6px; } -input[type="email"]:focus, -input[type="number"]:focus, -input[type="search"]:focus, -input[type="text"]:focus, -input[type="tel"]:focus, -input[type="url"]:focus, -input[type="password"]:focus, -textarea:focus, -select:focus { - border: 1px solid #33C3F0; - outline: 0; } -label, -legend { - display: block; - margin-bottom: .5rem; - font-weight: 600; } -fieldset { - padding: 0; - border-width: 0; } -input[type="checkbox"], -input[type="radio"] { - display: inline; } -label > .label-body { - display: inline-block; - margin-left: .5rem; - font-weight: normal; } - - -/* Lists -–––––––––––––––––––––––––––––––––––––––––––––––––– */ -ul { - list-style: circle inside; } -ol { - list-style: decimal inside; } -ol, ul { - padding-left: 0; - margin-top: 0; } -ul ul, -ul ol, -ol ol, -ol ul { - margin: 1.5rem 0 1.5rem 3rem; - font-size: 90%; } -li { - margin-bottom: 1rem; } - - -/* Code -–––––––––––––––––––––––––––––––––––––––––––––––––– */ -code { - padding: .2rem .5rem; - margin: 0 .2rem; - font-size: 90%; - white-space: nowrap; - background: #F1F1F1; - border: 1px solid #E1E1E1; - border-radius: 4px; } -pre > code { - display: block; - padding: 1rem 1.5rem; - white-space: pre; } - - -/* Tables -–––––––––––––––––––––––––––––––––––––––––––––––––– */ -th, -td { - padding: 12px 15px; - text-align: left; - border-bottom: 1px solid #E1E1E1; } -th:first-child, -td:first-child { - padding-left: 0; } -th:last-child, -td:last-child { - padding-right: 0; } - - -/* Spacing -–––––––––––––––––––––––––––––––––––––––––––––––––– */ -button, -.button { - margin-bottom: 1rem; } -input, -textarea, -select, -fieldset { - margin-bottom: 1.5rem; } -pre, -blockquote, -dl, -figure, -table, -p, -ul, -ol, -form { - margin-bottom: 2.5rem; } - - -/* Utilities -–––––––––––––––––––––––––––––––––––––––––––––––––– */ -.u-full-width { - width: 100%; - box-sizing: border-box; } -.u-max-full-width { - max-width: 100%; - box-sizing: border-box; } -.u-pull-right { - float: right; } -.u-pull-left { - float: left; } - - -/* Misc -–––––––––––––––––––––––––––––––––––––––––––––––––– */ -hr { - margin-top: 3rem; - margin-bottom: 3.5rem; - border-width: 0; - border-top: 1px solid #E1E1E1; } - - -/* Clearing -–––––––––––––––––––––––––––––––––––––––––––––––––– */ - -/* Self Clearing Goodness */ -.container:after, -.row:after, -.u-cf { - content: ""; - display: table; - clear: both; } - - -/* Media Queries -–––––––––––––––––––––––––––––––––––––––––––––––––– */ -/* -Note: The best way to structure the use of media queries is to create the queries -near the relevant code. For example, if you wanted to change the styles for buttons -on small devices, paste the mobile query code up in the buttons section and style it -there. -*/ - - -/* Larger than mobile */ -@media (min-width: 400px) {} - -/* Larger than phablet (also point when grid becomes active) */ -@media (min-width: 550px) {} - -/* Larger than tablet */ -@media (min-width: 750px) {} - -/* Larger than desktop */ -@media (min-width: 1000px) {} - -/* Larger than Desktop HD */ -@media (min-width: 1200px) {} diff --git a/tim_miller/app/css/state.css b/tim_miller/app/css/state.css deleted file mode 100644 index 7d96684..0000000 --- a/tim_miller/app/css/state.css +++ /dev/null @@ -1,7 +0,0 @@ -.resource { - background-color: #E74C3C; -} - -body { - background-color: #3498DB; -} diff --git a/tim_miller/app/index.html b/tim_miller/app/index.html index 69e518a..3958b22 100644 --- a/tim_miller/app/index.html +++ b/tim_miller/app/index.html @@ -3,34 +3,28 @@ Cops! + +

      Bad Boys Bad Boys

      {{outcome}}

      - -
      -
        -
      • {{error}}
      • -
      -
      -

      New Officer:

      - - - -
      -
        -
      • - - Name: {{officer.name}} Criminals Busted: {{officer.criminalsBusted}} - - - +
        +
        +
        +

        New Officer:

        + + + +
        +
          +
        • -

          Update Officer:

          +

          Update Officer:

          @@ -39,45 +33,51 @@

          Update Officer:

          - - -
        • -
        -
        -
        + + Name: {{officer.name}} Criminals Busted: {{officer.criminalsBusted}} + + + + + +
      • +
      +
      +
      -
      -

      New Felon:

      - - - -
      +
      +

      New Felon:

      + + + +
      -
        -
      • - - Name: {{felon.name}} In Jail: {{felon.inJail}} - - - +
          +
        • + + Name: {{felon.name}} In Jail: {{felon.inJail}} + + + -
          + -

          Update felon:

          +

          Update felon:

          - - + + - - + + -
          - -
          -
        • -
        + + +
        +
      • +
      -
      +
      +
    diff --git a/tim_miller/app/sass/application.scss b/tim_miller/app/sass/application.scss new file mode 100644 index 0000000..4707558 --- /dev/null +++ b/tim_miller/app/sass/application.scss @@ -0,0 +1,3 @@ +@import "layout"; +@import "module"; +@import "state"; diff --git a/tim_miller/app/sass/layout.scss b/tim_miller/app/sass/layout.scss new file mode 100644 index 0000000..1b8975e --- /dev/null +++ b/tim_miller/app/sass/layout.scss @@ -0,0 +1,44 @@ +.heading { + margin: 15ems; +} + +.resource { + display: flex; + flex-direction: column; + border: 1px solid; + margin: 10px; + button { + font-size: 10px; + } +} + +.outer-flex { + display: flex; + flex-direction: row; +} + +li{ + display: flex; + flex-wrap: wrap; + justify-content: center; +} + +.list-content{ + justify-content: center; + width: 100%; +} + +.input-form{ + dispaly: flex; + flex-wrap: wrap; + h2 { + width: 100%; + } + label{ + width: 30%; + } + input { + width: 70%; + } +} + diff --git a/tim_miller/app/sass/state.scss b/tim_miller/app/sass/state.scss new file mode 100644 index 0000000..06cb82f --- /dev/null +++ b/tim_miller/app/sass/state.scss @@ -0,0 +1,20 @@ +@import "variables"; + +body { + font-family: $primary-font; + background-color: $primary-color; +} + +.heading { + background-color: $secondary-color; + font-family: $secondary-font; +} + +.resource-heading { + background-color: $tertiary-color; + font-family: $secondary-font; + color: $primary-color; +} + + + diff --git a/tim_miller/app/sass/variables.scss b/tim_miller/app/sass/variables.scss new file mode 100644 index 0000000..91e2a80 --- /dev/null +++ b/tim_miller/app/sass/variables.scss @@ -0,0 +1,5 @@ +$primary-color: #ECF0F1; +$secondary-color: #E74C3C; +$tertiary-color: #2C3E50; +$primary-font: 'Roboto', sans-serif; +$secondary-font: 'Rock Salt', cursive; diff --git a/tim_miller/gulpfile.js b/tim_miller/gulpfile.js index e61cfb6..4b88b78 100644 --- a/tim_miller/gulpfile.js +++ b/tim_miller/gulpfile.js @@ -3,10 +3,10 @@ var mocha = require('gulp-mocha'); var jshint = require('gulp-jshint'); var webpack = require('webpack-stream'); var minifyCss = require('gulp-minify-css'); -var concatCss = require('gulp-concat-css'); var gulpWatch = require('gulp-watch'); - -gulp.task('default', ['jshint', 'test']); +var sass = require('gulp-sass'); +var concatCSS = require('gulp-concat-css'); +var maps = require('gulp-sourcemaps'); gulp.task('jshint', function(){ gulp.src(['gulpfile.js', 'lib/*.js', 'test/*.js', 'server.js', 'models/*.js', 'routes/*.js']) @@ -24,21 +24,26 @@ gulp.task('static:dev', function() { .pipe(gulp.dest('build/')); }); +gulp.task('sass:dev', function() { + gulp.src('./app/sass/application.scss') + .pipe(maps.init()) + .pipe(sass().on('error', sass.logError)) + .pipe(minifyCss()) + .pipe(maps.write('./')) + .pipe(gulp.dest('build/')); +}); + gulp.task('css:dev', function() { return gulp.src([ 'app/css/base.css', - 'app/css/skeleton.css', - 'app/css/state.css', - 'app/css/layout.css', - 'app/css/module.css', - ]) - .pipe(concatCss('styles.min.css')) - .pipe(minifyCss()) - .pipe(gulp.dest('build/')); + 'app/css/skeleton.css']) + .pipe(concatCSS('styles.min.css')) + .pipe(minifyCss()) + .pipe(gulp.dest('build/')); }); gulp.task('watch', function() { - gulp.watch('./app/**', ['default']); + gulp.watch('./app/**/*', ['styles']); }); gulp.task('webpack:dev', function() { @@ -61,6 +66,6 @@ gulp.task('webpack:test', function() { .pipe(gulp.dest('test/client/')); }); - +gulp.task('styles', ['sass:dev', 'css:dev']); gulp.task('build:dev', ['webpack:dev', 'static:dev', 'css:dev']); -gulp.task('default', ['build:dev']); +gulp.task('default', ['build:dev', 'jshint', 'test']); diff --git a/tim_miller/package.json b/tim_miller/package.json index c81b728..ac15236 100644 --- a/tim_miller/package.json +++ b/tim_miller/package.json @@ -30,17 +30,20 @@ "chai-http": "^1.0.0", "gulp": "^3.9.0", "gulp-concat-css": "^2.2.0", - "gulp-jshint": "^1.12.0", + "gulp-jshint": "^2.0.0", "gulp-minify-css": "^1.2.2", - "gulp-mocha": "^2.1.3", + "gulp-mocha": "^2.2.0", + "gulp-sass": "^2.1.0", + "gulp-sourcemaps": "^1.6.0", "gulp-watch": "^4.3.5", "jasmine-core": "^2.3.4", + "jshint": "^2.8.0", "jshint-stylish": "^2.0.1", "karma": "^0.13.15", "karma-jasmine": "^0.3.6", "karma-phantomjs-launcher": "^0.2.1", "mocha": "^2.3.3", "phantomjs": "^1.9.19", - "webpack-stream": "^2.1.1" + "webpack-stream": "^2.3.0" } } From 6c6aff33f50480f521114e42c260edd5ad806385 Mon Sep 17 00:00:00 2001 From: timcmiller Date: Tue, 8 Dec 2015 09:15:27 -0800 Subject: [PATCH 15/18] changed sass structure --- tim_miller/app/sass/application.scss | 2 +- .../app/{css/base.css => sass/base.scss} | 0 tim_miller/app/sass/layout.scss | 49 +++++-------------- tim_miller/app/sass/module.scss | 44 +++++++++++++++++ tim_miller/app/sass/state.scss | 20 -------- 5 files changed, 56 insertions(+), 59 deletions(-) rename tim_miller/app/{css/base.css => sass/base.scss} (100%) create mode 100644 tim_miller/app/sass/module.scss delete mode 100644 tim_miller/app/sass/state.scss diff --git a/tim_miller/app/sass/application.scss b/tim_miller/app/sass/application.scss index 4707558..294f70d 100644 --- a/tim_miller/app/sass/application.scss +++ b/tim_miller/app/sass/application.scss @@ -1,3 +1,3 @@ +@import "base"; @import "layout"; @import "module"; -@import "state"; diff --git a/tim_miller/app/css/base.css b/tim_miller/app/sass/base.scss similarity index 100% rename from tim_miller/app/css/base.css rename to tim_miller/app/sass/base.scss diff --git a/tim_miller/app/sass/layout.scss b/tim_miller/app/sass/layout.scss index 1b8975e..c740bf4 100644 --- a/tim_miller/app/sass/layout.scss +++ b/tim_miller/app/sass/layout.scss @@ -1,44 +1,17 @@ -.heading { - margin: 15ems; -} - -.resource { - display: flex; - flex-direction: column; - border: 1px solid; - margin: 10px; - button { - font-size: 10px; - } -} +@import "variables"; -.outer-flex { - display: flex; - flex-direction: row; +body { + font-family: $primary-font; + background-color: $primary-color; } -li{ - display: flex; - flex-wrap: wrap; - justify-content: center; -} - -.list-content{ - justify-content: center; - width: 100%; +.heading { + background-color: $secondary-color; + font-family: $secondary-font; } -.input-form{ - dispaly: flex; - flex-wrap: wrap; - h2 { - width: 100%; - } - label{ - width: 30%; - } - input { - width: 70%; - } +.resource-heading { + background-color: $tertiary-color; + font-family: $secondary-font; + color: $primary-color; } - diff --git a/tim_miller/app/sass/module.scss b/tim_miller/app/sass/module.scss new file mode 100644 index 0000000..1b8975e --- /dev/null +++ b/tim_miller/app/sass/module.scss @@ -0,0 +1,44 @@ +.heading { + margin: 15ems; +} + +.resource { + display: flex; + flex-direction: column; + border: 1px solid; + margin: 10px; + button { + font-size: 10px; + } +} + +.outer-flex { + display: flex; + flex-direction: row; +} + +li{ + display: flex; + flex-wrap: wrap; + justify-content: center; +} + +.list-content{ + justify-content: center; + width: 100%; +} + +.input-form{ + dispaly: flex; + flex-wrap: wrap; + h2 { + width: 100%; + } + label{ + width: 30%; + } + input { + width: 70%; + } +} + diff --git a/tim_miller/app/sass/state.scss b/tim_miller/app/sass/state.scss deleted file mode 100644 index 06cb82f..0000000 --- a/tim_miller/app/sass/state.scss +++ /dev/null @@ -1,20 +0,0 @@ -@import "variables"; - -body { - font-family: $primary-font; - background-color: $primary-color; -} - -.heading { - background-color: $secondary-color; - font-family: $secondary-font; -} - -.resource-heading { - background-color: $tertiary-color; - font-family: $secondary-font; - color: $primary-color; -} - - - From e3935a840cbe40296132b7552b6257536edd9176 Mon Sep 17 00:00:00 2001 From: timcmiller Date: Wed, 9 Dec 2015 13:01:57 -0800 Subject: [PATCH 16/18] commiting directive --- tim_miller/app/sass/_module.scss | 60 ++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 tim_miller/app/sass/_module.scss diff --git a/tim_miller/app/sass/_module.scss b/tim_miller/app/sass/_module.scss new file mode 100644 index 0000000..24dcdd3 --- /dev/null +++ b/tim_miller/app/sass/_module.scss @@ -0,0 +1,60 @@ +.heading { + padding-left: em(10); +} + +.btn-large { + justify-content: center; + margin: auto; + border-radius: em(25); + background-color: red; + text: em(20); + width: em(200); + height: em(50); +} + +.resource { + display: flex; + flex-direction: column; + border: em(1) solid; + width: 40%; + margin-left: auto; + margin-right: auto; + button { + font-size: em(10); + } +} + +.resource-heading { + margin-top: 0px; +} + +.outer-flex { + display: flex; + flex-direction: row; +} + +li{ + display: flex; + flex-wrap: wrap; + justify-content: center; +} + +.list-content{ + justify-content: center; + width: 100%; +} + +.input-form{ + dispaly: flex; + flex-wrap: wrap; + h2 { + width: 100%; + } + label{ + width: 30%; + } + input { + width: 70%; + } +} + From ae0a5d448bc2193eaa2c6923476b204ab6ac9f47 Mon Sep 17 00:00:00 2001 From: timcmiller Date: Thu, 10 Dec 2015 13:50:58 -0800 Subject: [PATCH 17/18] added directives --- tim_miller/app/index.html | 31 +--------- tim_miller/app/js/entry.js | 16 ++++- .../directives/officer_form_directive.js | 17 ++++++ tim_miller/app/js/officers/officers.js | 1 + tim_miller/app/sass/_module.scss | 60 ------------------- .../app/templates/officer_form_template.html | 12 ++++ tim_miller/app/templates/officers_view.html | 33 ++++++++++ tim_miller/package.json | 1 + .../test/client/busted_controller_test.js | 2 +- 9 files changed, 81 insertions(+), 92 deletions(-) create mode 100644 tim_miller/app/js/officers/directives/officer_form_directive.js delete mode 100644 tim_miller/app/sass/_module.scss create mode 100644 tim_miller/app/templates/officer_form_template.html create mode 100644 tim_miller/app/templates/officers_view.html diff --git a/tim_miller/app/index.html b/tim_miller/app/index.html index 3958b22..0893d38 100644 --- a/tim_miller/app/index.html +++ b/tim_miller/app/index.html @@ -13,36 +13,7 @@

    Bad Boys Bad Boys

    {{outcome}}

    -
    -
    -

    New Officer:

    - - - -
    -
      -
    • -
      - -

      Update Officer:

      - - - - - - - -
      - - Name: {{officer.name}} Criminals Busted: {{officer.criminalsBusted}} - - - - - -
    • -
    -
    +
    diff --git a/tim_miller/app/js/entry.js b/tim_miller/app/js/entry.js index 1ac769e..403fd9c 100644 --- a/tim_miller/app/js/entry.js +++ b/tim_miller/app/js/entry.js @@ -1,8 +1,22 @@ require('angular/angular'); +require('angular-route'); var angular = window.angular; -var officerAndFelonApp = angular.module('OfficerAndFelonApp', []); +var officerAndFelonApp = angular.module('OfficerAndFelonApp', ['ngRoute']); require('./services/services.js')(officerAndFelonApp); require('./officers/officers.js')(officerAndFelonApp); require('./felons/felons.js')(officerAndFelonApp); require('./busted/busted.js')(officerAndFelonApp); + +officerAndFelonApp.config(['$routeProvider', function($route) { + + $route + .when('/officers', { + templateUrl: '/templates/officers_view.html', + controller: 'OfficersController' + }) + .otherwise({ + redirectTo: '/officers' + }); + +}]); diff --git a/tim_miller/app/js/officers/directives/officer_form_directive.js b/tim_miller/app/js/officers/directives/officer_form_directive.js new file mode 100644 index 0000000..95c3bde --- /dev/null +++ b/tim_miller/app/js/officers/directives/officer_form_directive.js @@ -0,0 +1,17 @@ +module.exports = function(app) { + app.directive('officerFormDirective', function() { + return { + restrict: 'AC', + replace: true, + templateUrl: 'templates/officer_form_template.html', + transclude: true, + scope: { + buttonText: '@', + headingText: '@', + formName: '@', + officer: '=', + save: '&' + } + }; + }); +}; diff --git a/tim_miller/app/js/officers/officers.js b/tim_miller/app/js/officers/officers.js index bdfb8a3..a7d4c08 100644 --- a/tim_miller/app/js/officers/officers.js +++ b/tim_miller/app/js/officers/officers.js @@ -1,4 +1,5 @@ module.exports = function(app) { require('./controllers/officer_controller')(app); + require('./directives/officer_form_directive')(app); }; diff --git a/tim_miller/app/sass/_module.scss b/tim_miller/app/sass/_module.scss deleted file mode 100644 index 24dcdd3..0000000 --- a/tim_miller/app/sass/_module.scss +++ /dev/null @@ -1,60 +0,0 @@ -.heading { - padding-left: em(10); -} - -.btn-large { - justify-content: center; - margin: auto; - border-radius: em(25); - background-color: red; - text: em(20); - width: em(200); - height: em(50); -} - -.resource { - display: flex; - flex-direction: column; - border: em(1) solid; - width: 40%; - margin-left: auto; - margin-right: auto; - button { - font-size: em(10); - } -} - -.resource-heading { - margin-top: 0px; -} - -.outer-flex { - display: flex; - flex-direction: row; -} - -li{ - display: flex; - flex-wrap: wrap; - justify-content: center; -} - -.list-content{ - justify-content: center; - width: 100%; -} - -.input-form{ - dispaly: flex; - flex-wrap: wrap; - h2 { - width: 100%; - } - label{ - width: 30%; - } - input { - width: 70%; - } -} - diff --git a/tim_miller/app/templates/officer_form_template.html b/tim_miller/app/templates/officer_form_template.html new file mode 100644 index 0000000..ef5e3ab --- /dev/null +++ b/tim_miller/app/templates/officer_form_template.html @@ -0,0 +1,12 @@ + + +

    {{headingText}}

    + + + + + + + + +
    diff --git a/tim_miller/app/templates/officers_view.html b/tim_miller/app/templates/officers_view.html new file mode 100644 index 0000000..e85174c --- /dev/null +++ b/tim_miller/app/templates/officers_view.html @@ -0,0 +1,33 @@ +
    + +
    +
    + +
      +
    • + +
      + +
      + + + Name: {{officer.name}} Criminals Busted: {{officer.criminalsBusted}} + + + + + +
    • +
    +
    diff --git a/tim_miller/package.json b/tim_miller/package.json index ac15236..009ffbf 100644 --- a/tim_miller/package.json +++ b/tim_miller/package.json @@ -26,6 +26,7 @@ "devDependencies": { "angular": "^1.4.8", "angular-mocks": "^1.4.8", + "angular-route": "^1.4.8", "chai": "^3.4.1", "chai-http": "^1.0.0", "gulp": "^3.9.0", diff --git a/tim_miller/test/client/busted_controller_test.js b/tim_miller/test/client/busted_controller_test.js index 89de930..991d1e0 100644 --- a/tim_miller/test/client/busted_controller_test.js +++ b/tim_miller/test/client/busted_controller_test.js @@ -1,4 +1,4 @@ -require(__dirname + '/../../app/js/entry.js'); +require(__dirname + '/../../app/js/entry'); require('angular-mocks'); describe('busted controller', function() { From a33eb8ea6859744b662cf2268449c5b8c0889dba Mon Sep 17 00:00:00 2001 From: timcmiller Date: Mon, 14 Dec 2015 10:21:21 -0800 Subject: [PATCH 18/18] broke into directives --- tim_miller/app/index.html | 86 ++++++++++++++----- tim_miller/app/js/directives/directives.js | 5 ++ .../form_directive/form_directive.js} | 6 +- .../list_directive/list_directive.js | 14 +++ tim_miller/app/js/entry.js | 14 +-- tim_miller/app/js/officers/officers.js | 1 - tim_miller/app/templates/form_template.html | 12 +++ tim_miller/app/templates/list_template.html | 3 + .../app/templates/officer_form_template.html | 12 --- tim_miller/app/templates/officers_view.html | 33 ------- 10 files changed, 104 insertions(+), 82 deletions(-) create mode 100644 tim_miller/app/js/directives/directives.js rename tim_miller/app/js/{officers/directives/officer_form_directive.js => directives/form_directive/form_directive.js} (64%) create mode 100644 tim_miller/app/js/directives/list_directive/list_directive.js create mode 100644 tim_miller/app/templates/form_template.html create mode 100644 tim_miller/app/templates/list_template.html delete mode 100644 tim_miller/app/templates/officer_form_template.html delete mode 100644 tim_miller/app/templates/officers_view.html diff --git a/tim_miller/app/index.html b/tim_miller/app/index.html index 0893d38..c18eb47 100644 --- a/tim_miller/app/index.html +++ b/tim_miller/app/index.html @@ -4,45 +4,91 @@ Cops! - +

    Bad Boys Bad Boys

    {{outcome}}

    -
    + + +
    +
    +
    + +
      +
    • + +
      +
      + + + +
      + +
      + + + + + +
      +
    • +
    +
    +
    -
    -

    New Felon:

    - - - -
    +
    +
    • - - Name: {{felon.name}} In Jail: {{felon.inJail}} - - - - -
      -

      Update felon:

      +
      +
      - - + - +
      +
      + + - +
    diff --git a/tim_miller/app/js/directives/directives.js b/tim_miller/app/js/directives/directives.js new file mode 100644 index 0000000..ad536ea --- /dev/null +++ b/tim_miller/app/js/directives/directives.js @@ -0,0 +1,5 @@ +module.exports = function(app) { + require('./form_directive/form_directive.js')(app); + require('./list_directive/list_directive.js')(app); + require('./view_directive/view_directive.js')(app); +}; diff --git a/tim_miller/app/js/officers/directives/officer_form_directive.js b/tim_miller/app/js/directives/form_directive/form_directive.js similarity index 64% rename from tim_miller/app/js/officers/directives/officer_form_directive.js rename to tim_miller/app/js/directives/form_directive/form_directive.js index 95c3bde..afd37b2 100644 --- a/tim_miller/app/js/officers/directives/officer_form_directive.js +++ b/tim_miller/app/js/directives/form_directive/form_directive.js @@ -1,15 +1,15 @@ module.exports = function(app) { - app.directive('officerFormDirective', function() { + app.directive('formDirective', function() { return { restrict: 'AC', replace: true, - templateUrl: 'templates/officer_form_template.html', + templateUrl: 'templates/form_template.html', transclude: true, scope: { buttonText: '@', headingText: '@', formName: '@', - officer: '=', + resource: '=', save: '&' } }; diff --git a/tim_miller/app/js/directives/list_directive/list_directive.js b/tim_miller/app/js/directives/list_directive/list_directive.js new file mode 100644 index 0000000..07d896f --- /dev/null +++ b/tim_miller/app/js/directives/list_directive/list_directive.js @@ -0,0 +1,14 @@ +module.exports = function(app) { + app.directive('listDirective', function() { + return { + restrict: 'AC', + replace: true, + templateUrl: 'templates/list_template.html', + scope: { + name: '=', + attribute: '=', + attributeTitle: '@' + } + }; + }); +}; diff --git a/tim_miller/app/js/entry.js b/tim_miller/app/js/entry.js index 403fd9c..b549332 100644 --- a/tim_miller/app/js/entry.js +++ b/tim_miller/app/js/entry.js @@ -3,20 +3,8 @@ require('angular-route'); var angular = window.angular; var officerAndFelonApp = angular.module('OfficerAndFelonApp', ['ngRoute']); +require('./directives/directives.js')(officerAndFelonApp); require('./services/services.js')(officerAndFelonApp); require('./officers/officers.js')(officerAndFelonApp); require('./felons/felons.js')(officerAndFelonApp); require('./busted/busted.js')(officerAndFelonApp); - -officerAndFelonApp.config(['$routeProvider', function($route) { - - $route - .when('/officers', { - templateUrl: '/templates/officers_view.html', - controller: 'OfficersController' - }) - .otherwise({ - redirectTo: '/officers' - }); - -}]); diff --git a/tim_miller/app/js/officers/officers.js b/tim_miller/app/js/officers/officers.js index a7d4c08..bdfb8a3 100644 --- a/tim_miller/app/js/officers/officers.js +++ b/tim_miller/app/js/officers/officers.js @@ -1,5 +1,4 @@ module.exports = function(app) { require('./controllers/officer_controller')(app); - require('./directives/officer_form_directive')(app); }; diff --git a/tim_miller/app/templates/form_template.html b/tim_miller/app/templates/form_template.html new file mode 100644 index 0000000..a94f36c --- /dev/null +++ b/tim_miller/app/templates/form_template.html @@ -0,0 +1,12 @@ +
    + +

    {{headingText}}

    + + + + + + + + +
    diff --git a/tim_miller/app/templates/list_template.html b/tim_miller/app/templates/list_template.html new file mode 100644 index 0000000..6daddac --- /dev/null +++ b/tim_miller/app/templates/list_template.html @@ -0,0 +1,3 @@ + + Name: {{name}} {{attributeTitle}}: {{attribute}} + diff --git a/tim_miller/app/templates/officer_form_template.html b/tim_miller/app/templates/officer_form_template.html deleted file mode 100644 index ef5e3ab..0000000 --- a/tim_miller/app/templates/officer_form_template.html +++ /dev/null @@ -1,12 +0,0 @@ -
    - -

    {{headingText}}

    - - - - - - - - -
    diff --git a/tim_miller/app/templates/officers_view.html b/tim_miller/app/templates/officers_view.html deleted file mode 100644 index e85174c..0000000 --- a/tim_miller/app/templates/officers_view.html +++ /dev/null @@ -1,33 +0,0 @@ -
    - -
    -
    - -
      -
    • - -
      - -
      - - - Name: {{officer.name}} Criminals Busted: {{officer.criminalsBusted}} - - - - - -
    • -
    -