diff --git a/Sprint-3/todo-list/index.html b/Sprint-3/todo-list/index.html index 4d12c4654..f3cf8b3c0 100644 --- a/Sprint-3/todo-list/index.html +++ b/Sprint-3/todo-list/index.html @@ -14,7 +14,7 @@

My ToDo List

- +
@@ -34,7 +34,7 @@

My ToDo List

- + diff --git a/Sprint-3/todo-list/script.mjs b/Sprint-3/todo-list/script.mjs index ba0b2ceae..c23f72325 100644 --- a/Sprint-3/todo-list/script.mjs +++ b/Sprint-3/todo-list/script.mjs @@ -1,4 +1,4 @@ -// Store everything imported from './todos.mjs' module as properties of an object named Todos +// Store everything imported from './todos.mjs' module as properties of an object named Todos import * as Todos from "./todos.mjs"; // To store the todo tasks @@ -7,16 +7,20 @@ const todos = []; // Set up tasks to be performed once on page load window.addEventListener("load", () => { document.getElementById("add-task-btn").addEventListener("click", addNewTodo); + document.getElementById("delete-btn").addEventListener("click", (e) => { + console.log("Delete button clicked"); + Todos.deleteCompleted(todos); + render(); + }); // Populate sample data - Todos.addTask(todos, "Wash the dishes", false); + Todos.addTask(todos, "Wash the dishes", false); Todos.addTask(todos, "Do the shopping", true); render(); }); - -// A callback that reads the task description from an input field and +// A callback that reads the task description from an input field and // append a new task to the todo list. function addNewTodo() { const taskInput = document.getElementById("new-task-input"); @@ -45,12 +49,11 @@ function render() { }); } - // Note: // - First child of #todo-item-template is a
  • element. // We will create each ToDo list item as a clone of this node. // - This variable is declared here to be close to the only function that uses it. -const todoListItemTemplate = +const todoListItemTemplate = document.getElementById("todo-item-template").content.firstElementChild; // Create a
  • element for the given todo task @@ -62,15 +65,15 @@ function createListItem(todo, index) { li.classList.add("completed"); } - li.querySelector('.complete-btn').addEventListener("click", () => { + li.querySelector(".complete-btn").addEventListener("click", () => { Todos.toggleCompletedOnTask(todos, index); render(); }); - - li.querySelector('.delete-btn').addEventListener("click", () => { + + li.querySelector(".delete-btn").addEventListener("click", () => { Todos.deleteTask(todos, index); render(); }); return li; -} \ No newline at end of file +} diff --git a/Sprint-3/todo-list/style.css b/Sprint-3/todo-list/style.css index 535e91227..93aa891d2 100644 --- a/Sprint-3/todo-list/style.css +++ b/Sprint-3/todo-list/style.css @@ -105,3 +105,31 @@ h1 { text-decoration: line-through; color: gray; } +#delete-btn { + background-color: #e53935; + color: white; + border: none; + padding: 12px 20px; + font-size: 1rem; + font-weight: 600; + border-radius: 8px; + cursor: pointer; + transition: background-color 0.2s ease, transform 0.2s ease; +} + +#delete-btn:hover { + background-color: #c62828; +} + +#delete-btn:active { + transform: scale(0.97); +} + +#delete-btn:focus { + outline: 2px solid #ff8a80; + outline-offset: 3px; +} +#delete-btn { + display: block; + margin: 20px auto; +} \ No newline at end of file diff --git a/Sprint-3/todo-list/todos.mjs b/Sprint-3/todo-list/todos.mjs index f17ab6a25..14171e3b7 100644 --- a/Sprint-3/todo-list/todos.mjs +++ b/Sprint-3/todo-list/todos.mjs @@ -1,5 +1,5 @@ /* - A ToDo List (todos) is expected to be represented as an array of objects in + A ToDo List (todos) is expected to be represented as an array of objects in the following manner: [ @@ -26,4 +26,9 @@ export function toggleCompletedOnTask(todos, taskIndex) { if (todos[taskIndex]) { todos[taskIndex].completed = !todos[taskIndex].completed; } -} \ No newline at end of file +} // Delete completed todos +export function deleteCompleted(todoList) { + const incompleteTodos = todoList.filter((todo) => !todo.completed); + todoList.length = 0; //empty the original array + todoList.push(...incompleteTodos); //push incompleted task +} diff --git a/Sprint-3/todo-list/todos.test.mjs b/Sprint-3/todo-list/todos.test.mjs index bae7ae491..8f5a84ce7 100644 --- a/Sprint-3/todo-list/todos.test.mjs +++ b/Sprint-3/todo-list/todos.test.mjs @@ -13,7 +13,7 @@ function createMockTodos() { { task: "Task 1 description", completed: true }, { task: "Task 2 description", completed: false }, { task: "Task 3 description", completed: true }, - { task: "Task 4 description", completed: false }, + { task: "Task 4 description", completed: false }, ]; } @@ -29,7 +29,6 @@ describe("addTask()", () => { }); test("Should append a new task to the end of a ToDo list", () => { - const todos = createMockTodos(); const lengthBeforeAddition = todos.length; Todos.addTask(todos, theTask.task, theTask.completed); @@ -42,7 +41,6 @@ describe("addTask()", () => { }); describe("deleteTask()", () => { - test("Delete the first task", () => { const todos = createMockTodos(); const todosBeforeDeletion = createMockTodos(); @@ -53,7 +51,7 @@ describe("deleteTask()", () => { expect(todos[0]).toEqual(todosBeforeDeletion[1]); expect(todos[1]).toEqual(todosBeforeDeletion[2]); - expect(todos[2]).toEqual(todosBeforeDeletion[3]); + expect(todos[2]).toEqual(todosBeforeDeletion[3]); }); test("Delete the second task (a middle task)", () => { @@ -66,7 +64,7 @@ describe("deleteTask()", () => { expect(todos[0]).toEqual(todosBeforeDeletion[0]); expect(todos[1]).toEqual(todosBeforeDeletion[2]); - expect(todos[2]).toEqual(todosBeforeDeletion[3]); + expect(todos[2]).toEqual(todosBeforeDeletion[3]); }); test("Delete the last task", () => { @@ -79,7 +77,7 @@ describe("deleteTask()", () => { expect(todos[0]).toEqual(todosBeforeDeletion[0]); expect(todos[1]).toEqual(todosBeforeDeletion[1]); - expect(todos[2]).toEqual(todosBeforeDeletion[2]); + expect(todos[2]).toEqual(todosBeforeDeletion[2]); }); test("Delete a non-existing task", () => { @@ -92,9 +90,18 @@ describe("deleteTask()", () => { expect(todos).toEqual(todosBeforeDeletion); }); }); +test("Should delete all completed tasks", () => { + const todos = createMockTodos(); + const incompleteTasks = Todos.deleteCompleted(todos); + expect(incompleteTasks.length).toBe(2); + incompleteTasks.forEach((incompleteTask) => { + expect(incompleteTask.completed).toBe(false); + }); + expect(incompleteTasks[0].task).toBe("Task 2 description"); + expect(incompleteTasks[1].task).toBe("Task 4 description"); +}); describe("toggleCompletedOnTask()", () => { - test("Expect the 'completed' property to toggle on an existing task", () => { const todos = createMockTodos(); const taskIndex = 1; @@ -111,13 +118,12 @@ describe("toggleCompletedOnTask()", () => { const todos = createMockTodos(); const todosBeforeToggle = createMockTodos(); Todos.toggleCompletedOnTask(todos, 1); - - expect(todos[0]).toEqual(todosBeforeToggle[0]); + + expect(todos[0]).toEqual(todosBeforeToggle[0]); expect(todos[2]).toEqual(todosBeforeToggle[2]); expect(todos[3]).toEqual(todosBeforeToggle[3]); }); - test("Expect no change when toggling on a non-existing task", () => { const todos = createMockTodos(); const todosBeforeToggle = createMockTodos(); @@ -129,4 +135,3 @@ describe("toggleCompletedOnTask()", () => { expect(todos).toEqual(todosBeforeToggle); }); }); -