0% found this document useful (0 votes)
19 views36 pages

153 Internship Report

Uploaded by

Mohammad Adnan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
19 views36 pages

153 Internship Report

Uploaded by

Mohammad Adnan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 36

An Internship Report

on

Web Development
submitted in partial fulfillment for the reward of degree

BACHELOR OF ENGINEERING

In

COMPUTER SCIENCE AND ENGINEERING

By

MOHAMMAD ADNAN (160120733153)

Department of Computer Science and Engineering,


Chaitanya Bharathi Institute of Technology
(Autonomous),
(Affiliated to Osmania University,
Hyderabad) Hyderabad, TELANGANA
(INDIA) –500 075
[2022-2023]
1
CERTIFICATE

This is to certify that the internship titled “Web Development” is the work
carried out by MOHAMMAD ADNAN bearing roll no. 160120733153, a student of
B.E. (CSE) of Chaitanya Bharathi Institute of Technology(A), Hyderabad, affiliated to
Osmania University, Hyderabad, Telangana, India, during the academic year 2022-
2023.

Mentor Head, CSE Dept.


Dr .Y Rama Devi (HOD)

Place:
Date:

2
DECLARATION

I hereby declare that the internship entitled “To-Do Application ” is my original


work carried out by me.

Name & Signature of the Student

MOHAMMAD ADNAN

Place: Hyderabad
Date: 10-01-2022

3
Table of Contents

S. No. Content Page


no.
Title Page 1
Certificate by the Organization where the internship was carried
out
Certificate from the mentor 2
Declaration of the Student 3
Abstract 4
Acknowledgement 5
List of Figures

1. INTRODUCTION 6
1.1 Problem Definition including the significance and objective 6
1.2 Methodologies 6
1.3 Outline of Result 6
1.4 Future Scope of Project

2. REQUIREMENT SPECIFICATION 8
2.1 Concepts Required 8

3. 11
3.1 WD201 Levels 11
12

4 IMPLEMENTATION OF THE TODOLIST 14


4.1 Algorithm

5. RESULTS / OUTPUTS AND DISCUSSIONS 19


5.1 Screenshots of the output
6. CONCLUSIONS / RECOMMENDATIONS 21
6.1 Conclusions
6.2 Recommendations / Future Work /Future Scope
6.3 References

4
ABSTRACT

The Web development 101 course is for beginners in programming & web development,
who are looking forward to build a robust foundation in computational thinking. And the
continuation of the course is another course called Web development 201, which is Server-
side programming with Node.js.
A web-based tool called To-do List enables you to efficiently keep track of when your work
is due, which may help you prioritize and do excellent work.
For the front end, which is the user interface, HTML, CSS, and JavaScript are used. The
backend development of this to-do application, which connects to the database and makes
requests and responses with the server, was created using NodeJS.

5
ACKNOWLEDGEMENTS

We have taken efforts in this project. However, it would not have been
possible without the kind support and help of many individuals. I would like to
extend my sincere thanks to all of them who helped us in completing the project,
specifically to Dr. Rama Devi mam CSE Dept.HOD. It has been a great honor
and a privilege to undergo training and internship at Pupilfirst. We are highly
indebted to our mentors for their guidance and constant supervision as well as
for providing necessary information regarding the project and also for their support
in completing the project. My thanks and appreciations also go to my colleagues in
developing the project and people who have willingly helped me out with their
abilities and guidance.

6
1. INTRODUCTION

1.1. Problem Definition including the significance and objective

Web development is a well-known expanding industry in today's technology


world. The Pupilfirst WD 101 & 201 courses are internship training programs.
It is well known that to-do list is just a list of things you have to-do. Effectively
tracking when your work is due can help you prioritize and get great work done and
authentication is also required to do a to-do manager.

1.2. Methodology
There are numerous ways to go about creating a website. I've learned the fundamentals
of Node.js and database applications utilizing Sequelize through my project, which I
carried out step-by-step. I created a to-do application based on NodeJS. The projects'
GitHub connections have been provided for each level, and at levels 7 and 8, apps have
been deployed as web services using render software which is Paas used to render the
web application .

1.3. Outline of Results


The To-do Manager Node.js application with specified requirements has been
completed. The implemented design contains all the sections which include a header, a
form to create a new to-do, and three sections namely Overdue, Due Today, and Due
Later to list the to-dos. Todo items should be fetched from the database and rendered in
different sections.

