diff --git a/README.md b/README.md index dec285d123..f3d8dfa634 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,13 @@ Before you begin we recommend you read about the basic building blocks that asse * AngularJS - Angular's [Official Website](http://angularjs.org/) is a great starting point. You can also use [Thinkster Popular Guide](http://www.thinkster.io/), and the [Egghead Videos](https://egghead.io/). * Node.js - Start by going through [Node.js Official Website](http://nodejs.org/) and this [StackOverflow Thread](http://stackoverflow.com/questions/2353818/how-do-i-get-started-with-node-js), which should get you going with the Node.js platform in no time. +## Use MongoLabs - insert in server.js +var db = mongoose.connect('mongodb://cce:cce@ds039860.mongolab.com:39860/meandb', function(err) { + if (err) { + console.error('\x1b[31m', 'Could not connect to MongoLabDB!'); + console.log(err); + } +}); ## Prerequisites Make sure you have installed all these prerequisites on your development machine. diff --git a/app/controllers/qas.server.controller.js b/app/controllers/qas.server.controller.js new file mode 100644 index 0000000000..4ff4a6a9e7 --- /dev/null +++ b/app/controllers/qas.server.controller.js @@ -0,0 +1,129 @@ +'use strict'; + +/** + * Module dependencies... + */ +var mongoose = require('mongoose'), + Qa = mongoose.model('Qa'), + _ = require('lodash'); + +/** + * Get the error message from error object + */ +var getErrorMessage = function(err) { + var message = ''; + + if (err.code) { + switch (err.code) { + case 11000: + case 11001: + message = 'Qa already exists'; + break; + default: + message = 'Something went wrong'; + } + } else { + for (var errName in err.errors) { + if (err.errors[errName].message) message = err.errors[errName].message; + } + } + + return message; +}; + +/** + * Create a Qa + */ +exports.create = function(req, res) { + var qa = new Qa(req.body); + qa.user = req.user; + + qa.save(function(err) { + if (err) { + return res.send(400, { + message: getErrorMessage(err) + }); + } else { + res.jsonp(qa); + } + }); +}; + +/** + * * + * Show the current Qa + */ +exports.read = function(req, res) { + res.jsonp(req.qa); +}; + +/** + * Update a Qa + */ +exports.update = function(req, res) { + var qa = req.qa ; + + qa = _.extend(qa , req.body); + + qa.save(function(err) { + if (err) { + return res.send(400, { + message: getErrorMessage(err) + }); + } else { + res.jsonp(qa); + } + }); +}; + +/** + * Delete an Qa + */ +exports.delete = function(req, res) { + var qa = req.qa ; + + qa.remove(function(err) { + if (err) { + return res.send(400, { + message: getErrorMessage(err) + }); + } else { + res.jsonp(qa); + } + }); +}; + +/** + * List of Qas + */ +exports.list = function(req, res) { Qa.find().sort('-created').populate('user', 'displayName').exec(function(err, qas) { + if (err) { + return res.send(400, { + message: getErrorMessage(err) + }); + } else { + res.jsonp(qas); + } + }); +}; + +/** + * Qa middleware + */ +exports.qaByID = function(req, res, next, id) { Qa.findById(id).populate('user', 'displayName').exec(function(err, qa) { + if (err) return next(err); + if (! qa) return next(new Error('Failed to load Qa ' + id)); + req.qa = qa ; + next(); + }); +}; + +/** + * Qa authorization middleware + */ +exports.hasAuthorization = function(req, res, next) { + if (req.qa.user.id !== req.user.id) { + return res.send(403, 'User is not authorized'); + } + next(); +}; \ No newline at end of file diff --git a/app/controllers/quizzes.server.controller.js b/app/controllers/quizzes.server.controller.js new file mode 100644 index 0000000000..1925645ada --- /dev/null +++ b/app/controllers/quizzes.server.controller.js @@ -0,0 +1,129 @@ +'use strict'; + +/** + * Module dependencies... + */ +var mongoose = require('mongoose'), + Quiz = mongoose.model('Quiz'), + _ = require('lodash'); + +/** + * Get the error message from error object + */ +var getErrorMessage = function(err) { + var message = ''; + + if (err.code) { + switch (err.code) { + case 11000: + case 11001: + message = 'Quiz already exists'; + break; + default: + message = 'Something went wrong'; + } + } else { + for (var errName in err.errors) { + if (err.errors[errName].message) message = err.errors[errName].message; + } + } + + return message; +}; + +/** + * Create a Quiz + */ +exports.create = function(req, res) { + var quiz = new Quiz(req.body); + quiz.user = req.user; + + quiz.save(function(err) { + if (err) { + return res.send(400, { + message: getErrorMessage(err) + }); + } else { + res.jsonp(quiz); + } + }); +}; + +/** + * * + * Show the current Quiz + */ +exports.read = function(req, res) { + res.jsonp(req.quiz); +}; + +/** + * Update a Quiz + */ +exports.update = function(req, res) { + var quiz = req.quiz ; + + quiz = _.extend(quiz , req.body); + + quiz.save(function(err) { + if (err) { + return res.send(400, { + message: getErrorMessage(err) + }); + } else { + res.jsonp(quiz); + } + }); +}; + +/** + * Delete an Quiz + */ +exports.delete = function(req, res) { + var quiz = req.quiz ; + + quiz.remove(function(err) { + if (err) { + return res.send(400, { + message: getErrorMessage(err) + }); + } else { + res.jsonp(quiz); + } + }); +}; + +/** + * List of quizzes + */ +exports.list = function(req, res) { Quiz.find().sort('-created').populate('user', 'displayName').exec(function(err, quizzes) { + if (err) { + return res.send(400, { + message: getErrorMessage(err) + }); + } else { + res.jsonp(quizzes); + } + }); +}; + +/** + * Quiz middleware + */ +exports.quizByID = function(req, res, next, id) { Quiz.findById(id).populate('user', 'displayName').exec(function(err, quiz) { + if (err) return next(err); + if (! quiz) return next(new Error('Failed to load Quiz ' + id)); + req.quiz = quiz ; + next(); + }); +}; + +/** + * Quiz authorization middleware + */ +exports.hasAuthorization = function(req, res, next) { + if (req.quiz.user.id !== req.user.id) { + return res.send(403, 'User is not authorized'); + } + next(); +}; \ No newline at end of file diff --git a/app/controllers/takers.server.controller.js b/app/controllers/takers.server.controller.js new file mode 100644 index 0000000000..27faa175ac --- /dev/null +++ b/app/controllers/takers.server.controller.js @@ -0,0 +1,128 @@ +'use strict'; + +/** + * Module dependencies. + */ +var mongoose = require('mongoose'), + Taker = mongoose.model('Taker'), + _ = require('lodash'); + +/** + * Get the error message from error object + */ +var getErrorMessage = function(err) { + var message = ''; + + if (err.code) { + switch (err.code) { + case 11000: + case 11001: + message = 'Taker already exists'; + break; + default: + message = 'Something went wrong'; + } + } else { + for (var errName in err.errors) { + if (err.errors[errName].message) message = err.errors[errName].message; + } + } + + return message; +}; + +/** + * Create a Taker + */ +exports.create = function(req, res) { + var taker = new Taker(req.body); + taker.user = req.user; + + taker.save(function(err) { + if (err) { + return res.send(400, { + message: getErrorMessage(err) + }); + } else { + res.jsonp(taker); + } + }); +}; + +/** + * Show the current Taker + */ +exports.read = function(req, res) { + res.jsonp(req.taker); +}; + +/** + * Update a Taker + */ +exports.update = function(req, res) { + var taker = req.taker ; + + taker = _.extend(taker , req.body); + + taker.save(function(err) { + if (err) { + return res.send(400, { + message: getErrorMessage(err) + }); + } else { + res.jsonp(taker); + } + }); +}; + +/** + * Delete an Taker + */ +exports.delete = function(req, res) { + var taker = req.taker ; + + taker.remove(function(err) { + if (err) { + return res.send(400, { + message: getErrorMessage(err) + }); + } else { + res.jsonp(taker); + } + }); +}; + +/** + * List of Takers + */ +exports.list = function(req, res) { Taker.find().sort('-created').populate('user', 'displayName').exec(function(err, takers) { + if (err) { + return res.send(400, { + message: getErrorMessage(err) + }); + } else { + res.jsonp(takers); + } + }); +}; + +/** + * Taker middleware + */ +exports.takerByID = function(req, res, next, id) { Taker.findById(id).populate('user', 'displayName').exec(function(err, taker) { + if (err) return next(err); + if (! taker) return next(new Error('Failed to load Taker ' + id)); + req.taker = taker ; + next(); + }); +}; + +/** + * Taker authorization middleware + */ +exports.hasAuthorization = function(req, res, next) { + if (req.taker.user.id !== req.user.id) { + return res.send(403, 'User is not authorized'); + } + next(); +}; \ No newline at end of file diff --git a/app/models/qa.server.model.js b/app/models/qa.server.model.js new file mode 100644 index 0000000000..6524d7aec4 --- /dev/null +++ b/app/models/qa.server.model.js @@ -0,0 +1,136 @@ +'use strict'; + +/** + * Module dependencies. + */ +var mongoose = require('mongoose'), + Schema = mongoose.Schema; + +// +// Answer Schema +// +var AnswerSchema = new mongoose.Schema({ + text: String, + selectedAnswer: { + type: Boolean, + default: false + }}); + +var qaQuizSchema = new mongoose.Schema({ + name: String, + id: Number, + selected: { + type: Boolean, + default: false + }}); +/** + * Qa Schema + */ +var QaSchema = new Schema({ + created: { + type: Date, + default: Date.now + }, + selected: { + type: Boolean, + default: false + }, + question: { + type: String, + default: '', + trim: true + + }, + questionNumber: { + type: String, + default: '', + trim: true + }, + imageURL: { + type: String, + default: '', + trim: true + }, + choices: [AnswerSchema], + hint: { + type: String, + default: '', + trim: true + }, + user: { + type: Schema.ObjectId, + ref: 'User' + }, + difficulty: { + type: String, + default: 'Easy', + trim: true + }, + type: { + type: String, + default: 'FIB', + trim: true + }, + hintOn: { + type: Boolean, + default: false, + trim: true + }, + timeOn: { + type: Boolean, + default: false, + trim: true + }, + fifty50On: { + type: Boolean, + default: false, + trim: true + }, + randomizeQuestionsOn: { + type: Boolean, + default: false, + trim: true + }, + randomizeAnswersOn: { + type: Boolean, + default: false, + trim: true + + }, + qaQuizId: { + type: String, + default: 999 + }, + qaQuizName: { + type: String, + default: 'Quiz' + }, + qaQuiz: [qaQuizSchema], + quiz: { + type: Schema.ObjectId, + ref: 'Quiz' + } +}); + +//console.log(AnswerSchema); + +/** + * Validations + */ +QaSchema.path('question').validate(function(question) { + return question.length; +}, 'Question cannot be blank'); + +/** + * Statics + */ +QaSchema.statics = { + load: function(id, cb) { + this.findOne({ + _id: id + }).populate('user', 'displayName').exec(cb); + } +}; +//console.log(QaSchema); +mongoose.model('Qa', QaSchema); +mongoose.model('Answer', AnswerSchema); diff --git a/app/models/quiz.server.model.js b/app/models/quiz.server.model.js new file mode 100644 index 0000000000..6330dc7032 --- /dev/null +++ b/app/models/quiz.server.model.js @@ -0,0 +1,72 @@ +'use strict'; + +/** + * Module dependencies. + */ +var mongoose = require('mongoose'), + Schema = mongoose.Schema; + +/** + * Quiz Schema + */ +var QuizSchema = new Schema({ + name: { + type: String, + default: '', + required: 'Please fill Quiz name', + trim: true + }, + created: { + type: Date, + default: Date.now + }, + user: { + type: Schema.ObjectId, + ref: 'User' + }, + quizNumber: { + type: String, + default: '', + trim: true + }, + category: { + type: String, + default: '', + trim: true + }, + keyWords: { + type: String, + default: '', + trim: true + }, + hintOn: { + type: Boolean, + default: false, + trim: true + }, + timeOn: { + type: Boolean, + default: false, + trim: true + }, + fifty50On: { + type: Boolean, + default: false, + trim: true + }, + randomizeQuestionsOn: { + type: Boolean, + default: false, + trim: true + }, + randomizeAnswersOn: { + type: Boolean, + default: false, + trim: true + + }, + qa: [{ type: Schema.ObjectId, ref: 'Qa' }] + +}); + +mongoose.model('Quiz', QuizSchema); diff --git a/app/models/taker.server.model.js b/app/models/taker.server.model.js new file mode 100644 index 0000000000..e2f4db4dd1 --- /dev/null +++ b/app/models/taker.server.model.js @@ -0,0 +1,174 @@ +'use strict'; + +/** + * Module dependencies. + */ +var mongoose = require('mongoose'), + Schema = mongoose.Schema; + var takerAnswerSchema = new mongoose.Schema({ + text: String, + correctAnswer: Boolean}); +/** + * QA Schema + */ +var takerQASchema = new Schema({ + created: { + type: Date, + default: Date.now + }, + question: { + type: String, + default: '', + trim: true + }, + questionNumber: { + type: String, + default: '', + trim: true + }, + imageURL: { + type: String, + default: '', + trim: true + }, + choices: [takerAnswerSchema], + hint: { + type: String, + default: '', + trim: true + }, + user: { + type: Schema.ObjectId, + ref: 'User' + }, + difficulty: { + type: String, + default: 'Easy', + trim: true + }, + type: { + type: String, + default: 'FIB', + trim: true + }, + hintOn: { + type: Boolean, + default: false, + trim: true + }, + timeOn: { + type: Boolean, + default: false, + trim: true + }, + fifty50On: { + type: Boolean, + default: false, + trim: true + }, + randomizeQuestionsOn: { + type: Boolean, + default: false, + trim: true + }, + randomizeAnswersOn: { + type: Boolean, + default: false, + trim: true + + } +}); + + +/** + * Statics + */ +takerQASchema.statics = { + load: function(id, cb) { + this.findOne({ + _id: id + }).populate('user', 'displayName').exec(cb); + } +}; +// +// AnswerCorrect Schema +// +var AnswerSelectedSchema = new mongoose.Schema({ + text: String, + isSelected: Number}); + + + +var TakerAnswersSchema = new Schema({ + updated: { + type: Date, + default: Date.now + }, + questionViewed: { + type: Boolean, + default: false + }, + questionAnswered: { + type: Boolean, + default: false + }, + questionNumber: { + type: String, + default: '', + trim: true + }, + answer: [AnswerSelectedSchema] + +}); + +//console.log(TakerResultsSchema); + + +var TakerSchema = new Schema({ + updated: { + type: Date, + default: Date.now + }, + + quizNumber: { + type: Number, + default: 0 + }, + trialNumber: { + type: Number, + default: 0 + }, + trialOptions: { + type: String, + default: '', + trim: true + }, + results: [TakerAnswersSchema], + qa:[takerQASchema] + +}); + + //Validations + +//QASchema.path('question').validate(function(question) { +// return question.length; +//}, 'Question cannot be blank'); + + + // Statics + + TakerSchema.statics = { + load: function(id, cb) { + this.findOne({ + _id: id + }).populate('user', 'displayName').exec(cb); + } +}; + +mongoose.model('takerQA', takerQASchema); +mongoose.model('takerAnswer', takerAnswerSchema); +mongoose.model('AnswerSelected', AnswerSelectedSchema); +mongoose.model('TakerAnswers', TakerAnswersSchema); +mongoose.model('Taker', TakerSchema); + + diff --git a/app/routes/qas.server.routes.js b/app/routes/qas.server.routes.js new file mode 100644 index 0000000000..6ed1afc02b --- /dev/null +++ b/app/routes/qas.server.routes.js @@ -0,0 +1,24 @@ +'use strict'; +//Routes... +module.exports = function(app) { + var users = require('../../app/controllers/users'); + var qas = require('../../app/controllers/qas'); + var quizzes = require('../../app/controllers/qas'); + + // Qas Routes + app.route('/listQasQuizzes') + .get(quizzes.list) + .post(users.requiresLogin, quizzes.create); + + app.route('/qas') + .get(qas.list) + .post(users.requiresLogin, qas.create); + + app.route('/qas/:qaId') + .get(qas.read) + .put(users.requiresLogin, qas.hasAuthorization, qas.update) + .delete(users.requiresLogin, qas.hasAuthorization, qas.delete); + + // Finish by binding the Qa middleware + app.param('qaId', qas.qaByID); +}; \ No newline at end of file diff --git a/app/routes/quizzes.server.routes.js b/app/routes/quizzes.server.routes.js new file mode 100644 index 0000000000..4ad5563a34 --- /dev/null +++ b/app/routes/quizzes.server.routes.js @@ -0,0 +1,24 @@ +'use strict'; +//Routes... +module.exports = function(app) { + var users = require('../../app/controllers/users'); + var qas = require('../../app/controllers/qas'); + var quizzes = require('../../app/controllers/quizzes'); + + // Qas Routes +// app.route('/listQasQuizzes') +// .get(quizzes.list) +// .post(users.requiresLogin, quizzes.create); + + app.route('/quizzes') + .get(quizzes.list) + .post(users.requiresLogin, quizzes.create); + + app.route('/quizzes/:quizId') + .get(quizzes.read) + .put(users.requiresLogin, quizzes.hasAuthorization, quizzes.update) + .delete(users.requiresLogin, quizzes.hasAuthorization, qas.delete); + + // Finish by binding the Qa middleware + app.param('quizId', quizzes.quizByID); +}; diff --git a/app/routes/takers.server.routes.js b/app/routes/takers.server.routes.js new file mode 100644 index 0000000000..918c323921 --- /dev/null +++ b/app/routes/takers.server.routes.js @@ -0,0 +1,23 @@ +'use strict'; + +module.exports = function(app) { + var users = require('../../app/controllers/users'); + var takers = require('../../app/controllers/takers'); + var qas = require('../../app/controllers/takers'); + var quizzes = require('../../app/controllers/takers'); + // Takers Routes + + //app.route('/listTakersQuizzes') + // .get(quizzes.list) + // .post(users.requiresLogin, quizzes.create); + app.route('/takers') + .get(takers.list) + .post(users.requiresLogin, takers.create); + app.route('/takers/:takerId') + .get(takers.read) + .put(users.requiresLogin, takers.hasAuthorization, takers.update) + .delete(users.requiresLogin, takers.hasAuthorization, takers.delete); + + // Finish by binding the Taker middleware + app.param('takerId', takers.takerByID); +}; diff --git a/app/tests/qa.server.model.test.js b/app/tests/qa.server.model.test.js new file mode 100644 index 0000000000..0d1306cd64 --- /dev/null +++ b/app/tests/qa.server.model.test.js @@ -0,0 +1,64 @@ +'use strict'; + +/** + * Module dependencies. + */ +var should = require('should'), + mongoose = require('mongoose'), + User = mongoose.model('User'), + Qa = mongoose.model('Qa'); + +/** + * Globals + */ +var user, qa; + +/** + * Unit tests + */ +describe('Qa Model Unit Tests:', function() { + beforeEach(function(done) { + user = new User({ + firstName: 'Full', + lastName: 'Name', + displayName: 'Full Name', + email: 'test@test.com', + username: 'username', + password: 'password' + }); + + user.save(function() { + qa = new Qa({ + name: 'Qa Name', + user: user + }); + + done(); + }); + }); + + describe('Method Save', function() { + it('should be able to save without problems', function(done) { + return qa.save(function(err) { + should.not.exist(err); + done(); + }); + }); + + it('should be able to show an error when try to save without name', function(done) { + qa.name = ''; + + return qa.save(function(err) { + should.exist(err); + done(); + }); + }); + }); + + afterEach(function(done) { + Qa.remove().exec(); + User.remove().exec(); + + done(); + }); +}); \ No newline at end of file diff --git a/app/tests/taker.server.model.test.js b/app/tests/taker.server.model.test.js new file mode 100644 index 0000000000..f55980cd93 --- /dev/null +++ b/app/tests/taker.server.model.test.js @@ -0,0 +1,64 @@ +'use strict'; + +/** + * Module dependencies. + */ +var should = require('should'), + mongoose = require('mongoose'), + User = mongoose.model('User'), + Taker = mongoose.model('Taker'); + +/** + * Globals + */ +var user, taker; + +/** + * Unit tests + */ +describe('Taker Model Unit Tests:', function() { + beforeEach(function(done) { + user = new User({ + firstName: 'Full', + lastName: 'Name', + displayName: 'Full Name', + email: 'test@test.com', + username: 'username', + password: 'password' + }); + + user.save(function() { + taker = new Taker({ + name: 'Taker Name', + user: user + }); + + done(); + }); + }); + + describe('Method Save', function() { + it('should be able to save without problems', function(done) { + return taker.save(function(err) { + should.not.exist(err); + done(); + }); + }); + + it('should be able to show an error when try to save without name', function(done) { + taker.name = ''; + + return taker.save(function(err) { + should.exist(err); + done(); + }); + }); + }); + + afterEach(function(done) { + Taker.remove().exec(); + User.remove().exec(); + + done(); + }); +}); \ No newline at end of file diff --git a/gruntfile.js b/gruntfile.js index ca48bbd883..a977357986 100644 --- a/gruntfile.js +++ b/gruntfile.js @@ -31,7 +31,7 @@ module.exports = function(grunt) { clientViews: { files: watchFiles.clientViews, options: { - livereload: true, + livereload: true } }, clientJS: { @@ -59,7 +59,7 @@ module.exports = function(grunt) { }, csslint: { options: { - csslintrc: '.csslintrc', + csslintrc: '.csslintrc' }, all: { src: watchFiles.clientCSS diff --git a/public/dist/application.js b/public/dist/application.js index f59c8fee04..b5f3f6245f 100644 --- a/public/dist/application.js +++ b/public/dist/application.js @@ -44,6 +44,10 @@ angular.element(document).ready(function () { ApplicationConfiguration.registerModule('articles');'use strict'; // Use Applicaion configuration module to register a new module ApplicationConfiguration.registerModule('core');'use strict'; +// Use application configuration module to register a new module +ApplicationConfiguration.registerModule('qas');'use strict'; +// Use applicaion configuration module to register a new module +ApplicationConfiguration.registerModule('takers');'use strict'; // Use Applicaion configuration module to register a new module ApplicationConfiguration.registerModule('users');'use strict'; // Configuring the Articles module @@ -89,6 +93,7 @@ angular.module('articles').controller('ArticlesController', [ title: this.title, content: this.content }); + // console.log(response); article.$save(function (response) { $location.path('articles/' + response._id); $scope.title = ''; @@ -176,16 +181,20 @@ angular.module('core').controller('HomeController', [ //Menu service used for managing menus angular.module('core').service('Menus', [function () { // Define a set of default roles - this.defaultRoles = ['user']; + this.defaultRoles = ['*']; // Define the menus object this.menus = {}; // A private function for rendering decision var shouldRender = function (user) { if (user) { - for (var userRoleIndex in user.roles) { - for (var roleIndex in this.roles) { - if (this.roles[roleIndex] === user.roles[userRoleIndex]) { - return true; + if (!!~this.roles.indexOf('*')) { + return true; + } else { + for (var userRoleIndex in user.roles) { + for (var roleIndex in this.roles) { + if (this.roles[roleIndex] === user.roles[userRoleIndex]) { + return true; + } } } } @@ -245,7 +254,7 @@ angular.module('core').service('Menus', [function () { menuItemClass: menuItemType, uiRoute: menuItemUIRoute || '/' + menuItemURL, isPublic: isPublic === null || typeof isPublic === 'undefined' ? this.menus[menuId].isPublic : isPublic, - roles: roles || this.defaultRoles, + roles: roles === null || typeof roles === 'undefined' ? this.menus[menuId].roles : roles, position: position || 0, items: [], shouldRender: shouldRender @@ -266,7 +275,7 @@ angular.module('core').service('Menus', [function () { link: menuItemURL, uiRoute: menuItemUIRoute || '/' + menuItemURL, isPublic: isPublic === null || typeof isPublic === 'undefined' ? this.menus[menuId].items[itemIndex].isPublic : isPublic, - roles: roles || this.defaultRoles, + roles: roles === null || typeof roles === 'undefined' ? this.menus[menuId].items[itemIndex].roles : roles, position: position || 0, shouldRender: shouldRender }); @@ -306,6 +315,380 @@ angular.module('core').service('Menus', [function () { //Adding the topbar menu this.addMenu('topbar'); }]);'use strict'; +// Configuring the Articles module. +angular.module('qas').run([ + 'Menus', + function (Menus) { + // Set top bar menu items + Menus.addMenuItem('topbar', 'Qas', 'qas', 'dropdown', '/qas(/create)?'); + Menus.addSubMenuItem('topbar', 'qas', 'List Qas', 'qas'); + Menus.addSubMenuItem('topbar', 'qas', 'New Qa', 'qas/create'); + } +]);'use strict'; +//Setting up route... +angular.module('qas').config([ + '$stateProvider', + function ($stateProvider) { + // Qas state routing + $stateProvider.state('listQas', { + url: '/qas', + templateUrl: 'modules/qas/views/list-qas.client.view.html' + }).state('createQa', { + url: '/qas/create', + templateUrl: 'modules/qas/views/create-qa.client.view.html' + }).state('viewQa', { + url: '/qas/:qaId', + templateUrl: 'modules/qas/views/view-qa.client.view.html' + }).state('editQa', { + url: '/qas/:qaId/edit', + templateUrl: 'modules/qas/views/edit-qa.client.view.html' + }); + } +]);'use strict'; +// Qas controller... +angular.module('qas').controller('QasController', [ + '$scope', + '$stateParams', + '$location', + 'Authentication', + 'Qas', + 'CalculatorService', + 'MathService', + 'qasInitService', + function ($scope, $stateParams, $location, Authentication, Qas, CalculatorService, MathService, qasInitService) { + $scope.authentication = Authentication; + //Test of Calculator and Math Service + $scope.doit = CalculatorService.cce(77); + // Initialize Dropdown labels + $scope.typeDropdown = qasInitService.typeDropdown(); + $scope.difficultyDropdown = qasInitService.difficultyDropdown(); + $scope.qa = qasInitService.init(); + // Create and validate qa entries + $scope.create = function () { + var qa = new Qas({ + question: this.question, + imageURL: this.imageURL, + choices: [ + { + text: this.text, + selectedAnswer: false + }, + { + text: this.text, + selectedAnswer: this.correctAnswer + }, + { + text: this.text, + selectedAnswer: this.correctAnswer + } + ], + hint: this.hint, + type: this.td, + difficulty: this.difficulty, + hintOn: this.hintOn, + timeOn: this.timeOn, + fifty50On: this.fifty50On, + randomizeQuestionsOn: this.randomizeQuestionsOn, + randomizeAnswersOn: this.randomizeAnswersOn + }); + // Hack to load these variables. Not handled above??? + qa.choices = $scope.qa.choices; + qa.difficulty = $scope.dd.label; + qa.type = $scope.td.label; + // Check that question was entered + if (qa.question.length > 0) { + var choiceCount = 0; + //Loop through choices to get at least two + console.log('qa if', qa); + for (var i = 0, ln = qa.choices.length; i < ln; i++) { + var choice = qa.choices[i].text; + console.log('choice', choice, ' i', i); + if (choice.length > 0) { + choiceCount++; + } + } + if (choiceCount > 1) { + } else { + alert('You must have at least two choices'); + } + } else { + alert('You must have a question'); + } + console.log('qaFinal', qa); + qa.$save(function (response) { + $location.path('qas/' + response._id); + }); + }; + // Method to add an additional choice option + $scope.addChoice = function () { + console.log('qa add', $scope.qa); + $scope.qa.choices.push({ + text: this.text, + selectedAnswer: false + }); + }; + $scope.remove = function (qa) { + if (qa) { + qa.$remove(); + for (var i in $scope.qas) { + if ($scope.qas[i] === qa) { + $scope.qas.splice(i, 1); + } + } + } else { + $scope.qa.$remove(function () { + $location.path('qas'); + }); + } + }; + $scope.update = function () { + var qa = $scope.qa; + console.log('From update', qa); + if (!qa.updated) { + qa.updated = []; + } + qa.updated.push(new Date().getTime()); + qa.$update(function () { + $location.path('qas/' + qa._id); + }); + }; + $scope.find = function () { + Qas.query(function (qas) { + $scope.qas = qas; + }); + }; + $scope.findOne = function () { + Qas.get({ qaId: $stateParams.qaId }, function (qa) { + $scope.qa = qa; + }); + }; + $scope.deleteChoice = function (ev) { + var ss = ev.target.innerText.toString() - 1; + console.log(ss); + var qa = $scope.qa; + console.log(qa); + $scope.qa.choices.splice(ss, 1); + }; + } +]);'use strict'; +//Qas service used to communicate Qas REST endpoints +angular.module('qas').factory('Qas', [ + '$resource', + function ($resource) { + return $resource('qas/:qaId', { qaId: '@_id' }, { update: { method: 'PUT' } }); + } +]);/** + * Created by EbyC on 8/24/2014. + */ +'use strict'; +angular.module('qas').service('MathService', [function () { + this.add = function (a, b) { + return a + b; + }; + this.subtract = function (a, b) { + return a - b; + }; + this.multiply = function (a, b) { + return a * b; + }; + this.divide = function (a, b) { + return a / b; + }; + }]).service('CalculatorService', function (MathService) { + this.square = function (a) { + return MathService.multiply(a, a); + }; + this.cce = function (a) { + return a + a * 1000; + }; + this.cube = function (a) { + return MathService.multiply(a, MathService.multiply(a, a)); + }; +});/** + * Created by EbyC on 8/24/2014. + */ +'use strict'; +//Qas service used to communicate Qas REST endpoints +angular.module('qas').service('qasInitService', [function () { + this.typeDropdown = function () { + return [ + { + 'label': 'FIB', + 'value': 1 + }, + { + 'label': 'TF', + 'value': 2 + }, + { + 'label': 'MC', + 'value': 3 + }, + { + 'label': 'Matching', + 'value': 4 + } + ]; + }; + this.difficultyDropdown = function () { + return [ + { + 'label': 'Easy', + 'value': 1 + }, + { + 'label': 'Medium', + 'value': 2 + }, + { + 'label': 'Hard', + 'value': 3 + }, + { + 'label': 'Impossible', + 'value': 4 + } + ]; + }; + this.init = function () { + return { + choices: [ + { + text: '', + correctAnswer: false + }, + { + text: '', + correctAnswer: false + }, + { + text: '', + correctAnswer: false + } + ] + }; + }; + }]);'use strict'; +// Configuring the Takers module +angular.module('takers').run([ + 'Menus', + function (Menus) { + // Set top bar menu items + Menus.addMenuItem('topbar', 'Takers', 'takers', 'dropdown', '/takers(/create)?'); + Menus.addSubMenuItem('topbar', 'takers', 'List Takers', 'takers'); + Menus.addSubMenuItem('topbar', 'takers', 'New Taker', 'takers/create'); + Menus.addSubMenuItem('topbar', 'takers', 'Take', 'takers/'); + } +]);'use strict'; +//Setting up route +angular.module('takers').config([ + '$stateProvider', + function ($stateProvider) { + // Takers state routing + $stateProvider.state('listTakers', { + url: '/takers', + templateUrl: 'modules/takers/views/take.html' + }).state('createTaker', { + url: '/takers/create', + templateUrl: 'modules/takers/views/create-taker.client.view.html' + }).state('viewTaker', { + url: '/takers/:takerId', + templateUrl: 'modules/takers/views/view-taker.client.view.html' + }).state('editTaker', { + url: '/takers/:takerId/edit', + templateUrl: 'modules/takers/views/edit-taker.client.view.html' + }); + } +]);'use strict'; +angular.module('takers').controller('TakersController', [ + '$scope', + '$stateParams', + '$location', + 'Authentication', + 'Articles', + function ($scope, $stateParams, $location, Authentication, Qas, Takers) { + $scope.authentication = Authentication; + // Takers controller logic + var taker = new Takers(); + //taker.qa = qas; + $scope.taker = new Takers({ + quizNumber: '0', + trialNumber: '0', + trialOptions: '', + results: [{ + questionViewed: false, + questionAnswered: false, + questionNumber: '', + answer: [{ + selection: '0', + answer: '0' + }] + }] + }); + console.log('From ScopeTaker', $scope.taker); + $scope.find = function () { + Qas.query(function (qas) { + $scope.qas = qas; + }); + }; + console.log('From ScopeTaker', $scope.qas); + // Create and validate taker entries + $scope.next = function () { + $scope.questionIndex++; + taker.questionViewed = true; + taker.$save(function (response) { + $location.path('takers/' + response._id); + }); + console.log('next', $scope.questionIndex); + }; + $scope.prev = function () { + $scope.questionIndex--; + console.log('prev', $scope.questionIndex); + }; + $scope.answerToggled = function () { + //var taker = $scope.taker; + // Grab data from input boxes + //console.log(taker); + //taker.qa.question = qas[questionIndex].question; + //taker.questionNumber = $scope.questionNumber; + console.log('toggledtaker', taker); + for (var i = 0, ln = taker.qa[$scope.questionIndex].choices.length; i < ln; i++) { + //taker.results.answer.selection[i] = $scope.results.answer.selection[i]; + //console.log(taker.results[$scope.questionIndex].answer.isSelected[i],$scope.choice[i].selectedAnswer) + taker.results[$scope.questionIndex].answer.isSelected[i] = $scope.choice[i].selectedAnswer; + taker.updated.push(new Date().getTime()); + } + ; + console.log('From taker 1', taker); + // Check that question was entered + taker.$save(function (response) { + $location.path('takers/' + response._id); + }); + console.log(taker); + }; + $scope.find = function () { + Qas.query(function (qas) { + // $scope.qas = qas; + taker.qa = qas; + $scope.taker = taker; + console.log('From ScopeTaker1', qas[0].questionNumber, taker.qa[0].question, $scope.qas, taker); + }); + $scope.questionIndex = 0; + }; + $scope.findOne = function () { + takers.get({ qasId: $stateParams.qasId }, function (qas) { + $scope.taker = qas; + }); + }; + } +]);'use strict'; +//Takers service used to communicate Takers REST endpoints +angular.module('takers').factory('Takers', [ + '$resource', + function ($resource) { + return $resource('takers/:takerId', { takerId: '@_id' }, { update: { method: 'PUT' } }); + } +]);'use strict'; // Config HTTP Error Handling angular.module('users').config([ '$httpProvider', diff --git a/public/dist/application.min.js b/public/dist/application.min.js index 7c75a13709..1e663897bd 100644 --- a/public/dist/application.min.js +++ b/public/dist/application.min.js @@ -1 +1 @@ -"use strict";var ApplicationConfiguration=function(){var applicationModuleName="mean",applicationModuleVendorDependencies=["ngResource","ngAnimate","ui.router","ui.bootstrap","ui.utils"],registerModule=function(moduleName,dependencies){angular.module(moduleName,dependencies||[]),angular.module(applicationModuleName).requires.push(moduleName)};return{applicationModuleName:applicationModuleName,applicationModuleVendorDependencies:applicationModuleVendorDependencies,registerModule:registerModule}}();angular.module(ApplicationConfiguration.applicationModuleName,ApplicationConfiguration.applicationModuleVendorDependencies),angular.module(ApplicationConfiguration.applicationModuleName).config(["$locationProvider",function($locationProvider){$locationProvider.hashPrefix("!")}]),angular.element(document).ready(function(){"#_=_"===window.location.hash&&(window.location.hash="#!"),angular.bootstrap(document,[ApplicationConfiguration.applicationModuleName])}),ApplicationConfiguration.registerModule("articles"),ApplicationConfiguration.registerModule("core"),ApplicationConfiguration.registerModule("users"),angular.module("articles").run(["Menus",function(Menus){Menus.addMenuItem("topbar","Articles","articles","dropdown","/articles(/create)?"),Menus.addSubMenuItem("topbar","articles","List Articles","articles"),Menus.addSubMenuItem("topbar","articles","New Article","articles/create")}]),angular.module("articles").config(["$stateProvider",function($stateProvider){$stateProvider.state("listArticles",{url:"/articles",templateUrl:"modules/articles/views/list-articles.client.view.html"}).state("createArticle",{url:"/articles/create",templateUrl:"modules/articles/views/create-article.client.view.html"}).state("viewArticle",{url:"/articles/:articleId",templateUrl:"modules/articles/views/view-article.client.view.html"}).state("editArticle",{url:"/articles/:articleId/edit",templateUrl:"modules/articles/views/edit-article.client.view.html"})}]),angular.module("articles").controller("ArticlesController",["$scope","$stateParams","$location","Authentication","Articles",function($scope,$stateParams,$location,Authentication,Articles){$scope.authentication=Authentication,$scope.create=function(){var article=new Articles({title:this.title,content:this.content});article.$save(function(response){$location.path("articles/"+response._id),$scope.title="",$scope.content=""},function(errorResponse){$scope.error=errorResponse.data.message})},$scope.remove=function(article){if(article){article.$remove();for(var i in $scope.articles)$scope.articles[i]===article&&$scope.articles.splice(i,1)}else $scope.article.$remove(function(){$location.path("articles")})},$scope.update=function(){var article=$scope.article;article.$update(function(){$location.path("articles/"+article._id)},function(errorResponse){$scope.error=errorResponse.data.message})},$scope.find=function(){$scope.articles=Articles.query()},$scope.findOne=function(){$scope.article=Articles.get({articleId:$stateParams.articleId})}}]),angular.module("articles").factory("Articles",["$resource",function($resource){return $resource("articles/:articleId",{articleId:"@_id"},{update:{method:"PUT"}})}]),angular.module("core").config(["$stateProvider","$urlRouterProvider",function($stateProvider,$urlRouterProvider){$urlRouterProvider.otherwise("/"),$stateProvider.state("home",{url:"/",templateUrl:"modules/core/views/home.client.view.html"})}]),angular.module("core").controller("HeaderController",["$scope","Authentication","Menus",function($scope,Authentication,Menus){$scope.authentication=Authentication,$scope.isCollapsed=!1,$scope.menu=Menus.getMenu("topbar"),$scope.toggleCollapsibleMenu=function(){$scope.isCollapsed=!$scope.isCollapsed},$scope.$on("$stateChangeSuccess",function(){$scope.isCollapsed=!1})}]),angular.module("core").controller("HomeController",["$scope","Authentication",function($scope,Authentication){$scope.authentication=Authentication}]),angular.module("core").service("Menus",[function(){this.defaultRoles=["user"],this.menus={};var shouldRender=function(user){if(!user)return this.isPublic;for(var userRoleIndex in user.roles)for(var roleIndex in this.roles)if(this.roles[roleIndex]===user.roles[userRoleIndex])return!0;return!1};this.validateMenuExistance=function(menuId){if(menuId&&menuId.length){if(this.menus[menuId])return!0;throw new Error("Menu does not exists")}throw new Error("MenuId was not provided")},this.getMenu=function(menuId){return this.validateMenuExistance(menuId),this.menus[menuId]},this.addMenu=function(menuId,isPublic,roles){return this.menus[menuId]={isPublic:isPublic||!1,roles:roles||this.defaultRoles,items:[],shouldRender:shouldRender},this.menus[menuId]},this.removeMenu=function(menuId){this.validateMenuExistance(menuId),delete this.menus[menuId]},this.addMenuItem=function(menuId,menuItemTitle,menuItemURL,menuItemType,menuItemUIRoute,isPublic,roles,position){return this.validateMenuExistance(menuId),this.menus[menuId].items.push({title:menuItemTitle,link:menuItemURL,menuItemType:menuItemType||"item",menuItemClass:menuItemType,uiRoute:menuItemUIRoute||"/"+menuItemURL,isPublic:null===isPublic||"undefined"==typeof isPublic?this.menus[menuId].isPublic:isPublic,roles:roles||this.defaultRoles,position:position||0,items:[],shouldRender:shouldRender}),this.menus[menuId]},this.addSubMenuItem=function(menuId,rootMenuItemURL,menuItemTitle,menuItemURL,menuItemUIRoute,isPublic,roles,position){this.validateMenuExistance(menuId);for(var itemIndex in this.menus[menuId].items)this.menus[menuId].items[itemIndex].link===rootMenuItemURL&&this.menus[menuId].items[itemIndex].items.push({title:menuItemTitle,link:menuItemURL,uiRoute:menuItemUIRoute||"/"+menuItemURL,isPublic:null===isPublic||"undefined"==typeof isPublic?this.menus[menuId].items[itemIndex].isPublic:isPublic,roles:roles||this.defaultRoles,position:position||0,shouldRender:shouldRender});return this.menus[menuId]},this.removeMenuItem=function(menuId,menuItemURL){this.validateMenuExistance(menuId);for(var itemIndex in this.menus[menuId].items)this.menus[menuId].items[itemIndex].link===menuItemURL&&this.menus[menuId].items.splice(itemIndex,1);return this.menus[menuId]},this.removeSubMenuItem=function(menuId,submenuItemURL){this.validateMenuExistance(menuId);for(var itemIndex in this.menus[menuId].items)for(var subitemIndex in this.menus[menuId].items[itemIndex].items)this.menus[menuId].items[itemIndex].items[subitemIndex].link===submenuItemURL&&this.menus[menuId].items[itemIndex].items.splice(subitemIndex,1);return this.menus[menuId]},this.addMenu("topbar")}]),angular.module("users").config(["$httpProvider",function($httpProvider){$httpProvider.interceptors.push(["$q","$location","Authentication",function($q,$location,Authentication){return{responseError:function(rejection){switch(rejection.status){case 401:Authentication.user=null,$location.path("signin");break;case 403:}return $q.reject(rejection)}}}])}]),angular.module("users").config(["$stateProvider",function($stateProvider){$stateProvider.state("profile",{url:"/settings/profile",templateUrl:"modules/users/views/settings/edit-profile.client.view.html"}).state("password",{url:"/settings/password",templateUrl:"modules/users/views/settings/change-password.client.view.html"}).state("accounts",{url:"/settings/accounts",templateUrl:"modules/users/views/settings/social-accounts.client.view.html"}).state("signup",{url:"/signup",templateUrl:"modules/users/views/authentication/signup.client.view.html"}).state("signin",{url:"/signin",templateUrl:"modules/users/views/authentication/signin.client.view.html"}).state("forgot",{url:"/password/forgot",templateUrl:"modules/users/views/password/forgot-password.client.view.html"}).state("reset-invlaid",{url:"/password/reset/invalid",templateUrl:"modules/users/views/password/reset-password-invalid.client.view.html"}).state("reset-success",{url:"/password/reset/success",templateUrl:"modules/users/views/password/reset-password-success.client.view.html"}).state("reset",{url:"/password/reset/:token",templateUrl:"modules/users/views/password/reset-password.client.view.html"})}]),angular.module("users").controller("AuthenticationController",["$scope","$http","$location","Authentication",function($scope,$http,$location,Authentication){$scope.authentication=Authentication,$scope.authentication.user&&$location.path("/"),$scope.signup=function(){$http.post("/auth/signup",$scope.credentials).success(function(response){$scope.authentication.user=response,$location.path("/")}).error(function(response){$scope.error=response.message})},$scope.signin=function(){$http.post("/auth/signin",$scope.credentials).success(function(response){$scope.authentication.user=response,$location.path("/")}).error(function(response){$scope.error=response.message})}}]),angular.module("users").controller("PasswordController",["$scope","$stateParams","$http","$location","Authentication",function($scope,$stateParams,$http,$location,Authentication){$scope.authentication=Authentication,$scope.authentication.user&&$location.path("/"),$scope.askForPasswordReset=function(){$scope.success=$scope.error=null,$http.post("/auth/forgot",$scope.credentials).success(function(response){$scope.credentials=null,$scope.success=response.message}).error(function(response){$scope.credentials=null,$scope.error=response.message})},$scope.resetUserPassword=function(){$scope.success=$scope.error=null,$http.post("/auth/reset/"+$stateParams.token,$scope.passwordDetails).success(function(response){$scope.passwordDetails=null,Authentication.user=response,$location.path("/password/reset/success")}).error(function(response){$scope.error=response.message})}}]),angular.module("users").controller("SettingsController",["$scope","$http","$location","Users","Authentication",function($scope,$http,$location,Users,Authentication){$scope.user=Authentication.user,$scope.user||$location.path("/"),$scope.hasConnectedAdditionalSocialAccounts=function(){for(var i in $scope.user.additionalProvidersData)return!0;return!1},$scope.isConnectedSocialAccount=function(provider){return $scope.user.provider===provider||$scope.user.additionalProvidersData&&$scope.user.additionalProvidersData[provider]},$scope.removeUserSocialAccount=function(provider){$scope.success=$scope.error=null,$http.delete("/users/accounts",{params:{provider:provider}}).success(function(response){$scope.success=!0,$scope.user=Authentication.user=response}).error(function(response){$scope.error=response.message})},$scope.updateUserProfile=function(isValid){if(isValid){$scope.success=$scope.error=null;var user=new Users($scope.user);user.$update(function(response){$scope.success=!0,Authentication.user=response},function(response){$scope.error=response.data.message})}else $scope.submitted=!0},$scope.changeUserPassword=function(){$scope.success=$scope.error=null,$http.post("/users/password",$scope.passwordDetails).success(function(){$scope.success=!0,$scope.passwordDetails=null}).error(function(response){$scope.error=response.message})}}]),angular.module("users").factory("Authentication",[function(){var _this=this;return _this._data={user:window.user},_this._data}]),angular.module("users").factory("Users",["$resource",function($resource){return $resource("users",{},{update:{method:"PUT"}})}]); \ No newline at end of file +"use strict";var ApplicationConfiguration=function(){var applicationModuleName="mean",applicationModuleVendorDependencies=["ngResource","ngAnimate","ui.router","ui.bootstrap","ui.utils"],registerModule=function(moduleName,dependencies){angular.module(moduleName,dependencies||[]),angular.module(applicationModuleName).requires.push(moduleName)};return{applicationModuleName:applicationModuleName,applicationModuleVendorDependencies:applicationModuleVendorDependencies,registerModule:registerModule}}();angular.module(ApplicationConfiguration.applicationModuleName,ApplicationConfiguration.applicationModuleVendorDependencies),angular.module(ApplicationConfiguration.applicationModuleName).config(["$locationProvider",function($locationProvider){$locationProvider.hashPrefix("!")}]),angular.element(document).ready(function(){"#_=_"===window.location.hash&&(window.location.hash="#!"),angular.bootstrap(document,[ApplicationConfiguration.applicationModuleName])}),ApplicationConfiguration.registerModule("articles"),ApplicationConfiguration.registerModule("core"),ApplicationConfiguration.registerModule("qas"),ApplicationConfiguration.registerModule("takers"),ApplicationConfiguration.registerModule("users"),angular.module("articles").run(["Menus",function(Menus){Menus.addMenuItem("topbar","Articles","articles","dropdown","/articles(/create)?"),Menus.addSubMenuItem("topbar","articles","List Articles","articles"),Menus.addSubMenuItem("topbar","articles","New Article","articles/create")}]),angular.module("articles").config(["$stateProvider",function($stateProvider){$stateProvider.state("listArticles",{url:"/articles",templateUrl:"modules/articles/views/list-articles.client.view.html"}).state("createArticle",{url:"/articles/create",templateUrl:"modules/articles/views/create-article.client.view.html"}).state("viewArticle",{url:"/articles/:articleId",templateUrl:"modules/articles/views/view-article.client.view.html"}).state("editArticle",{url:"/articles/:articleId/edit",templateUrl:"modules/articles/views/edit-article.client.view.html"})}]),angular.module("articles").controller("ArticlesController",["$scope","$stateParams","$location","Authentication","Articles",function($scope,$stateParams,$location,Authentication,Articles){$scope.authentication=Authentication,$scope.create=function(){var article=new Articles({title:this.title,content:this.content});article.$save(function(response){$location.path("articles/"+response._id),$scope.title="",$scope.content=""},function(errorResponse){$scope.error=errorResponse.data.message})},$scope.remove=function(article){if(article){article.$remove();for(var i in $scope.articles)$scope.articles[i]===article&&$scope.articles.splice(i,1)}else $scope.article.$remove(function(){$location.path("articles")})},$scope.update=function(){var article=$scope.article;article.$update(function(){$location.path("articles/"+article._id)},function(errorResponse){$scope.error=errorResponse.data.message})},$scope.find=function(){$scope.articles=Articles.query()},$scope.findOne=function(){$scope.article=Articles.get({articleId:$stateParams.articleId})}}]),angular.module("articles").factory("Articles",["$resource",function($resource){return $resource("articles/:articleId",{articleId:"@_id"},{update:{method:"PUT"}})}]),angular.module("core").config(["$stateProvider","$urlRouterProvider",function($stateProvider,$urlRouterProvider){$urlRouterProvider.otherwise("/"),$stateProvider.state("home",{url:"/",templateUrl:"modules/core/views/home.client.view.html"})}]),angular.module("core").controller("HeaderController",["$scope","Authentication","Menus",function($scope,Authentication,Menus){$scope.authentication=Authentication,$scope.isCollapsed=!1,$scope.menu=Menus.getMenu("topbar"),$scope.toggleCollapsibleMenu=function(){$scope.isCollapsed=!$scope.isCollapsed},$scope.$on("$stateChangeSuccess",function(){$scope.isCollapsed=!1})}]),angular.module("core").controller("HomeController",["$scope","Authentication",function($scope,Authentication){$scope.authentication=Authentication}]),angular.module("core").service("Menus",[function(){this.defaultRoles=["*"],this.menus={};var shouldRender=function(user){if(!user)return this.isPublic;if(~this.roles.indexOf("*"))return!0;for(var userRoleIndex in user.roles)for(var roleIndex in this.roles)if(this.roles[roleIndex]===user.roles[userRoleIndex])return!0;return!1};this.validateMenuExistance=function(menuId){if(menuId&&menuId.length){if(this.menus[menuId])return!0;throw new Error("Menu does not exists")}throw new Error("MenuId was not provided")},this.getMenu=function(menuId){return this.validateMenuExistance(menuId),this.menus[menuId]},this.addMenu=function(menuId,isPublic,roles){return this.menus[menuId]={isPublic:isPublic||!1,roles:roles||this.defaultRoles,items:[],shouldRender:shouldRender},this.menus[menuId]},this.removeMenu=function(menuId){this.validateMenuExistance(menuId),delete this.menus[menuId]},this.addMenuItem=function(menuId,menuItemTitle,menuItemURL,menuItemType,menuItemUIRoute,isPublic,roles,position){return this.validateMenuExistance(menuId),this.menus[menuId].items.push({title:menuItemTitle,link:menuItemURL,menuItemType:menuItemType||"item",menuItemClass:menuItemType,uiRoute:menuItemUIRoute||"/"+menuItemURL,isPublic:null===isPublic||"undefined"==typeof isPublic?this.menus[menuId].isPublic:isPublic,roles:null===roles||"undefined"==typeof roles?this.menus[menuId].roles:roles,position:position||0,items:[],shouldRender:shouldRender}),this.menus[menuId]},this.addSubMenuItem=function(menuId,rootMenuItemURL,menuItemTitle,menuItemURL,menuItemUIRoute,isPublic,roles,position){this.validateMenuExistance(menuId);for(var itemIndex in this.menus[menuId].items)this.menus[menuId].items[itemIndex].link===rootMenuItemURL&&this.menus[menuId].items[itemIndex].items.push({title:menuItemTitle,link:menuItemURL,uiRoute:menuItemUIRoute||"/"+menuItemURL,isPublic:null===isPublic||"undefined"==typeof isPublic?this.menus[menuId].items[itemIndex].isPublic:isPublic,roles:null===roles||"undefined"==typeof roles?this.menus[menuId].items[itemIndex].roles:roles,position:position||0,shouldRender:shouldRender});return this.menus[menuId]},this.removeMenuItem=function(menuId,menuItemURL){this.validateMenuExistance(menuId);for(var itemIndex in this.menus[menuId].items)this.menus[menuId].items[itemIndex].link===menuItemURL&&this.menus[menuId].items.splice(itemIndex,1);return this.menus[menuId]},this.removeSubMenuItem=function(menuId,submenuItemURL){this.validateMenuExistance(menuId);for(var itemIndex in this.menus[menuId].items)for(var subitemIndex in this.menus[menuId].items[itemIndex].items)this.menus[menuId].items[itemIndex].items[subitemIndex].link===submenuItemURL&&this.menus[menuId].items[itemIndex].items.splice(subitemIndex,1);return this.menus[menuId]},this.addMenu("topbar")}]),angular.module("qas").run(["Menus",function(Menus){Menus.addMenuItem("topbar","Qas","qas","dropdown","/qas(/create)?"),Menus.addSubMenuItem("topbar","qas","List Qas","qas"),Menus.addSubMenuItem("topbar","qas","New Qa","qas/create")}]),angular.module("qas").config(["$stateProvider",function($stateProvider){$stateProvider.state("listQas",{url:"/qas",templateUrl:"modules/qas/views/list-qas.client.view.html"}).state("createQa",{url:"/qas/create",templateUrl:"modules/qas/views/create-qa.client.view.html"}).state("viewQa",{url:"/qas/:qaId",templateUrl:"modules/qas/views/view-qa.client.view.html"}).state("editQa",{url:"/qas/:qaId/edit",templateUrl:"modules/qas/views/edit-qa.client.view.html"})}]),angular.module("qas").controller("QasController",["$scope","$stateParams","$location","Authentication","Qas","CalculatorService","MathService","qasInitService",function($scope,$stateParams,$location,Authentication,Qas,CalculatorService,MathService,qasInitService){$scope.authentication=Authentication,$scope.doit=CalculatorService.cce(77),$scope.typeDropdown=qasInitService.typeDropdown(),$scope.difficultyDropdown=qasInitService.difficultyDropdown(),$scope.qa=qasInitService.init(),$scope.create=function(){var qa=new Qas({question:this.question,imageURL:this.imageURL,choices:[{text:this.text,selectedAnswer:!1},{text:this.text,selectedAnswer:this.correctAnswer},{text:this.text,selectedAnswer:this.correctAnswer}],hint:this.hint,type:this.td,difficulty:this.difficulty,hintOn:this.hintOn,timeOn:this.timeOn,fifty50On:this.fifty50On,randomizeQuestionsOn:this.randomizeQuestionsOn,randomizeAnswersOn:this.randomizeAnswersOn});if(qa.choices=$scope.qa.choices,qa.difficulty=$scope.dd.label,qa.type=$scope.td.label,qa.question.length>0){var choiceCount=0;console.log("qa if",qa);for(var i=0,ln=qa.choices.length;ln>i;i++){var choice=qa.choices[i].text;console.log("choice",choice," i",i),choice.length>0&&choiceCount++}choiceCount>1||alert("You must have at least two choices")}else alert("You must have a question");console.log("qaFinal",qa),qa.$save(function(response){$location.path("qas/"+response._id)})},$scope.addChoice=function(){console.log("qa add",$scope.qa),$scope.qa.choices.push({text:this.text,selectedAnswer:!1})},$scope.remove=function(qa){if(qa){qa.$remove();for(var i in $scope.qas)$scope.qas[i]===qa&&$scope.qas.splice(i,1)}else $scope.qa.$remove(function(){$location.path("qas")})},$scope.update=function(){var qa=$scope.qa;console.log("From update",qa),qa.updated||(qa.updated=[]),qa.updated.push((new Date).getTime()),qa.$update(function(){$location.path("qas/"+qa._id)})},$scope.find=function(){Qas.query(function(qas){$scope.qas=qas})},$scope.findOne=function(){Qas.get({qaId:$stateParams.qaId},function(qa){$scope.qa=qa})},$scope.deleteChoice=function(ev){var ss=ev.target.innerText.toString()-1;console.log(ss);var qa=$scope.qa;console.log(qa),$scope.qa.choices.splice(ss,1)}}]),angular.module("qas").factory("Qas",["$resource",function($resource){return $resource("qas/:qaId",{qaId:"@_id"},{update:{method:"PUT"}})}]),angular.module("qas").service("MathService",[function(){this.add=function(a,b){return a+b},this.subtract=function(a,b){return a-b},this.multiply=function(a,b){return a*b},this.divide=function(a,b){return a/b}}]).service("CalculatorService",function(MathService){this.square=function(a){return MathService.multiply(a,a)},this.cce=function(a){return a+1e3*a},this.cube=function(a){return MathService.multiply(a,MathService.multiply(a,a))}}),angular.module("qas").service("qasInitService",[function(){this.typeDropdown=function(){return[{label:"FIB",value:1},{label:"TF",value:2},{label:"MC",value:3},{label:"Matching",value:4}]},this.difficultyDropdown=function(){return[{label:"Easy",value:1},{label:"Medium",value:2},{label:"Hard",value:3},{label:"Impossible",value:4}]},this.init=function(){return{choices:[{text:"",correctAnswer:!1},{text:"",correctAnswer:!1},{text:"",correctAnswer:!1}]}}}]),angular.module("takers").run(["Menus",function(Menus){Menus.addMenuItem("topbar","Takers","takers","dropdown","/takers(/create)?"),Menus.addSubMenuItem("topbar","takers","List Takers","takers"),Menus.addSubMenuItem("topbar","takers","New Taker","takers/create"),Menus.addSubMenuItem("topbar","takers","Take","takers/")}]),angular.module("takers").config(["$stateProvider",function($stateProvider){$stateProvider.state("listTakers",{url:"/takers",templateUrl:"modules/takers/views/take.html"}).state("createTaker",{url:"/takers/create",templateUrl:"modules/takers/views/create-taker.client.view.html"}).state("viewTaker",{url:"/takers/:takerId",templateUrl:"modules/takers/views/view-taker.client.view.html"}).state("editTaker",{url:"/takers/:takerId/edit",templateUrl:"modules/takers/views/edit-taker.client.view.html"})}]),angular.module("takers").controller("TakersController",["$scope","$stateParams","$location","Authentication","Articles",function($scope,$stateParams,$location,Authentication,Qas,Takers){$scope.authentication=Authentication;var taker=new Takers;$scope.taker=new Takers({quizNumber:"0",trialNumber:"0",trialOptions:"",results:[{questionViewed:!1,questionAnswered:!1,questionNumber:"",answer:[{selection:"0",answer:"0"}]}]}),console.log("From ScopeTaker",$scope.taker),$scope.find=function(){Qas.query(function(qas){$scope.qas=qas})},console.log("From ScopeTaker",$scope.qas),$scope.next=function(){$scope.questionIndex++,taker.questionViewed=!0,taker.$save(function(response){$location.path("takers/"+response._id)}),console.log("next",$scope.questionIndex)},$scope.prev=function(){$scope.questionIndex--,console.log("prev",$scope.questionIndex)},$scope.answerToggled=function(){console.log("toggledtaker",taker);for(var i=0,ln=taker.qa[$scope.questionIndex].choices.length;ln>i;i++)taker.results[$scope.questionIndex].answer.isSelected[i]=$scope.choice[i].selectedAnswer,taker.updated.push((new Date).getTime());console.log("From taker 1",taker),taker.$save(function(response){$location.path("takers/"+response._id)}),console.log(taker)},$scope.find=function(){Qas.query(function(qas){taker.qa=qas,$scope.taker=taker,console.log("From ScopeTaker1",qas[0].questionNumber,taker.qa[0].question,$scope.qas,taker)}),$scope.questionIndex=0},$scope.findOne=function(){takers.get({qasId:$stateParams.qasId},function(qas){$scope.taker=qas})}}]),angular.module("takers").factory("Takers",["$resource",function($resource){return $resource("takers/:takerId",{takerId:"@_id"},{update:{method:"PUT"}})}]),angular.module("users").config(["$httpProvider",function($httpProvider){$httpProvider.interceptors.push(["$q","$location","Authentication",function($q,$location,Authentication){return{responseError:function(rejection){switch(rejection.status){case 401:Authentication.user=null,$location.path("signin");break;case 403:}return $q.reject(rejection)}}}])}]),angular.module("users").config(["$stateProvider",function($stateProvider){$stateProvider.state("profile",{url:"/settings/profile",templateUrl:"modules/users/views/settings/edit-profile.client.view.html"}).state("password",{url:"/settings/password",templateUrl:"modules/users/views/settings/change-password.client.view.html"}).state("accounts",{url:"/settings/accounts",templateUrl:"modules/users/views/settings/social-accounts.client.view.html"}).state("signup",{url:"/signup",templateUrl:"modules/users/views/authentication/signup.client.view.html"}).state("signin",{url:"/signin",templateUrl:"modules/users/views/authentication/signin.client.view.html"}).state("forgot",{url:"/password/forgot",templateUrl:"modules/users/views/password/forgot-password.client.view.html"}).state("reset-invlaid",{url:"/password/reset/invalid",templateUrl:"modules/users/views/password/reset-password-invalid.client.view.html"}).state("reset-success",{url:"/password/reset/success",templateUrl:"modules/users/views/password/reset-password-success.client.view.html"}).state("reset",{url:"/password/reset/:token",templateUrl:"modules/users/views/password/reset-password.client.view.html"})}]),angular.module("users").controller("AuthenticationController",["$scope","$http","$location","Authentication",function($scope,$http,$location,Authentication){$scope.authentication=Authentication,$scope.authentication.user&&$location.path("/"),$scope.signup=function(){$http.post("/auth/signup",$scope.credentials).success(function(response){$scope.authentication.user=response,$location.path("/")}).error(function(response){$scope.error=response.message})},$scope.signin=function(){$http.post("/auth/signin",$scope.credentials).success(function(response){$scope.authentication.user=response,$location.path("/")}).error(function(response){$scope.error=response.message})}}]),angular.module("users").controller("PasswordController",["$scope","$stateParams","$http","$location","Authentication",function($scope,$stateParams,$http,$location,Authentication){$scope.authentication=Authentication,$scope.authentication.user&&$location.path("/"),$scope.askForPasswordReset=function(){$scope.success=$scope.error=null,$http.post("/auth/forgot",$scope.credentials).success(function(response){$scope.credentials=null,$scope.success=response.message}).error(function(response){$scope.credentials=null,$scope.error=response.message})},$scope.resetUserPassword=function(){$scope.success=$scope.error=null,$http.post("/auth/reset/"+$stateParams.token,$scope.passwordDetails).success(function(response){$scope.passwordDetails=null,Authentication.user=response,$location.path("/password/reset/success")}).error(function(response){$scope.error=response.message})}}]),angular.module("users").controller("SettingsController",["$scope","$http","$location","Users","Authentication",function($scope,$http,$location,Users,Authentication){$scope.user=Authentication.user,$scope.user||$location.path("/"),$scope.hasConnectedAdditionalSocialAccounts=function(){for(var i in $scope.user.additionalProvidersData)return!0;return!1},$scope.isConnectedSocialAccount=function(provider){return $scope.user.provider===provider||$scope.user.additionalProvidersData&&$scope.user.additionalProvidersData[provider]},$scope.removeUserSocialAccount=function(provider){$scope.success=$scope.error=null,$http.delete("/users/accounts",{params:{provider:provider}}).success(function(response){$scope.success=!0,$scope.user=Authentication.user=response}).error(function(response){$scope.error=response.message})},$scope.updateUserProfile=function(isValid){if(isValid){$scope.success=$scope.error=null;var user=new Users($scope.user);user.$update(function(response){$scope.success=!0,Authentication.user=response},function(response){$scope.error=response.data.message})}else $scope.submitted=!0},$scope.changeUserPassword=function(){$scope.success=$scope.error=null,$http.post("/users/password",$scope.passwordDetails).success(function(){$scope.success=!0,$scope.passwordDetails=null}).error(function(response){$scope.error=response.message})}}]),angular.module("users").factory("Authentication",[function(){var _this=this;return _this._data={user:window.user},_this._data}]),angular.module("users").factory("Users",["$resource",function($resource){return $resource("users",{},{update:{method:"PUT"}})}]); \ No newline at end of file diff --git a/public/modules/articles/controllers/articles.client.controller.js b/public/modules/articles/controllers/articles.client.controller.js index 364987eb9e..ee02cd230a 100644 --- a/public/modules/articles/controllers/articles.client.controller.js +++ b/public/modules/articles/controllers/articles.client.controller.js @@ -9,6 +9,7 @@ angular.module('articles').controller('ArticlesController', ['$scope', '$statePa title: this.title, content: this.content }); + // console.log(response); article.$save(function(response) { $location.path('articles/' + response._id); diff --git a/public/modules/articles/services/articles.client.service.js b/public/modules/articles/services/articles.client.service.js index deeb7da58c..59e7355f59 100644 --- a/public/modules/articles/services/articles.client.service.js +++ b/public/modules/articles/services/articles.client.service.js @@ -3,12 +3,9 @@ //Articles service used for communicating with the articles REST endpoints angular.module('articles').factory('Articles', ['$resource', function($resource) { - return $resource('articles/:articleId', { - articleId: '@_id' - }, { - update: { - method: 'PUT' - } + return $resource('articles/:articleId', {articleId: '@_id' + },{ + update: {method: 'PUT'} }); } ]); \ No newline at end of file diff --git a/public/modules/qas/config/qas.client.config.js b/public/modules/qas/config/qas.client.config.js new file mode 100644 index 0000000000..bfb1dc4731 --- /dev/null +++ b/public/modules/qas/config/qas.client.config.js @@ -0,0 +1,12 @@ +'use strict'; + +// Configuring the Articles module. +angular.module('qas').run(['Menus', + function(Menus) { + // Set top bar menu items + Menus.addMenuItem('topbar', 'Qas', 'qas', 'dropdown', '/qas(/create)?'); + Menus.addSubMenuItem('topbar', 'qas', 'List Qas', 'qas'); + Menus.addSubMenuItem('topbar', 'qas', 'New Qa', 'qas/create'); + Menus.addSubMenuItem('topbar', 'qas', 'List Quizzes', 'listQasQuizzes'); + } +]); \ No newline at end of file diff --git a/public/modules/qas/config/qas.client.routes.js b/public/modules/qas/config/qas.client.routes.js new file mode 100644 index 0000000000..c67c7a20dd --- /dev/null +++ b/public/modules/qas/config/qas.client.routes.js @@ -0,0 +1,29 @@ +'use strict'; + +//Setting up route... +angular.module('qas').config(['$stateProvider', + function($stateProvider) { + // Qas state routing + $stateProvider. + state('listQas', { + url: '/qas', + templateUrl: 'modules/qas/views/list-qas.client.view.html' + }). + state('createQa', { + url: '/qas/create', + templateUrl: 'modules/qas/views/create-qa.client.view.html' + }). + state('viewQa', { + url: '/qas/:qaId', + templateUrl: 'modules/qas/views/view-qa.client.view.html' + }). + state('editQa', { + url: '/qas/:qaId/edit', + templateUrl: 'modules/qas/views/edit-qa.client.view.html' + }). + state('listQasQuizzes', { + url: '/listQasQuizzes', + templateUrl: 'modules/qas/views/listquizzes-qas.client.view.html' + }); + } +]); \ No newline at end of file diff --git a/public/modules/qas/controllers/qas.client.controller.js b/public/modules/qas/controllers/qas.client.controller.js new file mode 100644 index 0000000000..8c2beccc5a --- /dev/null +++ b/public/modules/qas/controllers/qas.client.controller.js @@ -0,0 +1,185 @@ +'use strict'; + +// Qas controller... +angular.module('qas').controller('QasController', ['$scope','$rootScope','$modal', '$stateParams', '$location', 'Authentication', + 'Qas','Quizzes', 'CalculatorService', 'MathService', 'qasInitService', + function ($scope, $rootScope, $modal, $stateParams, $location, Authentication, Qas,Quizzes, CalculatorService, MathService, qasInitService) { + $scope.authentication = Authentication; +//Test of Calculator and Math Service + $scope.doit = CalculatorService.cce(77); + +// Initialize Dropdown labels + $scope.typeDropdown = qasInitService.typeDropdown(); + $scope.difficultyDropdown = qasInitService.difficultyDropdown(); + + var selectedQuiz = qasInitService.getSelectedQuiz(); + //console.log('call to qasServiceQuiz',fixedQuiz); + + $scope.qa = qasInitService.init(); +// Create and validate qa entries + $scope.create = function () { + var quiz = new Quizzes(); + quiz.qa = new Qas({ + question: this.question, + imageURL: this.imageURL, + choices: [ + {text: this.text, selectedAnswer: false //doesn't work + }, + {text: this.text, selectedAnswer: this.correctAnswer //doesn't work + }, + {text: this.text, selectedAnswer: this.correctAnswer //doesn't work + } + ], + hint: this.hint, + type: this.td, //doesn't work + difficulty: this.difficulty, //doesn't work + hintOn: this.hintOn, + timeOn: this.timeOn, + fifty50On: this.fifty50On, + randomizeQuestionsOn: this.randomizeQuestionsOn, + randomizeAnswersOn: this.randomizeAnswersOn, + questionNumber: this.questionNumber + }); + +// Hack to load these variables. Not handled above??? + quiz.qa.choices = $scope.qa.choices; + // quiz.qa.difficulty = $scope.quiz.dd.label; + // quiz.qa.type = $scope.quiz.td.label; + quiz.qa.qaQuizName = selectedQuiz[0]; + quiz.qa.qaQuizId = selectedQuiz[1]; + // Check that question was entered + if (quiz.qa.question.length > 0) { + var choiceCount = 0; + //Loop through choices to get at least two + console.log('qa if', quiz.qa,qa); + for (var i = 0, ln = quiz.qa.choices.length; i < ln; i++) { + var choice = quiz.qa.choices[i].text; + console.log('choice', choice, " i", i); + if (choice.length > 0) { + choiceCount++; + } + } + if (choiceCount > 1) { + // Call API to save to database + + + } else { + alert('You must have at least two choices'); + } + } else { + alert('You must have a question'); + } + console.log('qaFinal', quiz,qa); + qa.$save(function (response) { + $location.path('qas/' + response._id) + }); + }; + + // Method to add an additional choice option + $scope.addChoice = function () { + console.log('qa add', $scope.qa); + $scope.qa.choices.push({ text: this.text, selectedAnswer: false }); + }; + + $scope.remove = function (qa) { + if (qa) { + qa.$remove(); + + for (var i in $scope.qas) { + if ($scope.qas[i] === qa) { + $scope.qas.splice(i, 1); + } + } + } else { + $scope.qa.$remove(function () { + $location.path('qas'); + }); + } + }; + + $scope.update = function () { + var qa = $scope.qa; + console.log('From update', qa); + if (!qa.updated) { + qa.updated = []; + } + qa.updated.push(new Date().getTime()); + + qa.$update(function () { + $location.path('qas/' + qa._id); + }); + }; + + $scope.find = function () { + Qas.query(function (qas) { + $scope.qas = qas; + }); + }; + + $scope.findQuizzes = function () { + Quizzes.query(function (quizzes) { + $scope.quizzes = quizzes; + }); + }; + $scope.findOne = function () { + Qas.get({ + qaId: $stateParams.qaId + }, function (qa) { + $scope.qa = qa; + }); + }; + $scope.findQuizzesOne = function (quiz) { + // $scope.quiz = quiz; + var data = [quiz.name,quiz._id]; + qasInitService.saveSelectedQuiz(data); + + + $rootScope.qname = quiz.name; + console.log($rootScope.qname); + }; + + $scope.deleteChoice = function (ev) { + var ss = ev.target.innerText.toString() - 1; + console.log(ss); + var qa = $scope.qa; + console.log(qa); + $scope.qa.choices.splice(ss, 1); + }; +// $scope.saveToOtherQuiz = function(){ +// var modalInstance = $modal.open({ +// templateUrl: 'modules/qas/views/modal-qa.client.html', +// controller: ModalInstanceCtrl, +// resolve: { +// items: function () { +// return $scope.items; +// } +// } +// }); +// +// modalInstance.result.then(function (selectedItem) { +// $scope.selected = selectedItem; +// +// }, function () { +// console.log('Modal dismissed at: ' + new Date()); +// }); +// }; +// var ModalInstanceCtrl = function ($scope, $modalInstance, Quizzes) { +// +// Quizzes.query(function(quizzes){ +// $scope.quizzes = quizzes; +// }); +// $scope.selected = { +// // quizzes: $scope.quizzes[0] +// }; +// +// $scope.ok = function () { +// $modalInstance.close($scope.selected.item); +// }; +// +// $scope.cancel = function () { +// $modalInstance.dismiss('cancel'); +// }; +// }; + } +]); + diff --git a/public/modules/qas/qas.client.module.js b/public/modules/qas/qas.client.module.js new file mode 100644 index 0000000000..abf27a7ec1 --- /dev/null +++ b/public/modules/qas/qas.client.module.js @@ -0,0 +1,4 @@ +'use strict'; + +// Use application configuration module to register a new module +ApplicationConfiguration.registerModule('qas'); \ No newline at end of file diff --git a/public/modules/qas/services/qas.client.service.js b/public/modules/qas/services/qas.client.service.js new file mode 100644 index 0000000000..a1d2e6bdee --- /dev/null +++ b/public/modules/qas/services/qas.client.service.js @@ -0,0 +1,11 @@ +'use strict'; + +//Qas service used to communicate Qas REST endpoints +angular.module('qas').factory('Qas', ['$resource', + function($resource) { + return $resource('qas/:qaId', { qaId: '@_id' + }, { + update: {method: 'PUT'} + }); + } +]); \ No newline at end of file diff --git a/public/modules/qas/services/qas.client.service1.js b/public/modules/qas/services/qas.client.service1.js new file mode 100644 index 0000000000..85e2309417 --- /dev/null +++ b/public/modules/qas/services/qas.client.service1.js @@ -0,0 +1,22 @@ +/** + * Created by EbyC on 8/24/2014. + */ +'use strict'; + +angular.module('qas') + .service('MathService', [ function() { + + this.add = function(a, b) { return a + b }; + this.subtract = function(a, b) { return a - b }; + this.multiply = function(a, b) { return a * b }; + this.divide = function(a, b) { return a / b }; + }]) + + .service('CalculatorService', function(MathService){ + + this.square = function(a) { return MathService.multiply(a,a); }; + this.cce = function(a) {return a+a*1000}; + this.cube = function(a) { return MathService.multiply(a, MathService.multiply(a,a)); }; + + }); + diff --git a/public/modules/qas/services/qas.client.service2.js b/public/modules/qas/services/qas.client.service2.js new file mode 100644 index 0000000000..44e7264bc9 --- /dev/null +++ b/public/modules/qas/services/qas.client.service2.js @@ -0,0 +1,70 @@ +/** + * Created by EbyC on 8/24/2014. + */ +'use strict'; + +//Qas service used to communicate Qas REST endpoints +angular.module('qas') + .service('qasInitService', [ function () { + var data; + this.saveSelectedQuiz = function (item){ + data = item + //console.log("service data",data); + return; + }; + this.getSelectedQuiz = function () { + return data; + }; + + this.typeDropdown = function () { + return [ + { + 'label': 'FIB', + 'value': 1 + }, + { + 'label': 'TF', + 'value': 2 + }, + { + 'label': 'MC', + 'value': 3 + }, + { + 'label': 'Matching', + 'value': 4 + } + ]; + }; + this.difficultyDropdown = function () { + return [ + { + 'label': 'Easy', + 'value': 1 + }, + { + 'label': 'Medium', + 'value': 2 + }, + { + 'label': 'Hard', + 'value': 3 + }, + { + 'label': 'Impossible', + 'value': 4 + } + ]; + }; + + this.init = function () { + return ({ + choices: [ + { text: '', correctAnswer: false }, + { text: '', correctAnswer: false}, + { text: '', correctAnswer: false} + ] + }); + } + + }]); diff --git a/public/modules/qas/tests/qas.client.controller.test.js b/public/modules/qas/tests/qas.client.controller.test.js new file mode 100644 index 0000000000..e841df9621 --- /dev/null +++ b/public/modules/qas/tests/qas.client.controller.test.js @@ -0,0 +1,163 @@ +'use strict'; + +(function() { + // Qas Controller Spec + describe('Qas Controller Tests', function() { + // Initialize global variables + var QasController, + scope, + $httpBackend, + $stateParams, + $location; + + // The $resource service augments the response object with methods for updating and deleting the resource. + // If we were to use the standard toEqual matcher, our tests would fail because the test values would not match + // the responses exactly. To solve the problem, we define a new toEqualData Jasmine matcher. + // When the toEqualData matcher compares two objects, it takes only object properties into + // account and ignores methods. + beforeEach(function() { + jasmine.addMatchers({ + toEqualData: function(util, customEqualityTesters) { + return { + compare: function(actual, expected) { + return { + pass: angular.equals(actual, expected) + }; + } + }; + } + }); + }); + + // Then we can start by loading the main application module + beforeEach(module(ApplicationConfiguration.applicationModuleName)); + + // The injector ignores leading and trailing underscores here (i.e. _$httpBackend_). + // This allows us to inject a service but then attach it to a variable + // with the same name as the service. + beforeEach(inject(function($controller, $rootScope, _$location_, _$stateParams_, _$httpBackend_) { + // Set a new global scope + scope = $rootScope.$new(); + + // Point global variables to injected services + $stateParams = _$stateParams_; + $httpBackend = _$httpBackend_; + $location = _$location_; + + // Initialize the Qas controller. + QasController = $controller('QasController', { + $scope: scope + }); + })); + + it('$scope.find() should create an array with at least one Qa object fetched from XHR', inject(function(Qas) { + // Create sample Qa using the Qas service + var sampleQa = new Qas({ + name: 'New Qa' + }); + + // Create a sample Qas array that includes the new Qa + var sampleQas = [sampleQa]; + + // Set GET response + $httpBackend.expectGET('qas').respond(sampleQas); + + // Run controller functionality + scope.find(); + $httpBackend.flush(); + + // Test scope value + expect(scope.qas).toEqualData(sampleQas); + })); + + it('$scope.findOne() should create an array with one Qa object fetched from XHR using a qaId URL parameter', inject(function(Qas) { + // Define a sample Qa object + var sampleQa = new Qas({ + name: 'New Qa' + }); + + // Set the URL parameter + $stateParams.qaId = '525a8422f6d0f87f0e407a33'; + + // Set GET response + $httpBackend.expectGET(/qas\/([0-9a-fA-F]{24})$/).respond(sampleQa); + + // Run controller functionality + scope.findOne(); + $httpBackend.flush(); + + // Test scope value + expect(scope.qa).toEqualData(sampleQa); + })); + + it('$scope.create() with valid form data should send a POST request with the form input values and then locate to new object URL', inject(function(Qas) { + // Create a sample Qa object + var sampleQaPostData = new Qas({ + name: 'New Qa' + }); + + // Create a sample Qa response + var sampleQaResponse = new Qas({ + _id: '525cf20451979dea2c000001', + name: 'New Qa' + }); + + // Fixture mock form input values + scope.name = 'New Qa'; + + // Set POST response + $httpBackend.expectPOST('qas', sampleQaPostData).respond(sampleQaResponse); + + // Run controller functionality + scope.create(); + $httpBackend.flush(); + + // Test form inputs are reset + expect(scope.name).toEqual(''); + + // Test URL redirection after the Qa was created + expect($location.path()).toBe('/qas/' + sampleQaResponse._id); + })); + + it('$scope.update() should update a valid Qa', inject(function(Qas) { + // Define a sample Qa put data + var sampleQaPutData = new Qas({ + _id: '525cf20451979dea2c000001', + name: 'New Qa' + }); + + // Mock Qa in scope + scope.qa = sampleQaPutData; + + // Set PUT response + $httpBackend.expectPUT(/qas\/([0-9a-fA-F]{24})$/).respond(); + + // Run controller functionality + scope.update(); + $httpBackend.flush(); + + // Test URL location to new object + expect($location.path()).toBe('/qas/' + sampleQaPutData._id); + })); + + it('$scope.remove() should send a DELETE request with a valid qaId and remove the Qa from the scope', inject(function(Qas) { + // Create new Qa object + var sampleQa = new Qas({ + _id: '525a8422f6d0f87f0e407a33' + }); + + // Create new Qas array and include the Qa + scope.qas = [sampleQa]; + + // Set expected DELETE response + $httpBackend.expectDELETE(/qas\/([0-9a-fA-F]{24})$/).respond(204); + + // Run controller functionality + scope.remove(sampleQa); + $httpBackend.flush(); + + // Test array after successful delete + expect(scope.qas.length).toBe(0); + })); + }); +}()); \ No newline at end of file diff --git a/public/modules/qas/views/create-qa.client.view.html b/public/modules/qas/views/create-qa.client.view.html new file mode 100644 index 0000000000..c893f47963 --- /dev/null +++ b/public/modules/qas/views/create-qa.client.view.html @@ -0,0 +1,115 @@ +
+ + + {{qd.label}} + {{td.label}} + {{dd.label}} +
+
+ +
+
+ + +
+ +
+ + + +
+ + + +
+ +
+
+ +
+
+ +
+
+
+ +
+
+
+
+ + +
+ +
+ +
+
+ +
+
+ +
+ +
+
+ + + +
+ + +
+ Allow Hint + Timed + 50/50 + Randomize Answers + Randomize Questions + + +
+ +
+
+
+ +
+
+
diff --git a/public/modules/qas/views/edit-qa.client.view.html b/public/modules/qas/views/edit-qa.client.view.html new file mode 100644 index 0000000000..aec514799d --- /dev/null +++ b/public/modules/qas/views/edit-qa.client.view.html @@ -0,0 +1,101 @@ +
+ +
+
+
+ + +
+ +
+
+
+ + +
+ + + +
+ + + + +
+ + + +
+ + +
+
+ + +
+ +
+
+ +
+
+ + +
+ +
+
+
+
+
+
+
+
+
+ + + + + + +
+ Allow Hint + Timed + 50/50 + Randomize Answers + Randomize Questions + + + + + + +
+ +
+ +
+
+
+ +
+
diff --git a/public/modules/qas/views/list-qas.client.view.html b/public/modules/qas/views/list-qas.client.view.html new file mode 100644 index 0000000000..d67573fe96 --- /dev/null +++ b/public/modules/qas/views/list-qas.client.view.html @@ -0,0 +1,21 @@ +
+ +
+ + {{qa.created | date:'medium'}} / {{qa.user.displayName}} + / {{qa.qaQuizName}} / {{qa.qaQuizId}} +

