From a2d68a1ec029eab6d9fff211eb809369495d7a08 Mon Sep 17 00:00:00 2001 From: John Joseph Casas Date: Wed, 19 Feb 2025 12:45:54 -0800 Subject: [PATCH 1/2] testing github --- .vscode/settings.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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 From 5f65281879cdf9fae7f5f7876e9e56d5c218bddc Mon Sep 17 00:00:00 2001 From: John Joseph Casas Date: Sat, 22 Feb 2025 12:57:17 -0800 Subject: [PATCH 2/2] finished comments --- .vscode/settings.json | 3 +- package.json | 15 ++++- public/css/style.css | 14 ++--- public/js/main.js | 126 ++++++++++++++++++++--------------------- server.js | 129 +++++++++++++++++++++--------------------- views/index.ejs | 75 +++++++++++------------- 6 files changed, 182 insertions(+), 180 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 2fdfc6cf..c05ac43e 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,4 +1,5 @@ // { // "editor.fontSize": 42, // "terminal.integrated.fontSize": 62 -// } \ No newline at end of file +// } +// Commented out to reduce font size in project \ No newline at end of file diff --git a/package.json b/package.json index 276ae590..8f83d3d4 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,11 @@ { "name": "rap-name-api", "version": "1.0.0", - "description": "", + "description": "npm install\r add DB_STRING to .env file", "main": "index.js", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "test": "echo \"Error: no test specified\" && exit 1", + "start": "node server.js" }, "author": "", "license": "ISC", @@ -14,5 +15,13 @@ "ejs": "^3.1.6", "express": "^4.17.1", "mongodb": "^3.6.5" - } + }, + "repository": { + "type": "git", + "url": "git+https://github.com/jjbcasas/todo-list-express.git" + }, + "bugs": { + "url": "https://github.com/jjbcasas/todo-list-express/issues" + }, + "homepage": "https://github.com/jjbcasas/todo-list-express#readme" } diff --git a/public/css/style.css b/public/css/style.css index 0475253a..88f2896a 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 all h1 tag in our ejs file */ + color: red; /* making our font/text color to red */ +} /* c;osing our selector */ +.completed{ /* targets the class name completed */ + color: gray; /* changes our text color to gray */ + text-decoration: line-through; /* making our text a strikethrough style */ +} /* c;osing our selector */ \ No newline at end of file diff --git a/public/js/main.js b/public/js/main.js index ff0eac39..3119eb41 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') /* selecting all our elements with fa-trash class and putting it in a variable */ +const item = document.querySelectorAll('.item span') /* selecting all our elements with a class of item that has a child elem of span */ +const itemCompleted = document.querySelectorAll('.item span.completed') /* selecting all our elements with a class of item that has a child elem of span and a class of completed */ -Array.from(deleteBtn).forEach((element)=>{ - element.addEventListener('click', deleteItem) -}) +Array.from(deleteBtn).forEach((element)=>{ /* selecting the deleteBtn class and putting it in an array and then using a forEach method to loop through */ + element.addEventListener('click', deleteItem) /* giving all the element that has a class of deleteBtn a click event or event listener and then calls a function called deleteItem*/ +}) /* closing tag */ -Array.from(item).forEach((element)=>{ - element.addEventListener('click', markComplete) -}) +Array.from(item).forEach((element)=>{ /* creating an array and starting a loop */ + element.addEventListener('click', markComplete) /* creating a click event for the elements and then calls for a function */ +}) /* closing our loop */ -Array.from(itemCompleted).forEach((element)=>{ - element.addEventListener('click', markUnComplete) -}) +Array.from(itemCompleted).forEach((element)=>{ /* creating an array from values on the variable selected and starting a loop */ + element.addEventListener('click', markUnComplete) /* adds event listener for ONLY completed items */ +}) /* 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(){ /* creating an async function named deleteItem */ + 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 for our response or to do something + const response = await fetch('deleteItem', { // creating a response variable and awaits a fetch to get data from deleteItem route + method: 'delete', // setting the CRUD method to delete for the route + headers: {'Content-Type': 'application/json'}, // setting the expected content type to json + body: JSON.stringify({ // stringify the content + 'itemFromJS': itemText // setting the content of the body as itemText and itemFromJS as the property + }) // closing the body + }) // closing the fetch + const data = await response.json() // we are waiting for the converted response json object and assigning it to the variable + console.log(data) // displaying the data on the console + location.reload() // reloading the page to update what is displayed - }catch(err){ - console.log(err) - } -} + }catch(err){ // starting a catch block for our errors if there is any + console.log(err) // displaying the error on the console if there's any + } // close the catch block +} // end of 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(){ /* creating an async function named markComplete */ + 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 for our response or to do something + const response = await fetch('markComplete', { // creating a response variable and awaits a fetch to get data from markComplete route + method: 'put', // setting the CRUD method to update for the route + headers: {'Content-Type': 'application/json'}, // setting the expected content type to json + body: JSON.stringify({ // stringify the content + 'itemFromJS': itemText // setting the content of the body as itemText and itemFromJS as the property + }) // closing the body + }) // closing the fetch + const data = await response.json() // we are waiting for the converted response json object and assigning it to the variable + console.log(data) // displaying the data on the console + location.reload() // reloading the page to update what is displayed - }catch(err){ - console.log(err) - } -} + }catch(err){ // starting a catch block for our errors if there is any + console.log(err) // displaying the error on the console if there's any + } // close the catch block +} // end of 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(){/* creating an async function named markUnComplete */ + 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 for our response or to do something + const response = await fetch('markUnComplete', { // creating a response variable and awaits a fetch to get data from markUnComplete route + method: 'put', // setting the CRUD method to update for the route + headers: {'Content-Type': 'application/json'}, // setting the expected content type to json + body: JSON.stringify({ // stringify the content + 'itemFromJS': itemText // setting the content of the body as itemText and itemFromJS as the property + }) // closing the body + }) // closing the fetch + const data = await response.json() // we are waiting for the converted response json object and assigning it to the variable + console.log(data) // displaying the data on the console + location.reload() // reloading the page to update what is displayed - }catch(err){ - console.log(err) - } -} \ No newline at end of file + }catch(err){ // starting a catch block for our errors if there is any + console.log(err) // displaying the error on the console if there's any + } // close the catch block +} // end of function \ No newline at end of file diff --git a/server.js b/server.js index 58b53e2f..a35947a7 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') // requiring express for it to be used in the file +const app = express() // setting a variable and assinging it the express call +const MongoClient = require('mongodb').MongoClient // setting it up to use the database and connect to it and talk to it using methods associated with MangoClient +const PORT = 2121 // setting a variable and where to host or location where to listen +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 + dbConnectionStr = process.env.DB_STRING, // declaring a variable and assigning our database connection string to it + dbName = 'todo' // declaring a variable and assigning 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) - }) - -app.set('view engine', 'ejs') -app.use(express.static('public')) -app.use(express.urlencoded({ extended: true })) -app.use(express.json()) +MongoClient.connect(dbConnectionStr, { useUnifiedTopology: true }) // creating a connecting to our mongodb, and passing in our connection string. passing also an additional property + .then(client => { //promise handler and passing all the client information + console.log(`Connected to ${dbName} Database`) // logging to the console a template literal informing that you connected successfully to your database + db = client.db(dbName) // assigning a value to previously declared 'db' variable that contains a db client factory method + }) // closing our then handler + +// Middleware +app.set('view engine', 'ejs') // sets as the default render method +app.use(express.static('public')) // sets the location for all static file on public folder +app.use(express.urlencoded({ extended: true })) // tells express to decode and encode URLs where the header matches the content, the extended part supports arrays and objects +app.use(express.json()) // parses json content from incoming requests -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)=>{ // read request when root route is passed in, sets up req and res parameters + const todoItems = await db.collection('todos').find().toArray() // setting a variable and awaits the collections in the database in the variable as an array + const itemsLeft = await db.collection('todos').countDocuments({completed: false}) // setting a variable and awaits the total count of uncompleted items to later display on ejs + response.render('index.ejs', { items: todoItems, left: itemsLeft }) // redndering our 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,59 @@ 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 create method when the /addTodo route is passed in from the action attribute of the form + db.collection('todos').insertOne({thing: request.body.todoItem, completed: false}) // selecting our todos collection for us to be able to insert one or add one document/object from the request.body.todoItem and gives it a completed value of false by default + .then(result => { // if insert is successful, do something + console.log('Todo Added') // log to the console the action + response.redirect('/') // gets rid of the /addTodo route, and redirect/refresh to the root or homepage + }) // closing the .then + .catch(error => console.error(error)) // catching for possible errors +}) // ending the POST method -app.put('/markComplete', (request, response) => { - db.collection('todos').updateOne({thing: request.body.itemFromJS},{ - $set: { - completed: true +app.put('/markComplete', (request, response) => { // starts an UPDATE method when /markComplete route is passed in with a response and request parameters + db.collection('todos').updateOne({thing: request.body.itemFromJS},{ // looks in the db for one item matching the name of the item passed in from the main.js file that was clicked on + $set: { + completed: true //set 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 => { // starts a then if update was successful + console.log('Marked Complete') // logging to the console if successful completion + response.json('Marked Complete') // sending a response back to the sender + }) // closing .then + .catch(error => console.error(error)) //catching errors -}) +}) // ending put -app.put('/markUnComplete', (request, response) => { - db.collection('todos').updateOne({thing: request.body.itemFromJS},{ +app.put('/markUnComplete', (request, response) => { //starts a PUT method when the markUncomplete route is passed in + db.collection('todos').updateOne({thing: request.body.itemFromJS},{ // looks in the db for one item matching the name of the item passed in from the main.js file that was clicked on $set: { - completed: false + completed: false //set 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 => { // starts a then if update was successful + console.log('Marked Complete') // logging to the console if successful completion + response.json('Marked Complete') // sending a response back to the sender + }) // closing .then + .catch(error => console.error(error)) //catching errors -}) +}) // ending PUT -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) => { // starts a DELETE method when delete route is passed + db.collection('todos').deleteOne({thing: request.body.itemFromJS}) // looks inside the todos collection for the ONE item that has a matching name from our JS file + .then(result => { // if the delete was successful + console.log('Todo Deleted') // logging successful completion + response.json('Todo Deleted') // send a response back to the sender + }) // closing .then + .catch(error => console.error(error)) // catching errors -}) +}) // closing delete method -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 w/c PORT we will be listening on - either the port from the .env file or the port variable we set + console.log(`Server running on port ${PORT}`) // console.log the running port +}) // close the listen method \ No newline at end of file diff --git a/views/index.ejs b/views/index.ejs index a26617ae..5e07eb2b 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -1,47 +1,38 @@ - - - - - - - Document - - - - - - - - - - - Document - - -

Todo List:

- + + + + + + + Document + + + + +

Todo List:

+ -

Left to do: <%= left %>

+

Left to do: <%= left %>

-

Add A Todo:

+

Add A Todo:

-
- - -
+
+ + +
- - - + + +