1.4. Future scope of the project


The last step is to submit a brand-new project for an online voting platform with voter &
administrator personals. This project guarantees that all of the Node.js & backend
principles necessary for web development have been fully understood & implemented

7
2. REQUIRED CONCEPTS

1. HTML :
HTML stands for Hyper Text Markup Language. It is the standard markup
language for creating Web pages. HTML describes the structure of a Web page.HTML
consists of a series of elements. HTML elements tell the browser how to display the
content.HTML elements label pieces of content such as "this is a heading", "this is a
paragraph", "this is a link".
2. CSS:
CSS stands for Cascading Style Sheet. CSS is used to define styles for your web
pages, including the design, layout and variations in display for different devices and screen
sizes.
3. JavaScript:
JavaScript is a Programming Language, that runs on the end user's browser, and
allows us to calculate, manipulate and validate data. Where HTML and CSS are
languages that give structure and style to web pages, JavaScript improves the user
experience of the web page by converting it from a static page into an interactive one.
4. NODEJS:
Node.js is a runtime environment for writing server-side JavaScript applications. Node.js is
open-source and completely free, it's used by thousands of developers around the world. Node
is often used to build back-end services that communicate with client-side applications.
5. EXPRESSJS:
Express.js is a fast and lightweight framework, used majorly for web application
development. Express is built on top of Node.js. It is designed to develop websites, web apps, &
API‟s easily. With that being said, let's create our first ever Express application.
6. POSTGRE SQL:
PostgreSQL is one of the most advanced general-purpose object-relational
database management system and is open-source. Being an open-source software, its
source code is available under PostgreSQL license, a liberal open source license.
Anyone with the right skills is free to use, modify, & distribute Postgre SQL in any form.

8
3. WD-201 LEVELS

3.1 LEVELWISE BREIFING:


LEVEL - 1:

 Creating a new public repository in your GitHub account.


 In your system, initialize a new git repository after switching to the hello-node folder
where you have created your first Node.js program.
 Commit all files locally with proper messages.
 Connect the local repository to your GitHub account by simply following the steps
shown in GitHub after executing git push
 Push your code to the repository created in step 1, copy the URL in the submissions
tab and submit your work.

LEVEL - 2:

 Create a new file called package.json and manually enter the configuration.
 Use the npm CLI, to generate one for us automatically.
 npm website – used for finding packages, creating profiles, and managing other
aspects of our npm usage.
 CLI or a Command Line Interface (CLI) – used to interact with npm and is run
from a Terminal/Command Prompt.
 npm registry – used as the public database of JavaScript
software/dependencies.

9
LEVEL - 3:

 Due today
 Due later
 Over due
 Above functions have to be created

LEVEL-4:

 A test that checks creating a new todo.


 checks marking a todo as completed.
 checks retrieval of overdue items.
 checks retrieval of due today items.
 checks retrieval of due later items.

LEVEL-5:

 A database is essentially a collection of tables


 Once a connection is established with the server, we can then issue commands
to it using Sequelize.
 you have to modify connectDB.js to export two functions.
 In Node.js, we export functions, objects etc. in a module to outside world to
consume using module. Exports.
 Implement the functions in models/todo.js as explained above and ensure that
listTodos.js, completeTodo.js and addTodo.js files work as intended. The
completed code for these files are already present in the template.
 Update config/config.js with your local database credentials to test locally.Do not
modify any other files other than models/todo.js.

10
LEVEL-6:

 Express.js is a fast and lightweight framework, used majorly for web application
development. Express is built on top of Node.js. It is designed to develop
websites, web apps, & API‟s easily.
 The app.listen() function tells the server to start listening for connections on a
particular port, in this case, port 3000.
 we've defined the route to delete a To-Do by its id (DELETE /todos/:id). You have
to complete the implementation for that.
 Also write tests for this DELETE /todos/:id endpoint using JEST.
LEVEL-7:

 Introduce ejs in the existing application and render an Index page.


 Render Header content using view templates on the Index page with a h1 tag
containing text "This is my Todo Application".
 Deploy your application.
 In these Ejs Templates define:
 Index.ejs
 Header.ejs
 Footer.ejs

LEVEL-8:
 Add a new EJS template todos.ejs in the views folder. This will have the UI for
