Last active
February 13, 2019 20:31
-
-
Save samguergen/4b053f1aa325402845d2039b5e3c86d5 to your computer and use it in GitHub Desktop.
Weekly shift scheduler functionality files isolated from the widget repo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var express = require('express'); | |
var nodemailer = require('nodemailer'); | |
var smtpTransport = require('nodemailer-smtp-transport'); | |
var app = express(); | |
const MongoClient = require('mongodb').MongoClient; | |
var mongo = require('mongodb'); | |
var session = require('express-session'); | |
var cookieParser = require('cookie-parser'); | |
var bodyParser = require('body-parser'); | |
var env = require(__dirname + '/env-vars.js'); | |
var gmail_login = env.gmail_login; | |
var gmail_pass = env.gmail_pass; | |
var db; | |
var http = require('http'); | |
var request=require('request'); | |
var _ =require('lodash'); | |
var multer = require('multer'); | |
var upload = multer({ dest: 'uploads/' }) | |
var multipart = require('connect-multiparty'); | |
var formidable = require('express-formidable'); | |
var fs = require('fs'); | |
app.use(function(req, res, next) { | |
res.header("Access-Control-Allow-Origin", "*"); | |
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); | |
next(); | |
}); | |
app.use(express.json()); //convert req to json | |
app.use(express.static(__dirname + '/app')); | |
app.use(session({secret: "Sam is awesome"})); | |
// app.use(formidable()); | |
app.use(bodyParser.json()); // Configures bodyParser to accept JSON | |
app.use(bodyParser.urlencoded({ | |
extended: false | |
})); | |
var allPages = ['/home','/portfolio', '/timesheets', '/timesheet', '/documents','/shift-scheduler','/comments','/blog-thumbnail']; | |
MongoClient.connect('mongodb://samguergen:[email protected]:19662/widgets', function(err, client) { | |
if (err) { | |
console.log('db not connecting, but inside mongo block - 1', err); | |
}; | |
db = client.db('widgets'); | |
console.log('inside first mongo block'); | |
app.get('/getTimesheets', function (req,res) { | |
db.collection('timesheets').find().toArray(function (err, result) { | |
res.send(result); | |
}) | |
}); | |
app.post('/addTimesheet', function (req,res) { | |
console.log('inside timesheet add') | |
var timesheet = req.body.timesheet; | |
console.log('ts to be saved, received from backend is ', timesheet); | |
db.collection('timesheets').save(timesheet, function(err, result){ | |
if (err) { return console.log('connecting to db, but not saving obj', err);} | |
console.log('ts saved to database'); | |
res.send(result); | |
}) | |
}); | |
app.delete('/deleteTimesheet', function (req,res) { | |
var timesheetId = req.query.timesheetId; | |
console.log('ts to be deleted, received from backend is ', timesheetId) | |
db.collection('timesheets').deleteOne({_id: new mongo.ObjectId(timesheetId)}, function(err, result){ | |
if (err) { throw new Error('No record found. ', err) }; | |
console.log('timesheet has been removed, i think'); | |
res.send(result); | |
}); | |
}); // end of deleteagendaevent request | |
app.get('/getDocuments', formidable(), function (req,res) { | |
db.collection('documents').find().toArray(function (err, result) { | |
res.send(result); | |
}) | |
}); // end of /getRidesData get request | |
app.post('/uploadFiles', formidable(), function(req, res) { | |
console.log('uploadFiles from backend is ', req.files); | |
var binaryLocation = req.files.file.path; | |
var fileName = req.files.file.name; | |
console.log('file name is ', fileName); | |
var binaryData = fs.readFileSync(binaryLocation); | |
var theFile = {}; | |
theFile.data = binaryData | |
theFile.name = fileName; | |
theFile.category = 'all'; | |
theFile.categoryGeneral = 'all'; | |
var tableName = req.query.tableName; | |
console.log('theFile is ', theFile); | |
db.collection('documents').save(theFile, function(err, result){ | |
if (err) { return console.log('connecting to db, but not saving obj', err);} | |
console.log('doc saved to database'); | |
res.send(result); | |
}) | |
}); | |
app.delete('/removeFile', formidable(), function (req,res) { | |
console.log('inside removeFile, queries are ', req.query.fileId); | |
var fileId = req.query.fileId; | |
db.collection('documents').deleteOne({_id: new mongo.ObjectId(fileId)}, function(err, result){ | |
if (err) { throw new Error('No record found. ', err) }; | |
console.log('file has been removed, i think'); | |
res.send(result); | |
}); | |
}); // end of /removeFile delete request | |
app.put('/updateCategory', function (req,res) { | |
var fileName = req.body.fileName; | |
var categoryDbName = req.body.categoryDbName; | |
var fileId = req.body.fileId; | |
console.log('file name is ', fileName, 'categoryDbName ', categoryDbName, 'fileId ', fileId); | |
var myQuery = {_id: new mongo.ObjectId(fileId)}; | |
var newValues = { | |
$set: { | |
category: categoryDbName | |
} | |
}; | |
db.collection('documents').findAndModify(myQuery, [['_id','asc']], newValues, {}, function(err, result){ | |
if (err) { throw new Error('No record found. ', err) }; | |
console.log('record has been updated, i think'); | |
res.send(result); | |
}); | |
}); // end of /updateCategory put request | |
app.get('/viewWeeklyCalendarEvents', function (req,res) { | |
db.collection('weekly-calendar').find().toArray(function (err, result) { | |
res.send(result); | |
}) | |
}); // end of /viewRISCalendarEvents get request | |
app.post('/addWeeklyCalendarEvent', function (req,res) { | |
var newEvent = req.body.newEvent; | |
console.log('event to be saved, received from backend is ', newEvent); | |
db.collection('weekly-calendar').save(newEvent, function(err, result){ | |
if (err) { return console.log('connecting to db, but not saving obj', err);} | |
console.log('event saved to database', result); | |
res.send(result); | |
}) | |
}); | |
app.delete('/deleteWeeklyCalendarEvent', function (req,res) { | |
var eventId = req.query.eventId; | |
console.log('event to be deleted, received from backend is ', eventId) | |
db.collection('weekly-calendar').deleteOne({_id: new mongo.ObjectId(eventId)}, function(err, result){ | |
if (err) { throw new Error('No record found. ', err) }; | |
console.log('event has been removed'); | |
res.send(result); | |
}); | |
}); // end of deleteagendaevent request | |
app.get('/getComments', function (req,res) { | |
db.collection('comments').find().toArray(function (err, result) { | |
res.send(result); | |
}) | |
}); // end of /getComments get request | |
app.post('/addComment', function (req,res) { | |
var comment = req.body.comment; | |
console.log('comment to be saved, received from backend is ', comment); | |
db.collection('comments').save(comment, function(err, result){ | |
if (err) { return console.log('connecting to db, but not saving obj', err);} | |
console.log('comment saved to database'); | |
res.send(result); | |
}) | |
}); | |
app.delete('/deleteComment', function (req,res) { | |
var commentId = req.query.commentId; | |
console.log('comment to be deleted, received from backend is ', commentId) | |
db.collection('comments').deleteOne({_id: new mongo.ObjectId(commentId)}, function(err, result){ | |
if (err) { throw new Error('No record found. ', err) }; | |
console.log('comment has been removed'); | |
res.send(result); | |
}); | |
}); // end of deleteagendaevent request | |
app.post('/sendmail', function(req, res){ | |
console.log('inside sendmail, post req', req.body); | |
let mailOptions = {}; | |
if (req.body){ //private contact form from ITN staff to ITN staff | |
console.log('sending email without pdf'); | |
mailOptions = { | |
from: req.body.from, // sender address | |
to: req.body.to, // list of receivers | |
subject: req.body.subject, // Subject line | |
html: req.body.html // html body | |
}; | |
} | |
let transporter = nodemailer.createTransport(smtpTransport({ | |
service: "Gmail", // sets automatically host, port and connection security settings | |
auth: { | |
user: gmail_login, | |
pass: gmail_pass | |
} | |
}) | |
) | |
// send mail with defined transport object | |
transporter.sendMail(mailOptions, function(error, info) { | |
if (error) { | |
return console.log(error); | |
} | |
console.log('Message sent: %s', info.messageId); | |
transporter.close(); | |
}); | |
console.log('after mongo block'); | |
res.end(); | |
}); | |
app.get('/getBlogContent', function(req, res) { | |
console.log('params are ', req.query) | |
request.get(req.query.blogURL, function(err,result,body) { | |
console.log('result is ', result) | |
res.send(result.body) | |
}); | |
}); | |
}); //end of main mongodb block | |
app.use(allPages, function(req, res){ | |
res.sendFile(__dirname + '/app/index.html'); | |
}); | |
app.listen(process.env.PORT || 13270); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var myApp = angular.module('myApp'); | |
myApp.controller('CalendarCtrl', ['$scope', '$transitions', '$http', '$anchorScroll', '$location', '$stateParams', '$timeout', '$state', '$rootScope', '$window', 'FormService', '$sce', 'DataService', 'ParseVariablesService', '$q', 'CalendarService', function($scope, $transitions, $http, $anchorScroll, $location, $stateParams, $timeout, $state, $rootScope, $window, FormService, $sce, DataService, ParseVariablesService, $q, CalendarService) { | |
console.log('inside calendar controller'); | |
$scope.eventObj = {} | |
$scope.adjustTimeForCalendar = function(theTime) { | |
var time = theTime.replace(" ", ""); | |
time = time.toUpperCase(); | |
var adjustedTime = { | |
hour: 0, | |
min: 0 | |
}; | |
if (time.includes("AM") && time.includes(":")){ | |
adjustedTime.hour = time.substr(0,time.indexOf(':')); | |
adjustedTime.min = time.substr(time.indexOf(':')+1,time.indexOf('AM')-2); | |
} else if (time.includes("AM")){ | |
adjustedTime.hour = time.substr(0,time.indexOf('AM')); | |
adjustedTime.min = 0; | |
} else if (time.includes("PM") && time.includes(":")){ | |
adjustedTime.hour = parseInt(time.substr(0,time.indexOf(':'))); | |
if (adjustedTime.hour < 12){ | |
adjustedTime.hour = adjustedTime.hour + 12; | |
} | |
adjustedTime.min = time.substr(time.indexOf(':')+1,time.indexOf('PM')-2); | |
} else if (time.includes("PM")){ | |
adjustedTime.hour = parseInt(time.substr(0,time.indexOf('PM'))); | |
if (adjustedTime.hour < 12){ | |
adjustedTime.hour = adjustedTime.hour + 12; | |
} | |
adjustedTime.min = 0; | |
} | |
adjustedTime.hour = parseInt(adjustedTime.hour); | |
adjustedTime.min = parseInt(adjustedTime.min); | |
return adjustedTime; | |
}; | |
//agenda here refers to a detailed day view of the monthly calendar after selecting day. | |
$scope.initAgenda = function() { | |
$scope.hideModal('calendarModal'); | |
$scope.hideModal('addOrShowModal'); | |
var promise = $scope.viewCalendarEventsPromise(); | |
promise.then(function(data){ | |
// console.log('calendar events are ', $scope.calendarEvents); | |
$('#calendar').fullCalendar({ | |
defaultView: 'agendaDay', | |
height: 650, | |
editable: true, | |
selectable: true, | |
slotEventOverlap: true, | |
minTime: "08:00:00", | |
eventRender: function(event, element){ | |
console.log("rendering " +event.title, 'elem is ', element); | |
}, | |
eventClick: function(calEvent, jsEvent, view) { | |
console.log('calEvent is ', calEvent); | |
$(this).css('border-color', 'red'); | |
var reconstructEvent = $scope.reconstructEventObjByTitle(calEvent); | |
swal({ | |
title: "Event Details", | |
html: "<h2>" + reconstructEvent.title + "</h2><p>" + reconstructEvent.description + "</p> <em>by " + reconstructEvent.author + "</em>", | |
showCancelButton: true, | |
showConfirmButton: true, | |
confirmButtonColor: "red", | |
confirmButtonText: "Delete event", | |
type: "warning" | |
}).then(function(eventToDelete){ | |
//if user confirms to delete | |
if (eventToDelete.value) { | |
$scope.serverMessage = "Deleting event..." | |
$scope.deleteAgendaEventPromise(reconstructEvent, calEvent, 'calendar') | |
.then(function(response){ | |
$scope.resetEventObj(); | |
swal("Deleted!","Your event was deleted.","success") | |
}).catch(function(error){ | |
swal("Oops!","Your event couldn't be deleted.","error"); | |
}) | |
} | |
}) | |
}, | |
dayClick: function(event) { | |
$scope.$apply(function() { | |
$scope.dayClicked = event._d; | |
}); | |
$('#calendarModal').modal('show'); | |
} | |
})//end of calendar config | |
//day agenda only accepts today's date. Agenda has been hacked so we only care about time. | |
var date = new Date(); | |
var d = date.getDate(); | |
var m = date.getMonth(); | |
var y = date.getFullYear(); | |
var theEvent = {}; | |
$scope.eventsArr = []; | |
//check if agenda defaults to today, then readjust dateformatted | |
if ($scope.loadAgendaDirectly) { | |
$scope.selectedEventDatePreviousFormatted = new Date($scope.selectedEventDatePrevious).toDateString(); | |
} | |
for (calendarEvent in $scope.calendarEvents) { | |
//only parse events for that day | |
var calendarEventDay = new Date($scope.calendarEvents[calendarEvent].day).addDays(1) | |
calendarEventDay = calendarEventDay.toDateString(); | |
if (calendarEventDay === $scope.selectedEventDateFormatted) { | |
//placing events in day agenda according to start and end times. | |
var st = $scope.calendarEvents[calendarEvent].startTime; | |
var adjustedSt = $scope.adjustTimeForCalendar(st); | |
var et = $scope.calendarEvents[calendarEvent].endTime; | |
var adjustedEt = $scope.adjustTimeForCalendar(et); | |
var startTime = new Date(y, m, d, adjustedSt.hour, adjustedSt.min); | |
var endTime = new Date(y, m, d, adjustedEt.hour, adjustedEt.min); | |
//draw on DOM | |
theEvent = {title: $scope.calendarEvents[calendarEvent].title, start: startTime, end: endTime, description: $scope.calendarEvents[calendarEvent].description, author: $scope.calendarEvents[calendarEvent].author}; | |
$("#calendar").fullCalendar("renderEvent", theEvent); | |
$scope.eventsArr.push(theEvent); | |
} | |
} | |
});//end of promise | |
}; | |
$scope.reconstructEventObjByTitle = function(calEvent) { | |
var fullEvent = {}; | |
for (var i in $scope.eventsArr){ | |
if ($scope.eventsArr[i].title === calEvent.title){ | |
fullEvent.title = calEvent.title; | |
fullEvent.startTime = $scope.eventsArr[i].startTime; | |
fullEvent.endTime = $scope.eventsArr[i].endTime; | |
fullEvent.description = $scope.eventsArr[i].description; | |
fullEvent.author = $scope.eventsArr[i].author; | |
return fullEvent; | |
} | |
} | |
}; | |
$scope.initMonthCalendar = function(){ | |
$('#calendar').fullCalendar({ | |
dayClick: function(event) { | |
$scope.$apply(function() { | |
$scope.dayClicked = event._d; | |
}); | |
console.log('a day has been clicked! event is ', $scope.dayClicked); | |
$('#addOrShowModal').modal('show'); | |
} | |
}); | |
}; | |
$scope.convert24ToPm = function(time){ | |
var adjustedTime; | |
if ((time > 0) && (time < 12)){ | |
adjustedTime = time + 'AM'; | |
} else if ((time >= 13) && (time < 24)){ | |
adjustedTime = (time-12) + 'PM'; | |
} else { | |
adjustedTime = time + 'PM' | |
} | |
return adjustedTime; | |
}; | |
$scope.initWeekCalendar = function(calendarType) { | |
$scope.serverMessage = "Loading calendar..."; | |
$scope.hideModal('calendarModal'); | |
$scope.hideModal('addOrShowModal'); | |
var promise = $scope.viewWeeklyCalendarEventsPromise(); | |
promise.then(function(data){ | |
console.log('weekly calendar events are ', $scope.calendarEvents); | |
$scope.serverMessage = ""; | |
$('#calendar-week').fullCalendar({ | |
defaultView: 'agendaWeek', | |
height: 650, | |
editable: true, | |
selectable: true, | |
slotEventOverlap: true, | |
minTime: "08:00:00", | |
maxTime: "20:00:00", | |
nowIndicator: true, | |
header: { | |
left: 'prev,next today', | |
center: 'Week of', | |
right: 'agendaWeek,agendaDay' | |
}, | |
eventRender: function(event, element){ | |
console.log("rendering " + event.title, 'elem is ', element); | |
}, | |
eventClick: function(calEvent, jsEvent, view) { | |
console.log('cal event is ', calEvent, 'js event is ', jsEvent); | |
$scope.theCalEvent = calEvent; | |
$scope.theJsEvent = jsEvent; | |
$(this).css('border-color', 'red'); | |
var complexEventObj = calEvent; | |
swal({ | |
title: "Event Details", | |
html: "<h2>" + $scope.theCalEvent.title + "</h2><p>" + $scope.theCalEvent.description + "</p> <em>by " + $scope.theCalEvent.author + "</em>", | |
showCancelButton: true, | |
showConfirmButton: true, | |
confirmButtonColor: "red", | |
confirmButtonText: "Delete event", | |
type: "warning" | |
}).then(function(readyToDelete){ | |
//On confirm, delete event from db | |
if (readyToDelete.value){ | |
console.log('event is ', complexEventObj); | |
var simpleEventObjToDelete = $scope.convertComplexToSimpleEventObj(complexEventObj); | |
$scope.deleteWeeklyCalendarEventPromise(simpleEventObjToDelete) | |
.then(function(response){ | |
console.log('final response from delete is ', response); | |
swal("Deleted!","Your event was deleted.","success"); | |
$scope.viewWeeklyCalendarEventsPromise() | |
.then(function(response){ | |
$('#calendar-week').fullCalendar('removeEvents'); | |
$('#calendar-week').fullCalendar('addEventSource', $scope.calendarEvents); | |
$('#calendar-week').fullCalendar('rerenderEvents'); | |
$scope.resetEventObj(); | |
}) | |
}) | |
.catch(function(error){ | |
swal("Oops!","Your event couldn't be deleted.","error"); | |
}) | |
} | |
}) | |
}, | |
dayClick: function(event, jsEvent) { | |
$scope.$apply(function() { | |
$scope.dayClicked = event._d; | |
}); | |
$scope.eventObj.startTime = $scope.dayClicked.getHours() + 4; | |
$scope.$apply(function() { | |
$scope.eventObj.startTime = $scope.convert24ToPm($scope.eventObj.startTime); | |
}); | |
$('#calendarModal').modal('show'); | |
}, | |
events: $scope.calendarEvents | |
})//end of calendar config | |
});//end of promise | |
}; | |
$scope.matchRelevantEvent = function(allEvents, calEvent){ | |
var eventTitle = calEvent.title; | |
var eventTitleSquashed = calEvent.title.replace(/[^a-zA-Z0-9]+/g, ""); | |
console.log('cal event is ', calEvent.title, eventTitleSquashed); | |
for (var obj in allEvents){ | |
var eventsObj = allEvents[obj]; | |
var substr = eventsObj.innerText.replace(/[^a-zA-Z0-9]+/g, ""); | |
substr = substr.replace(/[0-9]/g, ''); | |
console.log('substr is ', substr); | |
if (substr === eventTitleSquashed){ | |
console.log('a match!! the match is ', substr); | |
return substr; | |
} | |
} | |
}; | |
$scope.convertComplexToSimpleEventObj = function(eventToDelete) { | |
for (var i in $scope.calendarEvents){ | |
if ( ($scope.calendarEvents[i].author === eventToDelete.author) && ($scope.calendarEvents[i].description === eventToDelete.description) && ($scope.calendarEvents[i].title === eventToDelete.title) && ($scope.calendarEvents[i].day === eventToDelete.day) && ($scope.calendarEvents[i].startTime === eventToDelete.startTime) && ($scope.calendarEvents[i].endTime === eventToDelete.endTime) && ($scope.calendarEvents[i].day === eventToDelete.day) ){ | |
console.log('a match ', $scope.calendarEvents[i]); | |
return $scope.calendarEvents[i]; | |
} | |
} | |
}; | |
$scope.resetEventObj = function(){ | |
$scope.eventObj = {}; | |
$scope.serverMessage = ""; | |
}; | |
$scope.completeEventObj = function(){ | |
var date = $scope.dayClicked; | |
var d = date.getDate(); | |
var m = date.getMonth(); | |
var y = date.getFullYear(); | |
var st = $scope.eventObj.startTime; | |
var adjustedSt = $scope.adjustTimeForCalendar(st); | |
var et = $scope.eventObj.endTime; | |
var adjustedEt = $scope.adjustTimeForCalendar(et); | |
var startTime = new Date(y, m, d, adjustedSt.hour - 4, adjustedSt.min); | |
var endTime = new Date(y, m, d, adjustedEt.hour - 4, adjustedEt.min); | |
$scope.eventObj.start = startTime; | |
$scope.eventObj.end = endTime; | |
}; | |
$scope.addWeeklyCalendarEvent = function(){; | |
$scope.serverMessage = "Adding event..."; | |
//selects previous day by default, so need to adjust | |
$scope.eventObj.day = new Date($scope.dayClicked.getTime()); | |
console.log('event obj is ', $scope.eventObj); | |
//save event to database | |
$scope.completeEventObj(); | |
DataService.addWeeklyCalendarEvent($scope.eventObj) | |
.then(function(data){ | |
$('#calendarModal').modal('hide'); | |
$scope.serverMessage = "Your event has been succesfully added."; | |
//updates events on DOM | |
$scope.viewWeeklyCalendarEventsPromise() | |
.then(function(response){ | |
$('#calendar-week').fullCalendar('removeEvents'); | |
$('#calendar-week').fullCalendar('addEventSource', $scope.calendarEvents); | |
$('#calendar-week').fullCalendar('rerenderEvents'); | |
$scope.resetEventObj(); | |
}) | |
}) | |
}; | |
$scope.addAgendaEvent = function(){ | |
//selects following day by default, so need to adjust | |
$scope.eventObj.day = $scope.selectedEventDatePrevious; | |
//save event to database | |
DataService.addCalendarEvent($scope.eventObj).then(function(data){ | |
$('#calendarModal').modal('hide'); | |
$scope.serverMessage = "Your event has been succesfully added."; | |
//updates events on DOM | |
var date = new Date(); | |
var d = date.getDate(); | |
var m = date.getMonth(); | |
var y = date.getFullYear(); | |
var st = $scope.eventObj.startTime; | |
var adjustedSt = $scope.adjustTimeForCalendar(st); | |
var et = $scope.eventObj.endTime; | |
var adjustedEt = $scope.adjustTimeForCalendar(et); | |
var startTime = new Date(y, m, d, adjustedSt.hour, adjustedSt.min); | |
var endTime = new Date(y, m, d, adjustedEt.hour, adjustedEt.min); | |
var theEvent = {title: $scope.eventObj.title, start: startTime, end: endTime, description: $scope.eventObj.description, author: $scope.eventObj.author}; | |
$("#calendar").fullCalendar("renderEvent", theEvent); | |
$scope.resetEventObj(); | |
}) | |
}; | |
$scope.deleteAgendaEventPromise = function(eventToDelete, calEventToDelete, dbName){ | |
//delete event from database | |
var deferred = $q.defer(); | |
DataService.deleteAgendaEvent(eventToDelete, dbName) | |
.then(function(data){ | |
$('#calendarModal').modal('hide'); | |
$("#calendar").fullCalendar("removeEvents", calEventToDelete._id); | |
$scope.serverMessage = "Your event has been succesfully deleted."; | |
deferred.resolve(data); | |
}).catch(function(error){ | |
deferred.resolve(error) | |
}) | |
return deferred.promise | |
}; | |
$scope.deleteRISCalendarEventPromise = function(eventToDelete, dbName){ | |
//delete event from database | |
var deferred = $q.defer(); | |
DataService.deleteRISCalendarEvent(eventToDelete, dbName) | |
.then(function(data){ | |
$('#calendarModal').modal('hide'); | |
$scope.serverMessage = "Your event has been succesfully deleted."; | |
$("#calendar-week").fullCalendar("removeEvents", calEventToDelete._id); | |
deferred.resolve(data); | |
}).catch(function(error){ | |
deferred.resolve(error) | |
}) | |
return deferred.promise | |
}; | |
$scope.deleteWeeklyCalendarEventPromise = function(eventToDelete){ | |
var deferred = $q.defer(); | |
console.log('before delete affiliate calendar event call'); | |
DataService.deleteWeeklyCalendarEvent(eventToDelete) | |
.then(function(data){ | |
console.log('scheduler data is ', data.data[0].scheduler); | |
if (data.data[0] && data.data[0].scheduler){ | |
console.log('rendering something'); | |
$scope.serverMessage = "Your event has been succesfully deleted."; | |
// $("#calendar-week").fullCalendar("removeEvents", eventToDelete._id); | |
deferred.resolve(data); | |
} else { | |
console.log('rendering nothing'); | |
$scope.serverMessage = "There was a problem deleting your event."; | |
deferred.resolve(error); | |
} | |
$('#calendarModal').modal('hide'); | |
}).catch(function(error){ | |
deferred.resolve(error) | |
}) | |
return deferred.promise | |
}; | |
$scope.viewWeeklyCalendarEventsPromise = function(){ | |
var deferred = $q.defer(); | |
//get events from database | |
DataService.viewWeeklyCalendarEvents() | |
.then(function(data){ | |
$scope.calendarEvents = data.data; | |
$scope.drawEventsOnCalendar(); | |
deferred.resolve('Resolved: ', data.data); | |
}).catch(function(err){ | |
deferred.resolve('Error: ', err); | |
}) | |
return deferred.promise; | |
}; | |
//place events on their respective day tabs | |
//unlike the weekly calendar, which provides build-in help for drawing events, monthly calendar does not so I had to reinvent the wheel using JQuery to manually draw events on DOM. | |
$scope.drawEventsOnCalendar = function(){ | |
$scope.eventsinFC = []; | |
$('.fc-day').each(function(){ | |
var tabDate = $(this).context.dataset.date; | |
var count = 0; | |
var ctx; | |
for (event in $scope.calendarEvents){ | |
var event = $scope.calendarEvents[event]; | |
var eventDateShort = event.day.slice(0,10); | |
if (eventDateShort === tabDate){ | |
ctx = $(this).context; | |
// console.log('a match! event is ', event, 'tab ctx is ', $(this).context); | |
//orders events chronologically for a given day | |
var later = $scope.isLaterTime(event, $(this).context); | |
if (later){ | |
$(this).context.innerHTML = $(this).context.innerHTML + '<h6 class="agenda-link"><span class="badge badge-secondary">' + event.startTime + '-' + event.endTime + '<br>' + event.title + '</span></h6>'; | |
} else { | |
$(this).context.innerHTML = '<h6 class="agenda-link"><span class="badge badge-secondary">' + event.startTime + '-' + event.endTime + '<br>' + event.title + '</span></h6>' + $(this).context.innerHTML; | |
} | |
//if more than 2 events on tab, add the more button to prevent overflow | |
count = ctx.childElementCount; | |
if (count > 3) { | |
$(this).children().eq(1).nextAll().css("display","none"); | |
var moreBtn = '<button class="btn btn-sm" style="height:20px;width:70%;margin-top:-230px;font-size:14px;color: black">Show more</button>'; | |
$(this).context.innerHTML = $(this).context.innerHTML + moreBtn; | |
} | |
} | |
} | |
}) | |
}; | |
$scope.isLaterTime = function(theEvent, theContext){ | |
var numEventsInCell = theContext.children.length; | |
var lastChild = theContext.children[theContext.children.length -1]; | |
if (lastChild){ | |
var slicedTime = lastChild.innerText.slice(0, lastChild.innerText.indexOf('-')); | |
var eventAdjustedTime = $scope.adjustTimeForCalendar(theEvent.startTime); | |
var adjustedTime = $scope.adjustTimeForCalendar(slicedTime); | |
if (eventAdjustedTime.hour >= adjustedTime.hour){ | |
return true | |
} else { | |
return false; | |
} | |
} | |
}; | |
$scope.emptyCalendar = function(){ | |
$('.fc-day').each(function(){ | |
$(this).context.innerHTML = "" | |
}) | |
}; | |
$scope.retrieveFromSelectedEvent = function(){ | |
$scope.selectedEventDatePrevious = $stateParams.selectedEventDate; | |
var isValid = moment($scope.selectedEventDatePrevious, moment.ISO_8601, true).isValid(); | |
//if user loads agenda page without parameter, default to today | |
if (isValid){ | |
$scope.selectedEventDatePrevious = new Date($scope.selectedEventDatePrevious); | |
$scope.loadAgendaDirectly = true; | |
} | |
$scope.selectedEventDate = $scope.selectedEventDatePrevious.addDays(1); | |
$scope.selectedEventDateFormatted = new Date($scope.selectedEventDate).toDateString(); | |
}; | |
$scope.isAfterStartTime = function(endTime, startTime){ | |
var adjustedEndTime = $scope.adjustTimeForCalendar(endTime); | |
var adjustedStartTime = $scope.adjustTimeForCalendar(startTime); | |
if (adjustedEndTime.hour > adjustedStartTime.hour){ | |
$scope.afterStartTime = false; | |
return true; | |
} else if (adjustedEndTime.hour < adjustedStartTime.hour){ | |
$scope.afterStartTime = true; | |
return false; | |
} else if ( (adjustedEndTime.hour === adjustedStartTime.hour) && (adjustedEndTime.min < adjustedStartTime.min) ){ | |
$scope.afterStartTime = true; | |
return false; | |
} else if ( (adjustedEndTime.hour === adjustedStartTime.hour) && (adjustedEndTime.min > adjustedStartTime.min) ){ | |
$scope.afterStartTime = false; | |
return true; | |
} else { | |
$scope.afterStartTime = true; | |
return false; | |
} | |
}; | |
function compareNumbers(a, b) { | |
return a - b; | |
} //use as: numArray.sort(compareNumbers) | |
Date.prototype.addDays = function(days) { | |
var date = new Date(this.valueOf()); | |
date.setDate(date.getDate() + days); | |
return date; | |
}; | |
}]); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var myApp = angular.module('myApp'); | |
myApp.service('DataService', ['$http','$q', function($http, $q){ | |
this.getTimesheets = function(affiliateName){ | |
console.log('in service, getting ts'); | |
return $http.get('/getTimesheets') | |
.then(function(data){ | |
console.log('log from post is ', data); | |
if (data.status === 200){ | |
return data | |
} else { | |
return error | |
} | |
}).catch(function(error) { | |
return error | |
}) | |
}; | |
this.addTimesheet = function(timesheet){ | |
console.log('ts to be saved is ', timesheet); | |
return $http.post('/addTimesheet', {timesheet: timesheet}) | |
.then(function(data){ | |
console.log('log from post is ', data); | |
if (data.status === 200){ | |
return data | |
} else { | |
return error | |
} | |
}).catch(function(error) { | |
return error | |
}) | |
}; | |
this.deleteTimesheet = function(timesheet){ | |
console.log('timesheet to delete in service is ', timesheet._id); | |
// return $http.delete('/deleteTimesheet', {timesheetId: timesheet._id}) | |
return $http.delete('/deleteTimesheet', { | |
params: { | |
timesheetId: timesheet._id | |
} | |
}) | |
.then(function(data){ | |
console.log('log from post is ', data); | |
if (data.status === 200){ | |
return data | |
} else { | |
return error | |
} | |
}).catch(function(error) { | |
return error | |
}) | |
}; | |
this.editTimesheet = function(timesheet){ | |
return $http.put('/editTimesheet') | |
.then(function(data){ | |
console.log('log from post is ', data); | |
if (data.status === 200){ | |
return data | |
} else { | |
return error | |
} | |
}).catch(function(error) { | |
return error | |
}) | |
}; | |
this.getDocuments = function(){ | |
return $http.get('/getDocuments') | |
.then(function(data){ | |
return data; | |
}) | |
}; | |
this.getComments = function(){ | |
return $http.get('/getComments') | |
.then(function(data){ | |
console.log('log from post is ', data); | |
if (data.status === 200){ | |
return data | |
} else { | |
return error | |
} | |
}).catch(function(error) { | |
return error | |
}) | |
}; | |
this.addComment = function(comment){ | |
return $http.post('/addComment', {comment: comment}) | |
.then(function(data){ | |
console.log('data returned from add comment service is ', data); | |
return data; | |
}) | |
}; | |
this.deleteComment = function(comment){ | |
console.log('comment id is is ', comment, 'id is ', comment._id) | |
return $http.delete('/deleteComment', { | |
params: { | |
commentId: comment._id | |
} | |
}) | |
.then(function(data){ | |
console.log('data returned is ', data); | |
return data; | |
}).catch(function(error){ | |
console.log('error is ', error); | |
return error; | |
}) | |
}; | |
// this.editCommentDraft = function(content, affiliate){ | |
// console.log('inside delete comment service, content is ', content, 'affiliate is ', affiliate); | |
// var payload = {content: content, affiliate: affiliate, operation: 'delete'}; | |
// return $http.delete('/deleteComment', {params: payload}) | |
// .then(function(data){ | |
// console.log('return from update comments', data); | |
// return data; | |
// }) | |
// }; | |
this.viewWeeklyCalendarEvents = function(){ | |
return $http.get('/viewWeeklyCalendarEvents') | |
.then(function(data){ | |
return data; | |
}).catch(function(error){ | |
return error | |
}) | |
}; | |
this.addWeeklyCalendarEvent = function(newEvent){ | |
console.log('event in add calendar event is ', newEvent); | |
return $http.post('/addWeeklyCalendarEvent', {newEvent: newEvent}) | |
.then(function(data){ | |
console.log('data returned from add calendar event service is ', data); | |
return data; | |
}).catch(function(error){ | |
return error | |
}) | |
}; | |
this.deleteWeeklyCalendarEvent = function(agendaEvent){ | |
console.log('agenda event is ', agendaEvent, 'id is ', agendaEvent._id) | |
return $http.delete('/deleteWeeklyCalendarEvent', { | |
params: { | |
eventId: agendaEvent._id | |
} | |
}) | |
.then(function(data){ | |
console.log('data returned is ', data); | |
return data; | |
}).catch(function(error){ | |
console.log('error is ', error); | |
return error; | |
}) | |
}; | |
}]); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- <div class="portal calendar calendar-ris calendar-affiliate" ng-init="initWeekCalendar('affiliate', itnAffiliate.name)"> --> | |
<div class="portal calendar calendar-ris calendar-affiliate" ng-init="initWeekCalendar()"> | |
<div class="container-fluid" style="width:75%"> | |
<h2>Weekly Shift Scheduler</h2> | |
<div style="color:green">{{serverMessage}}</div> | |
<div id='calendar-week'></div> | |
</div> | |
</div> | |
<div class="back-btn-wrap"> | |
<a ui-sref="affiliate-landing" class="back-btn"> | |
<h3>Back to Previous Page</h3> | |
</a> | |
<a ui-sref="portal" class="back-btn"> | |
<h3>Back to Portal</h3> | |
</a> | |
</div> | |
<!-- Modal --> | |
<div class="modal fade" id="calendarModal" tabindex="-1" role="dialog" aria-labelledby="calendarModalLabel" aria-hidden="true"> | |
<div class="modal-dialog" role="document"> | |
<div class="modal-content" style="font-size:25px"> | |
<div class="modal-header" style="background:#529ba8;color:white"> | |
<h3 class="modal-title" id="calendarModalLabel">Add a new event</h3> | |
<button type="button" style="margin-top: -30px" class="close" data-dismiss="modal" aria-label="Close"> | |
<span aria-hidden="true">×</span> | |
</button> | |
</div> | |
<div class="modal-body"> | |
<div class="form-area" style="background: #c7dfe4;border:none;padding:1%;border-radius:5px"> | |
<form name="itnForm" id="addEventForm" novalidate ng-submit="addWeeklyCalendarEvent()" role="comment form" ng-model="eventObj" style="padding:2%;margin:0 5%"> | |
<div class="row"> | |
<div class="form-group" ng-class="{ 'has-error' : itnForm.startTime.$invalid && !itnForm.startTime.$pristine }"> | |
<input type="text" class="form-control" id="startTime" autofocus="autofocus" name="startTime" placeholder="Start time. Example: 10:00AM" ng-minlength="minlength" ng-maxlength="maxlength" ng-model="eventObj.startTime" required> | |
<span ng-if="itnForm.startTime.$error.required && !itnForm.startTime.$pristine" class="help-block">{{errorMessages.required}}</span> | |
<span ng-if="itnForm.startTime.$error.minlength" class="help-block">{{errorMessages.minlength}}</span> | |
<span ng-if="itnForm.startTime.$error.maxlength" class="help-block">{{errorMessages.maxlength}}</span> | |
</div> | |
<div class="form-group" ng-class="{ 'has-error' : itnForm.endTime.$invalid && !itnForm.endTime.$pristine }"> | |
<input type="text" class="form-control" id="endTime" autofocus="autofocus" name="endTime" placeholder="End time. Example: 2:15PM" ng-minlength="minlength" ng-maxlength="maxlength" ng-model="eventObj.endTime" ng-blur="isAfterStartTime(eventObj.endTime, eventObj.startTime)" required> | |
<span ng-if="itnForm.endTime.$error.required && !itnForm.endTime.$pristine" class="help-block">{{errorMessages.required}}</span> | |
<span ng-if="itnForm.endTime.$error.minlength" class="help-block">{{errorMessages.minlength}}</span> | |
<span ng-if="itnForm.endTime.$error.maxlength" class="help-block">{{errorMessages.maxlength}}</span> | |
<span ng-if="afterStartTime" class="help-block" style="color:red">{{errorMessages.endTime}}</span> | |
</div> | |
</div> | |
<div class="form-group" ng-class="{ 'has-error' : itnForm.title.$invalid && !itnForm.title.$pristine }"> | |
<input type="text" class="form-control" id="title" title="title" placeholder="Event title (keep it short)" ng-minlength="minlength" ng-maxlength="maxlength" ng-model="eventObj.title" required> | |
<span ng-if="itnForm.title.$error.required && !itnForm.title.$pristine" class="help-block">{{errorMessages.required}}</span> | |
<span ng-if="itnForm.title.$error.minlength" class="help-block">{{errorMessages.minlength}}</span> | |
<span ng-if="itnForm.title.$error.maxlength" class="help-block">{{errorMessages.maxlength}}</span> | |
</div> | |
<div class="form-group" ng-class="{ 'has-error' : itnForm.message.$invalid && !itnForm.message.$pristine }"> | |
<textarea class="form-control" type="textarea" name="message" id="message" placeholder="Event description" maxlength="2000" rows="7" ng-minlength="minlength" ng-maxlength="maxMsgLength" ng-model="eventObj.description" required></textarea> | |
<span ng-if="itnForm.message.$error.required && !itnForm.message.$pristine" class="help-block">{{errorMessages.required}}</span> | |
<span ng-if="itnForm.message.$error.minlength" class="help-block">{{errorMessages.minlength}}</span> | |
<span ng-if="itnForm.message.$error.maxlength" class="help-block">{{errorMessages.maxlength}}</span> | |
<span class="help-block"><p id="characterLeft" class="help-block ">You have reached the limit</p></span> | |
</div> | |
<div class="form-group" ng-class="{ 'has-error' : itnForm.author.$invalid && !itnForm.author.$pristine }"> | |
<input type="text" class="form-control" id="author" author="author" placeholder="Your name" ng-minlength="minlength" ng-maxlength="maxlength" ng-model="eventObj.author" required> | |
<span ng-if="itnForm.author.$error.required && !itnForm.author.$pristine" class="help-block">{{errorMessages.required}}</span> | |
<span ng-if="itnForm.author.$error.minlength" class="help-block">{{errorMessages.minlength}}</span> | |
<span ng-if="itnForm.author.$error.maxlength" class="help-block">{{errorMessages.maxlength}}</span> | |
</div> | |
<p ng-if="loading"><em>Loading. Please wait</em></p> | |
<p style="color:red; margin-top:50px"><strong>{{serverMessage}}</strong></p> | |
<div class="modal-footer"> | |
<input type="submit" id="submit" class="btn btn-lg pull-right itn-green-bg pull-right" value="Add event" ng-disabled="afterStartTime || !eventObj.startTime || !eventObj.endTime || !eventObj.title || !eventObj.description || !eventObj.author" style="margin-left:2%;background:red"> | |
<input type="button" ng-click="eventObj = {}" value="Reset Form" class="btn btn-lg pull-left itn-green-bg " style="margin-left:2%"> | |
<button type="button" class="btn btn-lg btn-secondary pull-left" data-dismiss="modal" aria-label="Cancel">Cancel</button> | |
</div> | |
</form> | |
</div> <!-- form-area--> | |
</div> | |
</div> | |
</div> | |
</div><!--end modal--> | |
<!-- Add or view Modal --> | |
<div class="modal fade" id="addOrShowModal" tabindex="-1" role="dialog" aria-labelledby="addShowModalLabel" aria-hidden="true"> | |
<div class="modal-dialog" role="document"> | |
<div class="modal-content" style="font-size:25px"> | |
<div class="modal-header" style="background:#529ba8;color:white"> | |
<h3 class="modal-title" id="addShowModalLabel">Add or View Events?</h3> | |
<button type="button" style="margin-top: -30px" class="close" data-dismiss="modal" aria-label="Close"> | |
<span aria-hidden="true">×</span> | |
</button> | |
</div> | |
<div class="modal-body mb-25"> | |
<h3 class="ta-center mb-50">Would you like to <strong>add an event</strong>, or <strong>view events</strong> for this day?</h3> | |
<div class="row ta-center"> | |
<div class="col-md-6"> | |
<a ui-sref="agenda({selectedEventDate: dayClicked})"><button class="btn btn-lg">View Events</button></a> | |
</div> | |
<div class="col-md-6"> | |
<button class="btn btn-lg" ng-click="toggleModal('calendarModal','addOrShowModal')">Add Event</button> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div><!--end modal--> | |
<script> | |
$(document).ready(function(){ | |
$('#characterLeft').text('2000 characters left'); | |
$('#message').keydown(function () { | |
var max = 2000; | |
var len = $(this).val().length; | |
if (len >= max) { | |
$('#characterLeft').text('You have reached the limit'); | |
$('#characterLeft').addClass('text-danger'); | |
$('#submit').addClass('disabled'); | |
} | |
else { | |
var ch = max - len; | |
$('#characterLeft').text(ch + ' characters left'); | |
$('#submit').removeClass('disabled'); | |
$('#characterLeft').removeClass('red'); | |
} | |
}); | |
$('.agenda-link').click(function(event){ | |
console.log('inside agenda click event'); | |
event.stopPropagation() | |
alert('You just clicked an event! Redirecting to its relevant day agenda'); | |
}) | |
}); | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment