From a37bd9f7b7e4fec9db5a1b42d0778e791a24f684 Mon Sep 17 00:00:00 2001 From: Septian Ahmad Fujianto Date: Thu, 2 Nov 2017 13:28:28 +0700 Subject: [PATCH 01/30] Sampai step 6 Create insert Table Teacher dan Subject --- .gitignore | 1 + config/config.json | 23 +++++++ migrations/20171102045822-create-teacher.js | 30 +++++++++ .../20171102050040-add-email-to-teacher.js | 26 ++++++++ migrations/20171102061643-create-subject.js | 27 ++++++++ models/index.js | 36 +++++++++++ models/subject.js | 13 ++++ models/teacher.js | 20 ++++++ package.json | 27 ++++++++ .../20171102060232-insert-data-teachers.js | 64 +++++++++++++++++++ seeders/20171102061755-add-data-to-subject.js | 45 +++++++++++++ 11 files changed, 312 insertions(+) create mode 100644 .gitignore create mode 100644 config/config.json create mode 100644 migrations/20171102045822-create-teacher.js create mode 100644 migrations/20171102050040-add-email-to-teacher.js create mode 100644 migrations/20171102061643-create-subject.js create mode 100644 models/index.js create mode 100644 models/subject.js create mode 100644 models/teacher.js create mode 100644 package.json create mode 100644 seeders/20171102060232-insert-data-teachers.js create mode 100644 seeders/20171102061755-add-data-to-subject.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b512c09 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules \ No newline at end of file diff --git a/config/config.json b/config/config.json new file mode 100644 index 0000000..1b69f95 --- /dev/null +++ b/config/config.json @@ -0,0 +1,23 @@ +{ + "development": { + "username": "rendsow", + "password": null, + "database": "school_db", + "host": "127.0.0.1", + "dialect": "postgres" + }, + "test": { + "username": "rendsow", + "password": null, + "database": "school_db", + "host": "127.0.0.1", + "dialect": "postgres" + }, + "production": { + "username": "rendsow", + "password": null, + "database": "school_db", + "host": "127.0.0.1", + "dialect": "postgres" + } +} diff --git a/migrations/20171102045822-create-teacher.js b/migrations/20171102045822-create-teacher.js new file mode 100644 index 0000000..e0ed651 --- /dev/null +++ b/migrations/20171102045822-create-teacher.js @@ -0,0 +1,30 @@ +'use strict'; +module.exports = { + up: (queryInterface, Sequelize) => { + return queryInterface.createTable('Teachers', { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER + }, + first_name: { + type: Sequelize.STRING + }, + last_name: { + type: Sequelize.STRING + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE + } + }); + }, + down: (queryInterface, Sequelize) => { + return queryInterface.dropTable('Teachers'); + } +}; \ No newline at end of file diff --git a/migrations/20171102050040-add-email-to-teacher.js b/migrations/20171102050040-add-email-to-teacher.js new file mode 100644 index 0000000..5b5954e --- /dev/null +++ b/migrations/20171102050040-add-email-to-teacher.js @@ -0,0 +1,26 @@ +'use strict'; + +module.exports = { + up: (queryInterface, Sequelize) => { + /* + Add altering commands here. + Return a promise to correctly handle asynchronicity. + + Example: + return queryInterface.createTable('users', { id: Sequelize.INTEGER }); + */ + + queryInterface.addColumn('Teachers', 'email', Sequelize.STRING); + }, + + down: (queryInterface, Sequelize) => { + /* + Add reverting commands here. + Return a promise to correctly handle asynchronicity. + + Example: + return queryInterface.dropTable('users'); + */ + queryInterface.removeColumn('Teachers', 'email'); + } +}; diff --git a/migrations/20171102061643-create-subject.js b/migrations/20171102061643-create-subject.js new file mode 100644 index 0000000..0963342 --- /dev/null +++ b/migrations/20171102061643-create-subject.js @@ -0,0 +1,27 @@ +'use strict'; +module.exports = { + up: (queryInterface, Sequelize) => { + return queryInterface.createTable('Subjects', { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER + }, + subject_name: { + type: Sequelize.STRING + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE + } + }); + }, + down: (queryInterface, Sequelize) => { + return queryInterface.dropTable('Subjects'); + } +}; \ No newline at end of file diff --git a/models/index.js b/models/index.js new file mode 100644 index 0000000..9504198 --- /dev/null +++ b/models/index.js @@ -0,0 +1,36 @@ +'use strict'; + +var fs = require('fs'); +var path = require('path'); +var Sequelize = require('sequelize'); +var basename = path.basename(__filename); +var env = process.env.NODE_ENV || 'development'; +var config = require(__dirname + '/../config/config.json')[env]; +var db = {}; + +if (config.use_env_variable) { + var sequelize = new Sequelize(process.env[config.use_env_variable]); +} else { + var sequelize = new Sequelize(config.database, config.username, config.password, config); +} + +fs + .readdirSync(__dirname) + .filter(file => { + return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js'); + }) + .forEach(file => { + var model = sequelize['import'](path.join(__dirname, file)); + db[model.name] = model; + }); + +Object.keys(db).forEach(modelName => { + if (db[modelName].associate) { + db[modelName].associate(db); + } +}); + +db.sequelize = sequelize; +db.Sequelize = Sequelize; + +module.exports = db; diff --git a/models/subject.js b/models/subject.js new file mode 100644 index 0000000..6505cc8 --- /dev/null +++ b/models/subject.js @@ -0,0 +1,13 @@ +'use strict'; +module.exports = (sequelize, DataTypes) => { + var Subject = sequelize.define('Subject', { + subject_name: DataTypes.STRING + }, { + classMethods: { + associate: function(models) { + // associations can be defined here + } + } + }); + return Subject; +}; \ No newline at end of file diff --git a/models/teacher.js b/models/teacher.js new file mode 100644 index 0000000..04ccb7b --- /dev/null +++ b/models/teacher.js @@ -0,0 +1,20 @@ +'use strict'; +module.exports = (sequelize, DataTypes) => { + var Teacher = sequelize.define('Teacher', { + first_name: DataTypes.STRING, + last_name: DataTypes.STRING, + email: { + type: DataTypes.STRING, + validate: { + isEmail: true + } + } + }, { + classMethods: { + associate: function(models) { + // associations can be defined here + } + } + }); + return Teacher; +}; \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..42ae74f --- /dev/null +++ b/package.json @@ -0,0 +1,27 @@ +{ + "name": "school-app", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/fujianto/school-app.git" + }, + "author": "", + "license": "ISC", + "bugs": { + "url": "https://github.com/fujianto/school-app/issues" + }, + "homepage": "https://github.com/fujianto/school-app#readme", + "dependencies": { + "body-parser": "^1.18.2", + "ejs": "^2.5.7", + "express": "^4.16.2", + "pg": "^7.3.0", + "pg-hstore": "^2.3.2", + "sequelize": "^4.20.3" + } +} diff --git a/seeders/20171102060232-insert-data-teachers.js b/seeders/20171102060232-insert-data-teachers.js new file mode 100644 index 0000000..626405c --- /dev/null +++ b/seeders/20171102060232-insert-data-teachers.js @@ -0,0 +1,64 @@ +'use strict'; + +module.exports = { + up: (queryInterface, Sequelize) => { + /* + Add altering commands here. + Return a promise to correctly handle asynchronicity. + + Example: + return queryInterface.bulkInsert('Person', [{ + name: 'John Doe', + isBetaMember: false + }], {}); + */ + + return queryInterface.bulkInsert('Teachers', [ + { + first_name : 'Bambang', + last_name : 'Suprapto', + email : 'bambangsuprapto@sekolah.id', + createdAt : new Date(), + updatedAt : new Date() + }, + { + first_name : 'Rukmana', + last_name : 'Fatmawati', + email : 'rukmanafatmawati@sekolah.id', + createdAt : new Date(), + updatedAt : new Date() + }, + { + first_name : 'Butet', + last_name : 'Naiborhu', + email : 'butetnaiborhu@sekolah.id', + createdAt : new Date(), + updatedAt : new Date() + }, + { + first_name : 'Yulius', + last_name : 'Prawiranegara', + email : 'yuliusprawiranegara@sekolah.id', + createdAt : new Date(), + updatedAt : new Date() + } + ]); + }, + + down: (queryInterface, Sequelize) => { + /* + Add reverting commands here. + Return a promise to correctly handle asynchronicity. + + Example: + return queryInterface.bulkDelete('Person', null, {}); + */ + + queryInterface.bulkDelete('Teachers', [ + { first_name : 'Bambang' }, + { first_name : 'Rukmana' }, + { first_name : 'Butet' }, + { first_name : 'Yulius' }, + ]) + } +}; diff --git a/seeders/20171102061755-add-data-to-subject.js b/seeders/20171102061755-add-data-to-subject.js new file mode 100644 index 0000000..835d69d --- /dev/null +++ b/seeders/20171102061755-add-data-to-subject.js @@ -0,0 +1,45 @@ +'use strict'; + +module.exports = { + up: (queryInterface, Sequelize) => { + /* + Add altering commands here. + Return a promise to correctly handle asynchronicity. + + Example: + return queryInterface.bulkInsert('Person', [{ + name: 'John Doe', + isBetaMember: false + }], {}); + */ + + return queryInterface.bulkInsert('Subjects', [ + { + subject_name: 'Kimia', + createdAt: new Date(), + updatedAt: new Date() + }, + { + subject_name: 'Ekonomi', + createdAt: new Date(), + updatedAt: new Date() + } + ], {}); + }, + + down: (queryInterface, Sequelize) => { + /* + Add reverting commands here. + Return a promise to correctly handle asynchronicity. + + Example: + return queryInterface.bulkDelete('Person', null, {}); + */ + queryInterface.bulkDelete('Subjects', [{ + subject_name :'John' + }, + { + subject_name :'Ekonomi' + }]) + } +}; From 5293eb22f0466f5100c8504c9e30a59d54b488d9 Mon Sep 17 00:00:00 2001 From: Septian Ahmad Fujianto Date: Thu, 2 Nov 2017 15:48:44 +0700 Subject: [PATCH 02/30] All findall() done --- app.js | 24 ++++++++ migrations/20171102082325-create-student.js | 27 +++++++++ .../20171102083513-add-email-to-student.js | 27 +++++++++ models/student.js | 20 +++++++ package.json | 2 +- routes/index-route.js | 8 +++ routes/student-route.js | 13 +++++ routes/subject-route.js | 14 +++++ routes/teacher-route.js | 15 +++++ .../20171102082415-insert-data-students.js | 55 +++++++++++++++++++ views/index.ejs | 10 ++++ views/student.ejs | 32 +++++++++++ views/subject.ejs | 28 ++++++++++ views/teacher.ejs | 32 +++++++++++ 14 files changed, 306 insertions(+), 1 deletion(-) create mode 100644 app.js create mode 100644 migrations/20171102082325-create-student.js create mode 100644 migrations/20171102083513-add-email-to-student.js create mode 100644 models/student.js create mode 100644 routes/index-route.js create mode 100644 routes/student-route.js create mode 100644 routes/subject-route.js create mode 100644 routes/teacher-route.js create mode 100644 seeders/20171102082415-insert-data-students.js create mode 100644 views/index.ejs create mode 100644 views/student.ejs create mode 100644 views/subject.ejs create mode 100644 views/teacher.ejs diff --git a/app.js b/app.js new file mode 100644 index 0000000..7c5218f --- /dev/null +++ b/app.js @@ -0,0 +1,24 @@ +const express = require('express') +const app = express() +const ejs = require('ejs') +const bodyParser = require('body-parser'); + +// Router +const indexRoute = require('./routes/index-route'); +const teacherRoute = require('./routes/teacher-route'); +const subjectRoute = require('./routes/subject-route'); +const studentRoute = require('./routes/student-route'); + + +app.set('view engine', 'ejs'); +app.use(bodyParser.urlencoded({ extended: false })) +app.use(bodyParser.json()) + +app.use('/', indexRoute); +app.use('/teachers', teacherRoute); +app.use('/subjects', subjectRoute); +app.use('/students', studentRoute); + +app.listen(3000, function () { + console.log('Example app listening on port 3000!') +}) \ No newline at end of file diff --git a/migrations/20171102082325-create-student.js b/migrations/20171102082325-create-student.js new file mode 100644 index 0000000..1a9d31f --- /dev/null +++ b/migrations/20171102082325-create-student.js @@ -0,0 +1,27 @@ +'use strict'; +module.exports = { + up: (queryInterface, Sequelize) => { + return queryInterface.createTable('Students', { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER + }, + first_name: { + type: Sequelize.STRING + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE + } + }); + }, + down: (queryInterface, Sequelize) => { + return queryInterface.dropTable('Students'); + } +}; \ No newline at end of file diff --git a/migrations/20171102083513-add-email-to-student.js b/migrations/20171102083513-add-email-to-student.js new file mode 100644 index 0000000..ceabd69 --- /dev/null +++ b/migrations/20171102083513-add-email-to-student.js @@ -0,0 +1,27 @@ +'use strict'; + +module.exports = { + up: (queryInterface, Sequelize) => { + /* + Add altering commands here. + Return a promise to correctly handle asynchronicity. + + Example: + return queryInterface.createTable('users', { id: Sequelize.INTEGER }); + */ + queryInterface.addColumn( 'Students', 'last_name', Sequelize.STRING ); + queryInterface.addColumn( 'Students', 'email', Sequelize.STRING ); + }, + + down: (queryInterface, Sequelize) => { + /* + Add reverting commands here. + Return a promise to correctly handle asynchronicity. + + Example: + return queryInterface.dropTable('users'); + */ + queryInterface.removeColumn( 'Students', 'last_name' ); + queryInterface.removeColumn( 'Students', 'email' ); + } +}; diff --git a/models/student.js b/models/student.js new file mode 100644 index 0000000..7a10b17 --- /dev/null +++ b/models/student.js @@ -0,0 +1,20 @@ +'use strict'; +module.exports = (sequelize, DataTypes) => { + var Student = sequelize.define('Student', { + first_name: DataTypes.STRING, + last_name: DataTypes.STRING, + email: { + type: DataTypes.STRING, + validate: { + isEmail: true + } + } + }, { + classMethods: { + associate: function(models) { + // associations can be defined here + } + } + }); + return Student; +}; \ No newline at end of file diff --git a/package.json b/package.json index 42ae74f..afb6a02 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "school-app", "version": "1.0.0", "description": "", - "main": "index.js", + "main": "app.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, diff --git a/routes/index-route.js b/routes/index-route.js new file mode 100644 index 0000000..b18e8e2 --- /dev/null +++ b/routes/index-route.js @@ -0,0 +1,8 @@ +const express = require('express'); +const router = express.Router(); + +router.get('/', function (req, res) { + res.render('index'); +}) + +module.exports = router; \ No newline at end of file diff --git a/routes/student-route.js b/routes/student-route.js new file mode 100644 index 0000000..f6fbe11 --- /dev/null +++ b/routes/student-route.js @@ -0,0 +1,13 @@ +const express = require('express'); +const router = express.Router(); +const Model = require('../models'); + +router.get('/', (req, res) => { + Model.Student.findAll() + .then(allStudents => { + res.render('student', {students: allStudents}); + }) + .catch(err => res.send(err)); +}) + +module.exports = router; \ No newline at end of file diff --git a/routes/subject-route.js b/routes/subject-route.js new file mode 100644 index 0000000..97cb99e --- /dev/null +++ b/routes/subject-route.js @@ -0,0 +1,14 @@ +const express = require('express'); +const router = express.Router(); +const Model = require('../models'); + + +router.get('/', function (req, res) { + Model.Subject.findAll() + .then((allSubjects) => { + res.render('subject', {subjects: allSubjects}); + }) + .catch(err => res.send(err)); +}) + +module.exports = router; \ No newline at end of file diff --git a/routes/teacher-route.js b/routes/teacher-route.js new file mode 100644 index 0000000..b53a2cd --- /dev/null +++ b/routes/teacher-route.js @@ -0,0 +1,15 @@ +const express = require('express'); +const router = express.Router(); +const Model = require('../models'); + +router.get('/', function (req, res) { + Model.Teacher.findAll() + .then(allTeachers => { + res.render('teacher', {teachers: allTeachers}); + }) + .catch(err => res.send(err)); + + +}) + +module.exports = router; \ No newline at end of file diff --git a/seeders/20171102082415-insert-data-students.js b/seeders/20171102082415-insert-data-students.js new file mode 100644 index 0000000..052ac71 --- /dev/null +++ b/seeders/20171102082415-insert-data-students.js @@ -0,0 +1,55 @@ +'use strict'; + +module.exports = { + up: (queryInterface, Sequelize) => { + /* + Add altering commands here. + Return a promise to correctly handle asynchronicity. + + Example: + return queryInterface.bulkInsert('Person', [{ + name: 'John Doe', + isBetaMember: false + }], {}); + */ + + return queryInterface.bulkInsert('Students', [ + { + first_name: 'Akbar', + last_name: 'Saharta', + email: 'akbar@mail.com', + createdAt: new Date(), + updatedAt: new Date() + }, + { + first_name: 'Jhon', + last_name: 'Doe', + email: 'jond@mail.com', + createdAt: new Date(), + updatedAt: new Date() + }, + { + first_name: 'Sherlock', + last_name: 'Holmes', + email: 'sherlockh@mail.com', + createdAt: new Date(), + updatedAt: new Date() + } + ], {}); + }, + + down: (queryInterface, Sequelize) => { + /* + Add reverting commands here. + Return a promise to correctly handle asynchronicity. + + Example: + return queryInterface.bulkDelete('Person', null, {}); + */ + queryInterface.bulkDelete('Students', [ + { first_name :'Akbar'}, + { first_name :'Jhon'}, + { first_name :'Sherlock'} + ]) + } +}; diff --git a/views/index.ejs b/views/index.ejs new file mode 100644 index 0000000..1b2ff20 --- /dev/null +++ b/views/index.ejs @@ -0,0 +1,10 @@ + + + + + Index + + +

Home

+ + \ No newline at end of file diff --git a/views/student.ejs b/views/student.ejs new file mode 100644 index 0000000..a82812e --- /dev/null +++ b/views/student.ejs @@ -0,0 +1,32 @@ + + + + + Students + + +

Student Data

+ + + + + + + + + + + + + <% students.forEach( function(student, index) { %> + + + + + + + <% }); %> + +
IdFirst NameLast NameEmail
<%= student.id %><%= student.first_name %><%= student.last_name %><%= student.email %>
+ + \ No newline at end of file diff --git a/views/subject.ejs b/views/subject.ejs new file mode 100644 index 0000000..f64e3f1 --- /dev/null +++ b/views/subject.ejs @@ -0,0 +1,28 @@ + + + + + Subject + + +

Subjects

+ + + + + + + + + + + <% subjects.forEach( function(subject, index) { %> + + + + + <% }); %> + +
IdSubject Name
<%= subject.id %><%= subject.subject_name %>
+ + \ No newline at end of file diff --git a/views/teacher.ejs b/views/teacher.ejs new file mode 100644 index 0000000..6afca4e --- /dev/null +++ b/views/teacher.ejs @@ -0,0 +1,32 @@ + + + + + Daftar Teacher + + +

Teacher Data

+ + + + + + + + + + + + + <% teachers.forEach( function(teacher, index) { %> + + + + + + + <% }); %> + +
IdFirst NameLast NameEmail
<%= teacher.id %><%= teacher.first_name %><%= teacher.last_name %><%= teacher.email %>
+ + \ No newline at end of file From abc5418c3aba8486a4ae811c223c58a766683193 Mon Sep 17 00:00:00 2001 From: Septian Ahmad Fujianto Date: Thu, 2 Nov 2017 17:47:48 +0700 Subject: [PATCH 03/30] Validasi tipe email dan delete --- routes/student-route.js | 57 +++++++++++++++++++++++++++++++++++++++++ views/add-student.ejs | 33 ++++++++++++++++++++++++ views/student.ejs | 18 ++++++++++++- 3 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 views/add-student.ejs diff --git a/routes/student-route.js b/routes/student-route.js index f6fbe11..afccaa5 100644 --- a/routes/student-route.js +++ b/routes/student-route.js @@ -10,4 +10,61 @@ router.get('/', (req, res) => { .catch(err => res.send(err)); }) +router.get('/add', (req, res) => { + res.render('add-student', {message: req.query.err}); +}) + +router.post('/add', (req, res) => { + Model.Student.create(req.body, { + validate: { + isEmail: { + msg: "Email address must be valid" + } + } + }) + .then(success => { + res.redirect('/students'); + }) + .catch(err => { + var msg = encodeURIComponent(err.message); + res.redirect('/students/add/?err=' + msg); + }); +}) + +router.get('/edit/:id', (req, res) => { + Model.Student.findById(req.params.id) + .then((studentEditFound) => { + res.render('add-student', {studentFound: studentEditFound, message: req.query.err}); + }) + .catch(err => res.send(err)); +}) + +router.post('/edit/', (req, res) => { + Model.Student.update(req.body,{ + where: { + id: req.body.id + }, + validate: { + isEmail: { + msg: "Email address must be valid" + } + } + }).then(success =>{ + res.redirect('/students'); + }).catch(err => { + var msg = encodeURIComponent(err.message); + res.redirect(`/students/edit/${req.body.id}/?err=`+msg); + }); +}) + +router.get('/delete/:id', (req, res) => { + Model.Student.destroy({ + where: { + id: req.params.id + } + }).then(success =>{ + res.redirect('/students'); + }).catch(err => res.send(err)); +}) + module.exports = router; \ No newline at end of file diff --git a/views/add-student.ejs b/views/add-student.ejs new file mode 100644 index 0000000..d8aa2ac --- /dev/null +++ b/views/add-student.ejs @@ -0,0 +1,33 @@ + + + + + Add Student + + +
+

Add Student Data

+ Show all data +

+
+ + <% if(typeof studentFound !== 'undefined' && studentFound !== null) { %> +
Editing user <%= studentFound.first_name %>
+ <% } %> + + <% if (typeof message !== 'undefined' && message !== null){ %> +

<%= message %>

+ <% } %> + +
+
+ + + + + + +
+
+ + \ No newline at end of file diff --git a/views/student.ejs b/views/student.ejs index a82812e..328acfa 100644 --- a/views/student.ejs +++ b/views/student.ejs @@ -5,7 +5,12 @@ Students -

Student Data

+
+

Student Data

+ Add Student +
+
+
@@ -14,6 +19,7 @@ + @@ -24,9 +30,19 @@ + <% }); %>
First Name Last Name EmailAction
<%= student.first_name %> <%= student.last_name %> <%= student.email %> + Edit + Delete +
+ + \ No newline at end of file From ef5e7b481ae84c0dc8c39f3cefbde5b319c4b1f3 Mon Sep 17 00:00:00 2001 From: Septian Ahmad Fujianto Date: Thu, 2 Nov 2017 18:17:44 +0700 Subject: [PATCH 04/30] Unique email done --- ...20171102110033-add-unique-email-to-user.js | 28 +++++++++++++++++++ models/student.js | 1 + 2 files changed, 29 insertions(+) create mode 100644 migrations/20171102110033-add-unique-email-to-user.js diff --git a/migrations/20171102110033-add-unique-email-to-user.js b/migrations/20171102110033-add-unique-email-to-user.js new file mode 100644 index 0000000..b61a54b --- /dev/null +++ b/migrations/20171102110033-add-unique-email-to-user.js @@ -0,0 +1,28 @@ +'use strict'; + +module.exports = { + up: (queryInterface, Sequelize) => { + /* + Add altering commands here. + Return a promise to correctly handle asynchronicity. + + Example: + return queryInterface.createTable('users', { id: Sequelize.INTEGER }); + */ + queryInterface.changeColumn( 'Students', 'email', { + type : Sequelize.STRING, + unique : true, + }); + }, + + down: (queryInterface, Sequelize) => { + /* + Add reverting commands here. + Return a promise to correctly handle asynchronicity. + + Example: + return queryInterface.dropTable('users'); + */ + queryInterface.removeConstraint( 'Students', 'email'); + } +}; diff --git a/models/student.js b/models/student.js index 7a10b17..efb2728 100644 --- a/models/student.js +++ b/models/student.js @@ -5,6 +5,7 @@ module.exports = (sequelize, DataTypes) => { last_name: DataTypes.STRING, email: { type: DataTypes.STRING, + unique : true, validate: { isEmail: true } From 337ab6e33000d7b461889681cb5ed47391486e28 Mon Sep 17 00:00:00 2001 From: Septian Ahmad Fujianto Date: Thu, 2 Nov 2017 18:32:22 +0700 Subject: [PATCH 05/30] Finish adding instance method fullname --- models/student.js | 10 ++++++++-- views/student.ejs | 4 +++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/models/student.js b/models/student.js index efb2728..229ba84 100644 --- a/models/student.js +++ b/models/student.js @@ -14,8 +14,14 @@ module.exports = (sequelize, DataTypes) => { classMethods: { associate: function(models) { // associations can be defined here - } + }, } }); + + Student.prototype.full_name = function(){ + return this.first_name +' '+this.last_name; + }; + return Student; -}; \ No newline at end of file +}; + diff --git a/views/student.ejs b/views/student.ejs index 328acfa..ef8c668 100644 --- a/views/student.ejs +++ b/views/student.ejs @@ -18,17 +18,19 @@ Id First Name Last Name + Full Name Email Action - + <% students.forEach( function(student, index) { %> <%= student.id %> <%= student.first_name %> <%= student.last_name %> + <%= student.full_name() %> <%= student.email %> Edit From 226a5abfaf2f7e1bb6ddc073f0ff822c2808eb61 Mon Sep 17 00:00:00 2001 From: Septian Ahmad Fujianto Date: Sat, 4 Nov 2017 12:14:40 +0700 Subject: [PATCH 06/30] Add validation not empty --- app.js | 2 +- models/student.js | 29 +++++++++++++++++-- routes/student-route.js | 14 ++------- seeders/20171102061755-add-data-to-subject.js | 2 +- test_validation.js | 7 +++++ 5 files changed, 37 insertions(+), 17 deletions(-) create mode 100644 test_validation.js diff --git a/app.js b/app.js index 7c5218f..d1af08c 100644 --- a/app.js +++ b/app.js @@ -19,6 +19,6 @@ app.use('/teachers', teacherRoute); app.use('/subjects', subjectRoute); app.use('/students', studentRoute); -app.listen(3000, function () { +app.listen(3002, function () { console.log('Example app listening on port 3000!') }) \ No newline at end of file diff --git a/models/student.js b/models/student.js index 229ba84..7e5d532 100644 --- a/models/student.js +++ b/models/student.js @@ -1,13 +1,36 @@ 'use strict'; module.exports = (sequelize, DataTypes) => { var Student = sequelize.define('Student', { - first_name: DataTypes.STRING, - last_name: DataTypes.STRING, + first_name: { + type: DataTypes.STRING, + validate: { + notEmpty: true + } + }, + last_name: { + type: DataTypes.STRING, + validate: { + notEmpty: true + } + }, email: { type: DataTypes.STRING, unique : true, validate: { - isEmail: true + isEmail: true, + isUnique: function(value, callback) { + if (this.dataValues.id === '') { + Student.findAll({ where: {email: value} }).then(emailFound => { + if (emailFound.length >= 1) { + return callback('Email not unique! Change!'); + } else { + callback(); + } + }) + } else { + callback(); + } + } } } }, { diff --git a/routes/student-route.js b/routes/student-route.js index afccaa5..d8d1886 100644 --- a/routes/student-route.js +++ b/routes/student-route.js @@ -15,17 +15,12 @@ router.get('/add', (req, res) => { }) router.post('/add', (req, res) => { - Model.Student.create(req.body, { - validate: { - isEmail: { - msg: "Email address must be valid" - } - } - }) + Model.Student.create(req.body) .then(success => { res.redirect('/students'); }) .catch(err => { + console.log(err); var msg = encodeURIComponent(err.message); res.redirect('/students/add/?err=' + msg); }); @@ -43,11 +38,6 @@ router.post('/edit/', (req, res) => { Model.Student.update(req.body,{ where: { id: req.body.id - }, - validate: { - isEmail: { - msg: "Email address must be valid" - } } }).then(success =>{ res.redirect('/students'); diff --git a/seeders/20171102061755-add-data-to-subject.js b/seeders/20171102061755-add-data-to-subject.js index 835d69d..cf4a923 100644 --- a/seeders/20171102061755-add-data-to-subject.js +++ b/seeders/20171102061755-add-data-to-subject.js @@ -36,7 +36,7 @@ module.exports = { return queryInterface.bulkDelete('Person', null, {}); */ queryInterface.bulkDelete('Subjects', [{ - subject_name :'John' + subject_name :'Kimia' }, { subject_name :'Ekonomi' diff --git a/test_validation.js b/test_validation.js new file mode 100644 index 0000000..f8c3aba --- /dev/null +++ b/test_validation.js @@ -0,0 +1,7 @@ +const Model = require('./models'); + +let Student = Model.Student; +let student = new Student(); + +student.email = 'akbar@mail.com'; +student.save(); \ No newline at end of file From 28074938d35cb47fc3686bba856a57cd79e7e0e4 Mon Sep 17 00:00:00 2001 From: Septian Ahmad Fujianto Date: Sat, 4 Nov 2017 14:02:26 +0700 Subject: [PATCH 07/30] Awas error --- ...4055109-add-one-subject-to-many-teacher.js | 35 +++++++++++++++++++ routes/student-route.js | 1 + 2 files changed, 36 insertions(+) create mode 100644 migrations/20171104055109-add-one-subject-to-many-teacher.js diff --git a/migrations/20171104055109-add-one-subject-to-many-teacher.js b/migrations/20171104055109-add-one-subject-to-many-teacher.js new file mode 100644 index 0000000..e5ec085 --- /dev/null +++ b/migrations/20171104055109-add-one-subject-to-many-teacher.js @@ -0,0 +1,35 @@ +'use strict'; + +module.exports = { + up: (queryInterface, Sequelize) => { + /* + Add altering commands here. + Return a promise to correctly handle asynchronicity. + + Example: + return queryInterface.createTable('users', { id: Sequelize.INTEGER }); + */ + queryInterface.addColumn('Teachers', 'SubjectsId', Sequelize.INTEGER); + queryInterface.addConstraint('Teachers', ['SubjectsId'], { + type: 'FOREIGN KEY', + name: 'SubjectsId', + references: { //Required field + table: 'Subjects', + field: 'id' + }, + onDelete: 'cascade', + onUpdate: 'cascade' + }); + }, + + down: (queryInterface, Sequelize) => { + /* + Add reverting commands here. + Return a promise to correctly handle asynchronicity. + + Example: + return queryInterface.dropTable('users'); + */ + queryInterface.removeColumn( 'Teachers', 'SubjectId'); + } +}; diff --git a/routes/student-route.js b/routes/student-route.js index d8d1886..2b75ccd 100644 --- a/routes/student-route.js +++ b/routes/student-route.js @@ -6,6 +6,7 @@ router.get('/', (req, res) => { Model.Student.findAll() .then(allStudents => { res.render('student', {students: allStudents}); + console.log(allStudents[0].full_name()) }) .catch(err => res.send(err)); }) From 03997e75e68344cca63daefb6b9380609cdc7671 Mon Sep 17 00:00:00 2001 From: Septian Ahmad Fujianto Date: Sat, 4 Nov 2017 14:20:20 +0700 Subject: [PATCH 08/30] Jaga2 sebelum migrate --- models/subject.js | 1 + models/teacher.js | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/models/subject.js b/models/subject.js index 6505cc8..127c856 100644 --- a/models/subject.js +++ b/models/subject.js @@ -5,6 +5,7 @@ module.exports = (sequelize, DataTypes) => { }, { classMethods: { associate: function(models) { + Subject.hasMany(Teacher); // associations can be defined here } } diff --git a/models/teacher.js b/models/teacher.js index 04ccb7b..395752e 100644 --- a/models/teacher.js +++ b/models/teacher.js @@ -8,13 +8,18 @@ module.exports = (sequelize, DataTypes) => { validate: { isEmail: true } + }, + SubjectsId: { + type: DataTypes.INTEGER } }, { classMethods: { associate: function(models) { + Teacher.belongTo(Subject); // associations can be defined here } } }); + return Teacher; }; \ No newline at end of file From 4c177745a904dc69de6fe40f038e978eb63758ab Mon Sep 17 00:00:00 2001 From: Septian Ahmad Fujianto Date: Sat, 4 Nov 2017 17:20:19 +0700 Subject: [PATCH 09/30] Table teacher joined --- ...4055109-add-one-subject-to-many-teacher.js | 12 +-------- ...104080750-add-subject-id-to-teacher-fix.js | 25 ++++++++++++++++++ models/subject.js | 6 ++++- models/teacher.js | 8 ++++-- routes/teacher-route.js | 26 ++++++++++++++++++- views/teacher.ejs | 8 +++++- 6 files changed, 69 insertions(+), 16 deletions(-) create mode 100644 migrations/20171104080750-add-subject-id-to-teacher-fix.js diff --git a/migrations/20171104055109-add-one-subject-to-many-teacher.js b/migrations/20171104055109-add-one-subject-to-many-teacher.js index e5ec085..032cba6 100644 --- a/migrations/20171104055109-add-one-subject-to-many-teacher.js +++ b/migrations/20171104055109-add-one-subject-to-many-teacher.js @@ -9,17 +9,7 @@ module.exports = { Example: return queryInterface.createTable('users', { id: Sequelize.INTEGER }); */ - queryInterface.addColumn('Teachers', 'SubjectsId', Sequelize.INTEGER); - queryInterface.addConstraint('Teachers', ['SubjectsId'], { - type: 'FOREIGN KEY', - name: 'SubjectsId', - references: { //Required field - table: 'Subjects', - field: 'id' - }, - onDelete: 'cascade', - onUpdate: 'cascade' - }); + queryInterface.addColumn('Teachers', 'SubjectId', Sequelize.INTEGER); }, down: (queryInterface, Sequelize) => { diff --git a/migrations/20171104080750-add-subject-id-to-teacher-fix.js b/migrations/20171104080750-add-subject-id-to-teacher-fix.js new file mode 100644 index 0000000..2a8bd56 --- /dev/null +++ b/migrations/20171104080750-add-subject-id-to-teacher-fix.js @@ -0,0 +1,25 @@ +'use strict'; + +module.exports = { + up: (queryInterface, Sequelize) => { + /* + Add altering commands here. + Return a promise to correctly handle asynchronicity. + + Example: + return queryInterface.createTable('users', { id: Sequelize.INTEGER }); + */ + queryInterface.addColumn('Teachers', 'SubjectId', Sequelize.INTEGER); + }, + + down: (queryInterface, Sequelize) => { + /* + Add reverting commands here. + Return a promise to correctly handle asynchronicity. + + Example: + return queryInterface.dropTable('users'); + */ + queryInterface.removeColumn( 'Teachers', 'SubjectId'); + } +}; diff --git a/models/subject.js b/models/subject.js index 127c856..b9f9399 100644 --- a/models/subject.js +++ b/models/subject.js @@ -5,10 +5,14 @@ module.exports = (sequelize, DataTypes) => { }, { classMethods: { associate: function(models) { - Subject.hasMany(Teacher); // associations can be defined here } } }); + + Subject.associate = function (models) { + Subject.hasMany(models.Teacher); + } + return Subject; }; \ No newline at end of file diff --git a/models/teacher.js b/models/teacher.js index 395752e..7ac6da8 100644 --- a/models/teacher.js +++ b/models/teacher.js @@ -9,17 +9,21 @@ module.exports = (sequelize, DataTypes) => { isEmail: true } }, - SubjectsId: { + SubjectId: { type: DataTypes.INTEGER } }, { classMethods: { associate: function(models) { - Teacher.belongTo(Subject); + // associations can be defined here } } }); + Teacher.associate = function(models) { + Teacher.belongsTo(models.Subject); + }; + return Teacher; }; \ No newline at end of file diff --git a/routes/teacher-route.js b/routes/teacher-route.js index b53a2cd..ad29209 100644 --- a/routes/teacher-route.js +++ b/routes/teacher-route.js @@ -8,8 +8,32 @@ router.get('/', function (req, res) { res.render('teacher', {teachers: allTeachers}); }) .catch(err => res.send(err)); +}) + +router.get('/tes', function (req, res) { + Model.Teacher.findAll() + .then(teachers => { + let newTeacher = teachers.map(teacher => { + return new Promise((resolve, reject) => { + teacher.getSubject().then((subjectWith) => { + if (subjectWith === null) { + teacher.subject_data.status = "Unassigned"; + resolve(teacher); + } else { + teacher.subject_data.status = "Assigned"; + teacher.subject_data = subjectWith; + resolve(teacher); + } + }) + .catch(err => res.send(err)); + }); + }) - + Promise.all(newTeacher) + .then((newSubject) => { + res.render('teacher', {teachers: teachers, teachersSubjects: newSubject}); + }) + }) }) module.exports = router; \ No newline at end of file diff --git a/views/teacher.ejs b/views/teacher.ejs index 6afca4e..15d7b36 100644 --- a/views/teacher.ejs +++ b/views/teacher.ejs @@ -14,16 +14,22 @@ First Name Last Name Email + Subject - <% teachers.forEach( function(teacher, index) { %> + <% teachersSubjects.forEach( function(teacher, index) { %> <%= teacher.id %> <%= teacher.first_name %> <%= teacher.last_name %> <%= teacher.email %> + <% if (teacher.SubjectId == null){ %> + <%= teacher.subject_data.status %> + <%} else { %> + <%= teacher.subject_data.subject_name %> + <% } %> <% }); %> From b3718f46834b42de1306cd1359fb95a3376db9bd Mon Sep 17 00:00:00 2001 From: fujianto Date: Sat, 4 Nov 2017 20:32:26 +0700 Subject: [PATCH 10/30] Fix unassigned --- config/config.json | 12 +- package-lock.json | 653 ++++++++++++++++++++++++++++++++++++++++ package.json | 2 +- routes/teacher-route.js | 28 +- views/teacher.ejs | 4 +- 5 files changed, 677 insertions(+), 22 deletions(-) create mode 100644 package-lock.json diff --git a/config/config.json b/config/config.json index 1b69f95..49c8a1b 100644 --- a/config/config.json +++ b/config/config.json @@ -1,21 +1,21 @@ { "development": { - "username": "rendsow", - "password": null, + "username": "postgres", + "password": "postgres", "database": "school_db", "host": "127.0.0.1", "dialect": "postgres" }, "test": { - "username": "rendsow", - "password": null, + "username": "postgres", + "password": "postgres", "database": "school_db", "host": "127.0.0.1", "dialect": "postgres" }, "production": { - "username": "rendsow", - "password": null, + "username": "postgres", + "password": "postgres", "database": "school_db", "host": "127.0.0.1", "dialect": "postgres" diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..e67a189 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,653 @@ +{ + "name": "school-app", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@types/geojson": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-1.0.6.tgz", + "integrity": "sha512-Xqg/lIZMrUd0VRmSRbCAewtwGZiAk3mEUDvV4op1tGl+LvyPcb/MIOSxTl9z+9+J+R4/vpjiCAT4xeKzH9ji1w==" + }, + "@types/node": { + "version": "8.0.47", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.47.tgz", + "integrity": "sha512-kOwL746WVvt/9Phf6/JgX/bsGQvbrK5iUgzyfwZNcKVFcjAUVSpF9HxevLTld2SG9aywYHOILj38arDdY1r/iQ==" + }, + "accepts": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz", + "integrity": "sha1-hiRnWMfdbSGmR0/whKR0DsBesh8=", + "requires": { + "mime-types": "2.1.17", + "negotiator": "0.6.1" + } + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" + }, + "bluebird": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", + "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==" + }, + "body-parser": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", + "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", + "requires": { + "bytes": "3.0.0", + "content-type": "1.0.4", + "debug": "2.6.9", + "depd": "1.1.1", + "http-errors": "1.6.2", + "iconv-lite": "0.4.19", + "on-finished": "2.3.0", + "qs": "6.5.1", + "raw-body": "2.3.2", + "type-is": "1.6.15" + } + }, + "buffer-writer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-1.0.1.tgz", + "integrity": "sha1-Iqk2kB4wKa/NdUfrRIfOtpejvwg=" + }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" + }, + "cls-bluebird": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/cls-bluebird/-/cls-bluebird-2.0.1.tgz", + "integrity": "sha1-wlmkgK4CwOUGE0MHuxPbMERu4uc=", + "requires": { + "is-bluebird": "1.0.2", + "shimmer": "1.1.0" + } + }, + "content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + }, + "cookie": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", + "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "depd": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", + "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "dottie": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.0.tgz", + "integrity": "sha1-2hkZgci41xPKARXViYzzl8Lw3dA=" + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "ejs": { + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.5.7.tgz", + "integrity": "sha1-zIcsFoiArjxxiXYv1f/ACJbJUYo=" + }, + "encodeurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz", + "integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA=" + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "express": { + "version": "4.16.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.16.2.tgz", + "integrity": "sha1-41xt/i1kt9ygpc1PIXgb4ymeB2w=", + "requires": { + "accepts": "1.3.4", + "array-flatten": "1.1.1", + "body-parser": "1.18.2", + "content-disposition": "0.5.2", + "content-type": "1.0.4", + "cookie": "0.3.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "1.1.1", + "encodeurl": "1.0.1", + "escape-html": "1.0.3", + "etag": "1.8.1", + "finalhandler": "1.1.0", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "1.1.2", + "on-finished": "2.3.0", + "parseurl": "1.3.2", + "path-to-regexp": "0.1.7", + "proxy-addr": "2.0.2", + "qs": "6.5.1", + "range-parser": "1.2.0", + "safe-buffer": "5.1.1", + "send": "0.16.1", + "serve-static": "1.13.1", + "setprototypeof": "1.1.0", + "statuses": "1.3.1", + "type-is": "1.6.15", + "utils-merge": "1.0.1", + "vary": "1.1.2" + }, + "dependencies": { + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + }, + "statuses": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=" + } + } + }, + "finalhandler": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", + "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=", + "requires": { + "debug": "2.6.9", + "encodeurl": "1.0.1", + "escape-html": "1.0.3", + "on-finished": "2.3.0", + "parseurl": "1.3.2", + "statuses": "1.3.1", + "unpipe": "1.0.0" + }, + "dependencies": { + "statuses": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=" + } + } + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "generic-pool": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.2.0.tgz", + "integrity": "sha512-JjcXDHT84icN/kFaF5+rNd1trZsgJFVqTSgM9dv6eayxSIQKMq0ilBJ+5pvf0SgimacMlZEsav4oL+4dUE4E2g==" + }, + "http-errors": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", + "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", + "requires": { + "depd": "1.1.1", + "inherits": "2.0.3", + "setprototypeof": "1.0.3", + "statuses": "1.4.0" + } + }, + "iconv-lite": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" + }, + "inflection": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.12.0.tgz", + "integrity": "sha1-ogCTVlbW9fa8TcdQLhrstwMihBY=" + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ipaddr.js": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.5.2.tgz", + "integrity": "sha1-1LUFvemUaYfM8PxY2QEP+WB+P6A=" + }, + "is-bluebird": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-bluebird/-/is-bluebird-1.0.2.tgz", + "integrity": "sha1-CWQ5Bg9KpBGr7hkUOoTWpVNG1uI=" + }, + "js-string-escape": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", + "integrity": "sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8=" + }, + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" + }, + "mime": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", + "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==" + }, + "mime-db": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz", + "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=" + }, + "mime-types": { + "version": "2.1.17", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz", + "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=", + "requires": { + "mime-db": "1.30.0" + } + }, + "moment": { + "version": "2.19.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.19.1.tgz", + "integrity": "sha1-VtoaLRy/AdOLfhr8McELz6GSkWc=" + }, + "moment-timezone": { + "version": "0.5.14", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.14.tgz", + "integrity": "sha1-TrOP+VOLgBCLpGekWPPtQmjM/LE=", + "requires": { + "moment": "2.19.1" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "negotiator": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", + "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "packet-reader": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-0.3.1.tgz", + "integrity": "sha1-zWLmCvjX/qinBexP+ZCHHEaHHyc=" + }, + "parseurl": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", + "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + }, + "pg": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/pg/-/pg-7.3.0.tgz", + "integrity": "sha1-J14nRm5UpkX2tKFvasrfa4Sa2Ds=", + "requires": { + "buffer-writer": "1.0.1", + "js-string-escape": "1.0.1", + "packet-reader": "0.3.1", + "pg-connection-string": "0.1.3", + "pg-pool": "2.0.3", + "pg-types": "1.12.1", + "pgpass": "1.0.2", + "semver": "4.3.2" + } + }, + "pg-connection-string": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-0.1.3.tgz", + "integrity": "sha1-2hhHsglA5C7hSSvq9l1J2RskXfc=" + }, + "pg-hstore": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/pg-hstore/-/pg-hstore-2.3.2.tgz", + "integrity": "sha1-9+8FPnubiSrphq8vfL6GQy388k8=", + "requires": { + "underscore": "1.8.3" + } + }, + "pg-pool": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-2.0.3.tgz", + "integrity": "sha1-wCIDLIlJ8xKk+R+2QJzgQHa+Mlc=" + }, + "pg-types": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-1.12.1.tgz", + "integrity": "sha1-1kCH45A7WP+q0nnnWVxSIIoUw9I=", + "requires": { + "postgres-array": "1.0.2", + "postgres-bytea": "1.0.0", + "postgres-date": "1.0.3", + "postgres-interval": "1.1.1" + } + }, + "pgpass": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.2.tgz", + "integrity": "sha1-Knu0G2BltnkH6R2hsHwYR8h3swY=", + "requires": { + "split": "1.0.1" + } + }, + "postgres-array": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-1.0.2.tgz", + "integrity": "sha1-jgsy6wO/d6XAp4UeBEHBaaJWojg=" + }, + "postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha1-AntTPAqokOJtFy1Hz5zOzFIazTU=" + }, + "postgres-date": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.3.tgz", + "integrity": "sha1-4tiXAu/bJY/52c7g/pG9BpdSV6g=" + }, + "postgres-interval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.1.1.tgz", + "integrity": "sha512-OkuCi9t/3CZmeQreutGgx/OVNv9MKHGIT5jH8KldQ4NLYXkvmT9nDVxEuCENlNwhlGPE374oA/xMqn05G49pHA==", + "requires": { + "xtend": "4.0.1" + } + }, + "proxy-addr": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.2.tgz", + "integrity": "sha1-ZXFQT0e7mI7IGAJT+F3X4UlSvew=", + "requires": { + "forwarded": "0.1.2", + "ipaddr.js": "1.5.2" + } + }, + "qs": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", + "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" + }, + "range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" + }, + "raw-body": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", + "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", + "requires": { + "bytes": "3.0.0", + "http-errors": "1.6.2", + "iconv-lite": "0.4.19", + "unpipe": "1.0.0" + } + }, + "retry-as-promised": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-2.3.2.tgz", + "integrity": "sha1-zZdO5P2bX+A8vzGHHuSCIcB3N7c=", + "requires": { + "bluebird": "3.5.1", + "debug": "2.6.9" + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + }, + "semver": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.2.tgz", + "integrity": "sha1-x6BxWKgL7dBSNVt3DYLWZA+AO+c=" + }, + "send": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.16.1.tgz", + "integrity": "sha512-ElCLJdJIKPk6ux/Hocwhk7NFHpI3pVm/IZOYWqUmoxcgeyM+MpxHHKhb8QmlJDX1pU6WrgaHBkVNm73Sv7uc2A==", + "requires": { + "debug": "2.6.9", + "depd": "1.1.1", + "destroy": "1.0.4", + "encodeurl": "1.0.1", + "escape-html": "1.0.3", + "etag": "1.8.1", + "fresh": "0.5.2", + "http-errors": "1.6.2", + "mime": "1.4.1", + "ms": "2.0.0", + "on-finished": "2.3.0", + "range-parser": "1.2.0", + "statuses": "1.3.1" + }, + "dependencies": { + "statuses": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", + "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=" + } + } + }, + "sequelize": { + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-4.22.2.tgz", + "integrity": "sha512-fsphZa8iybgytUh0vonPBh2KO3+KyFgQLaYh16Re11ASvZaklGuFjb8zQ10stqA5M0Zvl5puOeX4Srp6U0i3fg==", + "requires": { + "bluebird": "3.5.1", + "cls-bluebird": "2.0.1", + "debug": "3.1.0", + "depd": "1.1.1", + "dottie": "2.0.0", + "generic-pool": "3.2.0", + "inflection": "1.12.0", + "lodash": "4.17.4", + "moment": "2.19.1", + "moment-timezone": "0.5.14", + "retry-as-promised": "2.3.2", + "semver": "5.4.1", + "terraformer-wkt-parser": "1.1.2", + "toposort-class": "1.0.1", + "uuid": "3.1.0", + "validator": "9.1.1", + "wkx": "0.4.2" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "semver": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==" + } + } + }, + "serve-static": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.1.tgz", + "integrity": "sha512-hSMUZrsPa/I09VYFJwa627JJkNs0NrfL1Uzuup+GqHfToR2KcsXFymXSV90hoyw3M+msjFuQly+YzIH/q0MGlQ==", + "requires": { + "encodeurl": "1.0.1", + "escape-html": "1.0.3", + "parseurl": "1.3.2", + "send": "0.16.1" + } + }, + "setprototypeof": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", + "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=" + }, + "shimmer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.1.0.tgz", + "integrity": "sha1-l9c3cTf/u6tCVSLkKf4KqJpIizU=" + }, + "split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "requires": { + "through": "2.3.8" + } + }, + "statuses": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" + }, + "terraformer": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/terraformer/-/terraformer-1.0.8.tgz", + "integrity": "sha1-UeCtiXRvzyFh3G9lqnDkI3fItZM=", + "requires": { + "@types/geojson": "1.0.6" + } + }, + "terraformer-wkt-parser": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/terraformer-wkt-parser/-/terraformer-wkt-parser-1.1.2.tgz", + "integrity": "sha1-M2oMj8gglKWv+DKI9prt7NNpvww=", + "requires": { + "terraformer": "1.0.8" + } + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "toposort-class": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toposort-class/-/toposort-class-1.0.1.tgz", + "integrity": "sha1-f/0feMi+KMO6Rc1OGj9e4ZO9mYg=" + }, + "type-is": { + "version": "1.6.15", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz", + "integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA=", + "requires": { + "media-typer": "0.3.0", + "mime-types": "2.1.17" + } + }, + "underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "uuid": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", + "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==" + }, + "validator": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/validator/-/validator-9.1.1.tgz", + "integrity": "sha512-1TGGX1GKilfmcEa9rm+9nI9AqIUQK8oj4jZI0DmTGLTPM5jmowBBhyBIHCks73+P1QPZk2i6oOYUq583uOetHQ==" + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "wkx": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/wkx/-/wkx-0.4.2.tgz", + "integrity": "sha1-d201pjSlwi5lbkdEvetU+D/Szo0=", + "requires": { + "@types/node": "8.0.47" + } + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + } + } +} diff --git a/package.json b/package.json index afb6a02..91543f6 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,6 @@ "express": "^4.16.2", "pg": "^7.3.0", "pg-hstore": "^2.3.2", - "sequelize": "^4.20.3" + "sequelize": "^4.22.2" } } diff --git a/routes/teacher-route.js b/routes/teacher-route.js index ad29209..c3b4b6f 100644 --- a/routes/teacher-route.js +++ b/routes/teacher-route.js @@ -16,24 +16,26 @@ router.get('/tes', function (req, res) { let newTeacher = teachers.map(teacher => { return new Promise((resolve, reject) => { teacher.getSubject().then((subjectWith) => { - if (subjectWith === null) { - teacher.subject_data.status = "Unassigned"; - resolve(teacher); - } else { - teacher.subject_data.status = "Assigned"; - teacher.subject_data = subjectWith; - resolve(teacher); - } + console.log(teacher.SubjectId == null) + + if (teacher.SubjectId == null) { + teacher.subject_data = 'Unassigned'; + } else { + teacher.subject_data = subjectWith; + } + + resolve(teacher); }) .catch(err => res.send(err)); }); }) - Promise.all(newTeacher) - .then((newSubject) => { - res.render('teacher', {teachers: teachers, teachersSubjects: newSubject}); - }) - }) + + Promise.all(newTeacher) + .then((newSubject) => { + res.render('teacher', {teachers: teachers, teachersSubjects: newSubject}); + }) + }) }) module.exports = router; \ No newline at end of file diff --git a/views/teacher.ejs b/views/teacher.ejs index 15d7b36..a8e0424 100644 --- a/views/teacher.ejs +++ b/views/teacher.ejs @@ -25,8 +25,8 @@ <%= teacher.first_name %> <%= teacher.last_name %> <%= teacher.email %> - <% if (teacher.SubjectId == null){ %> - <%= teacher.subject_data.status %> + <% if (teacher.subject_data.subject_name == null){ %> + <%= teacher.subject_data %> <%} else { %> <%= teacher.subject_data.subject_name %> <% } %> From 85c2de6c30b8476df279ac1f03dbc9bd65a8dcb3 Mon Sep 17 00:00:00 2001 From: fujianto Date: Sat, 4 Nov 2017 21:24:33 +0700 Subject: [PATCH 11/30] Crud teachers --- models/teacher.js | 29 ++++++++++++-- routes/teacher-route.js | 88 +++++++++++++++++++++++++++++++++-------- views/add-teacher.ejs | 34 ++++++++++++++++ views/teacher.ejs | 12 +++++- 4 files changed, 143 insertions(+), 20 deletions(-) create mode 100644 views/add-teacher.ejs diff --git a/models/teacher.js b/models/teacher.js index 7ac6da8..2623f35 100644 --- a/models/teacher.js +++ b/models/teacher.js @@ -1,12 +1,35 @@ 'use strict'; module.exports = (sequelize, DataTypes) => { var Teacher = sequelize.define('Teacher', { - first_name: DataTypes.STRING, - last_name: DataTypes.STRING, + first_name: { + type: DataTypes.STRING, + validate: { + notEmpty: true + } + }, + last_name: { + type: DataTypes.STRING, + validate: { + notEmpty: true + } + }, email: { type: DataTypes.STRING, validate: { - isEmail: true + isEmail: true, + isUnique: function(value, callback) { + if (this.dataValues.id === '') { + Teacher.findAll({ where: {email: value} }).then(emailFound => { + if (emailFound.length >= 1) { + return callback('Email not unique! Change!'); + } else { + callback(); + } + }) + } else { + callback(); + } + } } }, SubjectId: { diff --git a/routes/teacher-route.js b/routes/teacher-route.js index c3b4b6f..65f25f9 100644 --- a/routes/teacher-route.js +++ b/routes/teacher-route.js @@ -3,21 +3,11 @@ const router = express.Router(); const Model = require('../models'); router.get('/', function (req, res) { - Model.Teacher.findAll() - .then(allTeachers => { - res.render('teacher', {teachers: allTeachers}); - }) - .catch(err => res.send(err)); -}) - -router.get('/tes', function (req, res) { Model.Teacher.findAll() .then(teachers => { let newTeacher = teachers.map(teacher => { return new Promise((resolve, reject) => { teacher.getSubject().then((subjectWith) => { - console.log(teacher.SubjectId == null) - if (teacher.SubjectId == null) { teacher.subject_data = 'Unassigned'; } else { @@ -30,12 +20,78 @@ router.get('/tes', function (req, res) { }); }) - - Promise.all(newTeacher) - .then((newSubject) => { - res.render('teacher', {teachers: teachers, teachersSubjects: newSubject}); - }) - }) + // Model.Teacher.findAll({include: [Model.Subject]}) + // .then((allTeach) => { + // console.log(allTeach[0].Subject); + // }); + + Promise.all(newTeacher) + .then((newSubject) => { + res.render('teacher', {teachers: teachers, teachersSubjects: newSubject}); + }) + }) +}) + + +router.get('/add', function (req, res) { + Model.Subject.findAll() + .then(allSubjects => { + res.render('add-teacher', { subjects: allSubjects, message: req.query.err}); + }) + .catch(err => res.send(err)); +}) + +router.post('/add', (req, res) => { + Model.Teacher.create({ + id: req.body.id, + first_name: req.body.first_name, + last_name: req.body.last_name, + email: req.body.email, + SubjectId: req.body.SubjectId + }) + .then(success => { + res.redirect('/teachers'); + }) + .catch(err => { + console.log(err); + var msg = encodeURIComponent(err.message); + res.redirect('/teachers/add/?err=' + msg); + }); +}) + +router.get('/edit/:id', (req, res) => { + Model.Subject.findAll() + .then(allSubjects => { + Model.Teacher.findById(req.params.id) + .then((teacherEditFound) => { + res.render('add-teacher', {subjects: allSubjects, teacherFound: teacherEditFound, message: req.query.err}); + }) + .catch(err => res.send(err)); + }) + .catch(err => res.send(err)); +}) + +router.post('/edit/', (req, res) => { + Model.Teacher.update(req.body,{ + where: { + id: req.body.id + } + }).then(success =>{ + res.redirect('/teachers'); + }).catch(err => { + var msg = encodeURIComponent(err.message); + res.redirect(`/teachers/edit/${req.body.id}/?err=`+msg); + }); +}) + +router.get('/delete/:id', (req, res) => { + Model.Teacher.destroy({ + where: { + id: req.params.id + } + }).then(success =>{ + res.redirect('/teachers'); + }).catch(err => res.send(err)); }) module.exports = router; \ No newline at end of file diff --git a/views/add-teacher.ejs b/views/add-teacher.ejs new file mode 100644 index 0000000..abe4f46 --- /dev/null +++ b/views/add-teacher.ejs @@ -0,0 +1,34 @@ + + + + + Add Teacher + + +
+

Add Teacher Data

+ Show all data +

+
+ +
+ <% if (typeof message !== 'undefined' && message !== null){ %> +

<%= message %>

+ <% } %> + +
+ + + + + + + +
+
+ + \ No newline at end of file diff --git a/views/teacher.ejs b/views/teacher.ejs index a8e0424..e8cdfc7 100644 --- a/views/teacher.ejs +++ b/views/teacher.ejs @@ -5,7 +5,12 @@ Daftar Teacher -

Teacher Data

+
+

Teacher Data

+ Add Teacher +
+
+
@@ -15,6 +20,7 @@ + @@ -30,6 +36,10 @@ <%} else { %> <% } %> + <% }); %> From 88c2e993895723dfcf76dcb8c890b0b848117ef1 Mon Sep 17 00:00:00 2001 From: fujianto Date: Sat, 4 Nov 2017 22:30:20 +0700 Subject: [PATCH 12/30] Loop da loop --- models/teacher.js | 4 ++++ routes/subject-route.js | 14 +++++++++----- views/subject.ejs | 18 ++++++++++++++++++ 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/models/teacher.js b/models/teacher.js index 2623f35..a6460f2 100644 --- a/models/teacher.js +++ b/models/teacher.js @@ -48,5 +48,9 @@ module.exports = (sequelize, DataTypes) => { Teacher.belongsTo(models.Subject); }; + Teacher.prototype.full_name = function(){ + return this.first_name +' '+this.last_name; + }; + return Teacher; }; \ No newline at end of file diff --git a/routes/subject-route.js b/routes/subject-route.js index 97cb99e..a0e6bdc 100644 --- a/routes/subject-route.js +++ b/routes/subject-route.js @@ -4,11 +4,15 @@ const Model = require('../models'); router.get('/', function (req, res) { - Model.Subject.findAll() - .then((allSubjects) => { - res.render('subject', {subjects: allSubjects}); - }) - .catch(err => res.send(err)); + Model.Subject.findAll({include: [Model.Teacher]}) + .then((allSubjects) => { + + + + // res.send(allSubjects) + res.render('subject', {subjects: allSubjects}); + }) + .catch(err => res.send(err.message)); }) module.exports = router; \ No newline at end of file diff --git a/views/subject.ejs b/views/subject.ejs index f64e3f1..c47d031 100644 --- a/views/subject.ejs +++ b/views/subject.ejs @@ -12,6 +12,8 @@ + + @@ -20,6 +22,22 @@ + + <% }); %> From 95f657b615d1360f5c1c6790f36040c2fab72a56 Mon Sep 17 00:00:00 2001 From: fujianto Date: Sun, 5 Nov 2017 00:52:59 +0700 Subject: [PATCH 13/30] Fix --- views/subject.ejs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/views/subject.ejs b/views/subject.ejs index c47d031..91d9a70 100644 --- a/views/subject.ejs +++ b/views/subject.ejs @@ -24,14 +24,8 @@ From 09ce81a069d4649aff61e3787f202992aa4bb13c Mon Sep 17 00:00:00 2001 From: fujianto Date: Sun, 5 Nov 2017 09:45:07 +0700 Subject: [PATCH 14/30] Add model StudentSubject --- .../20171105022108-create-student-subject.js | 33 +++++++++++++++++++ models/student.js | 7 +++- models/studentsubject.js | 21 ++++++++++++ models/subject.js | 1 + routes/teacher-route.js | 11 +++++-- views/add-teacher.ejs | 9 ++--- 6 files changed, 75 insertions(+), 7 deletions(-) create mode 100644 migrations/20171105022108-create-student-subject.js create mode 100644 models/studentsubject.js diff --git a/migrations/20171105022108-create-student-subject.js b/migrations/20171105022108-create-student-subject.js new file mode 100644 index 0000000..6421b15 --- /dev/null +++ b/migrations/20171105022108-create-student-subject.js @@ -0,0 +1,33 @@ +'use strict'; +module.exports = { + up: (queryInterface, Sequelize) => { + return queryInterface.createTable('StudentSubjects', { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER + }, + StudentId: { + type: Sequelize.INTEGER + }, + SubjectId: { + type: Sequelize.INTEGER + }, + Score: { + type: Sequelize.INTEGER + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE + } + }); + }, + down: (queryInterface, Sequelize) => { + return queryInterface.dropTable('StudentSubjects'); + } +}; \ No newline at end of file diff --git a/models/student.js b/models/student.js index 7e5d532..1e72e78 100644 --- a/models/student.js +++ b/models/student.js @@ -41,8 +41,13 @@ module.exports = (sequelize, DataTypes) => { } }); + Student.associate = function (models) { + Student.hasMany(models.Subject); + } + + Student.prototype.full_name = function(){ - return this.first_name +' '+this.last_name; + return this.first_name +' '+this.last_name; }; return Student; diff --git a/models/studentsubject.js b/models/studentsubject.js new file mode 100644 index 0000000..3a21e71 --- /dev/null +++ b/models/studentsubject.js @@ -0,0 +1,21 @@ +'use strict'; +module.exports = (sequelize, DataTypes) => { + var StudentSubject = sequelize.define('StudentSubject', { + StudentId: DataTypes.INTEGER, + SubjectId: DataTypes.INTEGER, + Score: DataTypes.INTEGER + }, { + classMethods: { + associate: function(models) { + // associations can be defined here + } + } + }); + + StudentSubject.associate = function (models) { + StudentSubject.belongsTo(models.Subject); + StudentSubject.belongsTo(models.Student); + } + + return StudentSubject; +}; \ No newline at end of file diff --git a/models/subject.js b/models/subject.js index b9f9399..0ed1122 100644 --- a/models/subject.js +++ b/models/subject.js @@ -12,6 +12,7 @@ module.exports = (sequelize, DataTypes) => { Subject.associate = function (models) { Subject.hasMany(models.Teacher); + Subject.hasMany(models.Student); } return Subject; diff --git a/routes/teacher-route.js b/routes/teacher-route.js index 65f25f9..68c780d 100644 --- a/routes/teacher-route.js +++ b/routes/teacher-route.js @@ -13,7 +13,7 @@ router.get('/', function (req, res) { } else { teacher.subject_data = subjectWith; } - + resolve(teacher); }) .catch(err => res.send(err)); @@ -72,7 +72,14 @@ router.get('/edit/:id', (req, res) => { }) router.post('/edit/', (req, res) => { - Model.Teacher.update(req.body,{ + console.log(req.body.SubjectId); + Model.Teacher.update({ + id: req.body.id, + first_name: req.body.first_name, + last_name: req.body.last_name, + email: req.body.email, + SubjectId: (req.body.SubjectId === '') ? null : req.body.SubjectId + },{ where: { id: req.body.id } diff --git a/views/add-teacher.ejs b/views/add-teacher.ejs index abe4f46..2c5711b 100644 --- a/views/add-teacher.ejs +++ b/views/add-teacher.ejs @@ -6,11 +6,11 @@
-

Add Teacher Data

+

Add Teacher Data

Show all data

- +
<% if (typeof message !== 'undefined' && message !== null){ %>

<%= message %>

@@ -21,12 +21,13 @@ - + +
From 03614eadbb25ee4240030f7016978c8c7a92dac2 Mon Sep 17 00:00:00 2001 From: fujianto Date: Sun, 5 Nov 2017 14:32:28 +0700 Subject: [PATCH 15/30] Part 8 tinggal give score --- models/student.js | 4 ++-- models/studentsubject.js | 8 ++++++- models/subject.js | 5 ++-- routes/student-route.js | 27 +++++++++++++++++++++ routes/subject-route.js | 26 ++++++++++++++++++--- routes/teacher-route.js | 48 ++++++++++++++++++++------------------ views/add-subject.ejs | 36 ++++++++++++++++++++++++++++ views/enrolled-student.ejs | 40 +++++++++++++++++++++++++++++++ views/student.ejs | 6 ++++- views/subject.ejs | 2 +- 10 files changed, 169 insertions(+), 33 deletions(-) create mode 100644 views/add-subject.ejs create mode 100644 views/enrolled-student.ejs diff --git a/models/student.js b/models/student.js index 1e72e78..e1f0b60 100644 --- a/models/student.js +++ b/models/student.js @@ -42,10 +42,10 @@ module.exports = (sequelize, DataTypes) => { }); Student.associate = function (models) { - Student.hasMany(models.Subject); + Student.belongsToMany(models.Subject, { through: models.StudentSubject }) + Student.hasMany(models.StudentSubject) } - Student.prototype.full_name = function(){ return this.first_name +' '+this.last_name; }; diff --git a/models/studentsubject.js b/models/studentsubject.js index 3a21e71..1f99661 100644 --- a/models/studentsubject.js +++ b/models/studentsubject.js @@ -1,5 +1,8 @@ 'use strict'; module.exports = (sequelize, DataTypes) => { + const Subject = sequelize.define('Subject', {}) + const Student = sequelize.define('Student', {}) + var StudentSubject = sequelize.define('StudentSubject', { StudentId: DataTypes.INTEGER, SubjectId: DataTypes.INTEGER, @@ -12,7 +15,10 @@ module.exports = (sequelize, DataTypes) => { } }); - StudentSubject.associate = function (models) { + StudentSubject.associate = function (models) { + // Subject.belongsToMany(Student, { through: StudentSubject }); + // Student.belongsToMany(Subject, {through: StudentSubject}); + StudentSubject.belongsTo(models.Subject); StudentSubject.belongsTo(models.Student); } diff --git a/models/subject.js b/models/subject.js index 0ed1122..0681a2d 100644 --- a/models/subject.js +++ b/models/subject.js @@ -11,8 +11,9 @@ module.exports = (sequelize, DataTypes) => { }); Subject.associate = function (models) { - Subject.hasMany(models.Teacher); - Subject.hasMany(models.Student); + Subject.hasMany (models.Teacher) + Subject.belongsToMany(models.Student, {through: models.StudentSubject}) + Subject.hasMany(models.StudentSubject) } return Subject; diff --git a/routes/student-route.js b/routes/student-route.js index 2b75ccd..d2e22a6 100644 --- a/routes/student-route.js +++ b/routes/student-route.js @@ -58,4 +58,31 @@ router.get('/delete/:id', (req, res) => { }).catch(err => res.send(err)); }) +router.get('/:id/addsubject', (req, res) => { + // res.send(req.params.id); + let arrModel = [ + Model.Student.findById(req.params.id), + Model.Subject.findAll() + ]; + + Promise.all(arrModel) + .then(allModelData => { + let studentFound = allModelData[0]; + let allSubject = allModelData[1]; + + res.render('add-subject', {studentFound: studentFound, subjects: allSubject}); + }).catch(err => res.send(err)); +}) + +router.post('/:id/addsubject', (req, res) => { + + Model.StudentSubject.create({ + StudentId : req.body.id, + SubjectId: (req.body.SubjectId !== '') ? req.body.SubjectId : null, + Score: null + }).then(allModelData => { + res.redirect('/students'); + }).catch(err => res.send(err)); +}) + module.exports = router; \ No newline at end of file diff --git a/routes/subject-route.js b/routes/subject-route.js index a0e6bdc..69b8534 100644 --- a/routes/subject-route.js +++ b/routes/subject-route.js @@ -7,12 +7,32 @@ router.get('/', function (req, res) { Model.Subject.findAll({include: [Model.Teacher]}) .then((allSubjects) => { - - - // res.send(allSubjects) res.render('subject', {subjects: allSubjects}); }) .catch(err => res.send(err.message)); }) +router.get('/:id/enrolledstudents', function (req, res) { + Model.Subject.findById(req.params.id).then(foundSubject => { + + // res.render('enrolled-student', {foundSubject: foundSubject}); + + Model.StudentSubject.findAll( + { + include: [Model.Student], + where: { + SubjectId: req.params.id + } + } + ).then(allStudentSubjectData => { + // res.send(allStudentSubjectData); + // console.log(allStudentSubjectData); + res.render('enrolled-student', {foundSubject: foundSubject, students: allStudentSubjectData}); + }).catch(err => res.send(err.message)); + + }).catch(err => res.send(err.message)); + + +}) + module.exports = router; \ No newline at end of file diff --git a/routes/teacher-route.js b/routes/teacher-route.js index 68c780d..0cde7da 100644 --- a/routes/teacher-route.js +++ b/routes/teacher-route.js @@ -3,32 +3,35 @@ const router = express.Router(); const Model = require('../models'); router.get('/', function (req, res) { - Model.Teacher.findAll() - .then(teachers => { - let newTeacher = teachers.map(teacher => { - return new Promise((resolve, reject) => { - teacher.getSubject().then((subjectWith) => { - if (teacher.SubjectId == null) { - teacher.subject_data = 'Unassigned'; - } else { - teacher.subject_data = subjectWith; - } - - resolve(teacher); - }) - .catch(err => res.send(err)); - }); - }) - // Model.Teacher.findAll({include: [Model.Subject]}) // .then((allTeach) => { - // console.log(allTeach[0].Subject); + // // console.log(allTeach[0].Subject); + // res.send(allTeach); // }); - Promise.all(newTeacher) - .then((newSubject) => { - res.render('teacher', {teachers: teachers, teachersSubjects: newSubject}); - }) + Model.Teacher.findAll() + .then(teachers => { + let newTeacher = teachers.map(teacher => { + return new Promise((resolve, reject) => { + teacher.getSubject().then((subjectWith) => { + if (teacher.SubjectId == null) { + teacher.subject_data = 'Unassigned'; + } else { + teacher.subject_data = subjectWith; + } + + resolve(teacher); + }) + .catch(err => res.send(err)); + }); + }) + + Promise.all(newTeacher) + .then((newSubject) => { + res.render('teacher', {teachers: teachers, teachersSubjects: newSubject}); + }) + + }) }) @@ -72,7 +75,6 @@ router.get('/edit/:id', (req, res) => { }) router.post('/edit/', (req, res) => { - console.log(req.body.SubjectId); Model.Teacher.update({ id: req.body.id, first_name: req.body.first_name, diff --git a/views/add-subject.ejs b/views/add-subject.ejs new file mode 100644 index 0000000..73654cd --- /dev/null +++ b/views/add-subject.ejs @@ -0,0 +1,36 @@ + + + + + Add Subject + + +
+

Add Subject Data

+ Show all data +

+
+ +
+ <% if (typeof message !== 'undefined' && message !== null){ %> +

<%= message %>

+ <% } %> + +
+ + + + + + + + + +
+ + \ No newline at end of file diff --git a/views/enrolled-student.ejs b/views/enrolled-student.ejs new file mode 100644 index 0000000..e538f8f --- /dev/null +++ b/views/enrolled-student.ejs @@ -0,0 +1,40 @@ + + + + + Enrolled Student + + +
+

<%= foundSubject.subject_name%>

+ Return to Subjects +
+

+ + +
Last Name Email SubjectAction
<%= teacher.subject_data.subject_name %> + Edit + Delete +
Id Subject NameTeacherActions
<%= subject.id %> <%= subject.subject_name %> +
    + <%= JSON.stringify(subject.Teachers) %> + <% subjects.forEach((subject, index) => { %> + + <% subject.Teachers.forEach( function(teacher, index) { %> + + <% console.log(teacher.first_name) %> +
  1. <%= teacher.full_name(); %>
  2. + <% }); %> + <% }); %> +
+
+ Enroll Students +
<%= subject.subject_name %>
    - <%= JSON.stringify(subject.Teachers) %> - <% subjects.forEach((subject, index) => { %> - - <% subject.Teachers.forEach( function(teacher, index) { %> - - <% console.log(teacher.first_name) %> -
  1. <%= teacher.full_name(); %>
  2. - <% }); %> + <% subject.Teachers.forEach((teacher, index) => { %> +
  3. <%= teacher.full_name() %>
  4. <% }); %>
+ + + + + + + + + + <% students.forEach( function(student, index) { %> + + + + + <%}); %> + +
Student NameScore
<%= student.Student.full_name(); %> + <% if(student.Score !== null) { %> + <%= student.Score; %> + <% } else { %> + Give Score + <% } %> +
+ + \ No newline at end of file diff --git a/views/student.ejs b/views/student.ejs index ef8c668..0a22349 100644 --- a/views/student.ejs +++ b/views/student.ejs @@ -21,9 +21,10 @@ Full Name Email Action + Option - + <% students.forEach( function(student, index) { %> @@ -32,6 +33,9 @@ <%= student.last_name %> <%= student.full_name() %> <%= student.email %> + + Add Subject + Edit Delete diff --git a/views/subject.ejs b/views/subject.ejs index 91d9a70..24d34de 100644 --- a/views/subject.ejs +++ b/views/subject.ejs @@ -30,7 +30,7 @@ - Enroll Students + Enrolled Students <% }); %> From 059dc39ef2d3c5d14a3bc32442e97cc6386547df Mon Sep 17 00:00:00 2001 From: fujianto Date: Sun, 5 Nov 2017 18:05:02 +0700 Subject: [PATCH 16/30] Sampai no 8 Score ok --- routes/subject-route.js | 32 ++++++++++++++++++++++++++------ views/enrolled-student.ejs | 2 +- views/give-score.ejs | 30 ++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 7 deletions(-) create mode 100644 views/give-score.ejs diff --git a/routes/subject-route.js b/routes/subject-route.js index 69b8534..baea37a 100644 --- a/routes/subject-route.js +++ b/routes/subject-route.js @@ -15,24 +15,44 @@ router.get('/', function (req, res) { router.get('/:id/enrolledstudents', function (req, res) { Model.Subject.findById(req.params.id).then(foundSubject => { - // res.render('enrolled-student', {foundSubject: foundSubject}); - Model.StudentSubject.findAll( { include: [Model.Student], where: { SubjectId: req.params.id } - } - ).then(allStudentSubjectData => { - // res.send(allStudentSubjectData); - // console.log(allStudentSubjectData); + }).then(allStudentSubjectData => { res.render('enrolled-student', {foundSubject: foundSubject, students: allStudentSubjectData}); }).catch(err => res.send(err.message)); }).catch(err => res.send(err.message)); +}) + +router.get('/:studentId/givescore', function (req, res) { + Model.StudentSubject.findOne({ + include: [Model.Student, Model.Subject], + where: { id: req.params.studentId } + }).then(foundStudentSubject => { + res.render('give-score', { foundStudentSubject: foundStudentSubject}) + + }).catch(err => res.send(err)); + +}) +router.post('/:id/givescore', function(req, res) { + Model.StudentSubject.update( + { + Score: req.body.Score + }, + { + where: { + StudentId: req.body.StudentId + } + }) + .then(allModelData => { + res.redirect('/subjects') + }).catch(err => res.send(err)); }) module.exports = router; \ No newline at end of file diff --git a/views/enrolled-student.ejs b/views/enrolled-student.ejs index e538f8f..38f427a 100644 --- a/views/enrolled-student.ejs +++ b/views/enrolled-student.ejs @@ -29,7 +29,7 @@ <% if(student.Score !== null) { %> <%= student.Score; %> <% } else { %> - Give Score + Give Score <% } %> diff --git a/views/give-score.ejs b/views/give-score.ejs new file mode 100644 index 0000000..59f2210 --- /dev/null +++ b/views/give-score.ejs @@ -0,0 +1,30 @@ + + + + + Give Score + + +
+

Give Score

+

+
+ + <% if (typeof message !== 'undefined' && message !== null){ %> +

<%= message %>

+ <% } %> + +
+

Student Name: <%= foundStudentSubject.Student.full_name() %>

+

Student Name: <%= foundStudentSubject.Subject.subject_name %>

+ +
+ + + + + +
+
+ + \ No newline at end of file From a992f7781259176613aa44cb1a7e8f60fc38a9cc Mon Sep 17 00:00:00 2001 From: fujianto Date: Sun, 5 Nov 2017 18:30:20 +0700 Subject: [PATCH 17/30] Rilis part 9 beres sorting tinggal enrolled student blom ke order --- routes/student-route.js | 2 +- routes/subject-route.js | 5 ++++- routes/teacher-route.js | 2 +- views/student.ejs | 2 ++ views/subject.ejs | 2 ++ views/teacher.ejs | 2 ++ 6 files changed, 12 insertions(+), 3 deletions(-) diff --git a/routes/student-route.js b/routes/student-route.js index d2e22a6..8f61b99 100644 --- a/routes/student-route.js +++ b/routes/student-route.js @@ -3,7 +3,7 @@ const router = express.Router(); const Model = require('../models'); router.get('/', (req, res) => { - Model.Student.findAll() + Model.Student.findAll({ order: [ ['first_name', 'ASC']] }) .then(allStudents => { res.render('student', {students: allStudents}); console.log(allStudents[0].full_name()) diff --git a/routes/subject-route.js b/routes/subject-route.js index baea37a..e28c6fe 100644 --- a/routes/subject-route.js +++ b/routes/subject-route.js @@ -17,7 +17,10 @@ router.get('/:id/enrolledstudents', function (req, res) { Model.StudentSubject.findAll( { - include: [Model.Student], + include: [{ + model: Model.Student, + order: [ [Model.Student.first_name, 'ASC'] ], + }], where: { SubjectId: req.params.id } diff --git a/routes/teacher-route.js b/routes/teacher-route.js index 0cde7da..5bd5212 100644 --- a/routes/teacher-route.js +++ b/routes/teacher-route.js @@ -9,7 +9,7 @@ router.get('/', function (req, res) { // res.send(allTeach); // }); - Model.Teacher.findAll() + Model.Teacher.findAll({ order: [ ['first_name', 'ASC'], ] }) .then(teachers => { let newTeacher = teachers.map(teacher => { return new Promise((resolve, reject) => { diff --git a/views/student.ejs b/views/student.ejs index 0a22349..848db2b 100644 --- a/views/student.ejs +++ b/views/student.ejs @@ -15,6 +15,7 @@ + @@ -28,6 +29,7 @@ <% students.forEach( function(student, index) { %> + diff --git a/views/subject.ejs b/views/subject.ejs index 24d34de..88d480e 100644 --- a/views/subject.ejs +++ b/views/subject.ejs @@ -10,6 +10,7 @@
No Id First Name Last Name
<%= index + 1 %> <%= student.id %> <%= student.first_name %> <%= student.last_name %>
+ @@ -20,6 +21,7 @@ <% subjects.forEach( function(subject, index) { %> + + <% students.forEach( function(student, index) { %> + + + + + + <%}); %> + +
No Id Subject Name Teacher
<%= index + 1 %> <%= subject.id %> <%= subject.subject_name %> diff --git a/views/teacher.ejs b/views/teacher.ejs index e8cdfc7..6c61962 100644 --- a/views/teacher.ejs +++ b/views/teacher.ejs @@ -15,6 +15,7 @@ + @@ -27,6 +28,7 @@ <% teachersSubjects.forEach( function(teacher, index) { %> + From ab94a3943ff6961361fa56b1251b8939a07904c1 Mon Sep 17 00:00:00 2001 From: fujianto Date: Sun, 5 Nov 2017 18:40:15 +0700 Subject: [PATCH 18/30] Order Enrolled student beres --- routes/subject-route.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routes/subject-route.js b/routes/subject-route.js index e28c6fe..e8ab5af 100644 --- a/routes/subject-route.js +++ b/routes/subject-route.js @@ -19,8 +19,8 @@ router.get('/:id/enrolledstudents', function (req, res) { { include: [{ model: Model.Student, - order: [ [Model.Student.first_name, 'ASC'] ], }], + order: [ [ { model: Model.Student, as: 'Student' }, 'first_name', 'ASC'] ], where: { SubjectId: req.params.id } From 7bdeb0ceccd765528a713eb8dae569f17bde878d Mon Sep 17 00:00:00 2001 From: fujianto Date: Sun, 5 Nov 2017 19:47:46 +0700 Subject: [PATCH 19/30] minor fix --- routes/teacher-route.js | 2 -- views/add-teacher.ejs | 2 +- views/enrolled-student.ejs | 3 ++- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/routes/teacher-route.js b/routes/teacher-route.js index 5bd5212..ea1c036 100644 --- a/routes/teacher-route.js +++ b/routes/teacher-route.js @@ -30,8 +30,6 @@ router.get('/', function (req, res) { .then((newSubject) => { res.render('teacher', {teachers: teachers, teachersSubjects: newSubject}); }) - - }) }) diff --git a/views/add-teacher.ejs b/views/add-teacher.ejs index 2c5711b..de4cefd 100644 --- a/views/add-teacher.ejs +++ b/views/add-teacher.ejs @@ -25,7 +25,7 @@ diff --git a/views/enrolled-student.ejs b/views/enrolled-student.ejs index 38f427a..46e3886 100644 --- a/views/enrolled-student.ejs +++ b/views/enrolled-student.ejs @@ -15,7 +15,7 @@
No Id First Name Last Name
<%= index + 1 %> <%= teacher.id %> <%= teacher.first_name %> <%= teacher.last_name %>
- + @@ -24,6 +24,7 @@ <% students.forEach( function(student, index) { %> + diff --git a/views/give-score.ejs b/views/give-score.ejs index 59f2210..4a89610 100644 --- a/views/give-score.ejs +++ b/views/give-score.ejs @@ -14,6 +14,7 @@

<%= message %>

<% } %> +

Student Name: <%= foundStudentSubject.Student.full_name() %>

Student Name: <%= foundStudentSubject.Subject.subject_name %>

From 49b0d0b4676b8415137ef68a27dd1740ca62cfd0 Mon Sep 17 00:00:00 2001 From: fujianto Date: Mon, 6 Nov 2017 11:47:29 +0700 Subject: [PATCH 21/30] Fix give score update bug --- routes/subject-route.js | 11 +++++------ views/give-score.ejs | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/routes/subject-route.js b/routes/subject-route.js index fa6f16f..4dc941a 100644 --- a/routes/subject-route.js +++ b/routes/subject-route.js @@ -12,8 +12,8 @@ router.get('/', function (req, res) { .catch(err => res.send(err.message)); }) -router.get('/:id/enrolledstudents', function (req, res) { - Model.Subject.findById(req.params.id).then(foundSubject => { +router.get('/:subjectId/enrolledstudents', function (req, res) { + Model.Subject.findById(req.params.subjectId).then(foundSubject => { Model.StudentSubject.findAll( { @@ -22,7 +22,7 @@ router.get('/:id/enrolledstudents', function (req, res) { }], order: [ [ { model: Model.Student, as: 'Student' }, 'first_name', 'ASC'] ], where: { - SubjectId: req.params.id + SubjectId: req.params.subjectId } }).then(allStudentSubjectData => { res.render('enrolled-student', {foundSubject: foundSubject, students: allStudentSubjectData}); @@ -33,6 +33,7 @@ router.get('/:id/enrolledstudents', function (req, res) { router.get('/:studentId/givescore', function (req, res) { Model.StudentSubject.findOne({ + attributes: ['id', 'StudentId', 'SubjectId', 'Score'], include: [Model.Student, Model.Subject], where: { StudentId: req.params.studentId } }).then(foundStudentSubject => { @@ -43,15 +44,13 @@ router.get('/:studentId/givescore', function (req, res) { }) router.post('/:id/givescore', function(req, res) { - Model.StudentSubject.update( { Score: req.body.Score }, { where: { - StudentId: req.body.StudentId, - SubjectId: req.body.SubjectId + id: req.body.StudentSubjectId, } }) .then(allModelData => { diff --git a/views/give-score.ejs b/views/give-score.ejs index 4a89610..1789e8b 100644 --- a/views/give-score.ejs +++ b/views/give-score.ejs @@ -14,12 +14,12 @@

<%= message %>

<% } %> -

Student Name: <%= foundStudentSubject.Student.full_name() %>

Student Name: <%= foundStudentSubject.Subject.subject_name %>

+ From d45ae257ee0d321764755f53d8ece78030d12ad7 Mon Sep 17 00:00:00 2001 From: fujianto Date: Mon, 6 Nov 2017 13:06:39 +0700 Subject: [PATCH 22/30] Fix bug conjunction give score --- routes/subject-route.js | 41 ++++++++++++++++++++------------------ views/enrolled-student.ejs | 4 ++-- views/give-score.ejs | 1 + 3 files changed, 25 insertions(+), 21 deletions(-) diff --git a/routes/subject-route.js b/routes/subject-route.js index 4dc941a..319ce0c 100644 --- a/routes/subject-route.js +++ b/routes/subject-route.js @@ -13,30 +13,31 @@ router.get('/', function (req, res) { }) router.get('/:subjectId/enrolledstudents', function (req, res) { - Model.Subject.findById(req.params.subjectId).then(foundSubject => { - - Model.StudentSubject.findAll( - { - include: [{ - model: Model.Student, - }], - order: [ [ { model: Model.Student, as: 'Student' }, 'first_name', 'ASC'] ], - where: { - SubjectId: req.params.subjectId - } - }).then(allStudentSubjectData => { - res.render('enrolled-student', {foundSubject: foundSubject, students: allStudentSubjectData}); - }).catch(err => res.send(err.message)); - - }).catch(err => res.send(err.message)); + Model.StudentSubject.findAll( + { + attributes: ['id', 'StudentId', 'SubjectId', 'Score'], + where: { + SubjectId: req.params.subjectId, + }, + include: [{ + model: Model.Student, + }], + order: [ [ { model: Model.Student, as: 'Student' }, 'first_name', 'ASC'] ] + }).then(allStudentSubjectData => { + res.render('enrolled-student', {students: allStudentSubjectData}); + }).catch(err => res.send(err.message)) }) -router.get('/:studentId/givescore', function (req, res) { +router.get('/:subjectId/givescore', function (req, res) { Model.StudentSubject.findOne({ attributes: ['id', 'StudentId', 'SubjectId', 'Score'], - include: [Model.Student, Model.Subject], - where: { StudentId: req.params.studentId } + where: { id: req.params.subjectId }, + include: [ + { model: Model.Student}, + { model: Model.Subject} + ] }).then(foundStudentSubject => { + // res.send(foundStudentSubject); res.render('give-score', { foundStudentSubject: foundStudentSubject}) }).catch(err => res.send(err)); @@ -51,6 +52,8 @@ router.post('/:id/givescore', function(req, res) { { where: { id: req.body.StudentSubjectId, + StudentId: req.body.StudentId, + SubjectId: req.body.SubjectId } }) .then(allModelData => { diff --git a/views/enrolled-student.ejs b/views/enrolled-student.ejs index 9567f69..13c3b96 100644 --- a/views/enrolled-student.ejs +++ b/views/enrolled-student.ejs @@ -6,7 +6,7 @@
-

<%= foundSubject.subject_name%>

+ Return to Subjects


@@ -30,7 +30,7 @@ <% if(student.Score !== null) { %> <%= student.Score; %> <% } else { %> - Give Score + Give Score <% } %> diff --git a/views/give-score.ejs b/views/give-score.ejs index 1789e8b..bd71fa1 100644 --- a/views/give-score.ejs +++ b/views/give-score.ejs @@ -14,6 +14,7 @@

<%= message %>

<% } %> +

Student Name: <%= foundStudentSubject.Student.full_name() %>

Student Name: <%= foundStudentSubject.Subject.subject_name %>

From 5c2c8d5cba93f6f9a0903f76a44b4626168b449f Mon Sep 17 00:00:00 2001 From: fujianto Date: Mon, 6 Nov 2017 13:17:10 +0700 Subject: [PATCH 23/30] Minor fix --- routes/subject-route.js | 10 ++++++- views/enrolled-student.ejs | 53 ++++++++++++++++++++------------------ 2 files changed, 37 insertions(+), 26 deletions(-) diff --git a/routes/subject-route.js b/routes/subject-route.js index 319ce0c..6e90f06 100644 --- a/routes/subject-route.js +++ b/routes/subject-route.js @@ -24,7 +24,15 @@ router.get('/:subjectId/enrolledstudents', function (req, res) { }], order: [ [ { model: Model.Student, as: 'Student' }, 'first_name', 'ASC'] ] }).then(allStudentSubjectData => { - res.render('enrolled-student', {students: allStudentSubjectData}); + + Model.Subject.findOne({ + where: { + id: req.params.subjectId, + } + }).then(foundSubject => { + res.render('enrolled-student', {foundSubject: foundSubject, students: allStudentSubjectData}); + }).catch(err => res.send(err)); + }).catch(err => res.send(err.message)) }) diff --git a/views/enrolled-student.ejs b/views/enrolled-student.ejs index 13c3b96..394f46e 100644 --- a/views/enrolled-student.ejs +++ b/views/enrolled-student.ejs @@ -6,36 +6,39 @@
- +

<%= foundSubject.subject_name %>

Return to Subjects


- -
No Student Name Score
<%= index+1 %> <%= student.Student.full_name(); %> <% if(student.Score !== null) { %> From 5e4ad5d15ed809ead4c2aad8fd24a87e200d67f5 Mon Sep 17 00:00:00 2001 From: fujianto Date: Mon, 6 Nov 2017 11:02:06 +0700 Subject: [PATCH 20/30] Fix bug give score salah kondisi where --- routes/subject-route.js | 7 ++++--- views/enrolled-student.ejs | 2 +- views/give-score.ejs | 1 + 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/routes/subject-route.js b/routes/subject-route.js index e8ab5af..fa6f16f 100644 --- a/routes/subject-route.js +++ b/routes/subject-route.js @@ -34,7 +34,7 @@ router.get('/:id/enrolledstudents', function (req, res) { router.get('/:studentId/givescore', function (req, res) { Model.StudentSubject.findOne({ include: [Model.Student, Model.Subject], - where: { id: req.params.studentId } + where: { StudentId: req.params.studentId } }).then(foundStudentSubject => { res.render('give-score', { foundStudentSubject: foundStudentSubject}) @@ -50,11 +50,12 @@ router.post('/:id/givescore', function(req, res) { }, { where: { - StudentId: req.body.StudentId + StudentId: req.body.StudentId, + SubjectId: req.body.SubjectId } }) .then(allModelData => { - res.redirect('/subjects') + res.redirect(`/subjects/${req.body.SubjectId}/enrolledstudents`) }).catch(err => res.send(err)); }) diff --git a/views/enrolled-student.ejs b/views/enrolled-student.ejs index 46e3886..9567f69 100644 --- a/views/enrolled-student.ejs +++ b/views/enrolled-student.ejs @@ -30,7 +30,7 @@ <% if(student.Score !== null) { %> <%= student.Score; %> <% } else { %> - Give Score + Give Score <% } %>
- - - - - - - - - - <% students.forEach( function(student, index) { %> + <% if (students.length > 0){ %> +
NoStudent NameScore
+ - - - + + + - <%}); %> - -
<%= index+1 %><%= student.Student.full_name(); %> - <% if(student.Score !== null) { %> - <%= student.Score; %> - <% } else { %> - Give Score - <% } %> - NoStudent NameScore
+ + +
<%= index+1 %><%= student.Student.full_name(); %> + <% if(student.Score !== null) { %> + <%= student.Score; %> + <% } else { %> + Give Score + <% } %> +
+ <%} else { %> +

Belum ada murid

+ <% } %> \ No newline at end of file From 57df1387228f8c85b1fd7b0f3a32772e1ba134e1 Mon Sep 17 00:00:00 2001 From: fujianto Date: Mon, 6 Nov 2017 13:22:53 +0700 Subject: [PATCH 24/30] handle when user deleted --- routes/student-route.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/routes/student-route.js b/routes/student-route.js index 8f61b99..41bb78f 100644 --- a/routes/student-route.js +++ b/routes/student-route.js @@ -54,8 +54,14 @@ router.get('/delete/:id', (req, res) => { id: req.params.id } }).then(success =>{ + Model.StudentSubject.destroy({ + where: { + StudentId: req.params.id + } + }) res.redirect('/students'); }).catch(err => res.send(err)); + }) router.get('/:id/addsubject', (req, res) => { From b7d54fc87194476cd6135a762dc9a98ec3253a77 Mon Sep 17 00:00:00 2001 From: fujianto Date: Mon, 6 Nov 2017 13:41:56 +0700 Subject: [PATCH 25/30] Minor fix --- routes/subject-route.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/routes/subject-route.js b/routes/subject-route.js index 6e90f06..74f0868 100644 --- a/routes/subject-route.js +++ b/routes/subject-route.js @@ -15,14 +15,14 @@ router.get('/', function (req, res) { router.get('/:subjectId/enrolledstudents', function (req, res) { Model.StudentSubject.findAll( { + order: [ [{model: Model.Student}, 'first_name', 'ASC'] ], attributes: ['id', 'StudentId', 'SubjectId', 'Score'], where: { SubjectId: req.params.subjectId, }, include: [{ model: Model.Student, - }], - order: [ [ { model: Model.Student, as: 'Student' }, 'first_name', 'ASC'] ] + }] }).then(allStudentSubjectData => { Model.Subject.findOne({ From db4ee72ddefe345ae43b61c1391a049eb2e83db8 Mon Sep 17 00:00:00 2001 From: fujianto Date: Mon, 6 Nov 2017 14:00:13 +0700 Subject: [PATCH 26/30] add menu with partials --- views/add-student.ejs | 6 ++++-- views/add-subject.ejs | 1 + views/add-teacher.ejs | 1 + views/enrolled-student.ejs | 1 + views/give-score.ejs | 1 + views/index.ejs | 2 +- views/partials/menu.ejs | 34 ++++++++++++++++++++++++++++++++++ views/student.ejs | 1 + views/subject.ejs | 1 + views/teacher.ejs | 1 + 10 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 views/partials/menu.ejs diff --git a/views/add-student.ejs b/views/add-student.ejs index d8aa2ac..2c36b47 100644 --- a/views/add-student.ejs +++ b/views/add-student.ejs @@ -5,12 +5,14 @@ Add Student + <%include ./partials/menu %> +
-

Add Student Data

+

Add Student Data

Show all data

- + <% if(typeof studentFound !== 'undefined' && studentFound !== null) { %>
Editing user <%= studentFound.first_name %>
<% } %> diff --git a/views/add-subject.ejs b/views/add-subject.ejs index 73654cd..cfb2666 100644 --- a/views/add-subject.ejs +++ b/views/add-subject.ejs @@ -5,6 +5,7 @@ Add Subject + <%include ./partials/menu %>

Add Subject Data

Show all data diff --git a/views/add-teacher.ejs b/views/add-teacher.ejs index de4cefd..cb12916 100644 --- a/views/add-teacher.ejs +++ b/views/add-teacher.ejs @@ -5,6 +5,7 @@ Add Teacher + <%include ./partials/menu %>

Add Teacher Data

Show all data diff --git a/views/enrolled-student.ejs b/views/enrolled-student.ejs index 394f46e..b823e34 100644 --- a/views/enrolled-student.ejs +++ b/views/enrolled-student.ejs @@ -5,6 +5,7 @@ Enrolled Student + <%include ./partials/menu %>

<%= foundSubject.subject_name %>

Return to Subjects diff --git a/views/give-score.ejs b/views/give-score.ejs index bd71fa1..5390fdf 100644 --- a/views/give-score.ejs +++ b/views/give-score.ejs @@ -5,6 +5,7 @@ Give Score + <%include ./partials/menu %>

Give Score



diff --git a/views/index.ejs b/views/index.ejs index 1b2ff20..b80ad66 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -6,5 +6,5 @@

Home

- + <% include ./partials/menu %> \ No newline at end of file diff --git a/views/partials/menu.ejs b/views/partials/menu.ejs new file mode 100644 index 0000000..304b78c --- /dev/null +++ b/views/partials/menu.ejs @@ -0,0 +1,34 @@ + + + \ No newline at end of file diff --git a/views/student.ejs b/views/student.ejs index 848db2b..aa663d5 100644 --- a/views/student.ejs +++ b/views/student.ejs @@ -5,6 +5,7 @@ Students + <%include ./partials/menu %>

Student Data

Add Student diff --git a/views/subject.ejs b/views/subject.ejs index 88d480e..6934add 100644 --- a/views/subject.ejs +++ b/views/subject.ejs @@ -5,6 +5,7 @@ Subject + <%include ./partials/menu %>

Subjects

diff --git a/views/teacher.ejs b/views/teacher.ejs index 6c61962..2cb3d45 100644 --- a/views/teacher.ejs +++ b/views/teacher.ejs @@ -5,6 +5,7 @@ Daftar Teacher + <%include ./partials/menu %>

Teacher Data

Add Teacher From 94e737a3b74b24acac7599979f8db635c0df2c93 Mon Sep 17 00:00:00 2001 From: fujianto Date: Mon, 6 Nov 2017 15:23:13 +0700 Subject: [PATCH 27/30] Finish partial --- views/add-student.ejs | 55 +++++++++++------------ views/add-subject.ejs | 16 +++---- views/add-teacher.ejs | 20 +++------ views/enrolled-student.ejs | 14 ++---- views/give-score.ejs | 16 +++---- views/index.ejs | 12 +---- views/partials/footer.ejs | 2 + views/partials/header.ejs | 65 +++++++++++++++++++++++++++ views/partials/menu.ejs | 34 -------------- views/student.ejs | 16 +++---- views/subject.ejs | 16 +++---- views/teacher.ejs | 90 ++++++++++++++++++-------------------- 12 files changed, 172 insertions(+), 184 deletions(-) create mode 100644 views/partials/footer.ejs create mode 100644 views/partials/header.ejs delete mode 100644 views/partials/menu.ejs diff --git a/views/add-student.ejs b/views/add-student.ejs index 2c36b47..2376f93 100644 --- a/views/add-student.ejs +++ b/views/add-student.ejs @@ -1,35 +1,30 @@ - - - - - Add Student - - - <%include ./partials/menu %> +<%- include('partials/header', {title: 'Tambah Student'}) %> -
-

Add Student Data

- Show all data -

-
+
+
+

Add Student Data

+ Show all data +

+
- <% if(typeof studentFound !== 'undefined' && studentFound !== null) { %> -
Editing user <%= studentFound.first_name %>
- <% } %> + <% if(typeof studentFound !== 'undefined' && studentFound !== null) { %> +
Editing user <%= studentFound.first_name %>
+ <% } %> - <% if (typeof message !== 'undefined' && message !== null){ %> -

<%= message %>

- <% } %> + <% if (typeof message !== 'undefined' && message !== null){ %> +

<%= message %>

+ <% } %> -
- - - - - +
+ + + + + - - -
- - \ No newline at end of file + + +
+
+ +<%- include('partials/footer') %> diff --git a/views/add-subject.ejs b/views/add-subject.ejs index cfb2666..b5f745d 100644 --- a/views/add-subject.ejs +++ b/views/add-subject.ejs @@ -1,11 +1,6 @@ - - - - - Add Subject - - - <%include ./partials/menu %> +<%- include('partials/header', {title: 'Tambah Subject'}) %> + +

Add Subject Data

Show all data @@ -33,5 +28,6 @@
- - \ No newline at end of file +
+ +<%- include('partials/footer') %> \ No newline at end of file diff --git a/views/add-teacher.ejs b/views/add-teacher.ejs index cb12916..8a7a843 100644 --- a/views/add-teacher.ejs +++ b/views/add-teacher.ejs @@ -1,11 +1,5 @@ - - - - - Add Teacher - - - <%include ./partials/menu %> +<%- include('partials/header', {title: 'Add Teacher'}) %> +

Add Teacher Data

Show all data @@ -25,12 +19,12 @@
- - \ No newline at end of file + +<%- include('partials/footer') %> \ No newline at end of file diff --git a/views/enrolled-student.ejs b/views/enrolled-student.ejs index b823e34..d55f51e 100644 --- a/views/enrolled-student.ejs +++ b/views/enrolled-student.ejs @@ -1,11 +1,5 @@ - - - - - Enrolled Student - - - <%include ./partials/menu %> +<%- include('partials/header', {title: 'Enrolled Students'}) %> +

<%= foundSubject.subject_name %>

Return to Subjects @@ -41,5 +35,5 @@ <%} else { %>

Belum ada murid

<% } %> - - \ No newline at end of file + +<%- include('partials/footer') %> \ No newline at end of file diff --git a/views/give-score.ejs b/views/give-score.ejs index 5390fdf..3d9f4d6 100644 --- a/views/give-score.ejs +++ b/views/give-score.ejs @@ -1,11 +1,6 @@ - - - - - Give Score - - - <%include ./partials/menu %> +<%- include('partials/header', {title: 'Give score'}) %> + +

Give Score



@@ -29,5 +24,6 @@
- - \ No newline at end of file +
+ +<%- include('partials/footer') %> \ No newline at end of file diff --git a/views/index.ejs b/views/index.ejs index b80ad66..4fabe9f 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -1,10 +1,2 @@ - - - - - Index - - -

Home

- <% include ./partials/menu %> - \ No newline at end of file +<%- include('partials/header', {title: 'Index'}) %> +<%- include('partials/footer') %> \ No newline at end of file diff --git a/views/partials/footer.ejs b/views/partials/footer.ejs new file mode 100644 index 0000000..691287b --- /dev/null +++ b/views/partials/footer.ejs @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/views/partials/header.ejs b/views/partials/header.ejs new file mode 100644 index 0000000..e5d04ce --- /dev/null +++ b/views/partials/header.ejs @@ -0,0 +1,65 @@ + + + + + <%= title %> + + + + + + \ No newline at end of file diff --git a/views/partials/menu.ejs b/views/partials/menu.ejs deleted file mode 100644 index 304b78c..0000000 --- a/views/partials/menu.ejs +++ /dev/null @@ -1,34 +0,0 @@ - - - \ No newline at end of file diff --git a/views/student.ejs b/views/student.ejs index aa663d5..4f453ba 100644 --- a/views/student.ejs +++ b/views/student.ejs @@ -1,11 +1,6 @@ - - - - - Students - - - <%include ./partials/menu %> +<%- include('partials/header', {title: 'Student'}) %> + +

Student Data

Add Student @@ -53,5 +48,6 @@ return confirm("Delete this student?"); } - - \ No newline at end of file +
+ +<%- include('partials/footer') %> \ No newline at end of file diff --git a/views/subject.ejs b/views/subject.ejs index 6934add..caf0b5c 100644 --- a/views/subject.ejs +++ b/views/subject.ejs @@ -1,11 +1,6 @@ - - - - - Subject - - - <%include ./partials/menu %> +<%- include('partials/header', {title: 'Subject'}) %> + +

Subjects

@@ -39,5 +34,6 @@ <% }); %>
- - \ No newline at end of file + + +<%- include('partials/footer') %> diff --git a/views/teacher.ejs b/views/teacher.ejs index 2cb3d45..cb06ab4 100644 --- a/views/teacher.ejs +++ b/views/teacher.ejs @@ -1,51 +1,47 @@ - - - - - Daftar Teacher - - - <%include ./partials/menu %> -
-

Teacher Data

- Add Teacher -
-
-
+<%- include('partials/header', {title: 'Teacher'}) %> - - - - - - - - - - - - +
+
+

Teacher Data

+ Add Teacher +
+
+
-
- <% teachersSubjects.forEach( function(teacher, index) { %> +
NoIdFirst NameLast NameEmailSubjectAction
+ - - - - - - <% if (teacher.subject_data.subject_name == null){ %> - - <%} else { %> - - <% } %> - + + + + + + + - <% }); %> - -
<%= index + 1 %><%= teacher.id %><%= teacher.first_name %><%= teacher.last_name %><%= teacher.email %><%= teacher.subject_data %><%= teacher.subject_data.subject_name %> - Edit - Delete - NoIdFirst NameLast NameEmailSubjectAction
- - \ No newline at end of file + + + + <% teachersSubjects.forEach( function(teacher, index) { %> + + <%= index + 1 %> + <%= teacher.id %> + <%= teacher.first_name %> + <%= teacher.last_name %> + <%= teacher.email %> + <% if (teacher.subject_data.subject_name == null){ %> + <%= teacher.subject_data %> + <%} else { %> + <%= teacher.subject_data.subject_name %> + <% } %> + + Edit + Delete + + + <% }); %> + + + + +<%- include('partials/footer') %> From 09fa9b2393f0ea8c9e7ce10b95998e9b4772c42e Mon Sep 17 00:00:00 2001 From: fujianto Date: Mon, 6 Nov 2017 15:57:10 +0700 Subject: [PATCH 28/30] Tambah helper function untuk table enrolled student --- helpers/helper.js | 27 +++++++++++++++++++++++++++ routes/student-route.js | 1 - routes/subject-route.js | 8 +++++++- views/enrolled-student.ejs | 2 ++ 4 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 helpers/helper.js diff --git a/helpers/helper.js b/helpers/helper.js new file mode 100644 index 0000000..6f20f5b --- /dev/null +++ b/helpers/helper.js @@ -0,0 +1,27 @@ +class Helper { + static getScoreLetter(score) { + let result = ''; + + if (score === null || typeof score === 'undefined') { + return 'Empty'; + } + + if (score > 85) { + return result = 'A'; + } + + if (score > 70) { + return result = 'B' + } + + if (score > 55) { + return result = 'C' + } + + if (score <= 55) { + return result = 'E' + } + } +} + +module.exports = Helper; \ No newline at end of file diff --git a/routes/student-route.js b/routes/student-route.js index 41bb78f..b267413 100644 --- a/routes/student-route.js +++ b/routes/student-route.js @@ -21,7 +21,6 @@ router.post('/add', (req, res) => { res.redirect('/students'); }) .catch(err => { - console.log(err); var msg = encodeURIComponent(err.message); res.redirect('/students/add/?err=' + msg); }); diff --git a/routes/subject-route.js b/routes/subject-route.js index 74f0868..a8e7e1c 100644 --- a/routes/subject-route.js +++ b/routes/subject-route.js @@ -1,7 +1,7 @@ const express = require('express'); const router = express.Router(); const Model = require('../models'); - +const Helper = require('../helpers/helper'); router.get('/', function (req, res) { Model.Subject.findAll({include: [Model.Teacher]}) @@ -30,10 +30,16 @@ router.get('/:subjectId/enrolledstudents', function (req, res) { id: req.params.subjectId, } }).then(foundSubject => { + + allStudentSubjectData.forEach( function(student, index) { + student.scoreLetter = Helper.getScoreLetter(student.Score); + }); + res.render('enrolled-student', {foundSubject: foundSubject, students: allStudentSubjectData}); }).catch(err => res.send(err)); }).catch(err => res.send(err.message)) + }) router.get('/:subjectId/givescore', function (req, res) { diff --git a/views/enrolled-student.ejs b/views/enrolled-student.ejs index d55f51e..03d8d3e 100644 --- a/views/enrolled-student.ejs +++ b/views/enrolled-student.ejs @@ -13,6 +13,7 @@ No Student Name Score + Score Letter @@ -28,6 +29,7 @@ Give Score <% } %> + <%= student.scoreLetter %> <%}); %> From 35105bd0fb114ae894b96bfb96707513607e200a Mon Sep 17 00:00:00 2001 From: fujianto Date: Mon, 6 Nov 2017 16:12:38 +0700 Subject: [PATCH 29/30] Add class helper on ejs --- app.js | 3 ++- views/enrolled-student.ejs | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app.js b/app.js index d1af08c..2299a27 100644 --- a/app.js +++ b/app.js @@ -9,11 +9,12 @@ const teacherRoute = require('./routes/teacher-route'); const subjectRoute = require('./routes/subject-route'); const studentRoute = require('./routes/student-route'); - app.set('view engine', 'ejs'); app.use(bodyParser.urlencoded({ extended: false })) app.use(bodyParser.json()) +app.locals.Helper = require('./helpers/helper') + app.use('/', indexRoute); app.use('/teachers', teacherRoute); app.use('/subjects', subjectRoute); diff --git a/views/enrolled-student.ejs b/views/enrolled-student.ejs index 03d8d3e..cda57c2 100644 --- a/views/enrolled-student.ejs +++ b/views/enrolled-student.ejs @@ -29,7 +29,8 @@ Give Score <% } %> - <%= student.scoreLetter %> + + <%= Helper.getScoreLetter(student.Score) %> <%}); %> From 7e9ca0f9a4257ca088fb9ee17db25ecd50aa24c4 Mon Sep 17 00:00:00 2001 From: Septian Ahmad Fujianto Date: Thu, 9 Nov 2017 17:17:41 +0700 Subject: [PATCH 30/30] Ready to deploy --- app.js | 6 +- config/config.json | 13 +- migrations/20171107142807-create-account.js | 33 + models/account.js | 29 + package-lock.json | 1475 +++++++++++++++++ package.json | 9 +- routes/index-route.js | 53 + routes/student-route.js | 9 + routes/subject-route.js | 21 +- seeders/20171107142905-insert-account-data.js | 43 + test_validation.js | 7 - views/login.ejs | 17 + views/partials/header.ejs | 2 + views/register.ejs | 19 + 14 files changed, 1712 insertions(+), 24 deletions(-) create mode 100644 migrations/20171107142807-create-account.js create mode 100644 models/account.js create mode 100644 seeders/20171107142905-insert-account-data.js delete mode 100644 test_validation.js create mode 100644 views/login.ejs create mode 100644 views/register.ejs diff --git a/app.js b/app.js index 2299a27..7609ea4 100644 --- a/app.js +++ b/app.js @@ -2,6 +2,7 @@ const express = require('express') const app = express() const ejs = require('ejs') const bodyParser = require('body-parser'); +const session = require('express-session') // Router const indexRoute = require('./routes/index-route'); @@ -12,6 +13,9 @@ const studentRoute = require('./routes/student-route'); app.set('view engine', 'ejs'); app.use(bodyParser.urlencoded({ extended: false })) app.use(bodyParser.json()) +app.use(session({ + secret: 'schoolmania' +})) app.locals.Helper = require('./helpers/helper') @@ -20,6 +24,6 @@ app.use('/teachers', teacherRoute); app.use('/subjects', subjectRoute); app.use('/students', studentRoute); -app.listen(3002, function () { +app.listen(process.env.PORT || '3000', function () { console.log('Example app listening on port 3000!') }) \ No newline at end of file diff --git a/config/config.json b/config/config.json index 49c8a1b..946087d 100644 --- a/config/config.json +++ b/config/config.json @@ -6,18 +6,7 @@ "host": "127.0.0.1", "dialect": "postgres" }, - "test": { - "username": "postgres", - "password": "postgres", - "database": "school_db", - "host": "127.0.0.1", - "dialect": "postgres" - }, "production": { - "username": "postgres", - "password": "postgres", - "database": "school_db", - "host": "127.0.0.1", - "dialect": "postgres" + "use_env_variable": "DATABASE_URL" } } diff --git a/migrations/20171107142807-create-account.js b/migrations/20171107142807-create-account.js new file mode 100644 index 0000000..edd208d --- /dev/null +++ b/migrations/20171107142807-create-account.js @@ -0,0 +1,33 @@ +'use strict'; +module.exports = { + up: (queryInterface, Sequelize) => { + return queryInterface.createTable('Accounts', { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER + }, + username: { + type: Sequelize.STRING + }, + password: { + type: Sequelize.STRING + }, + StudentId: { + type: Sequelize.INTEGER + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE + } + }); + }, + down: (queryInterface, Sequelize) => { + return queryInterface.dropTable('Accounts'); + } +}; \ No newline at end of file diff --git a/models/account.js b/models/account.js new file mode 100644 index 0000000..00d7daf --- /dev/null +++ b/models/account.js @@ -0,0 +1,29 @@ +'use strict'; +const bcrypt = require('bcrypt'); + +module.exports = (sequelize, DataTypes) => { + var Account = sequelize.define('Account', { + username: DataTypes.STRING, + password: DataTypes.STRING, + StudentId: DataTypes.INTEGER + }, { + classMethods: { + associate: function(models) { + // associations can be defined here + } + } + }); + + // Hook + Account.beforeCreate((account, options) => { + const saltRounds = 10; + let plainPassword = account.password; + + return bcrypt.hash(plainPassword, saltRounds).then(function(hash) { + account.password = hash; + }); + }); + + + return Account; +}; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index e67a189..576a73c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,11 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-8.0.47.tgz", "integrity": "sha512-kOwL746WVvt/9Phf6/JgX/bsGQvbrK5iUgzyfwZNcKVFcjAUVSpF9HxevLTld2SG9aywYHOILj38arDdY1r/iQ==" }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, "accepts": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz", @@ -23,11 +28,106 @@ "negotiator": "0.6.1" } }, + "ajv": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.3.0.tgz", + "integrity": "sha1-RBT/dKUIecII7l/cgm4ywwNUnto=", + "requires": { + "co": "4.6.0", + "fast-deep-equal": "1.0.0", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1" + } + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + }, + "are-we-there-yet": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz", + "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=", + "requires": { + "delegates": "1.0.0", + "readable-stream": "2.3.3" + } + }, "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" }, + "asn1": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", + "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=" + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", + "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=" + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "requires": { + "core-js": "2.5.1", + "regenerator-runtime": "0.11.0" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "bcrypt": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-1.0.3.tgz", + "integrity": "sha512-pRyDdo73C8Nim3jwFJ7DWe3TZCgwDfWZ6nHS5LSdU77kWbj1frruvdndP02AOavtD4y8v6Fp2dolbHgp4SDrfg==", + "requires": { + "nan": "2.6.2", + "node-pre-gyp": "0.6.36" + } + }, + "bcrypt-pbkdf": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", + "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", + "optional": true, + "requires": { + "tweetnacl": "0.14.5" + } + }, + "block-stream": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", + "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", + "requires": { + "inherits": "2.0.3" + } + }, "bluebird": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", @@ -50,16 +150,71 @@ "type-is": "1.6.15" } }, + "boom": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", + "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", + "requires": { + "hoek": "4.2.0" + } + }, + "brace-expansion": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", + "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", + "requires": { + "balanced-match": "1.0.0", + "concat-map": "0.0.1" + } + }, "buffer-writer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-1.0.1.tgz", "integrity": "sha1-Iqk2kB4wKa/NdUfrRIfOtpejvwg=" }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" + }, "bytes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "cli-color": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-1.2.0.tgz", + "integrity": "sha1-OlrnT9drYmevZm5p4q+70B3vNNE=", + "requires": { + "ansi-regex": "2.1.1", + "d": "1.0.0", + "es5-ext": "0.10.35", + "es6-iterator": "2.0.3", + "memoizee": "0.4.11", + "timers-ext": "0.1.2" + } + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wrap-ansi": "2.1.0" + } + }, "cls-bluebird": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/cls-bluebird/-/cls-bluebird-2.0.1.tgz", @@ -69,6 +224,48 @@ "shimmer": "1.1.0" } }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "combined-stream": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", + "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", + "requires": { + "delayed-stream": "1.0.0" + } + }, + "commander": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "config-chain": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.11.tgz", + "integrity": "sha1-q6CXR9++TD5w52am5BWG4YWfxvI=", + "requires": { + "ini": "1.3.4", + "proto-list": "1.2.4" + } + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + }, "content-disposition": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", @@ -89,6 +286,76 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" }, + "core-js": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.1.tgz", + "integrity": "sha1-rmh03GaTd4m4B1T/VCjfZoGcpQs=" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "crc": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/crc/-/crc-3.4.4.tgz", + "integrity": "sha1-naHpgOO9RPxck79as9ozeNheRms=" + }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "requires": { + "lru-cache": "4.1.1", + "shebang-command": "1.2.0", + "which": "1.3.0" + }, + "dependencies": { + "lru-cache": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", + "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", + "requires": { + "pseudomap": "1.0.2", + "yallist": "2.1.2" + } + } + } + }, + "cryptiles": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", + "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", + "requires": { + "boom": "5.2.0" + }, + "dependencies": { + "boom": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", + "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", + "requires": { + "hoek": "4.2.0" + } + } + } + }, + "d": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", + "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "requires": { + "es5-ext": "0.10.35" + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "1.0.0" + } + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -97,6 +364,26 @@ "ms": "2.0.0" } }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "deep-extend": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz", + "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=" + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + }, "depd": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", @@ -112,6 +399,34 @@ "resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.0.tgz", "integrity": "sha1-2hkZgci41xPKARXViYzzl8Lw3dA=" }, + "ecc-jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", + "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", + "optional": true, + "requires": { + "jsbn": "0.1.1" + } + }, + "editorconfig": { + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.13.3.tgz", + "integrity": "sha512-WkjsUNVCu+ITKDj73QDvi0trvpdDWdkDyHybDGSXPfekLCqwmpD7CP7iPbvBgosNuLcI96XTDwNa75JyFl7tEQ==", + "requires": { + "bluebird": "3.5.1", + "commander": "2.11.0", + "lru-cache": "3.2.0", + "semver": "5.4.1", + "sigmund": "1.0.1" + }, + "dependencies": { + "semver": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==" + } + } + }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -127,6 +442,53 @@ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz", "integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA=" }, + "error-ex": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", + "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", + "requires": { + "is-arrayish": "0.2.1" + } + }, + "es5-ext": { + "version": "0.10.35", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.35.tgz", + "integrity": "sha1-GO6FjOajxFx9eekcFfzKnsVoSU8=", + "requires": { + "es6-iterator": "2.0.3", + "es6-symbol": "3.1.1" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.35", + "es6-symbol": "3.1.1" + } + }, + "es6-symbol": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", + "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.35" + } + }, + "es6-weak-map": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", + "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.35", + "es6-iterator": "2.0.3", + "es6-symbol": "3.1.1" + } + }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -137,6 +499,29 @@ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" }, + "event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.35" + } + }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "requires": { + "cross-spawn": "5.1.0", + "get-stream": "3.0.0", + "is-stream": "1.1.0", + "npm-run-path": "2.0.2", + "p-finally": "1.0.0", + "signal-exit": "3.0.2", + "strip-eof": "1.0.0" + } + }, "express": { "version": "4.16.2", "resolved": "https://registry.npmjs.org/express/-/express-4.16.2.tgz", @@ -186,6 +571,42 @@ } } }, + "express-session": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.15.6.tgz", + "integrity": "sha512-r0nrHTCYtAMrFwZ0kBzZEXa1vtPVrw0dKvGSrKP4dahwBQ1BJpF2/y1Pp4sCD/0kvxV4zZeclyvfmw0B4RMJQA==", + "requires": { + "cookie": "0.3.1", + "cookie-signature": "1.0.6", + "crc": "3.4.4", + "debug": "2.6.9", + "depd": "1.1.1", + "on-headers": "1.0.1", + "parseurl": "1.3.2", + "uid-safe": "2.1.5", + "utils-merge": "1.0.1" + } + }, + "extend": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", + "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=" + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "fast-deep-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz", + "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=" + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + }, "finalhandler": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", @@ -207,6 +628,29 @@ } } }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "requires": { + "locate-path": "2.0.0" + } + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz", + "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=", + "requires": { + "asynckit": "0.4.0", + "combined-stream": "1.0.5", + "mime-types": "2.1.17" + } + }, "forwarded": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", @@ -217,11 +661,138 @@ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" }, + "fs-extra": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.2.tgz", + "integrity": "sha1-+RcExT0bRh+JNFKwwwfZmXZHq2s=", + "requires": { + "graceful-fs": "4.1.11", + "jsonfile": "4.0.0", + "universalify": "0.1.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fstream": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", + "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", + "requires": { + "graceful-fs": "4.1.11", + "inherits": "2.0.3", + "mkdirp": "0.5.1", + "rimraf": "2.6.2" + } + }, + "fstream-ignore": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/fstream-ignore/-/fstream-ignore-1.0.5.tgz", + "integrity": "sha1-nDHa40dnAY/h0kmyTa2mfQktoQU=", + "requires": { + "fstream": "1.0.11", + "inherits": "2.0.3", + "minimatch": "3.0.4" + } + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "requires": { + "aproba": "1.2.0", + "console-control-strings": "1.1.0", + "has-unicode": "2.0.1", + "object-assign": "4.1.1", + "signal-exit": "3.0.2", + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "wide-align": "1.1.2" + } + }, "generic-pool": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.2.0.tgz", "integrity": "sha512-JjcXDHT84icN/kFaF5+rNd1trZsgJFVqTSgM9dv6eayxSIQKMq0ilBJ+5pvf0SgimacMlZEsav4oL+4dUE4E2g==" }, + "get-caller-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", + "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=" + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "1.0.0" + } + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", + "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", + "requires": { + "ajv": "5.3.0", + "har-schema": "2.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + }, + "hawk": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", + "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", + "requires": { + "boom": "4.3.1", + "cryptiles": "3.1.2", + "hoek": "4.2.0", + "sntp": "2.1.0" + } + }, + "hoek": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz", + "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ==" + }, + "hosted-git-info": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", + "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==" + }, "http-errors": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", @@ -233,6 +804,16 @@ "statuses": "1.4.0" } }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "1.0.0", + "jsprim": "1.4.1", + "sshpk": "1.13.1" + } + }, "iconv-lite": { "version": "0.4.19", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", @@ -243,36 +824,234 @@ "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.12.0.tgz", "integrity": "sha1-ogCTVlbW9fa8TcdQLhrstwMihBY=" }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "1.4.0", + "wrappy": "1.0.2" + } + }, "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, + "ini": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz", + "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=" + }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" + }, "ipaddr.js": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.5.2.tgz", "integrity": "sha1-1LUFvemUaYfM8PxY2QEP+WB+P6A=" }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" + }, "is-bluebird": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-bluebird/-/is-bluebird-1.0.2.tgz", "integrity": "sha1-CWQ5Bg9KpBGr7hkUOoTWpVNG1uI=" }, + "is-builtin-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "requires": { + "builtin-modules": "1.1.1" + } + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "1.0.1" + } + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "js-beautify": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.7.4.tgz", + "integrity": "sha512-6YX1g+lIl0/JDxjFFbgj7fz6i0bWFa2Hdc7PfGqFhynaEiYe1NJ3R1nda0VGaRiGU82OllR+EGDoWFpGr3k5Kg==", + "requires": { + "config-chain": "1.1.11", + "editorconfig": "0.13.3", + "mkdirp": "0.5.1", + "nopt": "3.0.6" + }, + "dependencies": { + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "requires": { + "abbrev": "1.1.1" + } + } + } + }, "js-string-escape": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", "integrity": "sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8=" }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "optional": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, + "json-schema-traverse": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", + "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "4.1.11" + } + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "requires": { + "invert-kv": "1.0.0" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "requires": { + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "strip-bom": "3.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "requires": { + "p-locate": "2.0.0", + "path-exists": "3.0.0" + } + }, "lodash": { "version": "4.17.4", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" }, + "lru-cache": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-3.2.0.tgz", + "integrity": "sha1-cXibO39Tmb7IVl3aOKow0qCX7+4=", + "requires": { + "pseudomap": "1.0.2" + } + }, + "lru-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", + "integrity": "sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM=", + "requires": { + "es5-ext": "0.10.35" + } + }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" }, + "mem": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", + "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", + "requires": { + "mimic-fn": "1.1.0" + } + }, + "memoizee": { + "version": "0.4.11", + "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.11.tgz", + "integrity": "sha1-vemBdmPJ5A/bKk6hw2cpYIeujI8=", + "requires": { + "d": "1.0.0", + "es5-ext": "0.10.35", + "es6-weak-map": "2.0.2", + "event-emitter": "0.3.5", + "is-promise": "2.1.0", + "lru-queue": "0.1.0", + "next-tick": "1.0.0", + "timers-ext": "0.1.2" + } + }, "merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", @@ -301,6 +1080,32 @@ "mime-db": "1.30.0" } }, + "mimic-fn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz", + "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=" + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "1.1.8" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "requires": { + "minimist": "0.0.8" + } + }, "moment": { "version": "2.19.1", "resolved": "https://registry.npmjs.org/moment/-/moment-2.19.1.tgz", @@ -319,11 +1124,98 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, + "nan": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.6.2.tgz", + "integrity": "sha1-5P805slf37WuzAjeZZb0NgWn20U=" + }, "negotiator": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" }, + "next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" + }, + "node-pre-gyp": { + "version": "0.6.36", + "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.6.36.tgz", + "integrity": "sha1-22BBEst04NR3VU6bUFsXq936t4Y=", + "requires": { + "mkdirp": "0.5.1", + "nopt": "4.0.1", + "npmlog": "4.1.2", + "rc": "1.2.2", + "request": "2.83.0", + "rimraf": "2.6.2", + "semver": "5.4.1", + "tar": "2.2.1", + "tar-pack": "3.4.1" + }, + "dependencies": { + "semver": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==" + } + } + }, + "nopt": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", + "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", + "requires": { + "abbrev": "1.1.1", + "osenv": "0.1.4" + } + }, + "normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "requires": { + "hosted-git-info": "2.5.0", + "is-builtin-module": "1.0.0", + "semver": "4.3.2", + "validate-npm-package-license": "3.0.1" + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "requires": { + "path-key": "2.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "requires": { + "are-we-there-yet": "1.1.4", + "console-control-strings": "1.1.0", + "gauge": "2.7.4", + "set-blocking": "2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + }, + "oauth-sign": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=" + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, "on-finished": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", @@ -332,21 +1224,122 @@ "ee-first": "1.1.1" } }, + "on-headers": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz", + "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1.0.2" + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + }, + "os-locale": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", + "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", + "requires": { + "execa": "0.7.0", + "lcid": "1.0.0", + "mem": "1.1.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + }, + "osenv": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.4.tgz", + "integrity": "sha1-Qv5tWVPfBsgGS+bxdsPQWqqjRkQ=", + "requires": { + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" + } + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" + }, + "p-limit": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz", + "integrity": "sha1-sH/y2aXYi+yAYDWJWiurZqJ5iLw=" + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "requires": { + "p-limit": "1.1.0" + } + }, "packet-reader": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-0.3.1.tgz", "integrity": "sha1-zWLmCvjX/qinBexP+ZCHHEaHHyc=" }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "requires": { + "error-ex": "1.3.1" + } + }, "parseurl": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" + }, + "path-parse": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", + "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=" + }, "path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "requires": { + "pify": "2.3.0" + } + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, "pg": { "version": "7.3.0", "resolved": "https://registry.npmjs.org/pg/-/pg-7.3.0.tgz", @@ -399,6 +1392,11 @@ "split": "1.0.1" } }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + }, "postgres-array": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-1.0.2.tgz", @@ -422,6 +1420,16 @@ "xtend": "4.0.1" } }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + }, + "proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=" + }, "proxy-addr": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.2.tgz", @@ -431,11 +1439,26 @@ "ipaddr.js": "1.5.2" } }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + }, "qs": { "version": "6.5.1", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" }, + "random-bytes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", + "integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs=" + }, "range-parser": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", @@ -452,6 +1475,109 @@ "unpipe": "1.0.0" } }, + "rc": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.2.tgz", + "integrity": "sha1-2M6ctX6NZNnHut2YdsfDTL48cHc=", + "requires": { + "deep-extend": "0.4.2", + "ini": "1.3.4", + "minimist": "1.2.0", + "strip-json-comments": "2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + } + } + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "requires": { + "load-json-file": "2.0.0", + "normalize-package-data": "2.4.0", + "path-type": "2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "requires": { + "find-up": "2.1.0", + "read-pkg": "2.0.0" + } + }, + "readable-stream": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", + "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "safe-buffer": "5.1.1", + "string_decoder": "1.0.3", + "util-deprecate": "1.0.2" + } + }, + "regenerator-runtime": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz", + "integrity": "sha512-/aA0kLeRb5N9K0d4fw7ooEbI+xDe+DKD499EQqygGqeS8N3xto15p09uY2xj7ixP81sNPXvRLnAQIqdVStgb1A==" + }, + "request": { + "version": "2.83.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz", + "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==", + "requires": { + "aws-sign2": "0.7.0", + "aws4": "1.6.0", + "caseless": "0.12.0", + "combined-stream": "1.0.5", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.3.1", + "har-validator": "5.0.3", + "hawk": "6.0.2", + "http-signature": "1.2.0", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.17", + "oauth-sign": "0.8.2", + "performance-now": "2.1.0", + "qs": "6.5.1", + "safe-buffer": "5.1.1", + "stringstream": "0.0.5", + "tough-cookie": "2.3.3", + "tunnel-agent": "0.6.0", + "uuid": "3.1.0" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" + }, + "resolve": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", + "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==", + "requires": { + "path-parse": "1.0.5" + } + }, "retry-as-promised": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-2.3.2.tgz", @@ -461,6 +1587,14 @@ "debug": "2.6.9" } }, + "rimraf": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "requires": { + "glob": "7.1.2" + } + }, "safe-buffer": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", @@ -537,6 +1671,21 @@ } } }, + "sequelize-cli": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/sequelize-cli/-/sequelize-cli-3.0.0.tgz", + "integrity": "sha1-W61ruD8jOSMIMAdUOzgYKsNke/k=", + "requires": { + "bluebird": "3.5.1", + "cli-color": "1.2.0", + "fs-extra": "4.0.2", + "js-beautify": "1.7.4", + "lodash": "4.17.4", + "resolve": "1.5.0", + "umzug": "2.1.0", + "yargs": "8.0.2" + } + }, "serve-static": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.1.tgz", @@ -548,16 +1697,70 @@ "send": "0.16.1" } }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, "setprototypeof": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=" }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "requires": { + "shebang-regex": "1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" + }, "shimmer": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.1.0.tgz", "integrity": "sha1-l9c3cTf/u6tCVSLkKf4KqJpIizU=" }, + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=" + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + }, + "sntp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", + "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", + "requires": { + "hoek": "4.2.0" + } + }, + "spdx-correct": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", + "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", + "requires": { + "spdx-license-ids": "1.2.2" + } + }, + "spdx-expression-parse": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", + "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=" + }, + "spdx-license-ids": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", + "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=" + }, "split": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", @@ -566,11 +1769,97 @@ "through": "2.3.8" } }, + "sshpk": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", + "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", + "requires": { + "asn1": "0.2.3", + "assert-plus": "1.0.0", + "bcrypt-pbkdf": "1.0.1", + "dashdash": "1.14.1", + "ecc-jsbn": "0.1.1", + "getpass": "0.1.7", + "jsbn": "0.1.1", + "tweetnacl": "0.14.5" + } + }, "statuses": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "1.1.0", + "is-fullwidth-code-point": "1.0.0", + "strip-ansi": "3.0.1" + } + }, + "string_decoder": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", + "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "requires": { + "safe-buffer": "5.1.1" + } + }, + "stringstream": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", + "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "2.1.1" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + }, + "tar": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", + "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "requires": { + "block-stream": "0.0.9", + "fstream": "1.0.11", + "inherits": "2.0.3" + } + }, + "tar-pack": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/tar-pack/-/tar-pack-3.4.1.tgz", + "integrity": "sha512-PPRybI9+jM5tjtCbN2cxmmRU7YmqT3Zv/UDy48tAh2XRkLa9bAORtSWLkVc13+GJF+cdTh1yEnHEk3cpTaL5Kg==", + "requires": { + "debug": "2.6.9", + "fstream": "1.0.11", + "fstream-ignore": "1.0.5", + "once": "1.4.0", + "readable-stream": "2.3.3", + "rimraf": "2.6.2", + "tar": "2.2.1", + "uid-number": "0.0.6" + } + }, "terraformer": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/terraformer/-/terraformer-1.0.8.tgz", @@ -592,11 +1881,42 @@ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" }, + "timers-ext": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.2.tgz", + "integrity": "sha1-YcxHp2wavTGV8UUn+XjViulMUgQ=", + "requires": { + "es5-ext": "0.10.35", + "next-tick": "1.0.0" + } + }, "toposort-class": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toposort-class/-/toposort-class-1.0.1.tgz", "integrity": "sha1-f/0feMi+KMO6Rc1OGj9e4ZO9mYg=" }, + "tough-cookie": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz", + "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=", + "requires": { + "punycode": "1.4.1" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "5.1.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "optional": true + }, "type-is": { "version": "1.6.15", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz", @@ -606,16 +1926,50 @@ "mime-types": "2.1.17" } }, + "uid-number": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/uid-number/-/uid-number-0.0.6.tgz", + "integrity": "sha1-DqEOgDXo61uOREnwbaHHMGY7qoE=" + }, + "uid-safe": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", + "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", + "requires": { + "random-bytes": "1.0.0" + } + }, + "umzug": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/umzug/-/umzug-2.1.0.tgz", + "integrity": "sha512-BgT+ekpItEWaG+3JjLLj6yVTxw2wIH8Cr6JyKYIzukWAx9nzGhC6BGHb/IRMjpobMM1qtIrReATwLUjKpU2iOQ==", + "requires": { + "babel-runtime": "6.26.0", + "bluebird": "3.5.1", + "lodash": "4.17.4", + "resolve": "1.5.0" + } + }, "underscore": { "version": "1.8.3", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" }, + "universalify": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz", + "integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc=" + }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", @@ -626,6 +1980,15 @@ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==" }, + "validate-npm-package-license": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", + "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", + "requires": { + "spdx-correct": "1.0.2", + "spdx-expression-parse": "1.0.4" + } + }, "validator": { "version": "9.1.1", "resolved": "https://registry.npmjs.org/validator/-/validator-9.1.1.tgz", @@ -636,6 +1999,37 @@ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "1.3.0" + } + }, + "which": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", + "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", + "requires": { + "isexe": "2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + }, + "wide-align": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz", + "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==", + "requires": { + "string-width": "1.0.2" + } + }, "wkx": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/wkx/-/wkx-0.4.2.tgz", @@ -644,10 +2038,91 @@ "@types/node": "8.0.47" } }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "requires": { + "string-width": "1.0.2", + "strip-ansi": "3.0.1" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, "xtend": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + }, + "yargs": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz", + "integrity": "sha1-YpmpBVsc78lp/355wdkY3Osiw2A=", + "requires": { + "camelcase": "4.1.0", + "cliui": "3.2.0", + "decamelize": "1.2.0", + "get-caller-file": "1.0.2", + "os-locale": "2.1.0", + "read-pkg-up": "2.0.0", + "require-directory": "2.1.1", + "require-main-filename": "1.0.1", + "set-blocking": "2.0.0", + "string-width": "2.1.1", + "which-module": "2.0.0", + "y18n": "3.2.1", + "yargs-parser": "7.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "requires": { + "is-fullwidth-code-point": "2.0.0", + "strip-ansi": "4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "3.0.0" + } + } + } + }, + "yargs-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", + "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", + "requires": { + "camelcase": "4.1.0" + } } } } diff --git a/package.json b/package.json index 91543f6..94f68ab 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "description": "", "main": "app.js", "scripts": { + "start": "node app.js", "test": "echo \"Error: no test specified\" && exit 1" }, "repository": { @@ -17,11 +18,17 @@ }, "homepage": "https://github.com/fujianto/school-app#readme", "dependencies": { + "bcrypt": "^1.0.3", "body-parser": "^1.18.2", "ejs": "^2.5.7", "express": "^4.16.2", + "express-session": "^1.15.6", "pg": "^7.3.0", "pg-hstore": "^2.3.2", - "sequelize": "^4.22.2" + "sequelize": "^4.22.2", + "sequelize-cli": "^3.0.0" + }, + "engines": { + "node": "8.9.0" } } diff --git a/routes/index-route.js b/routes/index-route.js index b18e8e2..a3fc8d7 100644 --- a/routes/index-route.js +++ b/routes/index-route.js @@ -1,8 +1,61 @@ const express = require('express'); const router = express.Router(); +const Model = require('../models'); +const bcrypt = require('bcrypt'); router.get('/', function (req, res) { res.render('index'); }) +router.get('/register', function (req, res) { + res.render('register'); +}) + +router.post('/register', function (req, res) { + Model.Account.findOne({ + where: { + username: req.body.username + } + }).then((account) => { + if (account === null) { + Model.Account.create({ + username: req.body.username, + password: req.body.password, + StudentId: req.body.StudentId + }).then(account => { + res.redirect('/login'); + + }).catch(err => res.send(err.message)); + + } else { + res.render('register', {message: 'Username already taken'}); + } + }) +}) + +router.get('/login', function (req, res) { + res.render('login'); +}) + +router.post('/login', function (req, res) { + Model.Account.findOne({ + where: { username: req.body.username }, + }).then(account => { + if(account) { + bcrypt.compare(req.body.password, account.password).then(function(result) { + if (result) { + // Bikin Session disini + req.session.loggedIn = true + req.session.username = account.username + // Redirect ke halaman Member only + res.redirect('/students'); + } else { + res.render('login', {message: "Failed to login"}); + } + }); + } + + }).catch(err => res.send(err.message)); +}) + module.exports = router; \ No newline at end of file diff --git a/routes/student-route.js b/routes/student-route.js index b267413..c68a79a 100644 --- a/routes/student-route.js +++ b/routes/student-route.js @@ -2,6 +2,15 @@ const express = require('express'); const router = express.Router(); const Model = require('../models'); +// FUNGSI HELPER +// function checkLogin(req, res, next){ +// if (req.session.loggedIn) { +// next() +// }else{ +// res.redirect('/login') +// } +// } + router.get('/', (req, res) => { Model.Student.findAll({ order: [ ['first_name', 'ASC']] }) .then(allStudents => { diff --git a/routes/subject-route.js b/routes/subject-route.js index a8e7e1c..b37bda2 100644 --- a/routes/subject-route.js +++ b/routes/subject-route.js @@ -23,8 +23,8 @@ router.get('/:subjectId/enrolledstudents', function (req, res) { include: [{ model: Model.Student, }] - }).then(allStudentSubjectData => { - + } + ).then(allStudentSubjectData => { Model.Subject.findOne({ where: { id: req.params.subjectId, @@ -34,12 +34,27 @@ router.get('/:subjectId/enrolledstudents', function (req, res) { allStudentSubjectData.forEach( function(student, index) { student.scoreLetter = Helper.getScoreLetter(student.Score); }); - + // res.send(allStudentSubjectData); res.render('enrolled-student', {foundSubject: foundSubject, students: allStudentSubjectData}); }).catch(err => res.send(err)); }).catch(err => res.send(err.message)) + + /*Model.Subject.findAll({ + where: { + id: req.params.subjectId + }, + include: [{ + model: Model.StudentSubject, + include: [{ + model: Model.Student + }] + }] + }).then(allData => { + res.send(allData); + // res.render('enrolled-student', {foundSubject: allData, students: allData}); + }).catch(err => res.send(err.message));*/ }) router.get('/:subjectId/givescore', function (req, res) { diff --git a/seeders/20171107142905-insert-account-data.js b/seeders/20171107142905-insert-account-data.js new file mode 100644 index 0000000..ac7cb8c --- /dev/null +++ b/seeders/20171107142905-insert-account-data.js @@ -0,0 +1,43 @@ +'use strict'; + +module.exports = { + up: (queryInterface, Sequelize) => { + /* + Add altering commands here. + Return a promise to correctly handle asynchronicity. + + Example: + return queryInterface.bulkInsert('Person', [{ + name: 'John Doe', + isBetaMember: false + }], {}); + */ + + return queryInterface.bulkInsert('Accounts', [ + { + username: 'pandaman', + password: '1234', + StudentId: 2, + createdAt: new Date(), + updatedAt: new Date() + }, + { + username: 'taigaman', + password: '6789', + StudentId: 4, + createdAt: new Date(), + updatedAt: new Date() + } + ], {}); + }, + + down: (queryInterface, Sequelize) => { + /* + Add reverting commands here. + Return a promise to correctly handle asynchronicity. + + Example: + return queryInterface.bulkDelete('Person', null, {}); + */ + } +}; diff --git a/test_validation.js b/test_validation.js deleted file mode 100644 index f8c3aba..0000000 --- a/test_validation.js +++ /dev/null @@ -1,7 +0,0 @@ -const Model = require('./models'); - -let Student = Model.Student; -let student = new Student(); - -student.email = 'akbar@mail.com'; -student.save(); \ No newline at end of file diff --git a/views/login.ejs b/views/login.ejs new file mode 100644 index 0000000..02cb771 --- /dev/null +++ b/views/login.ejs @@ -0,0 +1,17 @@ +<%- include('partials/header', {title: 'Index'}) %> + +
+

Login

+ <% if(typeof message != 'undefined' && message != null) { %> +

<%= message %>

+ <% } %> + +
+ + + + +
+
+ +<%- include('partials/footer') %> \ No newline at end of file diff --git a/views/partials/header.ejs b/views/partials/header.ejs index e5d04ce..5342615 100644 --- a/views/partials/header.ejs +++ b/views/partials/header.ejs @@ -48,6 +48,8 @@