diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 00000000..906e9edf Binary files /dev/null and b/.DS_Store differ diff --git a/.gitignore b/.gitignore index 1dcef2d9..28cde21f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules -.env \ No newline at end of file +.env +.DS_Store \ No newline at end of file diff --git a/package.json b/package.json index 276ae590..1b819eae 100644 --- a/package.json +++ b/package.json @@ -1,3 +1,16 @@ +/* + This package.json defines the basic information and dependencies of the "rap-name-api" project. + - "name", "version", and "description" describe the project. + - "main" points to the entry file, which in this case is "index.js". + - "scripts" defines a test script placeholder. + - "dependencies" lists all the required npm packages for the app to run: + - express: web framework + - mongodb: connects to the MongoDB database + - ejs: renders HTML templates + - dotenv: loads environment variables from a .env file + - cors: enables Cross-Origin Resource Sharing + This file is essential for installing and managing everything the app needs to function. +*/ { "name": "rap-name-api", "version": "1.0.0", diff --git a/public/js/main.js b/public/js/main.js index ff0eac39..3c5ba474 100644 --- a/public/js/main.js +++ b/public/js/main.js @@ -1,38 +1,50 @@ +//Select all delete buttons (trash icons) const deleteBtn = document.querySelectorAll('.fa-trash') + +//Select all to-do item spans (that are not completed) const item = document.querySelectorAll('.item span') + +//Select all to-do item spans that are marked as completed const itemCompleted = document.querySelectorAll('.item span.completed') +//Add event listeners to all delete buttons Array.from(deleteBtn).forEach((element)=>{ - element.addEventListener('click', deleteItem) + element.addEventListener('click', deleteItem) //When clicked, run deleteItem() }) +//Add event listeners to all completed items Array.from(item).forEach((element)=>{ - element.addEventListener('click', markComplete) + element.addEventListener('click', markComplete)//When clicked, run markComplete() }) +//Add event listeners to all incomplete items Array.from(itemCompleted).forEach((element)=>{ - element.addEventListener('click', markUnComplete) + element.addEventListener('click', markUnComplete)//When clicked, run markUnComplete() }) + +//Async function to delete an item async function deleteItem(){ - const itemText = this.parentNode.childNodes[1].innerText + const itemText = this.parentNode.childNodes[1].innerText//Get the text of the to-do item try{ const response = await fetch('deleteItem', { - method: 'delete', + method: 'delete', //HTTP delete method headers: {'Content-Type': 'application/json'}, body: JSON.stringify({ - 'itemFromJS': itemText + 'itemFromJS': itemText //Send the item text to the server }) }) - const data = await response.json() - console.log(data) - location.reload() + const data = await response.json() //wait for server response + console.log(data) //log the response + location.reload() //reload the page to see changes }catch(err){ - console.log(err) + console.log(err) //log any error } } + +//Async function to mark item as complete async function markComplete(){ const itemText = this.parentNode.childNodes[1].innerText try{ @@ -52,6 +64,7 @@ async function markComplete(){ } } +//Async function to mark item as incomplete async function markUnComplete(){ const itemText = this.parentNode.childNodes[1].innerText try{ diff --git a/server.js b/server.js index 58b53e2f..08cbd4c6 100644 --- a/server.js +++ b/server.js @@ -1,30 +1,46 @@ + +//Import the Express framework to create the server const express = require('express') + +//create an instance of the Express app const app = express() + +//Import MongoClient from the MongoDB library to connect to the database const MongoClient = require('mongodb').MongoClient + +//Define the port number, using either the environment or defaulting to 2121 const PORT = 2121 require('dotenv').config() - +//Declare variables for the database connection let db, - dbConnectionStr = process.env.DB_STRING, - dbName = 'todo' + dbConnectionStr = process.env.DB_STRING,//Get the connection string from the .env file + dbName = 'todo'//Name of the database +//Connect to MongoDB using the connection string MongoClient.connect(dbConnectionStr, { useUnifiedTopology: true }) .then(client => { - console.log(`Connected to ${dbName} Database`) - db = client.db(dbName) + console.log(`Connected to ${dbName} Database`)//Log successful connection + db = client.db(dbName)//Store the database connection in the db variable }) - + +//Set tthe view engine to EJS so we can use templating in our HTML app.set('view engine', 'ejs') + +//Make the "public" folder accessible to the browser (for CSS, JS, images, etc.) app.use(express.static('public')) + +//Middleware to parse form data(from POST request) app.use(express.urlencoded({ extended: true })) -app.use(express.json()) +//Middleware to parse JSON data +app.use(express.json()) +//GET route for the homepage 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 }) + const todoItems = await db.collection('todos').find().toArray()//Get all to-do items from the collection + const itemsLeft = await db.collection('todos').countDocuments({completed: false})//Count how many items are not completed + response.render('index.ejs', { items: todoItems, left: itemsLeft })//Render the index page and pass the data to it // db.collection('todos').find().toArray() // .then(data => { // db.collection('todos').countDocuments({completed: false}) @@ -35,8 +51,10 @@ app.get('/',async (request, response)=>{ // .catch(error => console.error(error)) }) + +//POST route to add a new to-do item app.post('/addTodo', (request, response) => { - db.collection('todos').insertOne({thing: request.body.todoItem, completed: false}) + db.collection('todos').insertOne({thing: request.body.todoItem, completed: false})//Insert a new item into the database .then(result => { console.log('Todo Added') response.redirect('/') @@ -44,27 +62,29 @@ app.post('/addTodo', (request, response) => { .catch(error => console.error(error)) }) +//PUT route to mark an intem as complete app.put('/markComplete', (request, response) => { db.collection('todos').updateOne({thing: request.body.itemFromJS},{ $set: { - completed: true + completed: true //set the "completed" field to true } },{ - sort: {_id: -1}, - upsert: false + sort: {_id: -1},//sort by newest if there are duplicates + upsert: false //Do not insert a new document if none is found }) .then(result => { - console.log('Marked Complete') - response.json('Marked Complete') + console.log('Marked Complete') // Log a success message + response.json('Marked Complete') //Send a response to the client }) - .catch(error => console.error(error)) + .catch(error => console.error(error)) //Handle any errors }) +//PUT route to mark an item as incomplete app.put('/markUnComplete', (request, response) => { db.collection('todos').updateOne({thing: request.body.itemFromJS},{ $set: { - completed: false + completed: false //Set the "completed" field to false } },{ sort: {_id: -1}, @@ -78,8 +98,10 @@ app.put('/markUnComplete', (request, response) => { }) +//DELETE route to remove an item + app.delete('/deleteItem', (request, response) => { - db.collection('todos').deleteOne({thing: request.body.itemFromJS}) + db.collection('todos').deleteOne({thing: request.body.itemFromJS})//delete the item that matches the name .then(result => { console.log('Todo Deleted') response.json('Todo Deleted') @@ -88,6 +110,8 @@ app.delete('/deleteItem', (request, response) => { }) +//Start the server and listen on the defined port + app.listen(process.env.PORT || PORT, ()=>{ console.log(`Server running on port ${PORT}`) }) \ No newline at end of file diff --git a/todo-list-express b/todo-list-express new file mode 160000 index 00000000..8247adf5 --- /dev/null +++ b/todo-list-express @@ -0,0 +1 @@ +Subproject commit 8247adf50f08bd10000a520d0c12dd01ccaa776b diff --git a/views/index.ejs b/views/index.ejs index a26617ae..f03ce5fb 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -1,47 +1,54 @@ + + + + + Document + + + - - - - - - - Document - - +

Todo List:

+ + - +

Left to do: <%= left %>

- +

Add A Todo:

- +
- +
- +