Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Week 4 completed #13

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,20 @@ app.use(function (req, res, next) {
});

/* TODO: CONNECT MONGOOSE WITH OUR MONGO DB */
mongoose.set('useNewUrlParser', true);
mongoose.set('useFindAndModify', false);
mongoose.set('useCreateIndex', true);
mongoose.set('useUnifiedTopology', true);
var mongoDB = 'mongodb+srv://Roasters05:[email protected]/?retryWrites=true&w=majority'
mongoose.connect(mongoDB);
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'MongoDB connection error:'));

app.get("/", (req, res) => {
res.render("index", { title: "Library" });
});


/*-----------------Store ROUTES
TODO: Your task is to complete below controllers in controllers/store.js
If you need to add any new route add it here and define its controller
Expand All @@ -52,17 +61,20 @@ app.get("/books", store.getAllBooks);

app.get("/book/:id", store.getBook);

app.get("/books/loaned",
app.get("/books/loaned",middleware.isLoggedIn,
//TODO: call a function from middleware object to check if logged in (use the middleware object imported)
store.getLoanedBooks);

app.post("/books/issue",
app.post("/books/issue",middleware.isLoggedIn,
//TODO: call a function from middleware object to check if logged in (use the middleware object imported)
store.issueBook);

app.post("/books/search-book", store.searchBooks);

/* TODO: WRITE VIEW TO RETURN AN ISSUED BOOK YOURSELF */
app.post("/books/return",
middleware.isLoggedIn,
store.returnBook);

/*-----------------AUTH ROUTES
TODO: Your task is to complete below controllers in controllers/auth.js
Expand Down
34 changes: 34 additions & 0 deletions controllers/auth.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,57 @@

const passport = require("passport");
const User = require('../models/user');
var getLogin = (req, res) => {
//TODO: render login page
if(req.isAuthenticated())
res.redirect('/');
else{
res.render('login',{title: "Login|Page"});
}
};

var postLogin = (req, res) => {
// TODO: authenticate using passport
//On successful authentication, redirect to next page
const user = new User({
username: req.body.username,
password: req.body.password
});
req.login(user, function(err) {
if (err) console.log(err);
else {
passport.authenticate('local')(req, res, function(){
res.redirect('/');
})
}
})
};

var logout = (req, res) => {
// TODO: write code to logout user and redirect back to the page
req.logout()
res.redirect('/login')
};

var getRegister = (req, res) => {
// TODO: render register page
res.render('register', { title: 'Register' });
};

var postRegister = (req, res) => {
// TODO: Register user to User db using passport
//On successful authentication, redirect to next page
User.register({username: req.body.username,email:req.body.email} ,req.body.password , (err, user)=>{
if(!err)
{
passport.authenticate('local')(req,res,()=>{
res.redirect('/')})
}
else
{
res.json(err.message);

}})
};

module.exports = {
Expand Down
142 changes: 140 additions & 2 deletions controllers/store.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,172 @@
const Book = require("../models/book");
const User = require("../models/user");
const Bookcopy = require("../models/bookCopy");
var getAllBooks = (req, res) => {
//TODO: access all books from the book model and render book list page
res.render("book_list", { books: [], title: "Books | Library" });
Book.find({},function(err,book_list)
{
if(!err)
{
res.render("book_list", { books: book_list, title: "Books | Library" });
}


});

}

var getBook = (req, res) => {
//TODO: access the book with a given id and render book detail page
var book_id=req.params.id;
Book.findOne({_id:book_id},function(err,book)
{
if(!err && book)
{
res.render("book_detail",{book:book,title:"Book|"+book.title})
}
else if(!book)
{
res.send("Book is Not registered");
}
})
}

var getLoanedBooks = (req, res) => {

//TODO: access the books loaned for this user and render loaned books page
User.findOne({ username: req.user.username }, function (err, foundUser) {
if (!err) {
if (foundUser) {
Bookcopy.find({borrower: foundUser._id}).
populate('book').
populate('borrower').
exec((err, foundCopies)=>{
if(!err){
if(foundCopies){
res.render('loaned_books',{books: foundCopies, title: "Loans"});
}
}
})

}
}
})
}

var issueBook = (req, res) => {

// TODO: Extract necessary book details from request
// return with appropriate status
// Optionally redirect to page or display on same
var bookid=req.body.bid;
Book.findOne({_id:bookid},function(err,found)
{
if(!err && found)
{
var available_copies=found.available_copies-1;
if(available_copies>=0)
{
Book.updateOne(
{ _id: req.body.bid },
{ available_copies: available_copies },
(err) => {
if (err)
{
res.send('Error');
}
}
);
let isAvailable = available_copies ? true : false;
const issuedBook = new Bookcopy({
book: bookid,
status: isAvailable,
borrower: req.user._id,
borrow_date: Date.now(),
});
issuedBook.save();
User.findOneAndUpdate(
{ username: req.user.username },
{ $push: { loaned_books: issuedBook } },
{ safe: true, upsert: true, new: true },
(err, founduser) => {
if (err) res.send('Error');
}
);
Bookcopy.update(
{ book: found },
{ status: isAvailable },
{
borrow_date:Date.now()
},

(err) => {
if(err){
res.send('Error');
}
}
);
res.redirect('/books/loaned');


}


}
else{
res.send('No books are available to lend');
console.log(err);
}
})
}

var searchBooks = (req, res) => {
// TODO: extract search details
// query book model on these details
// render page with the above details


Book.findOne({title: req.body.title, author: req.body.author, genre: req.body.genre}, (err, found) => {

if(!err && found)
{
res.render('book_list', {books: found, title: 'Book | Search'});
}
else if(!found)
{
res.send("No such Book Exists");
}
})
}

var returnBook = (req, res) => {
Bookcopy.findOne({_id: req.body.bid}).populate('book').exec((err, foundBookCopy) => {
if (err) console.log(err);
else {
var available = foundBookCopy.book.available_copies;
Book.findByIdAndUpdate(foundBookCopy.book, {$set: {available_copies: available + 1}}, function(err, found)
{
if (err)
console.log(err)
});
User.findByIdAndUpdate(req.user._id, {$pull: {loaned_books: foundBookCopy._id}}, function(err, found)
{
if (err) console.log(err)
});
Bookcopy.findByIdAndUpdate(foundBookCopy._id, {$set: {status: true, borrower: null, borrow_date: null}}, function(err, found)
{
if (err) console.log(err)
});
res.redirect('/books/loaned');
}
})

}

module.exports = {
getAllBooks,
getBook,
getLoanedBooks,
issueBook,
searchBooks
searchBooks,
returnBook,
}
6 changes: 6 additions & 0 deletions middleware/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ middlewareObj.isLoggedIn=function(req,res,next){
If user is logged in: Redirect to next page
else, redirect to login page
*/
if(req.isAuthenticated()){
next();
}
else{
res.redirect('/login');
}
}