{{qa.question}}

+ +

{{qa.choices.length}}

+

{{doit}}

+ +
+ +
+
+ No qas yet, why don't you create one? +
+
diff --git a/public/modules/qas/views/listquizzes-qas.client.view.html b/public/modules/qas/views/listquizzes-qas.client.view.html new file mode 100644 index 0000000000..2146f2da93 --- /dev/null +++ b/public/modules/qas/views/listquizzes-qas.client.view.html @@ -0,0 +1,20 @@ +
+ +
+ +
+ {{quiz.created | date:'medium'}} / {{quiz.user.displayName}} +

{{quiz.name}} + select

+ + +
+ +
+
+ No quiz yet, why don't you create one? +
+
diff --git a/public/modules/qas/views/modal-qa.client.html b/public/modules/qas/views/modal-qa.client.html new file mode 100644 index 0000000000..b2adb5c5d7 --- /dev/null +++ b/public/modules/qas/views/modal-qa.client.html @@ -0,0 +1,14 @@ + + + + diff --git a/public/modules/qas/views/view-qa.client.view.html b/public/modules/qas/views/view-qa.client.view.html new file mode 100644 index 0000000000..7414cce405 --- /dev/null +++ b/public/modules/qas/views/view-qa.client.view.html @@ -0,0 +1,30 @@ +
+ + +
+ + + + + + +
+ + Updated on:{{qa.created | date:'mediumDate'}} by {{qa.user.displayName}} + + + + Quiz name and Id {{quiz.name}} - {{quiz.Id}} + +

