From a1a9008aa34e10913097e39cf4ce8b6d5f58c118 Mon Sep 17 00:00:00 2001 From: Quinn Davis Date: Sat, 23 Jul 2016 19:31:08 -0400 Subject: [PATCH 1/3] Change ServiceHour approval logic --- app/controllers/ServiceHourController.js | 6 +++--- app/routers/service.js | 3 +-- models/ServiceHour.js | 3 ++- public/app/approveService/approveService.html | 7 ++++++- public/app/services/service.service.js | 10 ++++++---- 5 files changed, 18 insertions(+), 11 deletions(-) diff --git a/app/controllers/ServiceHourController.js b/app/controllers/ServiceHourController.js index 959c02b..f59a924 100644 --- a/app/controllers/ServiceHourController.js +++ b/app/controllers/ServiceHourController.js @@ -14,12 +14,12 @@ }, submit: function(brotherId, hours) { hours.BrotherId = brotherId; - hours.state = 'u'; + hours.lookedAt = false; return ServiceHour.create(hours); }, approve: function(hourId) { return ServiceHour.update( - { state: 'a' }, + { lookedAt: true, approved: true }, { where: { id: hourId } } @@ -27,7 +27,7 @@ }, reject: function(hourId) { return ServiceHour.update( - { state: 'r' }, + { lookedAt: true, approved: false }, { where: { id: hourId } } diff --git a/app/routers/service.js b/app/routers/service.js index d160b92..d2465cf 100644 --- a/app/routers/service.js +++ b/app/routers/service.js @@ -46,8 +46,7 @@ //missing data var isHours = hour.startTime && hour.endTime; var isDonation = hour.amount; - var isBothOrNeither = isHours === isDonation; - if(!hour.description || isBothOrNeither) { + if(!hour.description || isHours === isDonation) { res.sendStatus(400); } if(isDonation) { diff --git a/models/ServiceHour.js b/models/ServiceHour.js index cb78d3d..94e95e7 100644 --- a/models/ServiceHour.js +++ b/models/ServiceHour.js @@ -7,7 +7,8 @@ module.exports = function(sequelize) { startTime: Sequelize.DATE, endTime: Sequelize.DATE, amount: Sequelize.INTEGER, - state: Sequelize.CHAR(1) + lookedAt: Sequelize.BOOLEAN, + approved: Sequelize.BOOLEAN }, { classMethods: { associate: function(models) { diff --git a/public/app/approveService/approveService.html b/public/app/approveService/approveService.html index d017416..58ab0a6 100644 --- a/public/app/approveService/approveService.html +++ b/public/app/approveService/approveService.html @@ -2,8 +2,13 @@
{{currentHour.Brother.firstName}} {{currentHour.Brother.lastName}}
- {{currentHour.startTime}} - {{currentHour.endTime}}
+
+ {{currentHour.startTime}} - {{currentHour.endTime}}
{{currentHour.duration}}
+
+
+ {{currentHour.amount}} +
diff --git a/public/app/services/service.service.js b/public/app/services/service.service.js index 5602f11..0ec9825 100644 --- a/public/app/services/service.service.js +++ b/public/app/services/service.service.js @@ -31,10 +31,12 @@ .then(function(hours) { var approvable = []; for(var i = 0; i < hours.length; i++) { - if(hours[i].state === 'u') { - hours[i].startTime = new Date(hours[i].startTime); - hours[i].endTime = new Date(hours[i].endTime); - hours[i].duration = hours[i].startTime - hours[i].endTime; + if(!hours[i].lookedAt) { + if(hours[i].startTime) { + hours[i].startTime = new Date(hours[i].startTime); + hours[i].endTime = new Date(hours[i].endTime); + hours[i].duration = hours[i].startTime - hours[i].endTime; + } approvable.push(hours[i]); } } From d5eddaa2714dc0a5f5583f4e2f616f9825b767a5 Mon Sep 17 00:00:00 2001 From: Quinn Davis Date: Sat, 23 Jul 2016 19:43:17 -0400 Subject: [PATCH 2/3] Add success message for service hours --- app/routers/service.js | 3 ++- public/app/services/service.service.js | 2 +- public/app/submitService/submitService.ctrl.js | 11 ++++++++++- public/app/submitService/submitService.html | 2 ++ 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/app/routers/service.js b/app/routers/service.js index d2465cf..0e15411 100644 --- a/app/routers/service.js +++ b/app/routers/service.js @@ -45,9 +45,10 @@ var hour = req.body; //missing data var isHours = hour.startTime && hour.endTime; - var isDonation = hour.amount; + var isDonation = hour.amount !== null; if(!hour.description || isHours === isDonation) { res.sendStatus(400); + return; } if(isDonation) { //remove extra data diff --git a/public/app/services/service.service.js b/public/app/services/service.service.js index 0ec9825..8c2b780 100644 --- a/public/app/services/service.service.js +++ b/public/app/services/service.service.js @@ -24,7 +24,7 @@ return { submit: function(hour) { - postHttp('/service/submit', hour); + return postHttp('/service/submit', hour); }, approvableHours: function() { return getHttp('/service') diff --git a/public/app/submitService/submitService.ctrl.js b/public/app/submitService/submitService.ctrl.js index 793ba12..f02ce9d 100644 --- a/public/app/submitService/submitService.ctrl.js +++ b/public/app/submitService/submitService.ctrl.js @@ -15,8 +15,17 @@ } else { cleanHour.amount = hour.amount; } - serviceService.submit(cleanHour); + serviceService.submit(cleanHour) + .then(function() { + $scope.hour = {}; + $scope.success = true; + }); }; + + //remove success when new service hour is input + $scope.$watch('hour', function() { + $scope.success = false; + }, true); } angular.module('KDRPoints') diff --git a/public/app/submitService/submitService.html b/public/app/submitService/submitService.html index 0d48bee..48a2fec 100644 --- a/public/app/submitService/submitService.html +++ b/public/app/submitService/submitService.html @@ -18,4 +18,6 @@
+ +
Hour successfully submitted.
From 303ef0529e3480256565c3d30db9b5f8e84c2572 Mon Sep 17 00:00:00 2001 From: Quinn Davis Date: Mon, 25 Jul 2016 07:07:39 -0400 Subject: [PATCH 3/3] Implement calendar and better time input for services --- bower.json | 3 +- public/app/app.module.js | 1 + public/app/directives/dateInput.drctv.js | 61 ++++++++++++ .../app/directives/templates/dateInput.html | 14 +++ public/app/services/service.service.js | 58 ++++++++++++ .../app/submitService/submitService.ctrl.js | 92 +++++++++++++++---- public/app/submitService/submitService.html | 57 +++++++++--- public/index.html | 3 + 8 files changed, 259 insertions(+), 30 deletions(-) create mode 100644 public/app/directives/dateInput.drctv.js create mode 100644 public/app/directives/templates/dateInput.html diff --git a/bower.json b/bower.json index f54edd9..3937a7c 100644 --- a/bower.json +++ b/bower.json @@ -16,6 +16,7 @@ ], "dependencies": { "angular": "~1.3.15", - "angular-ui-router": "~0.2.13" + "angular-ui-router": "~0.2.13", + "angularjs-datepicker": "^2.1.6" } } diff --git a/public/app/app.module.js b/public/app/app.module.js index 05f7e18..355a43d 100644 --- a/public/app/app.module.js +++ b/public/app/app.module.js @@ -102,6 +102,7 @@ angular.module('KDRPoints', [ 'ui.router', + '720kb.datepicker' ]) .config(['$stateProvider', '$urlRouterProvider', KDRPoints]); })(); diff --git a/public/app/directives/dateInput.drctv.js b/public/app/directives/dateInput.drctv.js new file mode 100644 index 0000000..9f7d435 --- /dev/null +++ b/public/app/directives/dateInput.drctv.js @@ -0,0 +1,61 @@ +(function() { + var months = [ + { id: 1, name: 'January' }, { id: 2, name: 'February' }, + { id: 3, name: 'March' }, { id: 4, name: 'April' }, + { id: 5, name: 'May' }, { id: 6, name: 'June' }, + { id: 7, name: 'July' }, { id: 8, name: 'August' }, + { id: 9, name: 'September' }, { id: 10, name: 'October' }, + { id: 11, name: 'November' }, { id: 12, name: 'December' } + ]; + + var monthToDays = function(month, year) { + if(month === 2) { + return (year % 4) ? 28 : 29; + } else if(month < 8) { + return 30 + month % 2; + } else { + return 30 + (month+1) % 2; + } + }; + + var verifyDate = function(date) { + date.min = parseInt(date.min); + var validHour = date.hour <= 12 && date.hour >= 1; + var validMin = date.min <=59 && date.min >= 0; + var validDay = date.day < monthToDays(date.month, date.year); + var currentDate = new Date(); + return (currentDate >= revParseDate(date)) && validHour && validMin && validDay; + }; + + var revParseDate = function(date) { + return new Date(date.year, date.month-1, date.day, date.hour, date.min); + }; + + var dateInputDirective = function() { + return { + restrict: 'E', + replace: false, + scope: { + date: '=', + notify: '=', + changeFn: '&' + }, + templateUrl: 'app/directives/templates/dateInput.html', + link: function(scope) { + scope.months = months; + scope.changeFunction = function() { + scope.notify = {}; + if(!verifyDate(scope.date)) { + scope.notify.error = 'Invalid Date.'; + return; + } + if(scope.changeFn) scope.notify.error = scope.changeFn(); + }; + + } + } + }; + + angular.module('KDRPoints') + .directive('dateInput', dateInputDirective); +})(); diff --git a/public/app/directives/templates/dateInput.html b/public/app/directives/templates/dateInput.html new file mode 100644 index 0000000..3d3767d --- /dev/null +++ b/public/app/directives/templates/dateInput.html @@ -0,0 +1,14 @@ +
+ + +
+ + : + + +
+ diff --git a/public/app/services/service.service.js b/public/app/services/service.service.js index 8c2b780..7596ce5 100644 --- a/public/app/services/service.service.js +++ b/public/app/services/service.service.js @@ -22,7 +22,65 @@ }); }; + var toDateObj = function(date) { + var newDate = date.date + ' ' + date.hour + ':' + date.min + ' ' + date.cycle; + newDate = new Date(Date.parse(newDate)); + return newDate.toString() !== 'Invalid Date' ? newDate : false; + }; + + var submitInProgress = false; + return { + cleanHour: function(hour, type) { + var cleanHour = {}; + cleanHour.description = hour.description; + if(!cleanHour.description) { + return 'Description is required.'; + }; + if(type === 'Hour') { + cleanHour.startTime = toDateObj(hour.start); + cleanHour.endTime = toDateObj(hour.end); + if(!cleanHour.startTime || !cleanHour.endTime) { + return 'Invalid Date'; + } + } else { + cleanHour.amount = hour.amount; + if(cleanHour.amount < 0) { + return 'Amount must be greater than zero.'; + } + } + return cleanHour; + }, + calculateHourEquivalent: function(amount) { + var amountToMinutes = amount / (5/60); + if(amountToMinutes < 0) { + return 'Amount must be greater than zero.'; + } + duration = { + hours: Math.floor(amountToMinutes / 60), + minutes: amountToMinutes % 60 + }; + if(duration.minutes < 10) { + duration.minutes = '0' + duration.minutes; + } + return duration; + }, + calculateDuration: function(startDate, endDate) { + startDate = toDateObj(startDate); + endDate = toDateObj(endDate); + var diffMinutes = (endDate - startDate) / 60000; + if(diffMinutes < 0) { + return 'Start date must be before end date.'; + } + var duration = { + hours: Math.floor(diffMinutes / 60), + minutes: diffMinutes % 60 + }; + if(duration.minutes < 10) { + duration.minutes = '0' + duration.minutes; + } + return duration; + }, submit: function(hour) { return postHttp('/service/submit', hour); }, diff --git a/public/app/submitService/submitService.ctrl.js b/public/app/submitService/submitService.ctrl.js index f02ce9d..fcd0237 100644 --- a/public/app/submitService/submitService.ctrl.js +++ b/public/app/submitService/submitService.ctrl.js @@ -1,31 +1,91 @@ (function() { + var months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', + 'August', 'September', 'October', 'November', 'December']; + var hours = ['1','2','3','4','5','6','7','8','9','10','11','12']; + var minutes = ['00','15','30','45']; + + var parseDate = function(date) { + var month = months[date.getMonth()]; + var day = date.getDate(); + var year = date.getFullYear(); + var min = date.getMinutes(); + min = minutes[Math.floor(min / 15)]; + var hour = date.getHours(); + return { + date: month + ' ' + day + ', ' + year, + hour: (hour % 12).toString(), + min: min, + cycle: hour / 12 < 1 ? 'AM' : 'PM' + } + }; + var submitServiceCtrl = function($scope, serviceService) { $scope.type = 'Hour'; - $scope.hour = {}; + $scope.notify = {}; + + $scope.hours = hours; + $scope.minutes = minutes; + + var submitInProgress = false; $scope.submit = function() { - var cleanHour = {}; - var hour = $scope.hour; - cleanHour.description = hour.description; - if($scope.type === 'Hour') { - cleanHour.startTime = hour.startTime; - cleanHour.endTime = hour.endTime; - } else { - cleanHour.amount = hour.amount; + if(submitInProgress) { + return; + } + submitInProgress = true; + var cleanHour = serviceService.cleanHour($scope.hour, $scope.type); + if(typeof cleanHour === 'string') { + submitInProgress = false; + $scope.notify.error = cleanHour; + return; } serviceService.submit(cleanHour) - .then(function() { - $scope.hour = {}; - $scope.success = true; + .then(function(success) { + submitInProgress = false; + if(success) { + resetData(); + } else { + $scope.notify.error = 'Submission failed.'; + $scope.notify.success = null; + } }); + + }; + + $scope.calculateDuration = function() { + var duration = serviceService.calculateDuration($scope.hour.start, + $scope.hour.end); + if(typeof duration === 'string') { + $scope.notify.error = duration; + return; + } + $scope.hour.duration = duration; }; - //remove success when new service hour is input - $scope.$watch('hour', function() { - $scope.success = false; - }, true); + $scope.calculateEquivalent = function() { + var duration = serviceService.calculateHourEquivalent($scope.hour.amount); + if(typeof duration === 'string') { + $scope.notify.error = duration; + return; + } + $scope.hour.equivalent = duration; + }; + + var resetData = function() { + $scope.hour = {}; + var endDate = new Date(); + var startDate = new Date(endDate.getTime() - 15 * 60000); + + $scope.hour.start = parseDate(startDate); + $scope.hour.end = parseDate(endDate); + $scope.hour.amount = 0; + + $scope.calculateDuration(); + $scope.calculateEquivalent(); + }; + resetData(); } angular.module('KDRPoints') diff --git a/public/app/submitService/submitService.html b/public/app/submitService/submitService.html index 48a2fec..1687f25 100644 --- a/public/app/submitService/submitService.html +++ b/public/app/submitService/submitService.html @@ -1,23 +1,54 @@
-
- Description: - - -
- Start Time:
- End Time:
-
+
+ Description: + -
- Amount: -
+
+ Start: + + +
+ + : + +
+ + End: + + +
+ + : + +
- +
+ Duration: {{hour.duration.hours}}:{{hour.duration.minutes}} +
+
+ +
+ Amount: $
+ Hour Equivalent: {{hour.equivalent.hours}}:{{hour.equivalent.minutes}} +
+ + + +
{{type}} successfully submitted.
+
{{notify.error}}
+ +
-
Hour successfully submitted.
diff --git a/public/index.html b/public/index.html index 43b0da6..6e75e5e 100644 --- a/public/index.html +++ b/public/index.html @@ -6,15 +6,18 @@ + + +