module.exports=middlewareObj;
18 changes: 18 additions & 0 deletions models/book.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,23 @@ var bookSchema=new mongoose.Schema({
/*TODO: DEFINE the following attributes-
title, genre, author, description, rating (out of 5), mrp, available_copies(instances).
*/
title: String,
genre: String,
author: String,
description: String,
rating:{
type:Number,
max : 5,
min : 0

},
mrp: Number,
available_copies:
{
type: Number,
default: 0
}


})
module.exports=mongoose.model("Book",bookSchema);
23 changes: 19 additions & 4 deletions models/bookCopy.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,24 @@ var mongoose=require("mongoose");
//DEFINING THE BOOK COPIES MODEL
var bookCopySchema=new mongoose.Schema({
//TODO: DEFINE the following attributes-
book: //embed reference to id of book of which its a copy
status: //TRUE IF AVAILABLE TO BE ISSUED, ELSE FALSE
borrow_data: //date when book was borrowed
borrower: //embed reference to id of user who has borrowed it
book:
{
type:mongoose.Schema.Types.ObjectId,
ref:'Book',

}, //embed reference to id of book of which its a copy
status:
{
type:Boolean,


}, //TRUE IF AVAILABLE TO BE ISSUED, ELSE FALSE
borrow_date:Date, //date when book was borrowed
borrower:
{
type:mongoose.Schema.Types.ObjectId,
ref:'User',

}, //embed reference to id of user who has borrowed it
})
module.exports=mongoose.model("Bookcopy",bookCopySchema);
11 changes: 11 additions & 0 deletions models/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,21 @@ var passportLocal=require("passport-local-mongoose");
var userSchema=new mongoose.Schema({

//TODO: DEFINE USERNAME AND PASSSWORD ATTRIBUTES
username:{
type:String,
},
password:{
type:String,
},


loaned_books:[
//TODO: embed reference to id's of book copies loaned by this particular user in this array
{
type:mongoose.Schema.Types.ObjectId,
ref:'BookCopy',

},
]
})
userSchema.plugin(passportLocal);
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"ejs": "^3.1.6",
"express": "^4.17.1",
"express-session": "^1.17.2",
"mongoose": "^5.13.2",
"mongoose": "^5.13.14",
"passport": "^0.4.1",
"passport-local": "^1.0.0",
"passport-local-mongoose": "^6.1.0"
Expand Down
2 changes: 1 addition & 1 deletion views/book_detail.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<dt>MRP:</dt>
<dd>Rs. <%= book.mrp %></dd>
<dt>Available Copies:</dt>
<dd><%= num_available %></dd>
<dd><%= book.available_copies %></dd>
</dl>
<form action="/books/issue" method="POST">
<input type="text" hidden value="<%= book.id %>" name="bid" />
Expand Down
Loading