+ {{qa.question}} +
+ +

{{choices.text}}
+
{{qa.user.displayName}}
+
{{quiz.name}}
+

+ +
\ No newline at end of file diff --git a/public/modules/quizzes/config/quizzes.client.config.js b/public/modules/quizzes/config/quizzes.client.config.js new file mode 100644 index 0000000000..4985dce2c1 --- /dev/null +++ b/public/modules/quizzes/config/quizzes.client.config.js @@ -0,0 +1,12 @@ +'use strict'; + +// Configuring the Articles module +angular.module('quizzes').run(['Menus', + function(Menus) { + // Set top bar menu items + Menus.addMenuItem('topbar', 'Quizzes', 'quizzes', 'dropdown', '/quizzes(/create)?'); + Menus.addSubMenuItem('topbar', 'quizzes', 'List Quizzes', 'quizzes'); + Menus.addSubMenuItem('topbar', 'quizzes', 'Create Quiz', 'quizzes/create'); + + } +]); diff --git a/public/modules/quizzes/config/quizzes.client.routes.js b/public/modules/quizzes/config/quizzes.client.routes.js new file mode 100644 index 0000000000..ffeb5e3ef9 --- /dev/null +++ b/public/modules/quizzes/config/quizzes.client.routes.js @@ -0,0 +1,25 @@ +'use strict'; + +//Setting up route +angular.module('quizzes').config(['$stateProvider', + function($stateProvider) { + // Quizzes state routing + $stateProvider. + state('listQuizzes', { + url: '/quizzes', + templateUrl: 'modules/quizzes/views/list-quizzes.client.view.html' + }). + state('createQuiz', { + url: '/quizzes/create', + templateUrl: 'modules/quizzes/views/create-quiz.client.view.html' + }). + state('viewQuiz', { + url: '/quizzes/:quizId', + templateUrl: 'modules/quizzes/views/view-quiz.client.view.html' + }). + state('editQuiz', { + url: '/quizzes/:quizId/edit', + templateUrl: 'modules/quizzes/views/edit-quiz.client.view.html' + }); + } +]); \ No newline at end of file diff --git a/public/modules/quizzes/controllers/quizzes.client.controller.js b/public/modules/quizzes/controllers/quizzes.client.controller.js new file mode 100644 index 0000000000..ae7bb486b7 --- /dev/null +++ b/public/modules/quizzes/controllers/quizzes.client.controller.js @@ -0,0 +1,137 @@ +'use strict'; + +// Quizzes controller +angular.module('quizzes').controller('QuizzesController', ['$scope', '$stateParams', '$location', + 'Authentication', 'Quizzes','Qas','qasInitService', + function($scope, $stateParams, $location, Authentication, Quizzes,Qas, qasInitService ) { + $scope.authentication = Authentication; + $scope.difficultyDropdown = qasInitService.difficultyDropdown(); + // Create new Quiz + $scope.create = function() { + // Create new Quiz object + var quiz = new Quizzes ({ + name: this.name, + category: this.category, + keyWords: this.keyWords, + quizNumber: this.quizNumber, + hintOn: this.hintOn, + timeOn: this.timeOn, + + randomizeQuestionsOn: this.randomizeQuestionsOn, + randomizeAnswersOn: this.randomizeAnswersOn + }); + + // Redirect after save + quiz.$save(function(response) { + $location.path('quizzes/' + response._id); + }, function(errorResponse) { + $scope.error = errorResponse.data.message; + }); + console.log(quiz); + // Clear form fields + this.name = ''; + this.keyWords = ''; + this.category = ''; + this.quizNumber = ''; + this.hintOn = ""; + this.timeOn = ""; + this.fifty50On = ""; + this.randomizeQuestionsOn = ""; + this.randomizeAnswersOn = ""; + }; + + // Remove existing Quiz + $scope.remove = function( quiz ) { + if ( quiz ) { quiz.$remove(); + + for (var i in $scope.quizzes ) { + if ($scope.quizzes [i] === quiz ) { + $scope.quizzes.splice(i, 1); + } + } + } else { + $scope.quiz.$remove(function() { + $location.path('quizzes'); + }); + } + }; + + // Update existing Quiz + $scope.update = function() { + + var qas = $scope.qas ; + var quiz= $scope.quiz; + var index = 0; + angular.forEach(qas, function(qa){ + if(qa.selected){ + qa.qaQuizName = 'no go it'; + quiz.qa[index]=(qa); + index++; + console.log('from ang.forEach', quiz.qa); + } + console.log('From update', qa); + + if (!qa.updated) { + qa.updated = []; + } + qa.updated.push(new Date().getTime()); + + qa.$update(function () { + $location.path('qas/' + qa._id); + }); + }); + + //quiz.qa= angular.copy(qas); + + console.log('quiz',quiz,quiz.qa); + + quiz.$update(function() { + $location.path('quizzes/' + quiz._id); + }, function(errorResponse) { + $scope.error = errorResponse.data.message; + }); + }; + + // Find a list of Quizzes + $scope.find = function() { + $scope.quizzes = Quizzes.query(); + }; + + // Find a list of Questions + $scope.findQas = function() { + $scope.qas = Qas.query(); + }; + + // Find existing Quiz + $scope.findOne = function() { + var quiz; + var qas = Qas.query(); + quiz = Quizzes.get({ + quizId: $stateParams.quizId + }); + $scope.quiz = quiz; + $scope.qas = qas; + + //if (qas.choices[0].selectedAnswer) + //{ + // $scope.qas.sAnswer[0]=qas[0].choices[0].text + //}; + $scope.todos =qas; + //[ + // {text:'learn angular', done:true, a:[1,2]}, + // {text:'build an angular app', done:false, a:[3,2]}]; + + console.log('todo',qas,Object.keys($scope.todos).length,$scope.todos); + var oldTodos = $scope.todos; + $scope.todos = []; + angular.forEach(oldTodos, function(todo) { + $scope.todos.push(todo); + }); + + console.log($scope.todos); + + + console.log("from quuizctrl.findOne",$scope.quiz,$scope.qas); + }; + } +]); diff --git a/public/modules/quizzes/quizzes.client.module.js b/public/modules/quizzes/quizzes.client.module.js new file mode 100644 index 0000000000..81eedf8b04 --- /dev/null +++ b/public/modules/quizzes/quizzes.client.module.js @@ -0,0 +1,4 @@ +'use strict'; + +// Use applicaion configuration module to register a new module +ApplicationConfiguration.registerModule('quizzes'); \ No newline at end of file diff --git a/public/modules/quizzes/services/quizzes.client.service.js b/public/modules/quizzes/services/quizzes.client.service.js new file mode 100644 index 0000000000..3740607cd7 --- /dev/null +++ b/public/modules/quizzes/services/quizzes.client.service.js @@ -0,0 +1,13 @@ +'use strict'; + +//Quizzes service used to communicate Quizzes REST endpoints +angular.module('quizzes').factory('Quizzes', ['$resource', + function($resource) { + return $resource('quizzes/:quizId', { quizId: '@_id' + }, { + update: { + method: 'PUT' + } + }); + } +]); \ No newline at end of file diff --git a/public/modules/quizzes/tests/quizzes.client.controller.test.js b/public/modules/quizzes/tests/quizzes.client.controller.test.js new file mode 100644 index 0000000000..268001b8c5 --- /dev/null +++ b/public/modules/quizzes/tests/quizzes.client.controller.test.js @@ -0,0 +1,163 @@ +'use strict'; + +(function() { + // Quizzes Controller Spec + describe('Quizzes Controller Tests', function() { + // Initialize global variables + var QuizzesController, + scope, + $httpBackend, + $stateParams, + $location; + + // The $resource service augments the response object with methods for updating and deleting the resource. + // If we were to use the standard toEqual matcher, our tests would fail because the test values would not match + // the responses exactly. To solve the problem, we define a new toEqualData Jasmine matcher. + // When the toEqualData matcher compares two objects, it takes only object properties into + // account and ignores methods. + beforeEach(function() { + jasmine.addMatchers({ + toEqualData: function(util, customEqualityTesters) { + return { + compare: function(actual, expected) { + return { + pass: angular.equals(actual, expected) + }; + } + }; + } + }); + }); + + // Then we can start by loading the main application module + beforeEach(module(ApplicationConfiguration.applicationModuleName)); + + // The injector ignores leading and trailing underscores here (i.e. _$httpBackend_). + // This allows us to inject a service but then attach it to a variable + // with the same name as the service. + beforeEach(inject(function($controller, $rootScope, _$location_, _$stateParams_, _$httpBackend_) { + // Set a new global scope + scope = $rootScope.$new(); + + // Point global variables to injected services + $stateParams = _$stateParams_; + $httpBackend = _$httpBackend_; + $location = _$location_; + + // Initialize the Quizzes controller. + QuizzesController = $controller('QuizzesController', { + $scope: scope + }); + })); + + it('$scope.find() should create an array with at least one Quiz object fetched from XHR', inject(function(Quizzes) { + // Create sample Quiz using the Quizzes service + var sampleQuiz = new Quizzes({ + name: 'New Quiz' + }); + + // Create a sample Quizzes array that includes the new Quiz + var sampleQuizzes = [sampleQuiz]; + + // Set GET response + $httpBackend.expectGET('quizzes').respond(sampleQuizzes); + + // Run controller functionality + scope.find(); + $httpBackend.flush(); + + // Test scope value + expect(scope.quizzes).toEqualData(sampleQuizzes); + })); + + it('$scope.findOne() should create an array with one Quiz object fetched from XHR using a quizId URL parameter', inject(function(Quizzes) { + // Define a sample Quiz object + var sampleQuiz = new Quizzes({ + name: 'New Quiz' + }); + + // Set the URL parameter + $stateParams.quizId = '525a8422f6d0f87f0e407a33'; + + // Set GET response + $httpBackend.expectGET(/quizzes\/([0-9a-fA-F]{24})$/).respond(sampleQuiz); + + // Run controller functionality + scope.findOne(); + $httpBackend.flush(); + + // Test scope value + expect(scope.quiz).toEqualData(sampleQuiz); + })); + + it('$scope.create() with valid form data should send a POST request with the form input values and then locate to new object URL', inject(function(Quizzes) { + // Create a sample Quiz object + var sampleQuizPostData = new Quizzes({ + name: 'New Quiz' + }); + + // Create a sample Quiz response + var sampleQuizResponse = new Quizzes({ + _id: '525cf20451979dea2c000001', + name: 'New Quiz' + }); + + // Fixture mock form input values + scope.name = 'New Quiz'; + + // Set POST response + $httpBackend.expectPOST('quizzes', sampleQuizPostData).respond(sampleQuizResponse); + + // Run controller functionality + scope.create(); + $httpBackend.flush(); + + // Test form inputs are reset + expect(scope.name).toEqual(''); + + // Test URL redirection after the Quiz was created + expect($location.path()).toBe('/quizzes/' + sampleQuizResponse._id); + })); + + it('$scope.update() should update a valid Quiz', inject(function(Quizzes) { + // Define a sample Quiz put data + var sampleQuizPutData = new Quizzes({ + _id: '525cf20451979dea2c000001', + name: 'New Quiz' + }); + + // Mock Quiz in scope + scope.quiz = sampleQuizPutData; + + // Set PUT response + $httpBackend.expectPUT(/quizzes\/([0-9a-fA-F]{24})$/).respond(); + + // Run controller functionality + scope.update(); + $httpBackend.flush(); + + // Test URL location to new object + expect($location.path()).toBe('/quizzes/' + sampleQuizPutData._id); + })); + + it('$scope.remove() should send a DELETE request with a valid quizId and remove the Quiz from the scope', inject(function(Quizzes) { + // Create new Quiz object + var sampleQuiz = new Quizzes({ + _id: '525a8422f6d0f87f0e407a33' + }); + + // Create new Quizzes array and include the Quiz + scope.quizzes = [sampleQuiz]; + + // Set expected DELETE response + $httpBackend.expectDELETE(/quizzes\/([0-9a-fA-F]{24})$/).respond(204); + + // Run controller functionality + scope.remove(sampleQuiz); + $httpBackend.flush(); + + // Test array after successful delete + expect(scope.quizzes.length).toBe(0); + })); + }); +}()); \ No newline at end of file diff --git a/public/modules/quizzes/views/create-quiz.client.view.html b/public/modules/quizzes/views/create-quiz.client.view.html new file mode 100644 index 0000000000..e9c5ceac04 --- /dev/null +++ b/public/modules/quizzes/views/create-quiz.client.view.html @@ -0,0 +1,42 @@ +
+ +
+
+
+
+ +
+ +

+ +

+ +

+ + +
+
+
+
+ {{dd.label}} + Allow Hint + Timed
+ 50/50 + Randomize Answers
+ Randomize Questions +
+ +
+ +
+
+ +
+
+
+
+
diff --git a/public/modules/quizzes/views/edit-quiz.client.view.html b/public/modules/quizzes/views/edit-quiz.client.view.html new file mode 100644 index 0000000000..c1d920e7d9 --- /dev/null +++ b/public/modules/quizzes/views/edit-quiz.client.view.html @@ -0,0 +1,48 @@ +
+ +
+
+
+ +
+ +
+ + + + + + + +
+
+
+ {{dd.label}} + Allow Hint + Timed
+ 50/50 + Randomize Answers
+ Randomize Questions +
+ +
+
+ +
+ + +
+ + + + {{qa.question}} {{qa.user.displayName}} +
+ +
+
+
+
diff --git a/public/modules/quizzes/views/list-quizzes.client.view.html b/public/modules/quizzes/views/list-quizzes.client.view.html new file mode 100644 index 0000000000..9ae90d2c87 --- /dev/null +++ b/public/modules/quizzes/views/list-quizzes.client.view.html @@ -0,0 +1,19 @@ +
+ +
+ + + Posted on + + by + + +

+
+
+
+ No Quizzes yet, why don't you create one? +
+
\ No newline at end of file diff --git a/public/modules/quizzes/views/view-quiz.client.view.html b/public/modules/quizzes/views/view-quiz.client.view.html new file mode 100644 index 0000000000..1696a97c67 --- /dev/null +++ b/public/modules/quizzes/views/view-quiz.client.view.html @@ -0,0 +1,21 @@ +
+ +
+ + + + + + +
+ + + Posted on + + by + + + +
\ No newline at end of file diff --git a/public/modules/takers/config/takers.client.config.js b/public/modules/takers/config/takers.client.config.js new file mode 100644 index 0000000000..41f1396998 --- /dev/null +++ b/public/modules/takers/config/takers.client.config.js @@ -0,0 +1,13 @@ +'use strict'; + +// Configuring the Takers module +angular.module('takers').run(['Menus', + function(Menus) { + // Set top bar menu items + Menus.addMenuItem('topbar', 'Takers', 'takers', 'dropdown', '/takers(/create)?'); + Menus.addSubMenuItem('topbar', 'takers', 'List Takers', 'takers'); + Menus.addSubMenuItem('topbar', 'takers', 'New Taker', 'takers/create'); + Menus.addSubMenuItem('topbar', 'takers', 'Take', 'takers/'); + Menus.addSubMenuItem('topbar', 'takers', 'List Quizzes', 'listTakersQuizzes'); + } +]); diff --git a/public/modules/takers/config/takers.client.routes.js b/public/modules/takers/config/takers.client.routes.js new file mode 100644 index 0000000000..185608b587 --- /dev/null +++ b/public/modules/takers/config/takers.client.routes.js @@ -0,0 +1,37 @@ +'use strict'; + +//Setting up route +angular.module('takers').config(['$stateProvider', + function($stateProvider) { + // Takers state routing + $stateProvider. + state('listTakers', { + url: '/takers', + templateUrl: 'modules/takers/views/take.html' + }). + + state('takers', { + url: '/takers', + templateUrl: 'modules/takers/views/take.html' + }). + + state('createTaker', { + url: '/takers/create', + templateUrl: 'modules/takers/views/create-taker.client.view.html' + }). + + state('viewTaker', { + url: '/takers/:takerId', + templateUrl: 'modules/takers/views/view-taker.client.view.html' + }). + state('editTaker', { + url: '/takers/:takerId/edit', + templateUrl: 'modules/takers/views/edit-taker.client.view.html' + }). + state('listTakersQuizzes', { + url: '/listTakersQuizzes', + templateUrl: 'modules/takers/views/listquizzes-takers.client.view.html' + }); + + } +]); diff --git a/public/modules/takers/controllers/takers.client.controller.js b/public/modules/takers/controllers/takers.client.controller.js new file mode 100644 index 0000000000..00c150f02a --- /dev/null +++ b/public/modules/takers/controllers/takers.client.controller.js @@ -0,0 +1,80 @@ +'use strict'; + +angular.module('takers').controller('TakersController', ['$scope', '$stateParams', '$location', 'Authentication', 'Qas', 'Quizzes','Takers', + function($scope, $stateParams, $location, Authentication, Qas, Quizzes, Takers) { + $scope.authentication = Authentication; + // Takers controller logic + + $scope.taker = new Takers({ + quizNumber: '0', + trialNumber: '0', + trialOptions: '', + results: [{ questionViewed: false, questionAnswered: false, + questionNumber: '', answer:[{selection: '0', answer: '0'}]}] + + }); + console.log('From ScopeTaker', $scope.taker); + //$scope.find = function() { + // Takers.query(function(qas) { + // $scope.qas = qas; + // $scope.taker.qa = qas; + // + // + // }); + //}; + // console.log('From ScopeTaker', $scope.qas); + // Create and validate taker entries + $scope.next = function () { + + $scope.questionIndex++; + taker.questionViewed = true; + taker.$save(function (response) { + $location.path('takers/' + response._id); + }); + console.log('next', $scope.questionIndex); + + }; + $scope.prev = function() { + $scope.questionIndex--; + console.log('prev',$scope.questionIndex); + }; + + $scope.answerToggled = function() { + //var taker = $scope.taker; + ////Grab data from input boxes + // + //console.log(taker); + //taker.qa.question = qas[questionIndex].question; + //taker.questionNumber = $scope.questionNumber; + //console.log('toggledtaker',taker); + //for (var i=0, ln = taker.qa[$scope.questionIndex].choices.length; i + +
+
+
+
+ +
+ +
+
+
+ +
+
+ +
+
+
+
+ \ No newline at end of file diff --git a/public/modules/takers/views/edit-taker.client.view.html b/public/modules/takers/views/edit-taker.client.view.html new file mode 100644 index 0000000000..a7bbbad0ea --- /dev/null +++ b/public/modules/takers/views/edit-taker.client.view.html @@ -0,0 +1,23 @@ +
+ +
+
+
+
+ +
+ +
+
+
+ +
+
+ +
+
+
+
+
\ No newline at end of file diff --git a/public/modules/takers/views/list-takers.client.view.html b/public/modules/takers/views/list-takers.client.view.html new file mode 100644 index 0000000000..a0d59302c8 --- /dev/null +++ b/public/modules/takers/views/list-takers.client.view.html @@ -0,0 +1,19 @@ +
+ + +
+ No Takers yet, why don't you create one? +
+
\ No newline at end of file diff --git a/public/modules/takers/views/listquizzes-takers.client.view.html b/public/modules/takers/views/listquizzes-takers.client.view.html new file mode 100644 index 0000000000..ee282c729e --- /dev/null +++ b/public/modules/takers/views/listquizzes-takers.client.view.html @@ -0,0 +1,20 @@ +
+ +
+ +
+ {{quiz.created | date:'medium'}} / {{quiz.user.displayName}} +

