diff --git a/.vscode/settings.json b/.vscode/settings.json index c3c81b8b..2fdfc6cf 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,4 +1,4 @@ -{ - "editor.fontSize": 42, - "terminal.integrated.fontSize": 62 -} \ No newline at end of file +// { +// "editor.fontSize": 42, +// "terminal.integrated.fontSize": 62 +// } \ No newline at end of file diff --git a/public/css/style.css b/public/css/style.css index 0475253a..40decb8b 100644 --- a/public/css/style.css +++ b/public/css/style.css @@ -1,7 +1,7 @@ -h1{ - color: red; -} -.completed{ - color: gray; - text-decoration: line-through; -} \ No newline at end of file +h1{ /*selecting the h1 element in the EJS file*/ + color: red; /*sets the text colour of the h1 to red */ +} /*closing the selector*/ +.completed{ /*selecting any element with the completed class*/ + color: gray; /*sets the text colour to gray*/ + text-decoration: line-through; /*applies a strike through styling to the text*/ +} /*closing the selector*/ \ No newline at end of file diff --git a/public/js/main.js b/public/js/main.js index ff0eac39..b013a22c 100644 --- a/public/js/main.js +++ b/public/js/main.js @@ -1,72 +1,72 @@ -const deleteBtn = document.querySelectorAll('.fa-trash') -const item = document.querySelectorAll('.item span') -const itemCompleted = document.querySelectorAll('.item span.completed') +const deleteBtn = document.querySelectorAll('.fa-trash') //creating a constant variable and assigning it to a selection to all elements with the class 'fa-trash' +const item = document.querySelectorAll('.item span') //creating a constant variable and assigning it to all span tags within a parent with the class of 'item' +const itemCompleted = document.querySelectorAll('.item span.completed') //creating a constant variable and assiging it to all span tags with the 'completed' class, that are within a parent with the class of 'item' -Array.from(deleteBtn).forEach((element)=>{ - element.addEventListener('click', deleteItem) -}) +Array.from(deleteBtn).forEach((element)=>{ //creating an array from our selection and starting a loop + element.addEventListener('click', deleteItem) //adding an event listener on the current item, and on a 'click' calls a function called deleteItem +}) //close our loop -Array.from(item).forEach((element)=>{ - element.addEventListener('click', markComplete) -}) +Array.from(item).forEach((element)=>{ //creating an array from our selection and starting a loop + element.addEventListener('click', markComplete) //adding an event listener on the current item, and on a 'click' calls a function called markComplete +}) //close our loop -Array.from(itemCompleted).forEach((element)=>{ - element.addEventListener('click', markUnComplete) -}) +Array.from(itemCompleted).forEach((element)=>{ //creating an array from our selection and starting a loop + element.addEventListener('click', markUnComplete) //adding an event listener on the current item, and on a 'click' calls a function called markUnComplete +}) //close our loop -async function deleteItem(){ - const itemText = this.parentNode.childNodes[1].innerText - try{ - const response = await fetch('deleteItem', { - method: 'delete', - headers: {'Content-Type': 'application/json'}, - body: JSON.stringify({ - 'itemFromJS': itemText - }) - }) - const data = await response.json() - console.log(data) - location.reload() +async function deleteItem(){ //declare an asynchronous function + const itemText = this.parentNode.childNodes[1].innerText //looks inside the list item and grabs only the inner text within the list span + try{ //starting a try block to do something + const response = await fetch('deleteItem', { //creates a response variable that waits on a fetch to retrieve data from the result of deleteItem route + method: 'delete', //sets the CRUD method for the route + headers: {'Content-Type': 'application/json'}, //specifiying the type of content expected, which is JSON + body: JSON.stringify({ //declare the message content being passed, and stringiy that content + 'itemFromJS': itemText //setting the content of the body to the inner text of the list item and naming it 'itemFromJS' + }) //closing the body + }) // closing the object + const data = await response.json() //waiting on JSON from the response to be converted + console.log(data) //log the data to the console + location.reload() //reloads the page to update what is displayed - }catch(err){ - console.log(err) - } -} + }catch(err){ //if an error occurs pass the error into the catch block + console.log(err) //log the error + } //close the catch block +} //ends the function -async function markComplete(){ - const itemText = this.parentNode.childNodes[1].innerText - try{ - const response = await fetch('markComplete', { - method: 'put', - headers: {'Content-Type': 'application/json'}, - body: JSON.stringify({ - 'itemFromJS': itemText - }) - }) - const data = await response.json() - console.log(data) - location.reload() +async function markComplete(){ //declare an asynchronous function + const itemText = this.parentNode.childNodes[1].innerText //looks inside of the list item and grabs only the inner text within the list span + try{ //starting a try block to do something + const response = await fetch('markComplete', { //creates a response variable that waits on a fetch to get data from the result of the markComplete route + method: 'put', //setting the CRUD method to "upsdate" for the route + headers: {'Content-Type': 'application/json'}, //specifying the type of content expected which is JSON + body: JSON.stringify({ //declare the message content being passed, and stringify that content + 'itemFromJS': itemText //setting the content of the body to the inner text of the list item and naming it 'itemFromJS' + }) //closing the body + }) //closing the object + const data = await response.json() //waiting on JSON from the response to be converted + console.log(data) //log the data to the console + location.reload() //reloads the page to update what is displayed - }catch(err){ - console.log(err) - } -} + }catch(err){ //if an error occurs pass the error into the catch block + console.log(err) //log the error to the console + } //close the catch block +} //ends the function -async function markUnComplete(){ - const itemText = this.parentNode.childNodes[1].innerText - try{ - const response = await fetch('markUnComplete', { - method: 'put', - headers: {'Content-Type': 'application/json'}, - body: JSON.stringify({ - 'itemFromJS': itemText - }) - }) - const data = await response.json() - console.log(data) - location.reload() +async function markUnComplete(){ //declare an asynchronous function + const itemText = this.parentNode.childNodes[1].innerText //looks inside of the list item and grabs only the inner text within the list span + try{ //starting a try block to do something + const response = await fetch('markUnComplete', { //creates a response variable that waits on a fetch to get data from the result of the markUnComplete route + method: 'put', //setting the CRUD method to "upsdate" for the route + headers: {'Content-Type': 'application/json'}, //specifying the type of content expected which is JSON + body: JSON.stringify({ //declare the message content being passed, and stringify that content + 'itemFromJS': itemText //setting the content of the body to the inner text of the list item and naming it 'itemFromJS' + }) //closing the body + }) //closing the object + const data = await response.json() //waiting on JSON from the response to be converted + console.log(data) + location.reload() //reloads the page to update what is displayed - }catch(err){ - console.log(err) - } -} \ No newline at end of file + }catch(err){ //if an error occurs pass the error into the catch block + console.log(err) //log the error to the console + } //close the catch block +} //ends the function \ No newline at end of file diff --git a/server.js b/server.js index 58b53e2f..8b25208b 100644 --- a/server.js +++ b/server.js @@ -1,30 +1,31 @@ -const express = require('express') -const app = express() -const MongoClient = require('mongodb').MongoClient -const PORT = 2121 -require('dotenv').config() +const express = require('express') //makes it possible to use express in this file +const app = express() //setting constant and assigning it to the instance of express +const MongoClient = require('mongodb').MongoClient //makes it possible to use methods associated with MongoClient and talk to our DB +const PORT = 2121 //setting a constant to determine the location where our server will be listening +require('dotenv').config() //allows us to look for variables inside of the .env file -let db, - dbConnectionStr = process.env.DB_STRING, - dbName = 'todo' +let db, //declaring a variable called db but not assigning a value + dbConnectionStr = process.env.DB_STRING, //declaring a variable and assigning it our database connection string + dbName = 'todo' //declaring a variable and assigning it the name of the database we will be using -MongoClient.connect(dbConnectionStr, { useUnifiedTopology: true }) - .then(client => { - console.log(`Connected to ${dbName} Database`) - db = client.db(dbName) - }) +MongoClient.connect(dbConnectionStr, { useUnifiedTopology: true }) //creating a connection to MongoDb and passing in our connection string. Alsom passing in an additional property + .then(client => { //waiting for the connection to the DB and proceeding if successful, also passing in all the client info + console.log(`Connected to ${dbName} Database`) //logging a template literal that we are to the console that we are connected to our database + db = client.db(dbName) //assigning a value to a previously declared db variable that contains a db client factory method + }) //closing our .then -app.set('view engine', 'ejs') -app.use(express.static('public')) -app.use(express.urlencoded({ extended: true })) -app.use(express.json()) +//middleware +app.set('view engine', 'ejs') //setting ejs as the default render +app.use(express.static('public')) //sets the location for static assets +app.use(express.urlencoded({ extended: true })) //tells express to decode and encode URLs where the header matches the content. Supports arrays and objects +app.use(express.json()) //parses JSON content -app.get('/',async (request, response)=>{ - const todoItems = await db.collection('todos').find().toArray() - const itemsLeft = await db.collection('todos').countDocuments({completed: false}) - response.render('index.ejs', { items: todoItems, left: itemsLeft }) +app.get('/',async (request, response)=>{ //starts a GET method when the root route is passed in, sets up req and res parameters + const todoItems = await db.collection('todos').find().toArray() //sets a variable and awaits all items from the todos collection + const itemsLeft = await db.collection('todos').countDocuments({completed: false}) //sets a variable and awaits a count of documents where the completed property is false + response.render('index.ejs', { items: todoItems, left: itemsLeft }) //redering the EJS file and passing through the db items and the count remaining inside of an object // db.collection('todos').find().toArray() // .then(data => { // db.collection('todos').countDocuments({completed: false}) @@ -35,59 +36,57 @@ app.get('/',async (request, response)=>{ // .catch(error => console.error(error)) }) -app.post('/addTodo', (request, response) => { - db.collection('todos').insertOne({thing: request.body.todoItem, completed: false}) - .then(result => { - console.log('Todo Added') - response.redirect('/') - }) - .catch(error => console.error(error)) -}) +app.post('/addTodo', (request, response) => { //starts a POST method when the /addTodo route is passed in + db.collection('todos').insertOne({thing: request.body.todoItem, completed: false}) //inserts a new item into the todos collection, giving it a completed value of false by default + .then(result => { //if insert is successful, do something + console.log('Todo Added') //log "Todo Added" to the console + response.redirect('/') //redirect from /addTodo back to the root route to refresh the page + }) //closing the .then + .catch(error => console.error(error)) //catching errors +}) //ending the POST request -app.put('/markComplete', (request, response) => { - db.collection('todos').updateOne({thing: request.body.itemFromJS},{ - $set: { - completed: true +app.put('/markComplete', (request, response) => { //starting a PUT method when the markComplete route is passed in + db.collection('todos').updateOne({thing: request.body.itemFromJS},{ //look in the db for one item matching the name of the item passed in from the main.js file that was clicked + $set: { + completed: true //setting the completed status to true } },{ - sort: {_id: -1}, - upsert: false - }) - .then(result => { - console.log('Marked Complete') - response.json('Marked Complete') + sort: {_id: -1}, //moves item to the bottom of the list + upsert: false //prevents insertion if the item does not already exist }) - .catch(error => console.error(error)) - + .then(result => { //starting a .then if the update was successful + console.log('Marked Complete') //logging successful completion + response.json('Marked Complete') //sending a response back to the sender + }) //closing the .then + .catch(error => console.error(error)) //catching errors }) -app.put('/markUnComplete', (request, response) => { - db.collection('todos').updateOne({thing: request.body.itemFromJS},{ - $set: { - completed: false +app.put('/markUnComplete', (request, response) => { //starting a PUT method when the markUnComplete route is passed in + db.collection('todos').updateOne({thing: request.body.itemFromJS},{ //look in the db for one item matching the name of the item passed in from the main.js file that was clicked + $set: { + completed: false //setting the completed status to false } },{ - sort: {_id: -1}, - upsert: false - }) - .then(result => { - console.log('Marked Complete') - response.json('Marked Complete') + sort: {_id: -1}, //moves item to the bottom of the list + upsert: false //prevents insertion if the item does not already exist }) - .catch(error => console.error(error)) - + .then(result => { //starting a .then if the update was successful + console.log('Marked Complete') //logging successful completion + response.json('Marked Complete') //sending a response back to the sender + }) //closing the .then + .catch(error => console.error(error)) //catching errors }) -app.delete('/deleteItem', (request, response) => { - db.collection('todos').deleteOne({thing: request.body.itemFromJS}) - .then(result => { - console.log('Todo Deleted') - response.json('Todo Deleted') - }) - .catch(error => console.error(error)) +app.delete('/deleteItem', (request, response) => { //starting a DELETE method when the delete route is passed + db.collection('todos').deleteOne({thing: request.body.itemFromJS}) //look in the db for one item matching the name of the item passed and deleting it + .then(result => { //starting a .then if the delete was successful + console.log('Todo Deleted') //logging successful completion + response.json('Todo Deleted') //sending a response back to the sender + }) // closing the .then + .catch(error => console.error(error)) //catching errors }) -app.listen(process.env.PORT || PORT, ()=>{ - console.log(`Server running on port ${PORT}`) -}) \ No newline at end of file +app.listen(process.env.PORT || PORT, ()=>{ //setting up which port we will be listening on - either the port from the .env file or the port variable + console.log(`Server running on port ${PORT}`) //logging the running port +}) //end ths listen method \ No newline at end of file diff --git a/views/index.ejs b/views/index.ejs index a26617ae..ed96fd04 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -1,47 +1,47 @@ - - -
- - - -