From 0cc51cd4e04f0bb0d0a81bf75ffbb69c8ee691fa Mon Sep 17 00:00:00 2001 From: MacDonald91 Date: Tue, 17 Mar 2026 22:28:19 +0000 Subject: [PATCH 1/2] complete build of quote generator app --- Sprint-3/quote-generator/index.html | 3 ++- Sprint-3/quote-generator/quotes.js | 15 ++++++++++++ Sprint-3/quote-generator/style.css | 36 +++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/Sprint-3/quote-generator/index.html b/Sprint-3/quote-generator/index.html index 30b434bcf..9a65b11ee 100644 --- a/Sprint-3/quote-generator/index.html +++ b/Sprint-3/quote-generator/index.html @@ -3,7 +3,8 @@ - Title here + Quote generator app + diff --git a/Sprint-3/quote-generator/quotes.js b/Sprint-3/quote-generator/quotes.js index 4a4d04b72..1c75d6e49 100644 --- a/Sprint-3/quote-generator/quotes.js +++ b/Sprint-3/quote-generator/quotes.js @@ -491,3 +491,18 @@ const quotes = [ ]; // call pickFromArray with the quotes array to check you get a random quote + +function displayRandomQuote() { + const randomQuote = pickFromArray(quotes); + + document.getElementById("quote").textContent = randomQuote.quote; + document.getElementById("author").textContent = randomQuote.author; +} + +// run when page loads2 +displayRandomQuote(); + +// button click +document + .getElementById("new-quote") + .addEventListener("click", displayRandomQuote); diff --git a/Sprint-3/quote-generator/style.css b/Sprint-3/quote-generator/style.css index 63cedf2d2..a3984bd5a 100644 --- a/Sprint-3/quote-generator/style.css +++ b/Sprint-3/quote-generator/style.css @@ -1 +1,37 @@ /** Write your CSS in here **/ +body { + font-family: Arial, sans-serif; + background-color: #f4f4f4; + text-align: center; + padding: 50px; +} + +h1 { + color: #333; +} + +#quote { + font-size: 1.5rem; + margin: 20px 0; + color: #222; +} + +#author { + font-size: 1.2rem; + color: #666; + margin-bottom: 30px; +} + +button { + padding: 10px 20px; + font-size: 1rem; + background-color: #007BFF; + color: white; + border: none; + border-radius: 5px; + cursor: pointer; +} + +button:hover { + background-color: #0056b3; +} \ No newline at end of file From 2d08ed259fe011f5191d248bac455c2dade8ae73 Mon Sep 17 00:00:00 2001 From: MacDonald91 Date: Sat, 21 Mar 2026 21:24:46 +0000 Subject: [PATCH 2/2] feat: implement delete completed todos with tests passing --- Sprint-3/todo-list/index.html | 2 + Sprint-3/todo-list/package.json | 4 +- Sprint-3/todo-list/script.mjs | 7 ++++ Sprint-3/todo-list/todos.js | 23 +++++++++++ Sprint-3/todo-list/todos.mjs | 29 -------------- .../{todos.test.mjs => todos.test.js} | 39 ++++++++++++++++++- 6 files changed, 72 insertions(+), 32 deletions(-) create mode 100644 Sprint-3/todo-list/todos.js delete mode 100644 Sprint-3/todo-list/todos.mjs rename Sprint-3/todo-list/{todos.test.mjs => todos.test.js} (81%) diff --git a/Sprint-3/todo-list/index.html b/Sprint-3/todo-list/index.html index 4d12c4654..081ef1507 100644 --- a/Sprint-3/todo-list/index.html +++ b/Sprint-3/todo-list/index.html @@ -18,6 +18,8 @@

My ToDo List