listing all to-dos in three sections. Import this partial todos.ejs to the main index.ejs
template to render the list of to-dos. This is similar to how header.ejs was imported
to index.ejs to show the application title.
 Todo items should be fetched from the database and rendered in different
sections.
 Display the count of items in each section after the title (Overdue, Due Today, Due
Later)
 Contains a header h1 tag with the title of the applicatio

11
LEVEL-9:

 Make it possible to add a new to-do


 Add client-side validation in new todo form to ensure that, no todo gets created in
database with empty title or dueDate.
 Mark a to-do as complete. Instead of markAsCompleted, implement a
setCompletionStatus method in the Todo model, which takes a boolean value and
updates the todo item accordingly.
 Mark a to-do as incomplete.
 Replace /todos/:id/markAsCompleted with /todos/:id to accept a PUT request and
use completed key in the PUT request body to update a todo item.
 Allow users to delete a to-do.
 Move completed items to its own section.
 So there would be over-due, due today, due later and completed items sections.

LEVEL - 10:

 In this level we are making login and sign up page


 We are managing cookies and sessions.
 We are using cookie-parser and express-session modules.

12
4. IMPLEMENTATION OF TO-DO

1.
Install NVM, NPM
curl -sL https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh -o
install_nvm.sh
nvm install -lts

2.
Create Package.json
A new directory has to be created first.
npm init
npm config set init-author-name "Jane Doe" --location=global
npm config set init-author-email "[email protected]" --location=global

package.json:

{
"name": "todo-manager",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "nodemon -e js,ejs",
"start:prod": "node index.js",
"pretest": "NODE_ENV=test npx sequelize-cli db:drop && NODE_ENV=test npx
sequelize-cli db:create",
"test": "NODE_ENV=test jest --detectOpenHandles",
"prepare": "husky install"
},
"lint-staged": {
"*.js": [
"eslint",
"prettier --write ."
]
},
"author": "",
"license": "ISC",
"dependencies": {
"bcrypt": "^5.1.0",
"connect-ensure-login": "^0.1.1",
"connect-flash": "^0.1.1",
"cookie-parser": "^1.4.6",
"ejs": "^3.1.8",
"express": "^4.18.1",
"express-session": "^1.17.3",
13
"passport": "^0.6.0",
"passport-local": "^1.0.0",
"pg": "^8.8.0",
"sequelize": "^6.23.0",
"tiny-csrf": "^1.1.3"
},
"devDependencies": {
"cheerio": "^1.0.0-rc.12",
"eslint": "^8.24.0",
"husky": "^8.0.1",
"jest": "^29.1.1",
"lint-staged": "^13.0.3",
"nodemon": "^2.0.20",
"prettier": "^2.7.1",
"sequelize-cli": "^6.4.1",
"supertest": "^6.2.4"
}
}

3.
Create Event Loop, Overdue, Duetoday, Completed Functions

setTimeout(() => {
// callback function
}, milliseconds);

__tests__/todo.js:

const request = require("supertest");

const db = require("../models/index");
const app = require("../app");
let server;
let agent;

describe("Test case for database", () => {


beforeAll(async () => {
await db.sequelize.sync({ force: true });
server = app.listen(3000, () => {});
agent = request.agent(server);
});

afterAll(async () => {
try {
await db.sequelize.close();
await server.close();

14
} catch (error) {
console.log(error);
}
});

test("Creates a todo and responds with json at /todos POST endpoint", async () => {
const response = await agent.post("/todos").send({
title: "Buy Chocolate",
dueDate: new Date().toISOString(),
completed: false,
});
expect(response.statusCode).toBe(200);
expect(response.header["content-type"]).toBe(
"application/json; charset=utf-8"
);
const parsedResponse = JSON.parse(response.text);
expect(parsedResponse.id).toBeDefined();
});

test("Mark todo as a completed", async () => {


const res = await agent.post("/todos").send({
title: "Do HomeWork",
dueDate: new Date().toISOString(),
completed: false,
});
const parseResponse = JSON.parse(res.text);
const todoID = parseResponse.id;
expect(parseResponse.completed).toBe(false);

const changeTodo = await agent


.put(`/todos/${todoID}/markAsCompleted`)
.send();
const parseUpadteTodo = JSON.parse(changeTodo.text);
expect(parseUpadteTodo.completed).toBe(true);
});

test("Fetches all todos in the database using /todos endpoint", async () => {
await agent.post("/todos").send({
title: "Buy xbox",
dueDate: new Date().toISOString(),
completed: false,
});
await agent.post("/todos").send({
title: "Buy ps3",
dueDate: new Date().toISOString(),
completed: false,

15
});
const response = await agent.get("/todos");
const parsedResponse = JSON.parse(response.text);

expect(parsedResponse.length).toBe(4);
expect(parsedResponse[3]["title"]).toBe("Buy ps3");
});

test("Deletes a todo with the given ID if it exists and sends a boolean response", async
() => {
// FILL IN YOUR CODE HERE
const response = await agent.post("/todos").send({
title: "Buy xbox",
dueDate: new Date().toISOString(),
completed: false,
});
const parsedResponse = JSON.parse(response.text);
const todoID = parsedResponse.id;

const res = await agent.delete(`/todos/${todoID}`).send();


const bool = Boolean(res.text);
expect(bool).toBe(true);
});
});