{{quiz.name}} + select

+ + +
+ +
+
+ No quiz yet, why don't you create one? +
+
diff --git a/public/modules/takers/views/take.html b/public/modules/takers/views/take.html new file mode 100644 index 0000000000..f457222cf1 --- /dev/null +++ b/public/modules/takers/views/take.html @@ -0,0 +1,62 @@ +
+ +
+
+ +
+ + + + +
+ +
+
+ +
+ +
+ + + +
+
+
+ +
+ +
+
+ +
+ +
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+ + + + + + +
+
+ +
+ + diff --git a/public/modules/takers/views/view-taker.client.view.html b/public/modules/takers/views/view-taker.client.view.html new file mode 100644 index 0000000000..a3c84f1acc --- /dev/null +++ b/public/modules/takers/views/view-taker.client.view.html @@ -0,0 +1,21 @@ +
+ + + + + Posted on + + by + + + +
\ No newline at end of file diff --git a/server.js b/server.js index e13d20d72b..91e5c75bac 100755 --- a/server.js +++ b/server.js @@ -12,13 +12,21 @@ var init = require('./config/init')(), */ // Bootstrap db connection -var db = mongoose.connect(config.db, function(err) { - if (err) { - console.error('\x1b[31m', 'Could not connect to MongoDB!'); - console.log(err); - } +var db = mongoose.connect('mongodb://cce:cce@ds039860.mongolab.com:39860/meandb', function(err) { + if (err) { + console.error('\x1b[31m', 'Could not connect to MongoLabDB!'); + console.log(err); + } }); +//var db = mongoose.connect(config.db, function(err) { +// if (err) { +// console.error('\x1b[31m', 'Could not connect to MongoDB!'); +// console.log(err); +// } +//}); + + // Init the express application var app = require('./config/express')(db); @@ -29,7 +37,8 @@ require('./config/passport')(); app.listen(config.port); // Expose app + exports = module.exports = app; // Logging initialization -console.log('MEAN.JS application started on port ' + config.port); \ No newline at end of file +console.log('MEAN.JS application started on port ' + config.port);