+ + diff --git a/Sprint-3/todo-list/package.json b/Sprint-3/todo-list/package.json index ce181158a..3676a1836 100644 --- a/Sprint-3/todo-list/package.json +++ b/Sprint-3/todo-list/package.json @@ -6,7 +6,7 @@ "type": "module", "scripts": { "serve": "http-server", - "test": "NODE_OPTIONS=--experimental-vm-modules jest" + "test": "set NODE_OPTIONS=--experimental-vm-modules && jest" }, "repository": { "type": "git", @@ -20,4 +20,4 @@ "http-server": "^14.1.1", "jest": "^30.0.4" } -} +} \ No newline at end of file diff --git a/Sprint-3/todo-list/script.mjs b/Sprint-3/todo-list/script.mjs index ba0b2ceae..b2d0f88ce 100644 --- a/Sprint-3/todo-list/script.mjs +++ b/Sprint-3/todo-list/script.mjs @@ -8,6 +8,13 @@ const todos = []; window.addEventListener("load", () => { document.getElementById("add-task-btn").addEventListener("click", addNewTodo); + document + .getElementById("delete-completed-btn") + .addEventListener("click", () => { + Todos.deleteCompleted(todos); + render(); + }); + // Populate sample data Todos.addTask(todos, "Wash the dishes", false); Todos.addTask(todos, "Do the shopping", true); diff --git a/Sprint-3/todo-list/todos.js b/Sprint-3/todo-list/todos.js new file mode 100644 index 000000000..e617c472e --- /dev/null +++ b/Sprint-3/todo-list/todos.js @@ -0,0 +1,23 @@ +// Add a new task +export function addTask(todos, task, completed) { + todos.push({ task, completed }); +} + +// Delete a task by index +export function deleteTask(todos, index) { + if (index < 0 || index >= todos.length) return; + todos.splice(index, 1); +} + +// Toggle completed status +export function toggleCompletedOnTask(todos, index) { + if (index < 0 || index >= todos.length) return; + todos[index].completed = !todos[index].completed; +} + +// Delete all completed tasks +export function deleteCompleted(todos) { + const remaining = todos.filter((todo) => !todo.completed); + todos.length = 0; + todos.push(...remaining); +} \ No newline at end of file diff --git a/Sprint-3/todo-list/todos.mjs b/Sprint-3/todo-list/todos.mjs deleted file mode 100644 index f17ab6a25..000000000 --- a/Sprint-3/todo-list/todos.mjs +++ /dev/null @@ -1,29 +0,0 @@ -/* - A ToDo List (todos) is expected to be represented as an array of objects in - the following manner: - - [ - { task: "Description of task 1", completed: false}, - { task: "Description of task 2", completed: true} - ] - -*/ - -// Append a new task to todos[] -export function addTask(todos, task, completed = false) { - todos.push({ task, completed }); -} - -// Delete todos[taskIndex] if it exists -export function deleteTask(todos, taskIndex) { - if (todos[taskIndex]) { - todos.splice(taskIndex, 1); - } -} - -// Toggle the "completed" property of todos[taskIndex] if the task exists. -export function toggleCompletedOnTask(todos, taskIndex) { - if (todos[taskIndex]) { - todos[taskIndex].completed = !todos[taskIndex].completed; - } -} \ No newline at end of file diff --git a/Sprint-3/todo-list/todos.test.mjs b/Sprint-3/todo-list/todos.test.js similarity index 81% rename from Sprint-3/todo-list/todos.test.mjs rename to Sprint-3/todo-list/todos.test.js index bae7ae491..36da5134f 100644 --- a/Sprint-3/todo-list/todos.test.mjs +++ b/Sprint-3/todo-list/todos.test.js @@ -5,7 +5,7 @@ // npm test todos.test.mjs // Import all the exported members through an object -import * as Todos from "./todos.mjs"; +import * as Todos from "./todos.js"; // Return a mock ToDo List data with exactly 4 elements. function createMockTodos() { @@ -130,3 +130,40 @@ describe("toggleCompletedOnTask()", () => { }); }); +describe("deleteCompleted()", () => { + test("removes all completed tasks from the list", () => { + const todos = createMockTodos(); + + Todos.deleteCompleted(todos); + + expect(todos).toEqual([ + { task: "Task 2 description", completed: false }, + { task: "Task 4 description", completed: false }, + ]); + }); + + test("does nothing if no tasks are completed", () => { + const todos = [ + { task: "Task A", completed: false }, + { task: "Task B", completed: false }, + ]; + + Todos.deleteCompleted(todos); + + expect(todos).toEqual([ + { task: "Task A", completed: false }, + { task: "Task B", completed: false }, + ]); + }); + + test("removes all tasks if all are completed", () => { + const todos = [ + { task: "Task A", completed: true }, + { task: "Task B", completed: true }, + ]; + + Todos.deleteCompleted(todos); + + expect(todos).toEqual([]); + }); +}); \ No newline at end of file