4.
Create husky to add a pre-commit hook to our project.

npm install husky -D


npm pkg set scripts.prepare="husky install"
npm run prepare

Add pre commit hook, Install and configure ESLint

npx husky add .husky/pre-commit "npm test"


git add .husky/pre-commit
npm init @eslint/config

16
5.
Connect Postgre Sql with NodeJS and create Models

npm install sequelize pg pg-hstore

Index.js:

const app = require("./app");

// eslint-disable-next-line no-undef
app.listen(process.env.PORT || 3000, () => {
console.log("Started express server at port 3000");
});

Todo.js:

const request = require("supertest");


const cheerio = require("cheerio");
const db = require("../models/index");
const app = require("../app");

let server, agent;

function extractCsrfToken(res) {
var $ = cheerio.load(res.text);
return $("[name=_csrf]").val();
}

const login = async (agent, username, password) => {


let res = await agent.get("/login");
let csrfToken = extractCsrfToken(res);
res = await agent.post("/session").send({
email: username,
password: password,
_csrf: csrfToken,
});
};

describe("My Todo Manager", function () {


beforeAll(async () => {
await db.sequelize.sync({ force: true });
server = app.listen(4000, () => {});
agent = request.agent(server);
});

17
afterAll(async () => {
try {
await db.sequelize.close();
await server.close();
} catch (error) {
console.log(error);
}
});

test("A test for sign up", async () => {


let res = await agent.get("/signup");
const csrfTokenIs = extractCsrfToken(res);
res = await agent.post("/users").send({
firstName: "Test1",
lastName: "User1",
email: "[email protected]",
password: "12345678",
_csrf: csrfTokenIs,
});
expect(res.statusCode).toBe(302);
});

test("A test for sign out", async () => {


let response = await agent.get("/todos");
expect(response.statusCode).toBe(200);
response = await agent.get("/signout");
expect(response.statusCode).toBe(302);
response = await agent.get("/todos");
expect(response.statusCode).toBe(302);
});

test("Test for creating a todo", async () => {


const agent = request.agent(server);
await login(agent, "[email protected]", "12345678");
const res = await agent.get("/todos");
const csrfToken = extractCsrfToken(res);
const response = await agent.post("/todos").send({
title: "To Watch Video Lectures",
dueDate: new Date().toISOString(),
completed: false,
_csrf: csrfToken,
});
expect(response.statusCode).toBe(302);
});

18
test("A test for marking a todo as complete", async () => {
const agent = request.agent(server);
await login(agent, "[email protected]", "12345678");
let res = await agent.get("/todos");
let csrfToken = extractCsrfToken(res);
await agent.post("/todos").send({
title: "Completed Studying for Mids ",
dueDate: new Date().toISOString(),
completed: false,
_csrf: csrfToken,
});

const groupedTodosResponse = await agent


.get("/todos")
.set("Accept", "application/json");
const parsedGroupedResponse = JSON.parse(groupedTodosResponse.text);
const dueTodayCount = parsedGroupedResponse.dueToday.length;
const latestTodo = parsedGroupedResponse.dueToday[dueTodayCount - 1];

res = await agent.get("/todos");


csrfToken = extractCsrfToken(res);

const markCompleteResponse = await agent


.put(`/todos/${latestTodo.id}`)
.send({
_csrf: csrfToken,
completed: true,
});
const parsedUpdateResponse = JSON.parse(markCompleteResponse.text);
expect(parsedUpdateResponse.completed).toBe(true);
});

test("To mark a todo as incomplete", async () => {


const agent = request.agent(server);
await login(agent, "[email protected]", "12345678");
let res = await agent.get("/todos");
let csrfToken = extractCsrfToken(res);
await agent.post("/todos").send({
title: "To complete Records",
dueDate: new Date().toISOString(),
completed: true,
_csrf: csrfToken,
});

const groupedTodosResponse = await agent


.get("/todos")

19
.set("Accept", "application/json");
const parsedGroupedResponse = JSON.parse(groupedTodosResponse.text);
const dueTodayCount = parsedGroupedResponse.dueToday.length;
const latestTodo = parsedGroupedResponse.dueToday[dueTodayCount - 1];

res = await agent.get("/todos");


csrfToken = extractCsrfToken(res);

const markCompleteResponse = await agent


.put(`/todos/${latestTodo.id}`)
.send({
_csrf: csrfToken,
completed: false,
});
const parsedUpdateResponse = JSON.parse(markCompleteResponse.text);
expect(parsedUpdateResponse.completed).toBe(false);
});

test("Test for deleting a todo", async () => {


const agent = request.agent(server);
await login(agent, "[email protected]", "12345678");
let res = await agent.get("/todos");
let csrfToken = extractCsrfToken(res);
await agent.post("/todos").send({
title: "Completed OS lab Internal",
dueDate: new Date().toISOString(),
completed: false,
_csrf: csrfToken,
});

const groupedTodosResponse1 = await agent


.get("/todos")
.set("Accept", "application/json");

const parsedGroupedResponse1 = JSON.parse(groupedTodosResponse1.text);


const dueTodayCount = parsedGroupedResponse1.dueToday.length;
const latestTodo = parsedGroupedResponse1.dueToday[dueTodayCount - 1];

res = await agent.get("/todos");


csrfToken = extractCsrfToken(res);
const todoID = latestTodo.id;
const deleteResponse1 = await agent.delete(`/todos/${todoID}`).send({
_csrf: csrfToken,
});
const parsedDeleteResponse1 = JSON.parse(deleteResponse1.text).success;
expect(parsedDeleteResponse1).toBe(true);

20
res = await agent.get("/todos");
csrfToken = extractCsrfToken(res);

const deleteResponse21 = await agent.delete(`/todos/${todoID}`).send({


_csrf: csrfToken,
});
const parsedDeleteResponse21 = JSON.parse(deleteResponse21.text).success;
expect(parsedDeleteResponse21).toBe(false);
});

//Additional Changes

//One of the user cannot mark as complete or incomplete a todo of another user
test("One of the user cannot mark as complete or incomplete a todo of another user",
async () => {
//creating UserA account
let res = await agent.get("/signup");
let csrfToken = extractCsrfToken(res);
res = await agent.post("/users").send({
firstName: "test",
lastName: "User A",
email: "[email protected]",
password: "123456789",
_csrf: csrfToken,
});
//create Todo from UserA account
res = await agent.get("/todos");
csrfToken = extractCsrfToken(res);
res = await agent.post("/todos").send({
title: "Buy the necessary Stationary",
dueDate: new Date().toISOString(),
completed: false,
_csrf: csrfToken,
});
const idOfTodoFromUserA1 = res.id;
//Signout UserA
await agent.get("/signout");
//Create UserB account
res = await agent.get("/signup");
csrfToken = extractCsrfToken(res);
res = await agent.post("/users").send({
firstName: "test",
lastName: "User B",
email: "[email protected]",
password: "123456",
_csrf: csrfToken,

21
});
//Try markAsComplete on UserA Todo from UserB account
res = await agent.get("/todos");
csrfToken = extractCsrfToken(res);
const markCompleteResponse = await agent
.put(`/todos/${idOfTodoFromUserA1}`)
.send({
_csrf: csrfToken,
completed: true,
});
expect(markCompleteResponse.statusCode).toBe(422);
//Try markAsIncomplete on UserA Todo from UserB account
res = await agent.get("/todos");
csrfToken = extractCsrfToken(res);
const markIncompleteResponse11 = await agent
.put(`/todos/${idOfTodoFromUserA1}`)
.send({
_csrf: csrfToken,
completed: false,
});
expect(markIncompleteResponse11.statusCode).toBe(422);
});

//One of the user can't delete a todo of another user


test("One of the user can't delete a todo of another user", async () => {
//create UserA account
let res = await agent.get("/signup");
let csrfToken = extractCsrfToken(res);
res = await agent.post("/users").send({
firstName: "Test",
lastName: "UserC",
email: "[email protected]",
password: "12345678",
_csrf: csrfToken,
});

//creating a todo from UserA account

res = await agent.get("/todos");


csrfToken = extractCsrfToken(res);
res = await agent.post("/todos").send({
title: "The Exams are going to be held soon",
dueDate: new Date().toISOString(),
completed: false,
_csrf: csrfToken,
});

22
const idOfTodoFromUserA2 = res.id;
//Signing out from UserA
await agent.get("/signout");
//Creating an UserB account
res = await agent.get("/signup");
csrfToken = extractCsrfToken(res);
res = await agent.post("/users").send({
firstName: "Test",
lastName: "User D",
email: "[email protected]",
password: "12345678",
_csrf: csrfToken,
});

//Tring to delete an UserA's Todo from UserB's accounts


res = await agent.get("/todos");
csrfToken = extractCsrfToken(res);
const deleteResponse22 = await agent
.delete(`/todos/${idOfTodoFromUserA2}`)
.send({
_csrf: csrfToken,
});
expect(deleteResponse22.statusCode).toBe(422);
});
});

6.
Express module installed Via NPM

const express = require('express');


const app=require(„express‟);

app.js:

const express = require("express");


const app = express();
var csrf = require("tiny-csrf");
var cookieParser = require("cookie-parser");
const { Todo, User } = require("./models");
const bodyParser = require("body-parser");
const path = require("path");
//exporting all the libraries related to level10
const bcrypt = require("bcrypt");
const passport = require("passport");
const connectEnsureLogin = require("connect-ensure-login");
const session = require("express-session");
const flash = require("connect-flash");

23
const LocalStratergy = require("passport-local");

const saltRounds = 10;

app.set("views", path.join(__dirname, "views"));


app.use(flash());
app.use(bodyParser.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser("Some secret string"));
app.use(csrf("this_should_be_32_character_long", ["POST", "PUT", "DELETE"]));

app.use(
session({
secret: "my-super-secret-key-2837428907583420",
cookie: {
maxAge: 24 * 60 * 60 * 1000,
},
})
);

app.use(function (request, response, next) {


response.locals.messages = request.flash();
next();
});

//initializing and session


app.use(passport.initialize());
app.use(passport.session());

passport.use(
new LocalStratergy(
{
usernameField: "email",
passwordField: "password",
},
(username, password, done) => {
User.findOne({ where: { email: username } })
.then(async (user) => {
const result = await bcrypt.compare(password, user.password);
if (result) {
return done(null, user);
} else {
return done(null, false, { message: "Password is invalid!!!" });
}
})
.catch(() => {
return done(null, false, { message: "EmailID is invalid" });
});
}
)
);

