├── .gitignore ├── images ├── background.jpg └── profile-pic.jpg ├── controllers ├── logout.js ├── signup.js ├── login.js ├── customer.js └── admin.js ├── package.json ├── views ├── admin │ ├── partials │ │ ├── template.html │ │ ├── sidebar.html │ │ └── navbar.html │ ├── home.ejs │ ├── change-password.ejs │ ├── customers-profile.ejs │ ├── profile.ejs │ ├── customers.ejs │ ├── profile-edit.ejs │ ├── books-delete.ejs │ ├── customers-delete.ejs │ ├── books-issue.ejs │ ├── books-requested.ejs │ ├── books-add.ejs │ ├── books-edit.ejs │ ├── customers-add.ejs │ ├── customers-edit.ejs │ ├── books.ejs │ └── issued-books.ejs ├── customer │ ├── partials │ │ ├── template.html │ │ ├── sidebar.html │ │ └── navbar.html │ ├── home.ejs │ ├── change-password.ejs │ ├── borrow-history.ejs │ ├── profile.ejs │ ├── books-request.ejs │ ├── borrowed-books.ejs │ ├── profile-edit.ejs │ └── books.ejs ├── partials │ ├── footer.html │ └── header.html ├── login.ejs └── signup.ejs ├── css ├── signup.css ├── login.css ├── admin.css └── customer.css ├── models ├── config.js ├── userModel.js └── bookModel.js ├── app.js ├── validation_rules └── rules.js └── library_management_system.sql /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /images/background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rafin007/Library-Management-System-Nodejs/HEAD/images/background.jpg -------------------------------------------------------------------------------- /images/profile-pic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rafin007/Library-Management-System-Nodejs/HEAD/images/profile-pic.jpg -------------------------------------------------------------------------------- /controllers/logout.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | 4 | router.get('/', (req, res)=> { 5 | req.session.destroy(); 6 | res.redirect('/login'); 7 | }); 8 | 9 | module.exports = router; 10 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "app.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "nodemon app.js" 9 | }, 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "async-validator-2": "^1.0.0", 14 | "body-parser": "^1.18.3", 15 | "ejs": "^2.6.1", 16 | "express": "^4.16.3", 17 | "express-session": "^1.15.6", 18 | "mysql": "^2.15.0", 19 | "nodemon": "^1.17.5" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /views/admin/partials/template.html: -------------------------------------------------------------------------------- 1 | <%-include('../partials/header.html')%> 2 | 3 | Admin Home 4 | 5 | 6 | 7 | 8 | <%-include('partials/navbar.html')%> 9 |
10 |
11 | <%-include('partials/sidebar.html')%> 12 |
13 | 14 |
15 |
16 |
17 | 18 | <%-include('../partials/footer.html')%> 19 | -------------------------------------------------------------------------------- /views/customer/partials/template.html: -------------------------------------------------------------------------------- 1 | <%-include('../partials/header.html')%> 2 | 3 | Admin Home 4 | 5 | 6 | 7 | 8 | <%-include('partials/navbar.html')%> 9 |
10 |
11 | <%-include('partials/sidebar.html')%> 12 |
13 | 14 |
15 |
16 |
17 | 18 | <%-include('../partials/footer.html')%> 19 | -------------------------------------------------------------------------------- /views/customer/partials/sidebar.html: -------------------------------------------------------------------------------- 1 | 23 | -------------------------------------------------------------------------------- /css/signup.css: -------------------------------------------------------------------------------- 1 | .bg-image { 2 | background-image: url('../images/background.jpg'); 3 | min-height: 100vh; 4 | min-width: 100vw; 5 | background-position: center; 6 | background-repeat: no-repeat; 7 | background-size: cover; 8 | background-attachment: fixed; 9 | } 10 | 11 | .signup-form { 12 | background-color: rgba(151, 174, 189, 0.7); 13 | min-height: 43rem; 14 | min-width: 20rem; 15 | margin: 3rem auto; 16 | /* text-align: center; */ 17 | } 18 | 19 | .header { 20 | text-align: center; 21 | color: black; 22 | text-shadow: 2px 2px 5px white; 23 | } 24 | 25 | .submit-button { 26 | text-align: center; 27 | } 28 | -------------------------------------------------------------------------------- /views/partials/footer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /views/partials/header.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /models/config.js: -------------------------------------------------------------------------------- 1 | var mysql = require('mysql'); 2 | var connection = mysql.createConnection({ 3 | host : 'localhost', 4 | user : 'root', 5 | password : '', 6 | database : 'library_management_system' 7 | }); 8 | 9 | module.exports = { 10 | executeQuery: function(sql, sqlParam, callback){ 11 | if(sqlParam == null) 12 | { 13 | connection.query(sql, function(error, result){ 14 | if(error) 15 | { 16 | console.log(error); 17 | } 18 | callback(result); 19 | }); 20 | } 21 | else 22 | { 23 | connection.query(sql, sqlParam, function(error, result){ 24 | if(error) 25 | { 26 | console.log(error); 27 | } 28 | callback(result); 29 | }); 30 | } 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /views/admin/partials/sidebar.html: -------------------------------------------------------------------------------- 1 | 30 | -------------------------------------------------------------------------------- /css/login.css: -------------------------------------------------------------------------------- 1 | .bg-image { 2 | background-image: url('../images/background.jpg'); 3 | min-height: 100vh; 4 | min-width: 100vw; 5 | background-position: center; 6 | background-repeat: no-repeat; 7 | background-size: cover; 8 | background-attachment: fixed; 9 | } 10 | 11 | .login-box { 12 | background-color: rgba(151, 174, 189, 0.7); 13 | height: 25rem; 14 | width: 30rem; 15 | margin: 3rem auto; 16 | text-align: center; 17 | } 18 | 19 | .header { 20 | text-align: center; 21 | color: black; 22 | text-shadow: 2px 2px 5px white; 23 | } 24 | 25 | .login-form { 26 | margin-top: 4.5rem; 27 | text-align: left; 28 | border-left: 2px solid black; 29 | 30 | } 31 | 32 | .sign-up { 33 | margin-top: 8rem; 34 | /* border-right: 2px solid black; */ 35 | } 36 | -------------------------------------------------------------------------------- /views/customer/home.ejs: -------------------------------------------------------------------------------- 1 | <%-include('../partials/header.html')%> 2 | 3 | Customer Home 4 | 5 | 6 | 7 | 8 | <%-include('partials/navbar.html')%> 9 |
10 |
11 | <%-include('partials/sidebar.html')%> 12 |
13 |

Home

14 | 17 | 20 | 23 |
24 |
25 |
26 | 27 | <%-include('../partials/footer.html')%> 28 | -------------------------------------------------------------------------------- /controllers/signup.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | var userModel = require.main.require('./models/userModel'); 4 | var validationRules = require.main.require('./validation_rules/rules'); 5 | var asyncValidator = require('async-validator-2'); 6 | 7 | router.get('/', (req, res)=>{ 8 | res.render('signup.ejs', {errs: []}); 9 | }); 10 | 11 | router.post('/', (req, res)=>{ 12 | 13 | var data = { 14 | name: req.body.name, 15 | email: req.body.email, 16 | phone: req.body.phone, 17 | address: req.body.address, 18 | password: req.body.password, 19 | gender: req.body.gender 20 | }; 21 | 22 | var rules = validationRules.users.create; 23 | var validator = new asyncValidator(rules); 24 | 25 | validator.validate(data, (errors, fields)=>{ 26 | if(!errors){ 27 | userModel.createUser(data, function(result){ 28 | if(result){ 29 | console.log(result); 30 | res.redirect('/login'); 31 | } 32 | else { 33 | res.send('Invalid'); 34 | } 35 | }); 36 | } 37 | else { 38 | console.log(fields); 39 | res.render('signup', {errs: errors}); 40 | } 41 | }); 42 | 43 | }); 44 | 45 | module.exports = router; 46 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | //declaration 2 | var express = require('express'); 3 | var expressSession = require('express-session'); 4 | var bodyParser = require('body-parser'); 5 | var app = express(); 6 | var port = 3000; 7 | 8 | //common controllers 9 | var signup = require('./controllers/signup'); 10 | var login = require('./controllers/login'); 11 | var logout = require('./controllers/logout'); 12 | 13 | //admin controllers 14 | var admin = require('./controllers/admin'); 15 | 16 | 17 | //customer controllers 18 | var customer = require('./controllers/customer'); 19 | 20 | //configure 21 | app.set('view engine', 'ejs'); 22 | 23 | //middlewares 24 | app.use(bodyParser.urlencoded({extended: false})); 25 | app.use(expressSession({secret: 'my top secret pass', resave: false, saveUninitialized: true})); 26 | app.use('/css', express.static(__dirname + '/css')); 27 | app.use('/images', express.static(__dirname + '/images')); 28 | 29 | app.use('*', function(req, res, next){ 30 | 31 | if(req.originalUrl == '/login' || req.originalUrl == '/signup') 32 | { 33 | next(); 34 | } 35 | else 36 | { 37 | if(!req.session.admin && !req.session.customer) 38 | { 39 | res.redirect('/login'); 40 | return; 41 | } 42 | next(); 43 | } 44 | }); 45 | 46 | 47 | //routes 48 | app.use('/login', login); 49 | app.use('/signup', signup); 50 | app.use('/logout', logout); 51 | 52 | //admin routes 53 | app.use('/admin', admin); 54 | 55 | 56 | //customer routes 57 | 58 | app.use('/customer', customer); 59 | 60 | //server start 61 | app.listen(port, ()=>{ 62 | console.log(`Server running on port ${port}`); 63 | }); 64 | -------------------------------------------------------------------------------- /controllers/login.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | var userModel = require.main.require('./models/userModel'); 4 | var validationRules = require.main.require('./validation_rules/rules'); 5 | var asyncValidator = require('async-validator-2'); 6 | 7 | router.get('/', (req, res)=>{ 8 | res.render('login.ejs', {errs: []}); 9 | }); 10 | 11 | router.post('/', (req, res)=>{ 12 | 13 | var data = { 14 | email: req.body.email, 15 | password: req.body.password 16 | }; 17 | 18 | var rules = validationRules.users.login; 19 | var validator = new asyncValidator(rules); 20 | 21 | validator.validate(data, (errors, fields)=>{ 22 | if(!errors){ 23 | userModel.validateUser(req.body.email, req.body.password, function(result){ 24 | if(!result){ 25 | res.render('login', {errs: [{message: 'Invalid email or password'}]}); 26 | } 27 | else{ 28 | console.log(result); 29 | if(result.is_admin == 1){ 30 | req.session.admin = result.user_id; 31 | res.redirect('/admin/home'); 32 | } 33 | else{ 34 | req.session.customer = result.user_id; 35 | res.redirect('/customer/home'); 36 | } 37 | } 38 | }); 39 | } 40 | else { 41 | console.log(fields); 42 | res.render('login', {errs: errors}); 43 | } 44 | }); 45 | 46 | }); 47 | 48 | module.exports = router; 49 | -------------------------------------------------------------------------------- /views/admin/home.ejs: -------------------------------------------------------------------------------- 1 | <%-include('../partials/header.html')%> 2 | 3 | Admin Home 4 | 5 | 6 | 7 | 8 | <%-include('partials/navbar.html')%> 9 |
10 |
11 | <%-include('partials/sidebar.html')%> 12 |
13 |

Quick Inventory

14 | 17 | 20 | 23 | 26 | 29 | 32 |
33 |
34 |
35 | 36 | <%-include('../partials/footer.html')%> 37 | -------------------------------------------------------------------------------- /views/login.ejs: -------------------------------------------------------------------------------- 1 | <%-include('partials/header.html')%> 2 | 3 | Login page 4 | 5 | 6 | 7 |
8 |

Library Management System

9 |
10 | 38 |
39 |
40 | 41 | <%-include('partials/footer.html')%> 42 | -------------------------------------------------------------------------------- /views/customer/partials/navbar.html: -------------------------------------------------------------------------------- 1 | 39 | -------------------------------------------------------------------------------- /css/admin.css: -------------------------------------------------------------------------------- 1 | /* admin/home.css */ 2 | .navbar-nav { 3 | margin-right: 6rem; 4 | } 5 | 6 | .navbar { 7 | min-height: 8vh; 8 | } 9 | 10 | .container-fluid { 11 | background-color: white; 12 | /* overflow-x: auto; */ 13 | /* margin-left: 200px; */ 14 | } 15 | 16 | .sidebar { 17 | min-height: 100vh; 18 | padding-top: 5rem; 19 | padding-left: 3rem; 20 | font-size: 1.3rem; 21 | position: fixed; 22 | z-index: 1; 23 | overflow-x: hidden; 24 | } 25 | 26 | .sidebar a:visited { 27 | text-decoration: none; 28 | } 29 | 30 | .sidebar a:hover { 31 | text-decoration: none; 32 | } 33 | 34 | .content { 35 | margin-top: 1rem; 36 | position: relative; 37 | left: 16%; 38 | } 39 | 40 | 41 | /* admin/books.css */ 42 | 43 | .dropbar { 44 | margin-right: 7rem; 45 | } 46 | 47 | .search-bar { 48 | margin-top: 2rem; 49 | } 50 | 51 | 52 | /* admin/profile.css */ 53 | 54 | .profile-content { 55 | /* background-color: #343A40; */ 56 | background-color: #CCE5FF; 57 | height: 35rem; 58 | margin-left: 2rem; 59 | float: left; 60 | /* opacity: 0.5; */ 61 | color: black; 62 | padding-top: 2rem; 63 | text-align: center; 64 | } 65 | 66 | .profile-content hr { 67 | background-color: grey; 68 | } 69 | 70 | .profile-content a:visited { 71 | text-decoration: none; 72 | } 73 | 74 | .profile-content a:hover { 75 | text-decoration: none; 76 | } 77 | 78 | .profile-pic { 79 | width: 25rem; 80 | padding-left: 2rem; 81 | } 82 | 83 | 84 | /* admin/books/add.css */ 85 | 86 | .books-content { 87 | /* background-color: #343A40; */ 88 | background-color: #CCE5FF; 89 | height: 46rem; 90 | margin-left: 2rem; 91 | float: left; 92 | /* opacity: 0.5; */ 93 | color: black; 94 | padding-top: 2rem; 95 | text-align: center; 96 | } 97 | 98 | /* admin/changepass.css */ 99 | 100 | .change-password { 101 | /* background-color: #343A40; */ 102 | background-color: #CCE5FF; 103 | height: 25rem; 104 | margin-left: 2rem; 105 | margin-top: 5rem; 106 | float: left; 107 | /* opacity: 0.5; */ 108 | color: black; 109 | padding-top: 2rem; 110 | text-align: center; 111 | } 112 | 113 | /* admin/customers/add.css */ 114 | 115 | .modify-customer { 116 | /* background-color: #343A40; */ 117 | background-color: #CCE5FF; 118 | height: 42rem; 119 | margin-left: 2rem; 120 | float: left; 121 | /* opacity: 0.5; */ 122 | color: black; 123 | padding-top: 2rem; 124 | text-align: center; 125 | } 126 | 127 | .gender { 128 | width: 20rem; 129 | margin: auto; 130 | } 131 | -------------------------------------------------------------------------------- /views/admin/partials/navbar.html: -------------------------------------------------------------------------------- 1 | 48 | -------------------------------------------------------------------------------- /css/customer.css: -------------------------------------------------------------------------------- 1 | /* customer/home.css */ 2 | 3 | .navbar-nav { 4 | margin-right: 6rem; 5 | } 6 | 7 | .navbar { 8 | min-height: 8vh; 9 | } 10 | 11 | .container-fluid { 12 | background-color: white; 13 | /* overflow-x: auto; */ 14 | /* margin-left: 200px; */ 15 | } 16 | 17 | .sidebar { 18 | min-height: 100vh; 19 | padding-top: 5rem; 20 | padding-left: 3rem; 21 | font-size: 1.3rem; 22 | position: fixed; 23 | z-index: 1; 24 | overflow-x: hidden; 25 | } 26 | 27 | .sidebar a:visited { 28 | text-decoration: none; 29 | } 30 | 31 | .sidebar a:hover { 32 | text-decoration: none; 33 | } 34 | 35 | .content { 36 | margin-top: 1rem; 37 | position: relative; 38 | left: 16%; 39 | } 40 | 41 | 42 | /* customer/books.css */ 43 | 44 | .dropbar { 45 | margin-right: 7rem; 46 | } 47 | 48 | .search-bar { 49 | margin-top: 2rem; 50 | } 51 | 52 | 53 | /* customer/profile.css */ 54 | 55 | .profile-content { 56 | /* background-color: #343A40; */ 57 | background-color: #CCE5FF; 58 | height: 35rem; 59 | margin-left: 2rem; 60 | float: left; 61 | /* opacity: 0.5; */ 62 | color: black; 63 | padding-top: 2rem; 64 | text-align: center; 65 | } 66 | 67 | .profile-content a:visited { 68 | text-decoration: none; 69 | } 70 | 71 | .profile-content a:hover { 72 | text-decoration: none; 73 | } 74 | 75 | .profile-pic { 76 | width: 25rem; 77 | padding-left: 2rem; 78 | } 79 | 80 | 81 | /* customer/books/add.css */ 82 | 83 | .books-content { 84 | /* background-color: #343A40; */ 85 | background-color: #CCE5FF; 86 | height: 46rem; 87 | margin-left: 2rem; 88 | float: left; 89 | /* opacity: 0.5; */ 90 | color: black; 91 | padding-top: 2rem; 92 | text-align: center; 93 | } 94 | 95 | /* customer/changepass.css */ 96 | 97 | .change-password { 98 | /* background-color: #343A40; */ 99 | background-color: #CCE5FF; 100 | height: 25rem; 101 | margin-left: 2rem; 102 | margin-top: 5rem; 103 | float: left; 104 | /* opacity: 0.5; */ 105 | color: black; 106 | padding-top: 2rem; 107 | text-align: center; 108 | } 109 | 110 | /* customer/customers/add.css */ 111 | 112 | .modify-customer { 113 | /* background-color: #343A40; */ 114 | background-color: #CCE5FF; 115 | height: 42rem; 116 | margin-left: 2rem; 117 | float: left; 118 | /* opacity: 0.5; */ 119 | color: black; 120 | padding-top: 2rem; 121 | text-align: center; 122 | } 123 | 124 | .gender { 125 | width: 20rem; 126 | margin: auto; 127 | } 128 | 129 | 130 | /* customer/books/request.css */ 131 | 132 | .request-books { 133 | /* background-color: #343A40; */ 134 | background-color: #CCE5FF; 135 | height: 40rem; 136 | margin-left: 2rem; 137 | float: left; 138 | /* opacity: 0.5; */ 139 | color: black; 140 | padding-top: 2rem; 141 | text-align: center; 142 | margin-top: 3rem; 143 | } 144 | -------------------------------------------------------------------------------- /views/admin/change-password.ejs: -------------------------------------------------------------------------------- 1 | <%-include('../partials/header.html')%> 2 | 3 | Admin Change Password 4 | 5 | 6 | 7 | 8 | <%-include('partials/navbar.html')%> 9 |
10 |
11 | <%-include('partials/sidebar.html')%> 12 |
13 |
14 |
15 |

Change Password

16 |
17 |
18 | 19 | 20 | 21 |
22 | 23 |
24 |
25 |
26 |
27 | 28 |
29 | 30 |
31 |
32 |
33 |
34 | 35 |
36 | 37 |
38 |
39 |
40 |
41 | 42 |
43 |
44 |
45 | <% for(var i=0; i< errs.length; i++){ %> 46 | <%= errs[i].message; %> 47 |
48 | <% } %> 49 | <% for(var i=0; i< success.length; i++){ %> 50 | <%= success[i].message; %> 51 |
52 | <% } %> 53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 | 61 | <%-include('../partials/footer.html')%> 62 | -------------------------------------------------------------------------------- /views/customer/change-password.ejs: -------------------------------------------------------------------------------- 1 | <%-include('../partials/header.html')%> 2 | 3 | customer Change Password 4 | 5 | 6 | 7 | 8 | <%-include('partials/navbar.html')%> 9 |
10 |
11 | <%-include('partials/sidebar.html')%> 12 |
13 |
14 |
15 |

Change Password

16 |
17 |
18 | 19 | 20 | 21 |
22 | 23 |
24 |
25 |
26 |
27 | 28 |
29 | 30 |
31 |
32 |
33 |
34 | 35 |
36 | 37 |
38 |
39 |
40 |
41 | 42 |
43 |
44 |
45 | <% for(var i=0; i< errs.length; i++){ %> 46 | <%= errs[i].message; %> 47 |
48 | <% } %> 49 | <% for(var i=0; i< success.length; i++){ %> 50 | <%= success[i].message; %> 51 |
52 | <% } %> 53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 | 61 | <%-include('../partials/footer.html')%> 62 | -------------------------------------------------------------------------------- /views/customer/borrow-history.ejs: -------------------------------------------------------------------------------- 1 | <%-include('../partials/header.html')%> 2 | 3 | Books 4 | 5 | 6 | 7 | 8 | <%-include('partials/navbar.html')%> 9 |
10 |
11 | <%-include('partials/sidebar.html')%> 12 |
13 |

Your History

14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | <% for(var i=0; i< res.length; i++){ %> 31 | 32 | 35 | 38 | 41 | 44 | 47 | 50 | 53 | 56 | 57 | 58 | <% } %> 59 | 60 | 61 |
User IDBook IDTitleAuthorPublisherEditionISBNDate Issued
33 | <%=res[i].user_id%> 34 | 36 | <%=res[i].book_id%> 37 | 39 | <%=res[i].title%> 40 | 42 | <%=res[i].author%> 43 | 45 | <%=res[i].publisher%> 46 | 48 | <%=res[i].edition%> 49 | 51 | <%=res[i].isbn%> 52 | 54 | <%=res[i].date%> 55 |
62 |
63 |
64 |
65 | 66 | <%-include('../partials/footer.html')%> 67 | -------------------------------------------------------------------------------- /models/userModel.js: -------------------------------------------------------------------------------- 1 | var db = require.main.require('./models/config'); 2 | 3 | var validateUser = (email, password, callback) => { 4 | var sql = "SELECT * FROM users WHERE email = ? AND password = ?"; 5 | db.executeQuery(sql, [email, password], function(result) { 6 | callback(result[0]); 7 | }); 8 | }; 9 | 10 | var createUser = (user, callback) => { 11 | var sql = "INSERT INTO users VALUES(null, ?, ?, ?, ?, ?, ?, ?)"; 12 | db.executeQuery(sql, [user.name, user.phone, user.email, 0, user.password, user.address, user.gender], function(result) { 13 | callback(result); 14 | }); 15 | }; 16 | 17 | var getUser = (id, callback) => { 18 | var sql = "SELECT * FROM users WHERE user_id=?"; 19 | db.executeQuery(sql, [id], function(result) { 20 | callback(result[0]); 21 | }); 22 | }; 23 | 24 | var updateUser = (user, callback) => { 25 | var sql = "UPDATE users SET name = ?, email = ?, phone = ?, address = ?, gender = ? WHERE user_id = ?"; 26 | db.executeQuery(sql, [user.name, user.email, user.phone, user.address, user.gender, user.user_id], function(result) { 27 | callback(result); 28 | }); 29 | }; 30 | 31 | var updatePassword = (password, id, callback) => { 32 | var sql = "UPDATE users SET password = ? WHERE user_id = ?"; 33 | db.executeQuery(sql, [password, id], function(result) { 34 | callback(result); 35 | }); 36 | }; 37 | 38 | var getAll = (callback) => { 39 | var sql = "SELECT * FROM users"; 40 | db.executeQuery(sql, null, function(result) { 41 | callback(result); 42 | }); 43 | }; 44 | 45 | var searchBy = (searchBy, word, callback) => { 46 | var sql = "SELECT * FROM users WHERE "+searchBy+" = ?"; 47 | db.executeQuery(sql, [word], function(result) { 48 | callback(result); 49 | }); 50 | }; 51 | 52 | var updateCustomer = (id, customer, callback) => { 53 | var sql = "UPDATE users SET name = ?, email = ?, phone = ?, address = ?, gender = ? WHERE user_id = ?"; 54 | db.executeQuery(sql, [customer.name, customer.email, customer.phone, customer.address, customer.gender, id], function(result) { 55 | callback(result); 56 | }); 57 | }; 58 | 59 | var deleteUser = (id, callback) => { 60 | var sql = "DELETE FROM users WHERE user_id = ?"; 61 | db.executeQuery(sql, [id], function(result) { 62 | callback(result); 63 | }); 64 | }; 65 | var getUserBorrow = (id, callback) => { 66 | var sql = "SELECT * FROM books WHERE user_id = ?"; 67 | db.executeQuery(sql, [id], function(result) { 68 | callback(result); 69 | }); 70 | }; 71 | var getUserHistory = (id, callback) => { 72 | var sql = "SELECT issue_date.user_id, issue_date.book_id, books.title, books.author, books.publisher, books.edition, books.isbn, issue_date.date FROM issue_date INNER JOIN books ON issue_date.book_id=books.book_id WHERE issue_date.user_id=?"; 73 | db.executeQuery(sql, [id], function(result) { 74 | callback(result); 75 | }); 76 | }; 77 | 78 | var totalBooksBorrowedByCustomer = (id, callback) => { 79 | var sql = "SELECT books.*, issue_date.book_id FROM issue_date INNER JOIN books ON issue_date.book_id=books.book_id WHERE issue_date.user_id = ?"; 80 | db.executeQuery(sql, [id], function(result) { 81 | callback(result); 82 | }); 83 | }; 84 | 85 | 86 | module.exports = { 87 | validateUser, 88 | createUser, 89 | getUser, 90 | updateUser, 91 | updatePassword, 92 | getAll, 93 | searchBy, 94 | updateCustomer, 95 | deleteUser, 96 | getUserBorrow, 97 | getUserHistory, 98 | totalBooksBorrowedByCustomer 99 | }; 100 | -------------------------------------------------------------------------------- /views/admin/customers-profile.ejs: -------------------------------------------------------------------------------- 1 | <%-include('../partials/header.html')%> 2 | 3 | Admin View Customer Profile 4 | 5 | 6 | 7 | 8 | <%-include('partials/navbar.html')%> 9 |
10 |
11 | <%-include('partials/sidebar.html')%> 12 |
13 |
14 |
15 |

<%=res.name%>'s Profile

16 |
17 | 18 |
19 | 20 |
21 |
22 |
23 |
24 | 25 |
26 | 27 |
28 |
29 |
30 |
31 | 32 |
33 | 34 |
35 |
36 |
37 |
38 | 39 |
40 | 41 |
42 |
43 |
44 |
45 | 46 |
47 | 48 |
49 |
50 |
51 | Edit Customer | 52 | Delete Customer 53 | 54 |
55 |
56 | 57 |
58 |
59 |
60 |
61 |
62 | 63 | <%-include('../partials/footer.html')%> 64 | -------------------------------------------------------------------------------- /views/admin/profile.ejs: -------------------------------------------------------------------------------- 1 | <%-include('../partials/header.html')%> 2 | 3 | Admin Profile 4 | 5 | 6 | 7 | 8 | <%-include('partials/navbar.html')%> 9 |
10 |
11 | <%-include('partials/sidebar.html')%> 12 |
13 |
14 |
15 |

Your Profile

16 |
17 | 18 |
19 | 20 |
21 |
22 |
23 |
24 | 25 |
26 | 27 |
28 |
29 |
30 |
31 | 32 |
33 | 34 |
35 |
36 |
37 |
38 | 39 |
40 | 41 |
42 |
43 |
44 |
45 | 46 |
47 | 48 |
49 |
50 |
51 | 52 | Edit Profile | 53 | Change Password 54 | 55 |
56 |
57 | 58 |
59 | Change Profile Picture 60 |
61 |
62 |
63 |
64 |
65 | 66 | <%-include('../partials/footer.html')%> 67 | -------------------------------------------------------------------------------- /views/customer/profile.ejs: -------------------------------------------------------------------------------- 1 | <%-include('../partials/header.html')%> 2 | 3 | customer Profile 4 | 5 | 6 | 7 | 8 | <%-include('partials/navbar.html')%> 9 |
10 |
11 | <%-include('partials/sidebar.html')%> 12 |
13 |
14 |
15 |

Your Profile

16 |
17 | 18 |
19 | 20 |
21 |
22 |
23 |
24 | 25 |
26 | 27 |
28 |
29 |
30 |
31 | 32 |
33 | 34 |
35 |
36 |
37 |
38 | 39 |
40 | 41 |
42 |
43 |
44 |
45 | 46 |
47 | 48 |
49 |
50 |
51 | 52 | Edit Profile | 53 | Change Password 54 | 55 |
56 |
57 | 58 |
59 | Change Profile Picture 60 |
61 |
62 |
63 |
64 |
65 | 66 | <%-include('../partials/footer.html')%> 67 | -------------------------------------------------------------------------------- /views/signup.ejs: -------------------------------------------------------------------------------- 1 | <%-include('partials/header.html')%> 2 | 3 | Signup page 4 | 5 | 6 | 7 |
8 |
9 | 69 |
70 |
71 | <%-include('partials/footer.html')%> 72 | -------------------------------------------------------------------------------- /views/customer/books-request.ejs: -------------------------------------------------------------------------------- 1 | <%-include('../partials/header.html')%> 2 | 3 | Request New Book 4 | 5 | 6 | 7 | 8 | <%-include('partials/navbar.html')%> 9 |
10 |
11 | <%-include('partials/sidebar.html')%> 12 |
13 |
14 |
15 |

Request a New Book

16 |
17 |
18 | 19 |
20 | 21 |
22 |
23 |
24 |
25 | 26 |
27 | 28 |
29 |
30 |
31 |
32 | 33 |
34 | 35 |
36 |
37 |
38 |
39 | 40 |
41 | 42 |
43 |
44 |
45 |
46 | 47 |
48 | 49 |
50 |
51 |
52 |
53 | 54 |
55 |
56 |
57 |
58 | <% for(var i=0; i< errs.length; i++){ %> 59 | <%= errs[i].message; %> 60 |
61 | <% } %> 62 | <% for(var i=0; i< success.length; i++){ %> 63 | <%= success[i].message; %> 64 |
65 | <% } %> 66 |
67 |
68 |
69 |
70 |
71 |
72 | 73 | <%-include('../partials/footer.html')%> 74 | -------------------------------------------------------------------------------- /views/customer/borrowed-books.ejs: -------------------------------------------------------------------------------- 1 | <%-include('../partials/header.html')%> 2 | 3 | Borrowed Books 4 | 5 | 6 | 7 | 8 | <%-include('partials/navbar.html')%> 9 |
10 |
11 | <%-include('partials/sidebar.html')%> 12 |
13 |

Your Borrowed Books..

14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | <% for(var i=0; i< res.length; i++){ %> 28 | 29 | 32 | 35 | 38 | 41 | 44 | 54 | 61 | 62 | <% } %> 63 | 64 |
IDGenreTitleAuthorIssued DateDays left until invalidStatus
30 | <%=res[i].book_id%> 31 | 33 | <%=res[i].genre%> 34 | 36 | <%=res[i].title%> 37 | 39 | <%=res[i].author%> 40 | 42 | <%=res[i].date_issued%> 43 | 45 | <% 46 | var date1 = new Date(res[i].date_issued); 47 | var date2 = new Date(); 48 | var timeDiff = Math.abs(date2.getTime() - date1.getTime()); 49 | var diffDays = Math.ceil(timeDiff / (1000 * 3600 * 24)); 50 | var leftValid = 30 - diffDays; 51 | %> 52 | <%=leftValid+" Days"%> 53 | 55 | <% if(leftValid >= 1) { %> 56 | Valid 57 | <% } else { %> 58 | Invalid 59 | <% } %> 60 |
65 |
66 |
67 |
68 | 69 | <%-include('../partials/footer.html')%> 70 | -------------------------------------------------------------------------------- /views/admin/customers.ejs: -------------------------------------------------------------------------------- 1 | <%-include('../partials/header.html')%> 2 | 3 | Customers 4 | 5 | 6 | 7 | 8 | <%-include('partials/navbar.html')%> 9 |
10 |
11 | <%-include('partials/sidebar.html')%> 12 |
13 |
14 | 31 |
32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | <% for(var i=0; i< res.length; i++){ %> 47 | 48 | <% if(res[i].is_admin == 1){ 49 | continue; 50 | } 51 | %> 52 | 53 | 54 | 55 | 56 | 57 | 58 | 62 | 63 | <% } %> 64 | 65 |
IDNamePhoneEmailAddressGenderAction
<%=res[i].user_id%><%=res[i].name%><%=res[i].phone%><%=res[i].email%><%=res[i].address%><%=res[i].gender%> 59 | Edit Customer | 60 | Delete Customer 61 |
66 |
67 |
68 |
69 | 70 | <%-include('../partials/footer.html')%> 71 | -------------------------------------------------------------------------------- /views/admin/profile-edit.ejs: -------------------------------------------------------------------------------- 1 | <%-include('../partials/header.html')%> 2 | 3 | Admin Profile Edit 4 | 5 | 6 | 7 | 8 | <%-include('partials/navbar.html')%> 9 |
10 |
11 | <%-include('partials/sidebar.html')%> 12 |
13 |
14 |
15 |

Edit Profile

16 |
17 | 18 |
19 | 20 |
21 | 22 |
23 |
24 |
25 |
26 | 27 |
28 | 29 |
30 |
31 |
32 |
33 | 34 |
35 | 36 |
37 |
38 |
39 |
40 | 41 |
42 | 43 |
44 |
45 |
46 | Gender 47 |
48 | 49 | 52 |
53 |
54 | 55 | 58 |
59 |
60 |
61 | 62 |
63 |
64 |
65 | <% for(var i=0; i< errs.length; i++){ %> 66 | <%= errs[i].message; %> 67 |
68 | <% } %> 69 |
70 |
71 | 72 |
73 |
74 |
75 |
76 |
77 | 78 | <%-include('../partials/footer.html')%> 79 | -------------------------------------------------------------------------------- /views/customer/profile-edit.ejs: -------------------------------------------------------------------------------- 1 | <%-include('../partials/header.html')%> 2 | 3 | customer Profile Edit 4 | 5 | 6 | 7 | 8 | <%-include('partials/navbar.html')%> 9 |
10 |
11 | <%-include('partials/sidebar.html')%> 12 |
13 |
14 |
15 |

Edit Profile

16 |
17 | 18 |
19 | 20 |
21 | 22 |
23 |
24 |
25 |
26 | 27 |
28 | 29 |
30 |
31 |
32 |
33 | 34 |
35 | 36 |
37 |
38 |
39 |
40 | 41 |
42 | 43 |
44 |
45 |
46 | Gender 47 |
48 | 49 | 52 |
53 |
54 | 55 | 58 |
59 |
60 |
61 | 62 |
63 |
64 |
65 | <% for(var i=0; i< errs.length; i++){ %> 66 | <%= errs[i].message; %> 67 |
68 | <% } %> 69 |
70 |
71 | 72 |
73 |
74 |
75 |
76 |
77 | 78 | <%-include('../partials/footer.html')%> 79 | -------------------------------------------------------------------------------- /validation_rules/rules.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | users: { 3 | create: { 4 | name: { 5 | required: true, 6 | message: 'Name cannot be empty' 7 | }, 8 | email: { 9 | required: true, 10 | type: 'email', 11 | message: 'Invalid email' 12 | }, 13 | phone: { 14 | required: true, 15 | len: 11, 16 | message: 'Invalid Phone' 17 | }, 18 | password: { 19 | required: true, 20 | min: 4, 21 | message: 'Invalid Password' 22 | }, 23 | address: { 24 | required: true, 25 | message: 'Invalid Address' 26 | }, 27 | gender: { 28 | required: true, 29 | message: 'Must select a gender' 30 | } 31 | }, 32 | update: { 33 | name: { 34 | required: true, 35 | message: 'Name cannot be empty' 36 | }, 37 | email: { 38 | required: true, 39 | type: 'email', 40 | message: 'Invalid email' 41 | }, 42 | phone: { 43 | required: true, 44 | len: 11, 45 | message: 'Invalid Phone' 46 | }, 47 | address: { 48 | required: true, 49 | message: 'Invalid Address' 50 | }, 51 | gender: { 52 | required: true, 53 | message: 'Must select a gender' 54 | } 55 | }, 56 | login: { 57 | email: { 58 | required: true, 59 | type: 'email', 60 | message: 'Invalid email' 61 | }, 62 | password: { 63 | required: true, 64 | message: 'Password cannot be empty' 65 | } 66 | }, 67 | changePassword: { 68 | oldPassword: { 69 | required: true, 70 | min: 4, 71 | message: 'Invalid old password' 72 | }, 73 | newPassword: { 74 | required: true, 75 | min: 4, 76 | message: 'Invalid new password' 77 | }, 78 | confirmPassword: { 79 | required: true, 80 | min: 4, 81 | message: 'Invalid confirm password' 82 | } 83 | } 84 | }, 85 | 86 | books: { 87 | create: { 88 | genre: { 89 | required: true, 90 | message: 'Genre cannot be empty' 91 | }, 92 | title: { 93 | required: true, 94 | message: 'Title cannot be empty' 95 | }, 96 | publisher: { 97 | required: true, 98 | message: 'Publisher cannot be empty' 99 | }, 100 | author: { 101 | required: true, 102 | message: 'Author cannot be empty' 103 | }, 104 | edition: { 105 | required: true, 106 | message: 'Invalid Edition' 107 | }, 108 | isbn: { 109 | required: true, 110 | message: 'ISBN cannot be empty' 111 | }, 112 | pages: { 113 | required: true, 114 | message: 'Invalid Pages' 115 | } 116 | }, 117 | request: { 118 | genre: { 119 | required: true, 120 | message: 'Genre cannot be empty' 121 | }, 122 | title: { 123 | required: true, 124 | message: 'Title cannot be empty' 125 | }, 126 | author: { 127 | required: true, 128 | message: 'Author cannot be empty' 129 | }, 130 | edition: { 131 | required: true, 132 | message: 'Invalid Edition' 133 | }, 134 | isbn: { 135 | required: true, 136 | message: 'ISBN cannot be empty' 137 | } 138 | } 139 | } 140 | }; 141 | -------------------------------------------------------------------------------- /views/admin/books-delete.ejs: -------------------------------------------------------------------------------- 1 | <%-include('../partials/header.html')%> 2 | 3 | Delete Book 4 | 5 | 6 | 7 | 8 | <%-include('partials/navbar.html')%> 9 |
10 |
11 | <%-include('partials/sidebar.html')%> 12 |
13 |
14 |
15 |

Delete Book

16 |
17 | 18 |
19 | 20 |
21 | 22 |
23 |
24 |
25 |
26 | 27 |
28 | 29 |
30 |
31 |
32 |
33 | 34 |
35 | 36 |
37 |
38 |
39 |
40 | 41 |
42 | 43 |
44 |
45 |
46 |
47 | 48 |
49 | 50 |
51 |
52 |
53 |
54 | 55 |
56 | 57 |
58 |
59 |
60 |
61 | 62 |
63 | 64 |
65 |
66 |
67 |
68 | 69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 | 78 | <%-include('../partials/footer.html')%> 79 | -------------------------------------------------------------------------------- /views/admin/customers-delete.ejs: -------------------------------------------------------------------------------- 1 | <%-include('../partials/header.html')%> 2 | 3 | Delete Customer 4 | 5 | 6 | 7 | 8 | <%-include('partials/navbar.html')%> 9 |
10 |
11 | <%-include('partials/sidebar.html')%> 12 |
13 |
14 |
15 |

Delete Customer

16 |
17 | 18 |
19 | 20 |
21 | 22 |
23 |
24 |
25 |
26 | 27 |
28 | 29 |
30 |
31 |
32 |
33 | 34 |
35 | 36 |
37 |
38 |
39 |
40 | 41 |
42 | 43 |
44 |
45 |
46 |
47 | 48 |
49 | 50 |
51 |
52 |
53 |
54 | 55 |
56 | 57 |
58 |
59 |
60 |
61 | 62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 | 71 | <%-include('../partials/footer.html')%> 72 | -------------------------------------------------------------------------------- /views/admin/books-issue.ejs: -------------------------------------------------------------------------------- 1 | <%-include('../partials/header.html')%> 2 | 3 | Issue Book to Customers 4 | 5 | 6 | 7 | 8 | <%-include('partials/navbar.html')%> 9 |
10 |
11 | <%-include('partials/sidebar.html')%> 12 |
13 |
14 | 31 |
32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | <% for(var i=0; i< res.length; i++){ %> 47 | 48 | <% if(res[i].is_admin == 1){ 49 | continue; 50 | } 51 | %> 52 | 53 | 54 | 55 | 56 | 57 | 58 | 67 | 68 | <% } %> 69 | 70 |
IDNamePhoneEmailAddressGenderAction
<%=res[i].user_id%><%=res[i].name%><%=res[i].phone%><%=res[i].email%><%=res[i].address%><%=res[i].gender%> 59 |
60 | 61 |
62 | 63 |
64 |
65 |
66 |
71 |
72 | <% for(var i=0; i< errs.length; i++){ %> 73 | <%= errs[i].message; %> 74 |
75 | <% } %> 76 |
77 |
78 |
79 |
80 | 81 | <%-include('../partials/footer.html')%> 82 | -------------------------------------------------------------------------------- /views/admin/books-requested.ejs: -------------------------------------------------------------------------------- 1 | <%-include('../partials/header.html')%> 2 | 3 | Requested Books 4 | 5 | 6 | 7 | 8 | <%-include('partials/navbar.html')%> 9 |
10 |
11 | <%-include('partials/sidebar.html')%> 12 |
13 |
14 | 32 |
33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | <% for(var i=0; i< res.length; i++){ %> 48 | 49 | 52 | 55 | 58 | 61 | 64 | 67 | 70 | 71 | <% } %> 72 |
73 | <% for(var i=0; i< errs.length; i++){ %> 74 | <%= errs[i].message %> 75 |
76 | <% } %> 77 |
78 | 79 | 80 |
Request IDGenreTitleAuthorEditionISBNDate Requested
50 | <%=res[i].request_id%> 51 | 53 | <%=res[i].genre%> 54 | 56 | <%=res[i].title%> 57 | 59 | <%=res[i].author%> 60 | 62 | <%=res[i].edition%> 63 | 65 | <%=res[i].isbn%> 66 | 68 | <%=res[i].date%> 69 |
81 |
82 |
83 |
84 | 85 | <%-include('../partials/footer.html')%> 86 | -------------------------------------------------------------------------------- /views/admin/books-add.ejs: -------------------------------------------------------------------------------- 1 | <%-include('../partials/header.html')%> 2 | 3 | Add New Book 4 | 5 | 6 | 7 | 8 | <%-include('partials/navbar.html')%> 9 |
10 |
11 | <%-include('partials/sidebar.html')%> 12 |
13 |
14 |
15 |

Add New Book

16 |
17 |
18 | 19 |
20 | 21 |
22 |
23 |
24 |
25 | 26 |
27 | 28 |
29 |
30 |
31 |
32 | 33 |
34 | 35 |
36 |
37 |
38 |
39 | 40 |
41 | 42 |
43 |
44 |
45 |
46 | 47 |
48 | 49 |
50 |
51 |
52 |
53 | 54 |
55 | 56 |
57 |
58 |
59 |
60 | 61 |
62 | 63 |
64 |
65 |
66 |
67 | 68 |
69 |
70 |
71 |
72 | <% for(var i=0; i< errs.length; i++){ %> 73 | <%= errs[i].message %> 74 |
75 | <% } %> 76 | <% for(var i=0; i< success.length; i++){ %> 77 | <%= success[i].message %> 78 |
79 | <% } %> 80 |
81 |
82 |
83 |
84 |
85 |
86 | 87 | <%-include('../partials/footer.html')%> 88 | -------------------------------------------------------------------------------- /views/admin/books-edit.ejs: -------------------------------------------------------------------------------- 1 | <%-include('../partials/header.html')%> 2 | 3 | Edit Book 4 | 5 | 6 | 7 | 8 | <%-include('partials/navbar.html')%> 9 |
10 |
11 | <%-include('partials/sidebar.html')%> 12 |
13 |
14 |
15 |

Edit Existing Book

16 |
17 | 18 |
19 | 20 |
21 | 22 |
23 |
24 |
25 |
26 | 27 |
28 | 29 |
30 |
31 |
32 |
33 | 34 |
35 | 36 |
37 |
38 |
39 |
40 | 41 |
42 | 43 |
44 |
45 |
46 |
47 | 48 |
49 | 50 |
51 |
52 |
53 |
54 | 55 |
56 | 57 |
58 |
59 |
60 |
61 | 62 |
63 | 64 |
65 |
66 |
67 |
68 | 69 |
70 |
71 |
72 |
73 | <% for(var i=0; i< errs.length; i++){ %> 74 | <%= errs[i].message %> 75 |
76 | <% } %> 77 | <% for(var i=0; i< success.length; i++){ %> 78 | <%= success[i].message %> 79 |
80 | <% } %> 81 |
82 |
83 |
84 |
85 |
86 |
87 | 88 | <%-include('../partials/footer.html')%> 89 | -------------------------------------------------------------------------------- /views/admin/customers-add.ejs: -------------------------------------------------------------------------------- 1 | <%-include('../partials/header.html')%> 2 | 3 | Add Customers 4 | 5 | 6 | 7 | 8 | <%-include('partials/navbar.html')%> 9 |
10 |
11 | <%-include('partials/sidebar.html')%> 12 |
13 |
14 |
15 |

Add New Customer

16 |
17 |
18 | 19 |
20 | 21 |
22 |
23 |
24 |
25 | 26 |
27 | 28 |
29 |
30 |
31 |
32 | 33 |
34 | 35 |
36 |
37 |
38 |
39 | 40 |
41 | 42 |
43 |
44 |
45 |
46 | 47 |
48 | 49 |
50 |
51 |
52 |
53 |
54 | 55 |
56 | 60 |
61 |
62 |
63 | 64 |
65 |
66 |
67 |
68 | <% for(var i=0; i< errs.length; i++){ %> 69 | <%= errs[i].message %> 70 |
71 | <% } %> 72 | <% for(var i=0; i< success.length; i++){ %> 73 | <%= success[i].message %> 74 |
75 | <% } %> 76 |
77 | 78 |
79 |
80 |
81 |
82 |
83 | 84 | <%-include('../partials/footer.html')%> 85 | -------------------------------------------------------------------------------- /views/admin/customers-edit.ejs: -------------------------------------------------------------------------------- 1 | <%-include('../partials/header.html')%> 2 | 3 | Edit Customer 4 | 5 | 6 | 7 | 8 | <%-include('partials/navbar.html')%> 9 |
10 |
11 | <%-include('partials/sidebar.html')%> 12 |
13 |
14 |
15 |

Edit Customer

16 |
17 | 18 |
19 | 20 |
21 | 22 |
23 |
24 |
25 |
26 | 27 |
28 | 29 |
30 |
31 |
32 |
33 | 34 |
35 | 36 |
37 |
38 |
39 |
40 | 41 |
42 | 43 |
44 |
45 |
46 |
47 | 48 |
49 | 50 |
51 |
52 |
53 |
54 |
55 | 56 |
57 | 61 |
62 |
63 |
64 | 65 |
66 |
67 |
68 |
69 | <% for(var i=0; i< errs.length; i++){ %> 70 | <%= errs[i].message %> 71 |
72 | <% } %> 73 | <% for(var i=0; i< success.length; i++){ %> 74 | <%= success[i].message %> 75 |
76 | <% } %> 77 |
78 |
79 |
80 |
81 |
82 |
83 | 84 | <%-include('../partials/footer.html')%> 85 | -------------------------------------------------------------------------------- /views/admin/books.ejs: -------------------------------------------------------------------------------- 1 | <%-include('../partials/header.html')%> 2 | 3 | Books 4 | 5 | 6 | 7 | 8 | <%-include('partials/navbar.html')%> 9 |
10 |
11 | <%-include('partials/sidebar.html')%> 12 |
13 |
14 | 34 |
35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | <% for(var i=0; i< res.length; i++){ %> 52 | 53 | 56 | 59 | 62 | 65 | 68 | 71 | 74 | 77 | 87 | 88 | <% } %> 89 | 90 | 91 |
IDGenreTitleAuthorPublisherEditionISBNPagesAction
54 | <%=res[i].book_id%> 55 | 57 | <%=res[i].genre%> 58 | 60 | <%=res[i].title%> 61 | 63 | <%=res[i].author%> 64 | 66 | <%=res[i].publisher%> 67 | 69 | <%=res[i].edition%> 70 | 72 | <%=res[i].isbn%> 73 | 75 | <%=res[i].pages%> 76 | 78 | <% if(res[i].user_id) { %> 79 | Edit Book | 80 | Delete Book 81 | <% } else { %> 82 | Issue Book | 83 | Edit Book | 84 | Delete Book 85 | <% } %> 86 |
92 |
93 |
94 |
95 | 96 | <%-include('../partials/footer.html')%> 97 | -------------------------------------------------------------------------------- /views/customer/books.ejs: -------------------------------------------------------------------------------- 1 | <%-include('../partials/header.html')%> 2 | 3 | Books 4 | 5 | 6 | 7 | 8 | <%-include('partials/navbar.html')%> 9 |
10 |
11 | <%-include('partials/sidebar.html')%> 12 |
13 |
14 | 34 |
35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | <% for(var i=0; i< res.length; i++){ %> 52 | 53 | 56 | 59 | 62 | 65 | 68 | 71 | 74 | 77 | 87 | 88 | <% } %> 89 | 90 | 91 |
IDGenreTitleAuthorPublisherEditionISBNPages
54 | <%=res[i].book_id%> 55 | 57 | <%=res[i].genre%> 58 | 60 | <%=res[i].title%> 61 | 63 | <%=res[i].author%> 64 | 66 | <%=res[i].publisher%> 67 | 69 | <%=res[i].edition%> 70 | 72 | <%=res[i].isbn%> 73 | 75 | <%=res[i].pages%> 76 |
92 |
93 |
94 |
95 | 96 | <%-include('../partials/footer.html')%> 97 | -------------------------------------------------------------------------------- /models/bookModel.js: -------------------------------------------------------------------------------- 1 | var db = require.main.require('./models/config'); 2 | 3 | var getAll = (callback) => { 4 | var sql = "SELECT * FROM books"; 5 | db.executeQuery(sql, null, function(result) { 6 | callback(result); 7 | }); 8 | }; 9 | 10 | var searchBy = (searchBy, word, callback) => { 11 | var sql = "SELECT * FROM books WHERE "+searchBy+" = ?"; 12 | db.executeQuery(sql, [word], function(result) { 13 | callback(result); 14 | }); 15 | }; 16 | 17 | var createBook = (book, callback) => { 18 | var date = new Date(); 19 | var sql = "INSERT INTO books VALUES(null, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; 20 | db.executeQuery(sql, [0, book.genre, book.title, book.author, book.publisher, book.edition, book.isbn, book.pages, date], function(result) { 21 | callback(result); 22 | }); 23 | }; 24 | 25 | var getBook = (id, callback) => { 26 | var sql = "SELECT * FROM books WHERE book_id=?"; 27 | db.executeQuery(sql, [id], function(result) { 28 | callback(result[0]); 29 | }); 30 | }; 31 | 32 | var updateBook = (id, book, callback) => { 33 | var sql = "UPDATE books SET genre = ?, title = ?, author = ?, publisher = ?, edition = ?, isbn = ?, pages = ? WHERE book_id = ?"; 34 | db.executeQuery(sql, [book.genre, book.title, book.author, book.publisher, book.edition, book.isbn, book.pages, id], function(result) { 35 | callback(result); 36 | }); 37 | }; 38 | 39 | var deleteBook = (id, callback) => { 40 | var sql = "DELETE FROM books WHERE book_id = ?"; 41 | db.executeQuery(sql, [id], function(result) { 42 | callback(result); 43 | }); 44 | }; 45 | 46 | var issueBook = (book_id, customer_id, callback) => { 47 | var date = new Date(); 48 | var sql = "UPDATE books SET user_id = ?, date_issued = ? WHERE book_id = ?"; 49 | db.executeQuery(sql, [customer_id, date, book_id], function(result) { 50 | callback(result); 51 | }); 52 | }; 53 | 54 | var unissueBook = (book_id, callback) => { 55 | var sql = "UPDATE books SET user_id = '', date_issued = '' WHERE book_id = ?"; 56 | db.executeQuery(sql, [book_id], function(result) { 57 | callback(result); 58 | }); 59 | }; 60 | 61 | var getIssuedBooks = (id, callback) => { 62 | var sql = "SELECT * FROM books WHERE NOT user_id = ''"; 63 | db.executeQuery(sql, null, function(result) { 64 | callback(result); 65 | }); 66 | }; 67 | 68 | var getUnborrowedBooks = (callback) => { 69 | var sql = "SELECT * FROM books WHERE (user_id = 'NULL') OR (user_id = 0)"; 70 | db.executeQuery(sql, null, function(result) { 71 | callback(result); 72 | }); 73 | }; 74 | 75 | var bookRequest = (customer_id, book, callback) => { 76 | var date = new Date(); 77 | var sql = "INSERT INTO books_request VALUES(null, ?, ?, ?, ?, ?, ?, ?)"; 78 | db.executeQuery(sql, [customer_id, book.genre, book.title, book.author, book.edition, book.isbn, date], function(result) { 79 | callback(result); 80 | }); 81 | }; 82 | 83 | var customerSearch = (searchBy, word, callback) => { 84 | var sql = "(SELECT * FROM books WHERE "+searchBy+" = ?) AND ((user_id = '') OR (user_id = 0))"; 85 | db.executeQuery(sql, [word], function(result) { 86 | callback(result); 87 | }); 88 | }; 89 | 90 | var getRequestedBooks = (callback) => { 91 | var sql = "SELECT * FROM books_request"; 92 | db.executeQuery(sql, null, function(result) { 93 | callback(result); 94 | }); 95 | }; 96 | 97 | var bookRequestSearch = (searchBy, word, callback) => { 98 | var sql = "SELECT * FROM books_request WHERE "+searchBy+" = ?"; 99 | db.executeQuery(sql, [word], function(result) { 100 | callback(result); 101 | }); 102 | }; 103 | 104 | var setIssueDate = (book_id, customer_id, callback) => { 105 | var date = new Date(); 106 | var sql = "INSERT INTO issue_date VALUES(null, ?, ?, ?)"; 107 | db.executeQuery(sql, [book_id, customer_id, date], function(result) { 108 | callback(result); 109 | }); 110 | }; 111 | 112 | var booksIssuedByCustomer = (customer_id, callback) => { 113 | var sql = "SELECT * FROM books WHERE user_id = ?"; 114 | db.executeQuery(sql, [customer_id], function(result) { 115 | callback(result); 116 | }); 117 | }; 118 | 119 | var getAllBorrowedBooks = (callback) => { 120 | var sql = "SELECT * FROM issue_date"; 121 | db.executeQuery(sql, null, function(result) { 122 | callback(result); 123 | }); 124 | }; 125 | 126 | var totalBorrowed30 = (callback) => { 127 | var result = new Date(); 128 | var newDate = result.setDate(result.getDate() + 30); 129 | var sql = "SELECT books.*, issue_date.book_id FROM issue_date INNER JOIN books ON issue_date.book_id=books.book_id WHERE (date BETWEEN ? AND ?)"; 130 | db.executeQuery(sql, [newDate, result], function(result) { 131 | callback(result); 132 | }); 133 | }; 134 | 135 | var mostBorrowedBook = (callback) => { 136 | var sql = "SELECT books.*, issue_date.book_id, COUNT(*) AS magnitude FROM issue_date INNER JOIN books ON issue_date.book_id=books.book_id GROUP BY books.isbn ORDER BY magnitude DESC LIMIT 1"; 137 | db.executeQuery(sql, null, function(result) { 138 | callback(result[0]); 139 | }); 140 | }; 141 | 142 | var mostRequestedBook = (callback) => { 143 | var sql = "SELECT *, COUNT(*) AS magnitude FROM books_request GROUP BY isbn ORDER BY magnitude DESC LIMIT 1"; 144 | db.executeQuery(sql, null, function(result) { 145 | callback(result[0]); 146 | }); 147 | }; 148 | 149 | // SELECT books.*, issue_date.book_id, COUNT(*) AS magnitude FROM issue_date INNER JOIN books ON issue_date.book_id=books.book_id WHERE (date BETWEEN '2018-07-10' AND '2018-08-10') GROUP BY books.isbn ORDER BY magnitude DESC LIMIT 1 150 | 151 | 152 | module.exports = { 153 | getAll, 154 | searchBy, 155 | createBook, 156 | getBook, 157 | updateBook, 158 | deleteBook, 159 | issueBook, 160 | unissueBook, 161 | getIssuedBooks, 162 | getUnborrowedBooks, 163 | bookRequest, 164 | customerSearch, 165 | getRequestedBooks, 166 | bookRequestSearch, 167 | setIssueDate, 168 | booksIssuedByCustomer, 169 | getAllBorrowedBooks, 170 | totalBorrowed30, 171 | mostRequestedBook, 172 | mostBorrowedBook 173 | }; 174 | -------------------------------------------------------------------------------- /views/admin/issued-books.ejs: -------------------------------------------------------------------------------- 1 | <%-include('../partials/header.html')%> 2 | 3 | Issued Books 4 | 5 | 6 | 7 | 8 | <%-include('partials/navbar.html')%> 9 |
10 |
11 | <%-include('partials/sidebar.html')%> 12 |
13 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | <% for(var i=0; i< res.length; i++){ %> 47 | 48 | <% if(res[i].user_id == null || res[i].user_id == 0) { 49 | continue; 50 | } 51 | %> 52 | 55 | 58 | 61 | 64 | 67 | 70 | 75 | 78 | 88 | 97 | 98 | <% } %> 99 | 100 |
IDGenreTitleAuthorEditionISBNIssued ToIssued DateDays left until invalidAction
53 | <%=res[i].book_id%> 54 | 56 | <%=res[i].genre%> 57 | 59 | <%=res[i].title%> 60 | 62 | <%=res[i].author%> 63 | 65 | <%=res[i].edition%> 66 | 68 | <%=res[i].isbn%> 69 | 71 | 72 | <%=res[i].user_id%> 73 | 74 | 76 | <%=res[i].date_issued%> 77 | 79 | <% 80 | var date1 = new Date(res[i].date_issued); 81 | var date2 = new Date(); 82 | var timeDiff = Math.abs(date2.getTime() - date1.getTime()); 83 | var diffDays = Math.ceil(timeDiff / (1000 * 3600 * 24)); 84 | var leftValid = 30 - diffDays; 85 | %> 86 | <%=leftValid+" Days"%> 87 | 89 |
90 | 91 |
92 | 93 |
94 |
95 |
96 |
101 |
102 |
103 |
104 | 105 | <%-include('../partials/footer.html')%> 106 | -------------------------------------------------------------------------------- /controllers/customer.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | var userModel = require.main.require('./models/userModel'); 4 | var bookModel = require.main.require('./models/bookModel'); 5 | var validationRules = require.main.require('./validation_rules/rules'); 6 | var asyncValidator = require('async-validator-2'); 7 | 8 | router.get('/home', (req, res)=> { 9 | userModel.totalBooksBorrowedByCustomer(req.session.customer, (booksBorrowed)=> { 10 | if(!booksBorrowed){ 11 | res.send("nothing here"); 12 | } 13 | else { 14 | res.render('customer/home', {tbbbc: booksBorrowed.length}); 15 | } 16 | }); 17 | }); 18 | 19 | router.get('/profile', (req, res)=> { 20 | var customer = userModel.getUser(req.session.customer, (result)=> { 21 | if(!result){ 22 | res.send("invalid!"); 23 | } 24 | else { 25 | console.log(result); 26 | res.render('customer/profile', {res: result}); 27 | } 28 | }); 29 | }); 30 | 31 | router.get('/profile/edit', (req, res)=> { 32 | var customer = userModel.getUser(req.session.customer, (result)=> { 33 | if(!result){ 34 | res.send("invalid"); 35 | } 36 | else { 37 | console.log(result); 38 | res.render('customer/profile-edit', {res: result, errs: []}); 39 | } 40 | }); 41 | }); 42 | 43 | router.post('/profile/edit', (req, res)=> { 44 | var rules = validationRules.users.update; 45 | var validator = new asyncValidator(rules); 46 | var data = { 47 | user_id: req.body.user_id, 48 | name: req.body.name, 49 | email: req.body.email, 50 | phone: req.body.phone, 51 | address: req.body.address, 52 | gender: req.body.gender 53 | }; 54 | 55 | validator.validate(data, (errors, fields)=> { 56 | if(!errors){ 57 | userModel.updateUser(data, (result)=> { 58 | if(!result){ 59 | res.send('invalid'); 60 | } 61 | else { 62 | res.redirect('/customer/profile'); 63 | } 64 | }); 65 | } 66 | else { 67 | console.log(fields); 68 | res.render('customer/profile-edit', {errs: errors, res: []}); 69 | } 70 | }); 71 | }); 72 | 73 | router.get('/changepass', (req, res)=> { 74 | var customer = userModel.getUser(req.session.customer, (result)=> { 75 | if(!result){ 76 | res.send("invalid!"); 77 | } 78 | else { 79 | console.log(result); 80 | res.render('customer/change-password', {res: result, errs: [], success: []}); 81 | } 82 | }); 83 | }); 84 | 85 | router.post('/changepass', (req, res)=> { 86 | var rules = validationRules.users.changePassword; 87 | var validator = new asyncValidator(rules); 88 | var data = { 89 | oldPassword: req.body.oldPassword, 90 | newPassword: req.body.newPassword, 91 | confirmPassword: req.body.confirmPassword 92 | }; 93 | 94 | if(req.body.password == req.body.oldPassword){ 95 | validator.validate(data, (errors, fields)=> { 96 | if(!errors){ 97 | if(req.body.newPassword == req.body.confirmPassword){ 98 | userModel.updatePassword(req.body.newPassword, req.body.user_id, (result)=> { 99 | if(!result){ 100 | res.send('invalid'); 101 | } 102 | else { 103 | res.render('customer/change-password', {errs:[], res: [], success: [{message: "Password changed successfully"}]}); 104 | } 105 | }); 106 | } 107 | else { 108 | res.render('customer/change-password', {errs:[{message: "Your new passwords don't match!"}], res: [], success: []}); 109 | } 110 | } 111 | else { 112 | console.log(fields); 113 | res.render('customer/change-password', {errs: errors, res: [], success: []}); 114 | } 115 | }); 116 | } 117 | else { 118 | res.render('customer/change-password', {errs: [{message: "Your old passsword does not match!"}], res: [], success: []}); 119 | } 120 | 121 | }); 122 | 123 | router.get('/books', (req, res)=> { 124 | bookModel.getUnborrowedBooks((result)=> { 125 | if(!result){ 126 | res.send("Invalid"); 127 | } 128 | else { 129 | console.log(result); 130 | res.render('customer/books', {res: result, errs: []}); 131 | } 132 | }); 133 | }); 134 | 135 | router.post('/books', (req, res)=> { 136 | var searchBy = req.body.searchBy; 137 | var word = req.body.word; 138 | bookModel.customerSearch(searchBy, word, (result)=> { 139 | if(!result){ 140 | res.render('customer/books', {res: [], errs: [{message: "No results found!"}]}); 141 | } 142 | else { 143 | console.log(result); 144 | res.render('customer/books', {res: result, errs: []}) 145 | } 146 | }); 147 | }); 148 | 149 | 150 | router.get('/books/borrowed', (req, res)=> { 151 | userModel.getUserBorrow(req.session.customer, (result)=> { 152 | if(!result){ 153 | res.send("Invalid"); 154 | } 155 | else { 156 | console.log(result); 157 | res.render('customer/borrowed-books', {res: result}); 158 | } 159 | }); 160 | }); 161 | 162 | router.get('/books/request', (req, res)=> { 163 | res.render('customer/books-request', {errs: [], success: []}); 164 | }); 165 | 166 | router.post('/books/request', (req, res)=> { 167 | var data = { 168 | genre: req.body.genre, 169 | title: req.body.title, 170 | author: req.body.author, 171 | edition: req.body.edition, 172 | isbn: req.body.isbn 173 | }; 174 | 175 | var rules = validationRules.books.request; 176 | var validator = new asyncValidator(rules); 177 | 178 | validator.validate(data, (errors, fields)=> { 179 | if(!errors){ 180 | bookModel.bookRequest(req.session.customer, data, (result)=> { 181 | if(result.length == 0){ 182 | res.send("Invalid"); 183 | } 184 | else { 185 | res.render('customer/books-request', {errs: [], success: [{message: "Your request has been noted, thank you!"}]}); 186 | } 187 | }); 188 | } 189 | else { 190 | console.log(fields); 191 | res.render('customer/books-request', {errs: errors, success: []}); 192 | } 193 | }); 194 | }); 195 | router.get('/books/history', (req, res)=> { 196 | userModel.getUserHistory(req.session.customer, (result)=> { 197 | if(!result){ 198 | res.send("Invalid"); 199 | } 200 | else { 201 | console.log(result); 202 | res.render('customer/borrow-history', {res: result}); 203 | } 204 | }); 205 | }); 206 | 207 | 208 | 209 | module.exports = router; 210 | -------------------------------------------------------------------------------- /library_management_system.sql: -------------------------------------------------------------------------------- 1 | -- phpMyAdmin SQL Dump 2 | -- version 4.5.1 3 | -- http://www.phpmyadmin.net 4 | -- 5 | -- Host: 127.0.0.1 6 | -- Generation Time: Jul 10, 2018 at 11:08 PM 7 | -- Server version: 10.1.13-MariaDB 8 | -- PHP Version: 7.0.8 9 | 10 | SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; 11 | SET time_zone = "+00:00"; 12 | 13 | 14 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 15 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; 16 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; 17 | /*!40101 SET NAMES utf8mb4 */; 18 | 19 | -- 20 | -- Database: `library_management_system` 21 | -- 22 | 23 | -- -------------------------------------------------------- 24 | 25 | -- 26 | -- Table structure for table `books` 27 | -- 28 | 29 | CREATE TABLE `books` ( 30 | `book_id` int(100) NOT NULL, 31 | `user_id` int(100) DEFAULT NULL, 32 | `genre` varchar(300) NOT NULL, 33 | `title` varchar(300) NOT NULL, 34 | `author` varchar(300) NOT NULL, 35 | `publisher` varchar(300) NOT NULL, 36 | `edition` int(100) NOT NULL, 37 | `isbn` varchar(100) NOT NULL, 38 | `pages` int(100) NOT NULL, 39 | `date_issued` date DEFAULT NULL 40 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 41 | 42 | -- 43 | -- Dumping data for table `books` 44 | -- 45 | 46 | INSERT INTO `books` (`book_id`, `user_id`, `genre`, `title`, `author`, `publisher`, `edition`, `isbn`, `pages`, `date_issued`) VALUES 47 | (1, 5, 'Horror', 'Zombie Day', 'Kazi Nazrul Islam', 'Nazrul Publications', 3, 'jfklsgsdlg5qw7q87w', 800, '2018-07-10'), 48 | (3, 4, 'Adventure', 'A Song of Ice & Fire', 'George R. R. Martin', 'Game of Thrones', 8, 'has23dadh123427', 1200, '2018-07-11'), 49 | (4, 5, 'Adventure', 'Harry Potter & The Half Blood Prince', 'J.K Rowling', 'Rowling''s Publications', 1, '31ghf1jk24kjb3l4l1gjh', 667, '2018-07-10'), 50 | (5, 2, 'Adventure', 'Harry Potter & The Deadly Hallows', 'J.K Rowling', 'Rowling''s Publications', 2, 'agsh32gqkj12bkl134', 798, '2018-07-10'), 51 | (7, 0, 'Mystery', 'The Mysterious Affair at Styles', 'Agatha Christie', 'Agatha Publications', 2, '4zgdhdv2dfh81v31sdgj', 669, '0000-00-00'), 52 | (10, 0, 'Modern Literature', 'In Search of Lost Time', 'Marcel Proust', 'NY Publishers', 8, '2j3nsd235habh3dfkj', 4215, '2018-07-11'); 53 | 54 | -- -------------------------------------------------------- 55 | 56 | -- 57 | -- Table structure for table `books_request` 58 | -- 59 | 60 | CREATE TABLE `books_request` ( 61 | `request_id` int(10) NOT NULL, 62 | `user_id` int(10) NOT NULL, 63 | `genre` varchar(300) NOT NULL, 64 | `title` varchar(300) NOT NULL, 65 | `author` varchar(300) NOT NULL, 66 | `edition` int(10) NOT NULL, 67 | `isbn` varchar(100) NOT NULL, 68 | `date` date NOT NULL 69 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 70 | 71 | -- 72 | -- Dumping data for table `books_request` 73 | -- 74 | 75 | INSERT INTO `books_request` (`request_id`, `user_id`, `genre`, `title`, `author`, `edition`, `isbn`, `date`) VALUES 76 | (1, 2, 'Mystery', 'Murder on the Orient Express', 'Agatha Christie', 3, '12gf3gj1jhr3jklj1ugjkb', '2018-07-10'), 77 | (2, 5, 'Mystery', 'The Mysterious Affair at Styles', 'Agatha Christie', 3, '4zgdhdv2dfh81v31sdgj', '2018-07-10'), 78 | (3, 4, 'Mystery', 'The Mysterious Affair at Styles', 'Agatha Christie', 3, '4zgdhdv2dfh81v31sdgj', '2018-07-10'); 79 | 80 | -- -------------------------------------------------------- 81 | 82 | -- 83 | -- Table structure for table `issue_date` 84 | -- 85 | 86 | CREATE TABLE `issue_date` ( 87 | `issue_id` int(10) NOT NULL, 88 | `book_id` int(10) NOT NULL, 89 | `user_id` int(10) NOT NULL, 90 | `date` date NOT NULL 91 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 92 | 93 | -- 94 | -- Dumping data for table `issue_date` 95 | -- 96 | 97 | INSERT INTO `issue_date` (`issue_id`, `book_id`, `user_id`, `date`) VALUES 98 | (1, 1, 2, '2018-07-10'), 99 | (2, 5, 2, '2018-07-10'), 100 | (3, 3, 2, '2018-07-10'), 101 | (4, 4, 5, '2018-07-10'), 102 | (5, 1, 2, '2018-07-10'), 103 | (6, 5, 5, '2018-07-10'), 104 | (7, 1, 5, '2018-07-10'), 105 | (8, 4, 5, '2018-07-10'), 106 | (9, 3, 5, '2018-07-10'), 107 | (10, 5, 5, '2018-07-10'), 108 | (11, 3, 5, '2018-07-10'), 109 | (12, 3, 5, '2018-07-10'), 110 | (13, 3, 5, '2018-07-10'), 111 | (14, 3, 5, '2018-07-10'), 112 | (15, 3, 4, '2018-07-10'), 113 | (16, 1, 5, '2018-07-10'), 114 | (17, 3, 5, '2018-07-10'), 115 | (18, 5, 2, '2018-07-10'), 116 | (19, 3, 4, '2018-07-11'), 117 | (20, 7, 4, '2018-07-11'), 118 | (21, 7, 5, '2018-07-11'), 119 | (22, 3, 4, '2018-07-11'); 120 | 121 | -- -------------------------------------------------------- 122 | 123 | -- 124 | -- Table structure for table `users` 125 | -- 126 | 127 | CREATE TABLE `users` ( 128 | `user_id` int(100) NOT NULL, 129 | `name` varchar(300) NOT NULL, 130 | `phone` varchar(11) NOT NULL, 131 | `email` varchar(300) NOT NULL, 132 | `is_admin` tinyint(1) NOT NULL, 133 | `password` varchar(300) NOT NULL, 134 | `address` varchar(300) NOT NULL, 135 | `gender` varchar(300) NOT NULL 136 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 137 | 138 | -- 139 | -- Dumping data for table `users` 140 | -- 141 | 142 | INSERT INTO `users` (`user_id`, `name`, `phone`, `email`, `is_admin`, `password`, `address`, `gender`) VALUES 143 | (1, 'Abrar', '01711568524', 'a.zshahriar@gmail.com', 1, '1234', 'Mirpur DOHS', 'Male'), 144 | (2, 'Arefin', '01764431859', 'arefin@gmail.com', 0, 'yellow', 'Mirpur 13', 'Male'), 145 | (4, 'Rafin', '01924184941', 'rafin.ryan.07@outlook.com', 0, 'horse', 'Mirpur 13, Dhaka', 'Male'), 146 | (5, 'Shimi', '01723645289', 'shimi@gmail.com', 0, 'abcd', 'Uttara, Sector 13', 'Female'), 147 | (6, 'Jhuma', '01782963175', 'fjhuma@gmail.com', 0, 'qwerty', 'Banani, Chairman Bari', 'Female'), 148 | (7, 'Istiak', '01932478293', 'istiakisha69@gmail.com', 0, 'istiak', 'Baily Road', 'Male'), 149 | (8, 'Fahim Ahmed', '01726972364', 'fahim152@gmail.com', 0, 'fahimma', 'Kallayanpur', 'Male'); 150 | 151 | -- 152 | -- Indexes for dumped tables 153 | -- 154 | 155 | -- 156 | -- Indexes for table `books` 157 | -- 158 | ALTER TABLE `books` 159 | ADD PRIMARY KEY (`book_id`), 160 | ADD KEY `user_id` (`user_id`); 161 | 162 | -- 163 | -- Indexes for table `books_request` 164 | -- 165 | ALTER TABLE `books_request` 166 | ADD PRIMARY KEY (`request_id`); 167 | 168 | -- 169 | -- Indexes for table `issue_date` 170 | -- 171 | ALTER TABLE `issue_date` 172 | ADD PRIMARY KEY (`issue_id`); 173 | 174 | -- 175 | -- Indexes for table `users` 176 | -- 177 | ALTER TABLE `users` 178 | ADD PRIMARY KEY (`user_id`), 179 | ADD UNIQUE KEY `email` (`email`); 180 | 181 | -- 182 | -- AUTO_INCREMENT for dumped tables 183 | -- 184 | 185 | -- 186 | -- AUTO_INCREMENT for table `books` 187 | -- 188 | ALTER TABLE `books` 189 | MODIFY `book_id` int(100) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=11; 190 | -- 191 | -- AUTO_INCREMENT for table `books_request` 192 | -- 193 | ALTER TABLE `books_request` 194 | MODIFY `request_id` int(10) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4; 195 | -- 196 | -- AUTO_INCREMENT for table `issue_date` 197 | -- 198 | ALTER TABLE `issue_date` 199 | MODIFY `issue_id` int(10) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=23; 200 | -- 201 | -- AUTO_INCREMENT for table `users` 202 | -- 203 | ALTER TABLE `users` 204 | MODIFY `user_id` int(100) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=9; 205 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; 206 | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; 207 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; 208 | -------------------------------------------------------------------------------- /controllers/admin.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var router = express.Router(); 3 | var userModel = require.main.require('./models/userModel'); 4 | var bookModel = require.main.require('./models/bookModel'); 5 | var validationRules = require.main.require('./validation_rules/rules'); 6 | var asyncValidator = require('async-validator-2'); 7 | 8 | router.get('/home', (req, res)=> { 9 | // var users = ""; 10 | userModel.getAll((users)=> { 11 | if(!users){ 12 | res.send("Invalid"); 13 | } 14 | else { 15 | bookModel.getAll((books)=> { 16 | if(!books){ 17 | res.send("Invalid"); 18 | } 19 | else { 20 | bookModel.getAllBorrowedBooks((borrowed)=> { 21 | if(!borrowed){ 22 | res.send("invalid"); 23 | } 24 | else { 25 | bookModel.totalBorrowed30((mostBorrowed)=> { 26 | if(!mostBorrowed){ 27 | res.send("not valid"); 28 | } 29 | else { 30 | bookModel.mostRequestedBook((mostRequested)=> { 31 | if(!mostRequested){ 32 | res.render("nothing here"); 33 | } 34 | else { 35 | bookModel.mostBorrowedBook((mostBorrowedBook)=> { 36 | if(!mostBorrowedBook){ 37 | res.send("no borrowed books"); 38 | } 39 | else { 40 | res.render('admin/home', {usr: users.length, bk: books.length, brwd: borrowed.length, mb: mostBorrowed.length, mrb: mostRequested, mbb: mostBorrowedBook}); 41 | } 42 | }); 43 | } 44 | }); 45 | } 46 | }); 47 | } 48 | }); 49 | } 50 | }); 51 | } 52 | }); 53 | 54 | 55 | }); 56 | 57 | router.get('/profile', (req, res)=> { 58 | var admin = userModel.getUser(req.session.admin, (result)=> { 59 | if(!result){ 60 | res.send("invalid!"); 61 | } 62 | else { 63 | console.log(result); 64 | res.render('admin/profile', {res: result}); 65 | } 66 | }); 67 | }); 68 | 69 | router.get('/profile/edit', (req, res)=> { 70 | var admin = userModel.getUser(req.session.admin, (result)=> { 71 | if(!result){ 72 | res.send("invalid"); 73 | } 74 | else { 75 | console.log(result); 76 | res.render('admin/profile-edit', {res: result, errs: []}); 77 | } 78 | }); 79 | }); 80 | 81 | router.post('/profile/edit', (req, res)=> { 82 | var rules = validationRules.users.update; 83 | var validator = new asyncValidator(rules); 84 | var data = { 85 | user_id: req.body.user_id, 86 | name: req.body.name, 87 | email: req.body.email, 88 | phone: req.body.phone, 89 | address: req.body.address, 90 | gender: req.body.gender 91 | }; 92 | 93 | validator.validate(data, (errors, fields)=> { 94 | if(!errors){ 95 | userModel.updateUser(data, (result)=> { 96 | if(!result){ 97 | res.send('invalid'); 98 | } 99 | else { 100 | res.redirect('/admin/profile'); 101 | } 102 | }); 103 | } 104 | else { 105 | console.log(fields); 106 | res.render('admin/profile-edit', {errs: errors, res: []}); 107 | } 108 | }); 109 | }); 110 | 111 | router.get('/changepass', (req, res)=> { 112 | var admin = userModel.getUser(req.session.admin, (result)=> { 113 | if(!result){ 114 | res.send("invalid!"); 115 | } 116 | else { 117 | console.log(result); 118 | res.render('admin/change-password', {res: result, errs: [], success: []}); 119 | } 120 | }); 121 | }); 122 | 123 | router.post('/changepass', (req, res)=> { 124 | var rules = validationRules.users.changePassword; 125 | var validator = new asyncValidator(rules); 126 | var data = { 127 | oldPassword: req.body.oldPassword, 128 | newPassword: req.body.newPassword, 129 | confirmPassword: req.body.confirmPassword 130 | }; 131 | 132 | if(req.body.password == req.body.oldPassword){ 133 | validator.validate(data, (errors, fields)=> { 134 | if(!errors){ 135 | if(req.body.newPassword == req.body.confirmPassword){ 136 | userModel.updatePassword(req.body.newPassword, req.body.user_id, (result)=> { 137 | if(!result){ 138 | res.send('invalid'); 139 | } 140 | else { 141 | res.render('admin/change-password', {errs:[], res: [], success: [{message: "Password changed successfully"}]}); 142 | } 143 | }); 144 | } 145 | else { 146 | res.render('admin/change-password', {errs:[{message: "Your new passwords don't match!"}], res: [], success: []}); 147 | } 148 | } 149 | else { 150 | console.log(fields); 151 | res.render('admin/change-password', {errs: errors, res: [], success: []}); 152 | } 153 | }); 154 | } 155 | else { 156 | res.render('admin/change-password', {errs: [{message: "Your old passsword does not match!"}], res: [], success: []}); 157 | } 158 | 159 | }); 160 | 161 | router.get('/books', (req, res)=> { 162 | bookModel.getAll((result)=> { 163 | if(!result){ 164 | res.send("Invalid"); 165 | } 166 | else { 167 | console.log(result); 168 | res.render('admin/books', {res: result, errs: []}); 169 | } 170 | }); 171 | }); 172 | 173 | router.post('/books', (req, res)=> { 174 | var searchBy = req.body.searchBy; 175 | var word = req.body.word; 176 | bookModel.searchBy(searchBy, word, (result)=> { 177 | if(!result){ 178 | res.render('admin/books', {res: [], errs: [{message: "No results found!"}]}); 179 | } 180 | else { 181 | console.log(result); 182 | res.render('admin/books', {res: result, errs: []}) 183 | } 184 | }); 185 | }); 186 | 187 | router.get('/customers', (req, res)=> { 188 | userModel.getAll((result)=> { 189 | if(!result){ 190 | res.send("Invalid"); 191 | } 192 | else { 193 | console.log(result); 194 | res.render('admin/customers', {res: result, errs: []}); 195 | } 196 | }); 197 | }); 198 | 199 | router.post('/customers', (req, res)=> { 200 | var searchBy = req.body.searchBy; 201 | var word = req.body.word; 202 | userModel.searchBy(searchBy, word, (result)=> { 203 | if(!result){ 204 | res.render('admin/customers', {res: [], errs: [{message: "No results found!"}]}); 205 | } 206 | else { 207 | console.log(result); 208 | res.render('admin/customers', {res: result, errs: []}) 209 | } 210 | }); 211 | }); 212 | 213 | router.get('/customers/add', (req, res)=> { 214 | res.render('admin/customers-add', {errs: [], success: [], data: []}); 215 | }); 216 | 217 | router.post('/customers/add', (req, res)=> { 218 | var data = { 219 | name: req.body.name, 220 | email: req.body.email, 221 | phone: req.body.phone, 222 | password: req.body.password, 223 | address: req.body.address, 224 | gender: req.body.gender 225 | }; 226 | 227 | var rules = validationRules.users.create; 228 | var validator = new asyncValidator(rules); 229 | 230 | validator.validate(data, (errors, fields)=> { 231 | if(!errors){ 232 | userModel.createUser(data, (result)=> { 233 | if(!result){ 234 | res.send("Invalid"); 235 | } 236 | else { 237 | console.log(result); 238 | res.render('admin/customers-add', {errs: [], success: [{message: "Customer added successfully!"}], data: []}); 239 | } 240 | }); 241 | } 242 | else { 243 | console.log(fields); 244 | res.render('admin/customers-add', {errs: errors, success: [], data}); 245 | } 246 | }); 247 | }); 248 | 249 | router.get('/books/add', (req, res)=> { 250 | res.render('admin/books-add', {errs: [], success: [], data: []}); 251 | }); 252 | 253 | router.post('/books/add', (req, res)=> { 254 | var data = { 255 | genre: req.body.genre, 256 | title: req.body.title, 257 | author: req.body.author, 258 | publisher: req.body.publisher, 259 | edition: req.body.edition, 260 | isbn: req.body.isbn, 261 | pages: req.body.pages 262 | }; 263 | 264 | var rules = validationRules.books.create; 265 | var validator = new asyncValidator(rules); 266 | 267 | validator.validate(data, (errors, fields)=> { 268 | if(!errors){ 269 | bookModel.createBook(data, (result)=> { 270 | if(!result){ 271 | res.send("Invalid"); 272 | } 273 | else { 274 | console.log(result); 275 | res.render('admin/books-add', {errs: [], success: [{message: "Book added successfully!"}], data: []}); 276 | } 277 | }); 278 | } 279 | else { 280 | console.log(fields); 281 | res.render('admin/books-add', {errs: errors, success: [], data}); 282 | } 283 | }); 284 | }); 285 | 286 | router.get('/books/edit/:id', (req, res)=> { 287 | var book = req.params.id; 288 | bookModel.getBook(book, (result)=> { 289 | if(result.length == 0){ 290 | res.send("Invalid"); 291 | } 292 | else { 293 | res.render('admin/books-edit', {res: result, errs: [], success: []}); 294 | } 295 | }); 296 | }); 297 | 298 | router.post('/books/edit/:id', (req, res)=> { 299 | var data = { 300 | genre: req.body.genre, 301 | title: req.body.title, 302 | author: req.body.author, 303 | publisher: req.body.publisher, 304 | edition: req.body.edition, 305 | isbn: req.body.isbn, 306 | pages: req.body.pages 307 | }; 308 | var book_id = req.body.book_id; 309 | 310 | var rules = validationRules.books.create; 311 | var validator = new asyncValidator(rules); 312 | 313 | validator.validate(data, (errors, fields)=> { 314 | if(!errors){ 315 | bookModel.updateBook(book_id, data, (result)=> { 316 | if(!result){ 317 | res.send("Invalid"); 318 | } 319 | else { 320 | console.log(result); 321 | res.render('admin/books-edit', {res: result, errs:[], success: [{message: "Book updated successfully!"}]}); 322 | } 323 | }); 324 | } 325 | else { 326 | console.log(fields); 327 | res.render('admin/books-edit', {res: data, errs: errors, success: []}) 328 | } 329 | }); 330 | 331 | }); 332 | 333 | router.get('/customers/edit/:id', (req, res)=> { 334 | var customer = req.params.id; 335 | userModel.getUser(customer, (result)=> { 336 | if(result.length == 0){ 337 | res.send("Invalid"); 338 | } 339 | else { 340 | res.render('admin/customers-edit', {res: result, errs: [], success: []}); 341 | } 342 | }); 343 | }); 344 | 345 | router.post('/customers/edit/:id', (req, res)=> { 346 | var data = { 347 | name: req.body.name, 348 | email: req.body.email, 349 | phone: req.body.phone, 350 | password: req.body.password, 351 | address: req.body.address, 352 | gender: req.body.gender 353 | }; 354 | var customer_id = req.body.user_id; 355 | 356 | var rules = validationRules.users.create; 357 | var validator = new asyncValidator(rules); 358 | 359 | validator.validate(data, (errors, fields)=> { 360 | if(!errors){ 361 | userModel.updateCustomer(customer_id, data, (result)=> { 362 | if(!result){ 363 | res.send("Invalid"); 364 | } 365 | else { 366 | console.log(result); 367 | res.render('admin/customers-edit', {res: result, errs:[], success: [{message: "Customer updated successfully!"}]}); 368 | } 369 | }); 370 | } 371 | else { 372 | console.log(fields); 373 | res.render('admin/customers-edit', {res: data, errs: errors, success: []}); 374 | } 375 | }); 376 | 377 | }); 378 | 379 | router.get('/customers/profile/:id', (req, res)=> { 380 | var id = req.params.id; 381 | var customer = userModel.getUser(id, (result)=> { 382 | if(result.length == 0){ 383 | res.send("Invalid"); 384 | } 385 | else { 386 | console.log(result); 387 | res.render('admin/customers-profile', {res: result}); 388 | } 389 | }); 390 | }); 391 | 392 | router.get('/customers/delete/:id', (req, res)=> { 393 | var id = req.params.id; 394 | var customer = userModel.getUser(id, (result)=> { 395 | if(result.length == 0){ 396 | res.send("Invalid"); 397 | } 398 | else { 399 | console.log(result); 400 | res.render('admin/customers-delete', {res: result}); 401 | } 402 | }); 403 | }); 404 | 405 | router.post('/customers/delete/:id', (req, res)=> { 406 | var id = req.body.user_id; 407 | var customer = userModel.deleteUser(id, (result)=> { 408 | if(result.length == 0){ 409 | res.send("Invalid"); 410 | } 411 | else { 412 | console.log(result); 413 | res.redirect('/admin/customers'); 414 | } 415 | }); 416 | }); 417 | 418 | router.get('/books/delete/:id', (req, res)=> { 419 | var id = req.params.id; 420 | var book = bookModel.getBook(id, (result)=> { 421 | if(result.length == 0){ 422 | res.send("Invalid"); 423 | } 424 | else { 425 | console.log(result); 426 | res.render('admin/books-delete', {res: result}); 427 | } 428 | }); 429 | }); 430 | 431 | router.post('/books/delete/:id', (req, res)=> { 432 | var id = req.body.book_id; 433 | var book = bookModel.deleteBook(id, (result)=> { 434 | if(result.length == 0){ 435 | res.send("Invalid"); 436 | } 437 | else { 438 | console.log(result); 439 | res.redirect('/admin/books'); 440 | } 441 | }); 442 | }); 443 | 444 | router.get('/books/:id/issue', (req, res)=> { 445 | userModel.getAll((result)=> { 446 | if(!result){ 447 | res.send("Invalid"); 448 | } 449 | else { 450 | console.log(result); 451 | res.render('admin/books-issue', {res: result, errs: [], success: []}); 452 | } 453 | }); 454 | }); 455 | 456 | router.post('/books/:id/issue', (req, res)=> { 457 | var book_id = req.params.id; 458 | var customer_id = req.body.user_id; 459 | 460 | bookModel.booksIssuedByCustomer(customer_id, (books)=> { 461 | if(!books){ 462 | res.send("Invalid"); 463 | } 464 | else { 465 | console.log(books.length); 466 | if(books.length <= 2){ 467 | bookModel.setIssueDate(book_id, customer_id, (result)=> { 468 | if(!result){ 469 | res.send("Invalid"); 470 | } 471 | else { 472 | console.log(result); 473 | } 474 | }); 475 | bookModel.issueBook(book_id, customer_id, (result)=> { 476 | if(!result){ 477 | res.send("Invalid"); 478 | } 479 | else { 480 | console.log(result); 481 | res.redirect('/admin/books'); 482 | } 483 | }); 484 | } 485 | else{ 486 | userModel.getAll((result)=> { 487 | if(!result){ 488 | res.send("Invalid"); 489 | } 490 | else { 491 | console.log(result); 492 | res.render('admin/books-issue', {res: result, errs: [{message: "This customer has already issued 3 books, please unissue one first!"}], success: []}); 493 | } 494 | }); 495 | } 496 | } 497 | }); 498 | }); 499 | 500 | router.get('/books/issued', (req, res)=> { 501 | bookModel.getAll((result)=> { 502 | if(!result){ 503 | res.send("Invalid!"); 504 | } 505 | else { 506 | console.log(result); 507 | res.render('admin/issued-books', {res: result}); 508 | } 509 | }); 510 | }); 511 | 512 | router.post('/books/issued', (req, res)=> { 513 | var book_id = req.body.book_id; 514 | bookModel.unissueBook(book_id, (result)=> { 515 | if(!result){ 516 | res.send("Invalid"); 517 | } 518 | else { 519 | console.log(result); 520 | res.redirect('/admin/books'); 521 | } 522 | }); 523 | }); 524 | 525 | router.get('/books/requested', (req, res)=> { 526 | bookModel.getRequestedBooks((result)=> { 527 | if(!result){ 528 | res.send("Invalid"); 529 | } 530 | else { 531 | console.log(result); 532 | res.render('admin/books-requested', {res: result, errs: []}); 533 | } 534 | }); 535 | }); 536 | 537 | router.post('/books/requested', (req, res)=> { 538 | var searchBy = req.body.searchBy; 539 | var word = req.body.word; 540 | bookModel.bookRequestSearch(searchBy, word, (result)=> { 541 | if(!result){ 542 | res.render('admin/books-requested', {res: [], errs: [{message: "No results found!"}]}); 543 | } 544 | else { 545 | console.log(result); 546 | res.render('admin/books-requested', {res: result, errs: []}) 547 | } 548 | }); 549 | }); 550 | 551 | 552 | 553 | module.exports = router; 554 | --------------------------------------------------------------------------------