From 12b07673c394d79fcec46bd441e1e9b6e4a69814 Mon Sep 17 00:00:00 2001 From: MuhammadAsimKundi Date: Mon, 25 Aug 2025 18:54:16 +0500 Subject: [PATCH 1/2] updated the delete api. to delete by id. --- .vscode/settings.json | 4 +- public/css/style.css | 134 ++++++++++++++++++++++++++++++++++++++++-- public/js/main.js | 46 +++++++-------- server.js | 16 ++++- views/index.ejs | 51 ++++++++++++---- 5 files changed, 206 insertions(+), 45 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index c3c81b8b..e176a2dd 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,4 +1,4 @@ { - "editor.fontSize": 42, - "terminal.integrated.fontSize": 62 + "editor.fontSize": 16.5, + "terminal.integrated.fontSize": 16.5 } \ No newline at end of file diff --git a/public/css/style.css b/public/css/style.css index 0475253a..2602e6fe 100644 --- a/public/css/style.css +++ b/public/css/style.css @@ -1,7 +1,129 @@ -h1{ - color: red; +/* ===== Reset some default browser styles ===== */ +* { + margin: 0; + padding: 0; + box-sizing: border-box; + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; +} + +/* ===== Body styling ===== */ +body { + background: linear-gradient(135deg, #667eea, #764ba2); + color: #333; + min-height: 100vh; + display: flex; + flex-direction: column; + align-items: center; + justify-content: flex-start; + padding: 40px 20px; +} + +/* ===== Page Title ===== */ +h1 { + font-size: 2.5rem; + color: #fff; + margin-bottom: 20px; + letter-spacing: 1px; +} + +/* ===== Todo List Container ===== */ +ul.todoItems { + list-style: none; + width: 100%; + max-width: 500px; + background: #fff; + padding: 20px; + border-radius: 15px; + box-shadow: 0px 4px 15px rgba(0, 0, 0, 0.1); + margin-bottom: 30px; + transition: all 0.3s ease; +} + +/* ===== Todo Item Styling ===== */ +li.item { + display: flex; + justify-content: space-between; + align-items: center; + background: #f9f9f9; + padding: 12px 15px; + margin-bottom: 12px; + border-radius: 10px; + transition: background 0.3s; +} + +li.item:hover { + background: #f0f0f0; +} + +/* ===== Completed Todo Styling ===== */ +.completed { + text-decoration: line-through; + color: #999; +} + +/* ===== Trash Icon Styling ===== */ +.fa-trash { + color: #ff5c5c; + cursor: pointer; + transition: transform 0.2s ease, color 0.2s ease; +} + +.fa-trash:hover { + transform: scale(1.2); + color: #e60000; +} + +/* ===== Left Todo Heading ===== */ +h2 { + color: #fff; + margin-bottom: 20px; + font-size: 1.3rem; +} + +/* ===== Form Styling ===== */ +form { + width: 100%; + max-width: 500px; + display: flex; + gap: 10px; +} + +input[type="text"] { + flex: 1; + padding: 12px 15px; + border: none; + border-radius: 10px; + outline: none; + font-size: 1rem; + box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.1); +} + +input[type="text"]:focus { + border: 2px solid #667eea; +} + +input[type="submit"] { + background: #667eea; + color: #fff; + padding: 12px 20px; + border: none; + border-radius: 10px; + cursor: pointer; + font-size: 1rem; + transition: background 0.3s ease; +} + +input[type="submit"]:hover { + background: #5a67d8; +} + +/* ===== Responsive ===== */ +@media (max-width: 600px) { + ul.todoItems, form { + max-width: 90%; + } + + h1 { + font-size: 2rem; + } } -.completed{ - color: gray; - text-decoration: line-through; -} \ No newline at end of file diff --git a/public/js/main.js b/public/js/main.js index ff0eac39..7534e9c0 100644 --- a/public/js/main.js +++ b/public/js/main.js @@ -2,71 +2,69 @@ const deleteBtn = document.querySelectorAll('.fa-trash') const item = document.querySelectorAll('.item span') const itemCompleted = document.querySelectorAll('.item span.completed') -Array.from(deleteBtn).forEach((element)=>{ +Array.from(deleteBtn).forEach((element) => { element.addEventListener('click', deleteItem) }) -Array.from(item).forEach((element)=>{ +Array.from(item).forEach((element) => { element.addEventListener('click', markComplete) }) -Array.from(itemCompleted).forEach((element)=>{ +Array.from(itemCompleted).forEach((element) => { element.addEventListener('click', markUnComplete) }) -async function deleteItem(){ - const itemText = this.parentNode.childNodes[1].innerText - try{ +// 🔹 Delete through ID instead of text +async function deleteItem() { + const itemId = this.parentNode.dataset.id // Get ID from data-id attribute + try { const response = await fetch('deleteItem', { method: 'delete', - headers: {'Content-Type': 'application/json'}, + headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ - 'itemFromJS': itemText + id: itemId }) - }) + }) const data = await response.json() console.log(data) location.reload() - - }catch(err){ + } catch (err) { console.log(err) } } -async function markComplete(){ +async function markComplete() { const itemText = this.parentNode.childNodes[1].innerText - try{ + try { const response = await fetch('markComplete', { method: 'put', - headers: {'Content-Type': 'application/json'}, + headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ 'itemFromJS': itemText }) - }) + }) const data = await response.json() console.log(data) location.reload() - - }catch(err){ + } catch (err) { console.log(err) } } -async function markUnComplete(){ +async function markUnComplete() { const itemText = this.parentNode.childNodes[1].innerText - try{ + try { const response = await fetch('markUnComplete', { method: 'put', - headers: {'Content-Type': 'application/json'}, + headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ 'itemFromJS': itemText }) - }) + }) const data = await response.json() console.log(data) location.reload() - - }catch(err){ + } catch (err) { console.log(err) } -} \ No newline at end of file +} diff --git a/server.js b/server.js index 58b53e2f..38ad7455 100644 --- a/server.js +++ b/server.js @@ -1,6 +1,6 @@ const express = require('express') const app = express() -const MongoClient = require('mongodb').MongoClient +const { MongoClient, ObjectId } = require('mongodb') const PORT = 2121 require('dotenv').config() @@ -20,7 +20,6 @@ app.use(express.static('public')) app.use(express.urlencoded({ extended: true })) app.use(express.json()) - app.get('/',async (request, response)=>{ const todoItems = await db.collection('todos').find().toArray() const itemsLeft = await db.collection('todos').countDocuments({completed: false}) @@ -78,8 +77,19 @@ app.put('/markUnComplete', (request, response) => { }) + +// 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) => { - db.collection('todos').deleteOne({thing: request.body.itemFromJS}) + db.collection('todos').deleteOne({_id: new ObjectId(request.body.id)}) .then(result => { console.log('Todo Deleted') response.json('Todo Deleted') diff --git a/views/index.ejs b/views/index.ejs index a26617ae..b55bcb06 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -1,4 +1,4 @@ - + + + + + + + + + + + + Document + + + + +

Todo List

+ + +

Left todo: <%= left %>

+ +
+ + +
+ + From 06ffbd72726b8b24ba33c97f822bc5f2dff76247 Mon Sep 17 00:00:00 2001 From: MuhammadAsimKundi Date: Mon, 25 Aug 2025 19:35:46 +0500 Subject: [PATCH 2/2] Updated the delete to soft delete. removes from UI, Stays in DB. --- public/js/main.js | 1 + server.js | 4 +++- views/index.ejs | 36 ++++++++++++++++++++++++------------ 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/public/js/main.js b/public/js/main.js index 7534e9c0..d0470a79 100644 --- a/public/js/main.js +++ b/public/js/main.js @@ -27,6 +27,7 @@ async function deleteItem() { }) const data = await response.json() console.log(data) + this.parentNode.remove() location.reload() } catch (err) { console.log(err) diff --git a/server.js b/server.js index 38ad7455..332487cb 100644 --- a/server.js +++ b/server.js @@ -89,7 +89,9 @@ app.put('/markUnComplete', (request, response) => { // }) app.delete('/deleteItem', (request, response) => { - db.collection('todos').deleteOne({_id: new ObjectId(request.body.id)}) + db.collection('todos').deleteOne({_id: new ObjectId(request.body.id)}, + { $set: { hidden: true } } + ) .then(result => { console.log('Todo Deleted') response.json('Todo Deleted') diff --git a/views/index.ejs b/views/index.ejs index b55bcb06..e27e968b 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -52,18 +52,30 @@

Todo List

- +

Left todo: <%= left %>