24
//serializing the user
passport.serializeUser((user, done) => {
console.log("Serialize use in session", user.id);
done(null, user.id);
});

//deserializing the user


passport.deserializeUser((id, done) => {
User.findByPk(id)
.then((user) => {
done(null, user);
})
.catch((error) => {
done(error, null);
});
});

app.set("view engine", "ejs");


// eslint-disable-next-line no-undef
app.use(express.static(path.join(__dirname, "public")));

app.get("/", async function (request, response) {


// response.render("index", {
// title: "My Todo Manager",
// csrfToken: request.csrfToken(),
// });
if (request.user) {
return response.redirect("/todos");
} else {
response.render("index", {
title: "My Todo Manager",
csrfToken: request.csrfToken(),
});
}
});

app.get("/todos",
connectEnsureLogin.ensureLoggedIn(),
async function (request, response) {
try {
const userName = request.user.firstName + " " + request.user.lastName;
const loggedIn = request.user.id;
const overDue = await Todo.overDue(loggedIn);
const dueToday = await Todo.dueToday(loggedIn);
const dueLater = await Todo.dueLater(loggedIn);
const completedItems = await Todo.completedItemsAre(loggedIn);
if (request.accepts("html")) {
response.render("todos", {
title: "To-Do Manager",
userName,

25
overDue,
dueToday,
dueLater,
completedItems,
csrfToken: request.csrfToken(),
});
} else {
response.json({
overDue,dueToday,dueLater,completedItems,
});
}
} catch (err1) {
console.log(err1);
return response.status(422).json(err1);
}
}
);

