From 43c3dcf533aa1abf8a85106c6c2fc6bdeea563c7 Mon Sep 17 00:00:00 2001 From: jamesishimwe Date: Fri, 1 May 2026 15:13:23 +0200 Subject: [PATCH 01/30] Implement the set alarm function --- Sprint-3/alarmclock/alarmclock.js | 27 ++++++++++++++++++++++++++- Sprint-3/alarmclock/package.json | 5 ++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/Sprint-3/alarmclock/alarmclock.js b/Sprint-3/alarmclock/alarmclock.js index 6ca81cd3b..984dca1c0 100644 --- a/Sprint-3/alarmclock/alarmclock.js +++ b/Sprint-3/alarmclock/alarmclock.js @@ -1,4 +1,29 @@ -function setAlarm() {} +function setAlarm() { +const inputField = document.getElementById("alarmSet"); +const timeRemainingHeading = document.getElementById("timeRemaining"); +let totalSeconds = parseInt(inputField.value); +function updateDisplay(secondsLeft) { + const minutes = Math.floor(secondsLeft / 60); + const seconds = secondsLeft % 60; + const formattedMinutes = String(minutes).padStart(2, "0"); + const formattedSeconds = String(seconds).padStart(2, "0"); + + timeRemainingHeading.innerText = `Time Remaining: ${formattedMinutes}:${formattedSeconds}`; + updateDisplay(totalSeconds); + } + const countdown = setInterval(() => { + totalSeconds--; + + if (totalSeconds >= 0) { + updateDisplay(totalSeconds); + } + + if (totalSeconds === 0) { + playAlarm(); + clearInterval(countdown); + } + }, 1000); +} // DO NOT EDIT BELOW HERE diff --git a/Sprint-3/alarmclock/package.json b/Sprint-3/alarmclock/package.json index e1331e071..940fb8df3 100644 --- a/Sprint-3/alarmclock/package.json +++ b/Sprint-3/alarmclock/package.json @@ -13,5 +13,8 @@ "bugs": { "url": "https://github.com/CodeYourFuture/CYF-Coursework-Template/issues" }, - "homepage": "https://github.com/CodeYourFuture/CYF-Coursework-Template#readme" + "homepage": "https://github.com/CodeYourFuture/CYF-Coursework-Template#readme", + "devDependencies": { + "jsdom": "^24.0.0" + } } From b356574930fe9037fdfabb8915f3fa2b45036692 Mon Sep 17 00:00:00 2001 From: jamesishimwe Date: Fri, 1 May 2026 15:14:00 +0200 Subject: [PATCH 02/30] Add code for empty timer --- Sprint-3/alarmclock/alarmclock.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Sprint-3/alarmclock/alarmclock.js b/Sprint-3/alarmclock/alarmclock.js index 984dca1c0..e69bb308f 100644 --- a/Sprint-3/alarmclock/alarmclock.js +++ b/Sprint-3/alarmclock/alarmclock.js @@ -2,6 +2,7 @@ function setAlarm() { const inputField = document.getElementById("alarmSet"); const timeRemainingHeading = document.getElementById("timeRemaining"); let totalSeconds = parseInt(inputField.value); +if (isNaN(totalSeconds)) return; function updateDisplay(secondsLeft) { const minutes = Math.floor(secondsLeft / 60); const seconds = secondsLeft % 60; From 6b91460fd535cc31b6407ced4589a4af51904e8f Mon Sep 17 00:00:00 2001 From: jamesishimwe Date: Fri, 1 May 2026 15:14:52 +0200 Subject: [PATCH 03/30] Add code to set alarm to html element --- Sprint-3/alarmclock/alarmclock.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Sprint-3/alarmclock/alarmclock.js b/Sprint-3/alarmclock/alarmclock.js index e69bb308f..bbb578b39 100644 --- a/Sprint-3/alarmclock/alarmclock.js +++ b/Sprint-3/alarmclock/alarmclock.js @@ -25,6 +25,7 @@ function updateDisplay(secondsLeft) { } }, 1000); } +window.setAlarm = setAlarm; // DO NOT EDIT BELOW HERE From 4aca328297c381ce22b61c904c9b8a2ab2caf649 Mon Sep 17 00:00:00 2001 From: jamesishimwe Date: Fri, 1 May 2026 15:35:43 +0200 Subject: [PATCH 04/30] Add code to make the countdown clear when multiple started --- Sprint-3/alarmclock/alarmclock.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Sprint-3/alarmclock/alarmclock.js b/Sprint-3/alarmclock/alarmclock.js index bbb578b39..16930304c 100644 --- a/Sprint-3/alarmclock/alarmclock.js +++ b/Sprint-3/alarmclock/alarmclock.js @@ -1,4 +1,6 @@ +let countdown; function setAlarm() { +clearInterval(countdown); const inputField = document.getElementById("alarmSet"); const timeRemainingHeading = document.getElementById("timeRemaining"); let totalSeconds = parseInt(inputField.value); @@ -12,7 +14,7 @@ function updateDisplay(secondsLeft) { timeRemainingHeading.innerText = `Time Remaining: ${formattedMinutes}:${formattedSeconds}`; updateDisplay(totalSeconds); } - const countdown = setInterval(() => { + countdown = setInterval(() => { totalSeconds--; if (totalSeconds >= 0) { From 023e46ac315b9ff7f2e92ca462835ecadca89551 Mon Sep 17 00:00:00 2001 From: jamesishimwe Date: Fri, 1 May 2026 16:15:44 +0200 Subject: [PATCH 05/30] Fix bug to make sound play --- Sprint-3/alarmclock/alarmclock.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/Sprint-3/alarmclock/alarmclock.js b/Sprint-3/alarmclock/alarmclock.js index 16930304c..838d1d70a 100644 --- a/Sprint-3/alarmclock/alarmclock.js +++ b/Sprint-3/alarmclock/alarmclock.js @@ -1,3 +1,15 @@ +if (typeof expect !== 'undefined' && !expect.prototype.toHaveTextContent) { + expect.extend({ + toHaveTextContent(received, expected) { + // Checks if the element's text matches what the test is looking for + const pass = received.textContent.includes(expected) || received.innerText.includes(expected); + return { + pass, + message: () => `expected "${received.textContent}" to contain "${expected}"`, + }; + }, + }); +} let countdown; function setAlarm() { clearInterval(countdown); @@ -17,7 +29,7 @@ function updateDisplay(secondsLeft) { countdown = setInterval(() => { totalSeconds--; - if (totalSeconds >= 0) { + if (totalSeconds > 0) { updateDisplay(totalSeconds); } From 4dc5b9518950d10a666ce75723e5df79768c0797 Mon Sep 17 00:00:00 2001 From: jamesishimwe Date: Fri, 1 May 2026 16:19:30 +0200 Subject: [PATCH 06/30] Fix the code --- Sprint-3/alarmclock/alarmclock.js | 1 + 1 file changed, 1 insertion(+) diff --git a/Sprint-3/alarmclock/alarmclock.js b/Sprint-3/alarmclock/alarmclock.js index 838d1d70a..f31d797c4 100644 --- a/Sprint-3/alarmclock/alarmclock.js +++ b/Sprint-3/alarmclock/alarmclock.js @@ -35,6 +35,7 @@ function updateDisplay(secondsLeft) { if (totalSeconds === 0) { playAlarm(); + updateDisplay(totalSeconds); clearInterval(countdown); } }, 1000); From 280ae30835abd1ac94ff0edf49ca4e984457fd4a Mon Sep 17 00:00:00 2001 From: jamesishimwe Date: Fri, 1 May 2026 16:23:35 +0200 Subject: [PATCH 07/30] Fix the code --- Sprint-3/alarmclock/alarmclock.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sprint-3/alarmclock/alarmclock.js b/Sprint-3/alarmclock/alarmclock.js index f31d797c4..7bdbe1179 100644 --- a/Sprint-3/alarmclock/alarmclock.js +++ b/Sprint-3/alarmclock/alarmclock.js @@ -35,8 +35,8 @@ function updateDisplay(secondsLeft) { if (totalSeconds === 0) { playAlarm(); - updateDisplay(totalSeconds); clearInterval(countdown); + updateDisplay(totalSeconds); } }, 1000); } From 8015573b9c2d3c4bdfa7abb84f2d7d14c7342e8d Mon Sep 17 00:00:00 2001 From: jamesishimwe Date: Fri, 1 May 2026 16:30:28 +0200 Subject: [PATCH 08/30] Fix code --- Sprint-3/alarmclock/alarmclock.js | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/Sprint-3/alarmclock/alarmclock.js b/Sprint-3/alarmclock/alarmclock.js index 7bdbe1179..8643fb6af 100644 --- a/Sprint-3/alarmclock/alarmclock.js +++ b/Sprint-3/alarmclock/alarmclock.js @@ -1,15 +1,4 @@ -if (typeof expect !== 'undefined' && !expect.prototype.toHaveTextContent) { - expect.extend({ - toHaveTextContent(received, expected) { - // Checks if the element's text matches what the test is looking for - const pass = received.textContent.includes(expected) || received.innerText.includes(expected); - return { - pass, - message: () => `expected "${received.textContent}" to contain "${expected}"`, - }; - }, - }); -} + let countdown; function setAlarm() { clearInterval(countdown); From b21c9ce2698983a3b8c21a74a235ce469c66ae2d Mon Sep 17 00:00:00 2001 From: jamesishimwe Date: Fri, 1 May 2026 17:01:41 +0200 Subject: [PATCH 09/30] Get resources from html --- Sprint-3/quote-generator/quotes.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Sprint-3/quote-generator/quotes.js b/Sprint-3/quote-generator/quotes.js index 4a4d04b72..24e7a4148 100644 --- a/Sprint-3/quote-generator/quotes.js +++ b/Sprint-3/quote-generator/quotes.js @@ -491,3 +491,6 @@ const quotes = [ ]; // call pickFromArray with the quotes array to check you get a random quote +const quoteText = document.getElementById('quote'); +const authorText = document.getElementById('author'); +const newQuoteBtn = document.getElementById('new-quote'); From b55904c64b53ad8a70261e8e0999a903c88d3053 Mon Sep 17 00:00:00 2001 From: jamesishimwe Date: Fri, 1 May 2026 17:02:10 +0200 Subject: [PATCH 10/30] Add function displayNewQuote --- Sprint-3/quote-generator/quotes.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Sprint-3/quote-generator/quotes.js b/Sprint-3/quote-generator/quotes.js index 24e7a4148..3ec1969b6 100644 --- a/Sprint-3/quote-generator/quotes.js +++ b/Sprint-3/quote-generator/quotes.js @@ -494,3 +494,9 @@ const quotes = [ const quoteText = document.getElementById('quote'); const authorText = document.getElementById('author'); const newQuoteBtn = document.getElementById('new-quote'); + +function displayNewQuote() { + const randomQuote = pickFromArray(quotes); + quoteText.textContent = randomQuote.quote; + authorText.textContent = `- ${randomQuote.author}`; +} \ No newline at end of file From b715ba1e1e9a08345dcc1b594e6fa76a397141fd Mon Sep 17 00:00:00 2001 From: jamesishimwe Date: Fri, 1 May 2026 17:02:46 +0200 Subject: [PATCH 11/30] Run function --- Sprint-3/quote-generator/quotes.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Sprint-3/quote-generator/quotes.js b/Sprint-3/quote-generator/quotes.js index 3ec1969b6..d4ee0b000 100644 --- a/Sprint-3/quote-generator/quotes.js +++ b/Sprint-3/quote-generator/quotes.js @@ -499,4 +499,8 @@ function displayNewQuote() { const randomQuote = pickFromArray(quotes); quoteText.textContent = randomQuote.quote; authorText.textContent = `- ${randomQuote.author}`; -} \ No newline at end of file +} + +newQuoteBtn.addEventListener('click', displayNewQuote); + +displayNewQuote(); \ No newline at end of file From fbe53f64c444e2eae521de8cd157ee07bc099c0b Mon Sep 17 00:00:00 2001 From: jamesishimwe Date: Fri, 1 May 2026 17:04:09 +0200 Subject: [PATCH 12/30] Add css --- Sprint-3/quote-generator/style.css | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Sprint-3/quote-generator/style.css b/Sprint-3/quote-generator/style.css index 63cedf2d2..fe0ed3227 100644 --- a/Sprint-3/quote-generator/style.css +++ b/Sprint-3/quote-generator/style.css @@ -1 +1,16 @@ /** Write your CSS in here **/ +body { + background-color: #ffa500; /* That bright orange */ + display: flex; + justify-content: center; + align-items: center; + height: 100vh; + margin: 0; +} + +#quote-container { /* If you wrap your p tags in a div */ + background: white; + padding: 40px; + border-radius: 8px; + max-width: 600px; +} \ No newline at end of file From a2f2c625ae5b6452e1754a33e5b941530ae93385 Mon Sep 17 00:00:00 2001 From: jamesishimwe Date: Fri, 1 May 2026 17:05:40 +0200 Subject: [PATCH 13/30] Link css --- Sprint-3/quote-generator/index.html | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Sprint-3/quote-generator/index.html b/Sprint-3/quote-generator/index.html index 30b434bcf..6b448ce29 100644 --- a/Sprint-3/quote-generator/index.html +++ b/Sprint-3/quote-generator/index.html @@ -4,12 +4,14 @@ Title here + -

hello there

-

-

- +
+

+

+ +
From 9b5f4d1a3a1275241528914c68c6023f9648f3fe Mon Sep 17 00:00:00 2001 From: jamesishimwe Date: Fri, 1 May 2026 17:28:04 +0200 Subject: [PATCH 14/30] Implement reading list --- Sprint-3/reading-list/script.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Sprint-3/reading-list/script.js b/Sprint-3/reading-list/script.js index 6024d73a0..9487102f6 100644 --- a/Sprint-3/reading-list/script.js +++ b/Sprint-3/reading-list/script.js @@ -21,3 +21,14 @@ const books = [ }, ]; +const readingList = document.querySelector("#reading-list"); + +books.forEach((book) => { + const li = document.createElement("li"); + li.textContent = `${book.title} by ${book.author}`; + const img = document.createElement("img"); + img.src = book.bookCoverImage; + li.appendChild(img); + li.style.backgroundColor = book.alreadyRead ? "green" : "red"; + readingList.appendChild(li); +}); \ No newline at end of file From 0feca6c37d10da2d8fb08335f8c99c8c9f56f6e5 Mon Sep 17 00:00:00 2001 From: jamesishimwe Date: Fri, 1 May 2026 17:31:08 +0200 Subject: [PATCH 15/30] Change css to fit image --- Sprint-3/reading-list/style.css | 170 ++++---------------------------- 1 file changed, 19 insertions(+), 151 deletions(-) diff --git a/Sprint-3/reading-list/style.css b/Sprint-3/reading-list/style.css index 74406e64f..2e804d984 100644 --- a/Sprint-3/reading-list/style.css +++ b/Sprint-3/reading-list/style.css @@ -1,159 +1,27 @@ -/** - * Base styles to use at the start of the class - * - * Module: HTML/CSS - * Lesson: 1,2 - * Class: Scotland 2017 - */ - -html, -body { - font-family: "Source Sans Pro", -apple-system, system-ui, BlinkMacSystemFont, - "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; -} - -.site-footer { - margin-top: 4em; -} - -.site-footer p { - border-top: 1px solid #dccdc6; - padding-top: 2em; - padding-bottom: 2em; -} - -.navbar-brand > img { - max-height: 40px; - width: auto; -} - -.navbar-light .navbar-nav .nav-link { - color: #292b2c; - font-weight: 600; - text-transform: uppercase; -} - -/* Buttons */ -.btn { - border-radius: 0.15em; -} - -/* Alert */ -.alert { - position: relative; - margin-top: 2em; - margin-bottom: 3em; - padding-top: 1.5em; - padding-bottom: 1.5em; - border: 1px solid #dccdc6; - border-radius: 0; - font-size: 0.85rem; - line-height: 1.3em; - background: transparent; - color: #292b2c; -} - -.alert:before { - content: ""; - position: absolute; - left: -1px; - top: 0; - height: 100%; - width: 1px; - background: #ce5f31; -} - -/* Jumbotron */ -.jumbotron { - border-radius: 0; -} - -/* Headings */ -.heading-underline { - position: relative; - margin-bottom: 2em; - padding-bottom: 0.5em; - border-bottom: 1px solid #dccdc6; - font-size: 1rem; - font-weight: 600; - text-transform: uppercase; -} - -.heading-underline:before { - content: ""; - position: absolute; - bottom: -1px; - left: 0; - width: 25%; - height: 1px; - max-width: 100px; - background: #ce5f31; +/* Base styles from your class file */ +html, body { + font-family: "Source Sans Pro", -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; + padding: 20px; } -/* Article */ -.article { - margin-bottom: 2em; +#reading-list { + list-style-type: none; + padding: 0; + max-width: 600px; } -.article-title { - margin-bottom: 0.5em; - font-weight: 700; -} - -.article-read-more a { - font-size: 0.85em; - font-weight: 700; - text-decoration: uppercase; -} - -.article-read-more a:hover, -.article-read-more a:focus { - text-decoration: none; -} - -.article-read-more .fa { - margin-right: 0.5em; - color: #ce5f31; -} - -.article-read-more:last-child { - margin-bottom: 0; -} - -.red { - background-color: red; -} - -.addArticle { - margin-bottom: 10px; -} - -#addArticleBtn { - margin-left: 20px; - height: 37px; -} - -.colorButton { +#reading-list li { + display: flex; + flex-direction: column; + padding: 20px; margin-bottom: 20px; - margin-right: 20px; - width: 100px; - height: 50px; -} - -#blueBtn { - background: #588fbd; -} - -#orangeBtn { - background: #f0ad4e; -} - -#greenBtn { - background: #87ca8a; + font-weight: 600; + } -@media screen and (min-width: 992px) { - .navbar-brand > img { - max-height: 80px; - } +#reading-list img { + width: 150px; + height: auto; + margin-top: 15px; + display: block; } From fdb1b7ad7564e4aa3a94a577b8556a323b2d9dc1 Mon Sep 17 00:00:00 2001 From: jamesishimwe Date: Fri, 1 May 2026 17:36:36 +0200 Subject: [PATCH 16/30] Add auto slideshow buttons --- Sprint-3/slideshow/index.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Sprint-3/slideshow/index.html b/Sprint-3/slideshow/index.html index 50f2eb1c0..360c997d4 100644 --- a/Sprint-3/slideshow/index.html +++ b/Sprint-3/slideshow/index.html @@ -10,5 +10,8 @@ cat-pic + + + From eff3edc67c8e56e16ddfaa2ee7d838a02a695ada Mon Sep 17 00:00:00 2001 From: jamesishimwe Date: Fri, 1 May 2026 17:40:39 +0200 Subject: [PATCH 17/30] Implement slideshow buttons --- Sprint-3/slideshow/slideshow.js | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/Sprint-3/slideshow/slideshow.js b/Sprint-3/slideshow/slideshow.js index 063ceefb5..dd26b3d28 100644 --- a/Sprint-3/slideshow/slideshow.js +++ b/Sprint-3/slideshow/slideshow.js @@ -4,5 +4,28 @@ const images = [ "./assets/cute-cat-c.jpg", ]; +let currentIndex = 0; +let intervalId = null; -// Write your code here \ No newline at end of file +const imgElement = document.querySelector("#carousel-img"); +const forwardBtn = document.querySelector("#forward-btn"); +const backwardBtn = document.querySelector("#backward-btn"); +const autoForwardBtn = document.querySelector("#auto-forward"); +const autoBackBtn = document.querySelector("#auto-backward"); +const stopBtn = document.querySelector("#stop"); + +function updateImage() { + imgElement.src = images[currentIndex]; +} +function moveForward() { + currentIndex = (currentIndex + 1) % images.length; + updateImage(); +} + +function moveBackward() { + currentIndex = (currentIndex - 1 + images.length) % images.length; + updateImage(); +} + +forwardBtn.addEventListener("click", moveForward); +backwardBtn.addEventListener("click", moveBackward); From 7349199bdc0a5253273e5b8ce2fc070fdfbfde44 Mon Sep 17 00:00:00 2001 From: jamesishimwe Date: Fri, 1 May 2026 17:43:24 +0200 Subject: [PATCH 18/30] Add code for auto slideshow --- Sprint-3/slideshow/package.json | 5 ++++- Sprint-3/slideshow/slideshow.js | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/Sprint-3/slideshow/package.json b/Sprint-3/slideshow/package.json index 306353179..c7c9ddd47 100644 --- a/Sprint-3/slideshow/package.json +++ b/Sprint-3/slideshow/package.json @@ -13,5 +13,8 @@ "bugs": { "url": "https://github.com/CodeYourFuture/CYF-Coursework-Template/issues" }, - "homepage": "https://github.com/CodeYourFuture/CYF-Coursework-Template#readme" + "homepage": "https://github.com/CodeYourFuture/CYF-Coursework-Template#readme", + "devDependencies": { + "jsdom": "^29.1.1" + } } diff --git a/Sprint-3/slideshow/slideshow.js b/Sprint-3/slideshow/slideshow.js index dd26b3d28..95da544a7 100644 --- a/Sprint-3/slideshow/slideshow.js +++ b/Sprint-3/slideshow/slideshow.js @@ -29,3 +29,21 @@ function moveBackward() { forwardBtn.addEventListener("click", moveForward); backwardBtn.addEventListener("click", moveBackward); + +function startAuto(directionFn) { + // Disable buttons as required by tests + autoForwardBtn.disabled = true; + autoBackBtn.disabled = true; + + intervalId = setInterval(directionFn, 2000); +} + +autoForwardBtn.addEventListener("click", () => startAuto(moveForward)); +autoBackBtn.addEventListener("click", () => startAuto(moveBackward)); + +stopBtn.addEventListener("click", () => { + clearInterval(intervalId); + // Re-enable buttons + autoForwardBtn.disabled = false; + autoBackBtn.disabled = false; +}); \ No newline at end of file From 92dd08e58d9d567f7e9661a20b4ff4e0e1da9ac0 Mon Sep 17 00:00:00 2001 From: jamesishimwe Date: Fri, 1 May 2026 17:58:52 +0200 Subject: [PATCH 19/30] Add code to make app better --- Sprint-3/slideshow/index.html | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Sprint-3/slideshow/index.html b/Sprint-3/slideshow/index.html index 360c997d4..54039659f 100644 --- a/Sprint-3/slideshow/index.html +++ b/Sprint-3/slideshow/index.html @@ -4,14 +4,19 @@ Title here + - cat-pic +
+ cat-pic width: 400px; height: 300px; +
+
+
From a236d5c75010ea05c5b0a8ee80acbd5037ce6d79 Mon Sep 17 00:00:00 2001 From: jamesishimwe Date: Fri, 1 May 2026 17:59:05 +0200 Subject: [PATCH 20/30] Add css to buttons and images --- Sprint-3/slideshow/style.css | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/Sprint-3/slideshow/style.css b/Sprint-3/slideshow/style.css index 63cedf2d2..022063f3d 100644 --- a/Sprint-3/slideshow/style.css +++ b/Sprint-3/slideshow/style.css @@ -1 +1,21 @@ -/** Write your CSS in here **/ +#carousel-img { + /* This locks every "next" image to these exact dimensions */ + width: 500px; + height: 350px; + display: block; + margin: 0 auto; +} + +.slideshow-frame { + width: 500px; + height: 350px; + margin: 0 auto; + border: 2px solid black; +} + +.slideshow-controls { + display: flex; + justify-content: center; + gap: 10px; + margin-top: 20px; +} \ No newline at end of file From 76a132b7b1868782042764b6db658c9ed96073be Mon Sep 17 00:00:00 2001 From: jamesishimwe Date: Fri, 1 May 2026 18:01:29 +0200 Subject: [PATCH 21/30] Change title of reading list --- Sprint-3/reading-list/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sprint-3/reading-list/index.html b/Sprint-3/reading-list/index.html index dbdb0f471..88102fc1f 100644 --- a/Sprint-3/reading-list/index.html +++ b/Sprint-3/reading-list/index.html @@ -4,7 +4,7 @@ - Title here + Reading List
From 00283fbe128e58768767ab0843a874ef0f7d60ea Mon Sep 17 00:00:00 2001 From: jamesishimwe Date: Fri, 1 May 2026 18:02:03 +0200 Subject: [PATCH 22/30] Change title of Quote generator --- Sprint-3/quote-generator/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sprint-3/quote-generator/index.html b/Sprint-3/quote-generator/index.html index 6b448ce29..6c5b41350 100644 --- a/Sprint-3/quote-generator/index.html +++ b/Sprint-3/quote-generator/index.html @@ -3,7 +3,7 @@ - Title here + Quote Generator From 584a357eeff864970d4affa5f77d977f27259406 Mon Sep 17 00:00:00 2001 From: jamesishimwe Date: Fri, 1 May 2026 18:03:13 +0200 Subject: [PATCH 23/30] Change title of Alarm Clock --- Sprint-3/alarmclock/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sprint-3/alarmclock/index.html b/Sprint-3/alarmclock/index.html index 48e2e80d9..9b71b5b6e 100644 --- a/Sprint-3/alarmclock/index.html +++ b/Sprint-3/alarmclock/index.html @@ -4,7 +4,7 @@ - Title here + Alarm Clock
From c37939b3fe5a7ad89792f27228b9d6ddd90edc71 Mon Sep 17 00:00:00 2001 From: jamesishimwe Date: Fri, 1 May 2026 18:03:58 +0200 Subject: [PATCH 24/30] Change title of Slideshow --- Sprint-3/slideshow/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sprint-3/slideshow/index.html b/Sprint-3/slideshow/index.html index 54039659f..a1f24da47 100644 --- a/Sprint-3/slideshow/index.html +++ b/Sprint-3/slideshow/index.html @@ -3,7 +3,7 @@ - Title here + Slideshow From 8c3a8b9a4ecc36478284b9556744504e57f4e085 Mon Sep 17 00:00:00 2001 From: jamesishimwe Date: Fri, 1 May 2026 23:00:02 +0200 Subject: [PATCH 25/30] implement populateTodoList and load hardcoded data --- Sprint-3/todo-list/package.json | 3 ++- Sprint-3/todo-list/script.mjs | 10 +++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Sprint-3/todo-list/package.json b/Sprint-3/todo-list/package.json index ce181158a..1e6403d8b 100644 --- a/Sprint-3/todo-list/package.json +++ b/Sprint-3/todo-list/package.json @@ -18,6 +18,7 @@ "homepage": "https://github.com/CodeYourFuture/CYF-Coursework-Template#readme", "devDependencies": { "http-server": "^14.1.1", - "jest": "^30.0.4" + "jest": "^30.0.4", + "jsdom": "^29.1.1" } } diff --git a/Sprint-3/todo-list/script.mjs b/Sprint-3/todo-list/script.mjs index ba0b2ceae..cf0c8bb18 100644 --- a/Sprint-3/todo-list/script.mjs +++ b/Sprint-3/todo-list/script.mjs @@ -12,7 +12,7 @@ window.addEventListener("load", () => { Todos.addTask(todos, "Wash the dishes", false); Todos.addTask(todos, "Do the shopping", true); - render(); + populateTodoList(); }); @@ -23,7 +23,7 @@ function addNewTodo() { const task = taskInput.value.trim(); if (task) { Todos.addTask(todos, task, false); - render(); + populateTodoList(); } taskInput.value = ""; @@ -36,7 +36,7 @@ function addNewTodo() { const todoListEl = document.getElementById("todo-list"); // Render the whole todo list -function render() { +function populateTodoList() { todoListEl.innerHTML = ""; todos.forEach((todo, index) => { @@ -64,12 +64,12 @@ function createListItem(todo, index) { li.querySelector('.complete-btn').addEventListener("click", () => { Todos.toggleCompletedOnTask(todos, index); - render(); + populateTodoList(); }); li.querySelector('.delete-btn').addEventListener("click", () => { Todos.deleteTask(todos, index); - render(); + populateTodoList(); }); return li; From d572a3a94a4177fabe1ced66b1f025ae75c330b6 Mon Sep 17 00:00:00 2001 From: jamesishimwe Date: Fri, 1 May 2026 23:10:02 +0200 Subject: [PATCH 26/30] Add mass deleting completed tasks --- Sprint-3/todo-list/todos.mjs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Sprint-3/todo-list/todos.mjs b/Sprint-3/todo-list/todos.mjs index f17ab6a25..43f9b3b4a 100644 --- a/Sprint-3/todo-list/todos.mjs +++ b/Sprint-3/todo-list/todos.mjs @@ -26,4 +26,9 @@ export function toggleCompletedOnTask(todos, taskIndex) { if (todos[taskIndex]) { todos[taskIndex].completed = !todos[taskIndex].completed; } -} \ No newline at end of file +} +export function deleteCompleted(todos) { + const remaining = todos.filter(t => !t.completed); + todos.length = 0; + todos.push(...remaining); +} From 646edf28d4c31d81e3d8fa63b4291334e5817083 Mon Sep 17 00:00:00 2001 From: jamesishimwe Date: Fri, 1 May 2026 23:14:40 +0200 Subject: [PATCH 27/30] add button and listener for mass deletion --- Sprint-3/todo-list/index.html | 2 ++ Sprint-3/todo-list/script.mjs | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/Sprint-3/todo-list/index.html b/Sprint-3/todo-list/index.html index 4d12c4654..053048715 100644 --- a/Sprint-3/todo-list/index.html +++ b/Sprint-3/todo-list/index.html @@ -31,6 +31,8 @@

My ToDo List

+ +
diff --git a/Sprint-3/todo-list/script.mjs b/Sprint-3/todo-list/script.mjs index cf0c8bb18..765a39337 100644 --- a/Sprint-3/todo-list/script.mjs +++ b/Sprint-3/todo-list/script.mjs @@ -7,6 +7,10 @@ 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("clear-completed-btn").addEventListener("click", () => { + Todos.deleteCompleted(todos); + populateTodoList(); + }); // Populate sample data Todos.addTask(todos, "Wash the dishes", false); From 34419581bc16c87b0d43d2e5f6258b411adfc0cd Mon Sep 17 00:00:00 2001 From: jamesishimwe Date: Fri, 1 May 2026 23:18:33 +0200 Subject: [PATCH 28/30] add deadline input and update addTask --- Sprint-3/todo-list/index.html | 2 ++ Sprint-3/todo-list/todos.mjs | 3 +++ 2 files changed, 5 insertions(+) diff --git a/Sprint-3/todo-list/index.html b/Sprint-3/todo-list/index.html index 053048715..0595f66f9 100644 --- a/Sprint-3/todo-list/index.html +++ b/Sprint-3/todo-list/index.html @@ -15,6 +15,8 @@

My ToDo List

+ +
diff --git a/Sprint-3/todo-list/todos.mjs b/Sprint-3/todo-list/todos.mjs index 43f9b3b4a..558b217e1 100644 --- a/Sprint-3/todo-list/todos.mjs +++ b/Sprint-3/todo-list/todos.mjs @@ -32,3 +32,6 @@ export function deleteCompleted(todos) { todos.length = 0; todos.push(...remaining); } +export function addTask(todos, task, deadline = "", completed = false) { + todos.push({ task, deadline, completed }); +} From c21ed694c18410cd4fe5308a0f7626a1225c9866 Mon Sep 17 00:00:00 2001 From: jamesishimwe Date: Fri, 1 May 2026 23:24:35 +0200 Subject: [PATCH 29/30] display deadline next to todo text in the list --- Sprint-3/todo-list/script.mjs | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/Sprint-3/todo-list/script.mjs b/Sprint-3/todo-list/script.mjs index 765a39337..4226908a6 100644 --- a/Sprint-3/todo-list/script.mjs +++ b/Sprint-3/todo-list/script.mjs @@ -31,6 +31,35 @@ function addNewTodo() { } taskInput.value = ""; + deadlineInput.value = ""; +} +function createListItem(todo, index) { + const li = todoListItemTemplate.cloneNode(true); + + // Requirement: Display deadline next to the todo text + const deadlineDisplay = todo.deadline ? ` (Due: ${todo.deadline})` : ""; + li.querySelector(".description").textContent = todo.task + deadlineDisplay; + + // Requirement: If completed, add strikethrough class and change icon to ✅ + if (todo.completed) { + li.classList.add("completed"); + const icon = li.querySelector(".complete-btn span"); + icon.className = "fa-solid fa-square-check"; // Ticked checkbox + } + + // Requirement: When checkbox icon is clicked, toggle completion + li.querySelector('.complete-btn').addEventListener("click", () => { + Todos.toggleCompletedOnTask(todos, index); + populateTodoList(); // Refresh the list to show strikethrough/tick + }); + + // Requirement: When trash icon is clicked, delete the item + li.querySelector('.delete-btn').addEventListener("click", () => { + Todos.deleteTask(todos, index); + populateTodoList(); // Refresh the list to remove the item + }); + + return li; } // Note: From e081426d82fd661ddc0262ae209f5af175ebadda Mon Sep 17 00:00:00 2001 From: jamesishimwe Date: Fri, 1 May 2026 23:59:35 +0200 Subject: [PATCH 30/30] Fix bugs --- Sprint-3/todo-list/index.html | 3 ++- Sprint-3/todo-list/script.mjs | 43 ++++++++++------------------------- Sprint-3/todo-list/todos.mjs | 7 ++---- 3 files changed, 16 insertions(+), 37 deletions(-) diff --git a/Sprint-3/todo-list/index.html b/Sprint-3/todo-list/index.html index 0595f66f9..4144aaf95 100644 --- a/Sprint-3/todo-list/index.html +++ b/Sprint-3/todo-list/index.html @@ -27,13 +27,14 @@

My ToDo List

This is a template for the To-do list item. It can simplify the creation of list item node in JS script. --> +