//Route for users


app.post("/users", async (request, response) => {
if (!request.body.firstName) {
request.flash("error", "Please do enter your first name");
return response.redirect("/signup");
}
if (!request.body.email) {
request.flash("error", "Please do enter your email ID");
return response.redirect("/signup");
}
if (!request.body.password) {
request.flash("error", "Please do enter your password");
return response.redirect("/signup");
}
if (request.body.password < 8) {
request.flash("error", "Length of password should be atleast 8");
return response.redirect("/signup");
}
const hashedPwd = await bcrypt.hash(request.body.password, saltRounds);
try {
const user = await User.create({
firstName: request.body.firstName,
lastName: request.body.lastName,
email: request.body.email,
password: hashedPwd,
});
request.login(user, (err1) => {
if (err1) {
console.log(err1);
response.redirect("/");
} else {
response.redirect("/todos");

26
}
});
} catch (errori) {
request.flash("error", errori.message);
return response.redirect("/signup");
}
});

//Route for login


app.get("/login", (request, response) => {
response.render("login", {
title: "Login",
csrfToken: request.csrfToken(),
});
});

//Route for signup


app.get("/signup", (request, response) => {
response.render("signup", {
title: "Sign up",
csrfToken: request.csrfToken(),
});
});

//Route for session


app.post("/session",
passport.authenticate("local", {
failureRedirect: "/login",
failureFlash: true,
}),
(request, response) => {
response.redirect("/todos");
}
);

//Route for signout


app.get("/signout", (req, res, next) => {
req.logout((err1) => {
if (err1) {
return next(err1);
}
res.redirect("/");
});
});

//Not required for this level


app.get("/todos/:id",
connectEnsureLogin.ensureLoggedIn(),
async function (request, response) {
try {
const todo1 = await Todo.findByPk(request.params.id);

27
return response.json(todo1);
} catch (error2) {
console.log(error2);
return response.status(422).json(error2);
}
}
);

//Route for todos


app.post("/todos",
connectEnsureLogin.ensureLoggedIn(),
async function (request, response) {
if (request.body.title.length < 5) {
request.flash("error", "Lenght of title should be atleast 5");
return response.redirect("/todos");
}
if (!request.body.dueDate) {
request.flash("error", "Please do select a due date");
return response.redirect("/todos");
}
try {
await Todo.addaTodo({
title: request.body.title,
dueDate: request.body.dueDate,
userID: request.user.id,
});
return response.redirect("/todos");
} catch (error1) {
console.log(error1);
return response.status(422).json(error1);
}
}
);

//Route for completion status


app.put("/todos/:id",
connectEnsureLogin.ensureLoggedIn(),
async function (request, response) {
// const todo = await Todo.findByPk(request.params.id);
try {
const todo = await Todo.findByPk(request.params.id);
const updatedTodoIs = await todo.setCompletionStatusAs(
request.body.completed
);
return response.json(updatedTodoIs);
} catch (error1) {
console.log(error1);
return response.status(422).json(error1);
}
}
);

28
//Route for deleting
app.delete("/todos/:id",
connectEnsureLogin.ensureLoggedIn(),
async function (req, resp) {
console.log("Delete a todo with a particular id : ", req.params.id);
// FILL IN YOUR CODE HERE
try {
const res = await Todo.remove(req.params.id, req.user.id);
return res.json({ success: res === 1 });
} catch (error1) {
console.log(error1);
return resp.status(422).json(error1);
}
}
);

module.exports = app;

7.
Creating EJS Template:

 Header.ejs:

<h1 class="text-3xl font-semibold text-slate-1000 text-blue-600">My <a class="text-blue-


600" href="/">Todo-list</a></h1>

 Index.ejs:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="csrf-token" content="<%= csrfToken %>">
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="./css/style.css">
<title><%= title %></title>
</head>
<body>
<div class="grid grid-cols-6 my-10">
<div class="col-start-3 col-span-2">
<%- include('header.ejs') %>
<p class="py-3">Welcome to My Todo Manager</p>
<p class="py-3">Are you new here?<a class="text-blue-700" href="/signup">sign-
up</a></p>
<p class="py-3">Do you already have an account?<a class="text-blue-600"

29
href="/login">sign-in</a></p>
</div>
</div>
</body>
</html>

 Todos.ejs:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="csrf-token" content="<%= csrfToken %>">
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="./css/style.css">
<title><%= title %></title>
<style>
#bt{
border-radius: 50px;
}
</style>
<script>
var token = document.querySelector('meta[name="csrf-
token"]').getAttribute("content");
function deleteATodo(id) {
fetch(`/todos/${id}`, {
method: "delete",
headers: {"Content-Type":"application/json"},
body: JSON.stringify({
"_csrf":token
})
}).then((res)=>{
if (res.ok) {
window.location.reload();
}
}).catch((err2)=> console.error(err2))
}
function updateATodo(id, status) {
fetch(`/todos/${id}`, {
method: "put",
headers: {"Content-Type":"application/json"},
body: JSON.stringify({
"_csrf":token,

30
"completed":status
})
}).then((res)=>{
if (res.ok) {
window.location.reload();
}
}).catch((err1)=> console.error(err1))
}
</script>
</head>
<body>
<div class="grid grid-cols-6">
<div class="col-start-3 col-span-2">
<%- include('header.ejs') %>
<p class="text-gray-600 my-1">Hello <%= userName %></p>
<a class="text-green-600" href="/signout">sign out</a>
<form action="/todos" method="post">
<input type="hidden" name="_csrf" value="<%= csrfToken %>" />
<div class="flex gap-2 py-4">
<div class="flex-auto">
<input type="text" name="title" placeholder="What's next?" class="border
border-gray-300 text-gray-900 w-full rounded p-3 text-sm" required />
</div>
<div class="flex-auto">
<input type="date" name="dueDate" class="border border-gray-300 text-
gray-900 w-full rounded p-2 text-sm leading-4" />
</div>
<div class="flex-none">
<button type="submit" id="bt" class="bg-green-600 text-white px-5 py-1.5
rounded mr-2 mb-2">Add Todo</button>
</div>
</div>
</form>
<div>
<% if (messages && messages.error && messages.error.length > 0) { %>
<% for(var i=0; i<messages.error.length; i++) { %>
<p class="bg-red-100 my-3 list-none rounded px-4 py-2"><%=
messages.error[i] %></p>
<% } %>
<% } %>
</div>
<div>
<%- include('todo.ejs', {title: "Overdue", data: overDue}) %>
<%- include('todo.ejs', {title: "Due Today", data: dueToday}) %>
<%- include('todo.ejs', {title: "Due Later", data: dueLater}) %>
<%- include('todo.ejs', {title: "Completed Items", data: completedItems}) %>
</div>
</div>
</div>
</body>
</html>

31
8.
Deploying Application Online using render:

Render is a PaaS that lets companies build, deliver, monitor and scale apps.
Update Production inside the Config.json

config.json:

{
"development": {
"username": "postgres",
"password": "postgres",
"database": "wd-todo-dev",
"host": "127.0.0.1",
"dialect": "postgres"
},
"test": {
"username": "postgres",
"password": "postgres",
"database": "wd-todo-test",
"host": "127.0.0.1",
"dialect": "postgres"
},
"production": {
"use_env_variable": "DATABASE_URL",
"dialect": "postgres"
}
}

32
5. RESULTS / OUTPUTS AND DISCUSSIONS

Home page:

User Authentication:

1. Sign up Page(Creating New Account):

33
2. Log In Page:

My To-do List Page :

34
After Adding into Todos list:

After Marking Todo list in Check Boxes:

35
6. CONCLUSIONS / RECOMMENDATIONS

6.1 CONCLUSIONS:
That list of things you have to complete is one of the core time
management tools. It places all of your duties in one location. From there,
you may order them by importance and focus on the most crucial ones first
and no one can access it other that the user because it checks for the
authentication.

6.2 FUTURE SCOPE


➔ In future this is used for future tasks and projects and alert the worker to
make sure they complete the task.so you don't forget anything important.
➔ organization of a good work with precise planning of each assignment and a
brief description of it. Simplify the process and execute the required task
scope on time. the development of each employee's time management and
productivity abilities.

6.3 REFERENCES

Web Development 201 (Node.js) | Pupilfirst School


Web Development 101 | Pupilfirst School
Tailwind CSS

36

You might also like