From c3824f304d5e68a6406567405a00d445a0161fff Mon Sep 17 00:00:00 2001 From: Samuel Tarawally <41825140+Tarawally@users.noreply.github.com> Date: Fri, 12 Dec 2025 03:42:54 +0000 Subject: [PATCH 01/11] feat: update structure and layout for alarm clock --- Sprint-3/alarmclock/index.html | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/Sprint-3/alarmclock/index.html b/Sprint-3/alarmclock/index.html index 48e2e80d9..887f5559e 100644 --- a/Sprint-3/alarmclock/index.html +++ b/Sprint-3/alarmclock/index.html @@ -1,4 +1,4 @@ - + @@ -7,13 +7,18 @@ Title here -
+

Time Remaining: 00:00

- - - - +
+ + +
+ +
+ + +
From 3a0ada8620e1997a6bd98e1beb5ca7f78466d540 Mon Sep 17 00:00:00 2001 From: Samuel Tarawally <41825140+Tarawally@users.noreply.github.com> Date: Fri, 12 Dec 2025 03:42:59 +0000 Subject: [PATCH 02/11] feat: implement digital clock design --- Sprint-3/alarmclock/style.css | 95 ++++++++++++++++++++++++++++++++--- 1 file changed, 87 insertions(+), 8 deletions(-) diff --git a/Sprint-3/alarmclock/style.css b/Sprint-3/alarmclock/style.css index 0c72de38b..a2ddb3d2c 100644 --- a/Sprint-3/alarmclock/style.css +++ b/Sprint-3/alarmclock/style.css @@ -1,15 +1,94 @@ -.centre { - position: fixed; - top: 50%; - left: 50%; - -webkit-transform: translate(-50%, -50%); - transform: translate(-50%, -50%); +body { + background-color: #1a1a1a; + font-family: 'Courier New', Courier, monospace; + color: #00ff00; + display: flex; + justify-content: center; + align-items: center; + min-height: 100vh; + margin: 0; + transition: background-color 0.5s ease; } -#alarmSet { - margin: 20px; +.flash { + animation: flash-bg 0.5s infinite alternate; +} + +@keyframes flash-bg { + from { background-color: #ff0000; } + to { background-color: #330000; } +} + +.container { + background-color: #000; + border: 4px solid #333; + border-radius: 20px; + padding: 40px; + box-shadow: 0 0 20px rgba(0, 255, 0, 0.2); + text-align: center; + max-width: 500px; + width: 90%; } h1 { + font-size: 3rem; + margin-bottom: 30px; + text-shadow: 0 0 10px #00ff00; +} + +.input-group { + margin-bottom: 25px; +} + +label { + display: block; + margin-bottom: 10px; + font-size: 1.2rem; +} + +input { + background-color: #111; + border: 2px solid #00ff00; + color: #00ff00; + padding: 10px; + font-size: 1.5rem; + border-radius: 5px; + width: 120px; text-align: center; + font-family: inherit; +} + +input:focus { + outline: none; + box-shadow: 0 0 15px rgba(0, 255, 0, 0.3); +} + +.controls { + display: flex; + gap: 15px; + justify-content: center; +} + +button { + background-color: #1a1a1a; + color: #00ff00; + border: 2px solid #00ff00; + padding: 10px 20px; + font-size: 1.1rem; + cursor: pointer; + border-radius: 5px; + font-family: inherit; + font-weight: bold; + transition: all 0.2s; + text-transform: uppercase; +} + +button:hover { + background-color: #00ff00; + color: #000; + box-shadow: 0 0 15px #00ff00; +} + +button:active { + transform: translateY(2px); } From c964595659391fa181c1ec3e58b1247ed21fb6d3 Mon Sep 17 00:00:00 2001 From: Samuel Tarawally <41825140+Tarawally@users.noreply.github.com> Date: Fri, 12 Dec 2025 03:43:02 +0000 Subject: [PATCH 03/11] feat: implement alarm clock logic with set, update and stop functions --- Sprint-3/alarmclock/alarmclock.js | 74 ++++++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 1 deletion(-) diff --git a/Sprint-3/alarmclock/alarmclock.js b/Sprint-3/alarmclock/alarmclock.js index 6ca81cd3b..cead57428 100644 --- a/Sprint-3/alarmclock/alarmclock.js +++ b/Sprint-3/alarmclock/alarmclock.js @@ -1,4 +1,76 @@ -function setAlarm() {} +// Variables to track state +let timeRemaining = 0; +let alarmInterval = null; + +// DOM Elements (will be fetched dynamically in functions to avoid load issues) + +/** + * Formats a number of seconds into "MM:SS" format. + * @param totalSeconds - The total number of seconds. + * @return A string formatted as "MM:SS". + */ +function formatTime(totalSeconds) { + const minutes = Math.floor(totalSeconds / 60); + const seconds = totalSeconds % 60; + + // Pad with leading zeros + const formattedMinutes = minutes < 10 ? "0" + minutes : minutes; + const formattedSeconds = seconds < 10 ? "0" + seconds : seconds; + + return "Time Remaining: " + formattedMinutes + ":" + formattedSeconds; +} + +/** + * Updates the display and handles the alarm trigger logic. + * Called every second by the interval. + */ +function updateTime() { + // Update display + const title = document.getElementById("timeRemaining"); + title.innerText = formatTime(timeRemaining); + + // Check if alarm should trigger + if (timeRemaining === 0) { + playAlarm(); + + // Change background color to flash + document.body.classList.add("flash"); + } else { + // Decrement time + timeRemaining = timeRemaining - 1; + } +} + +/** + * Sets the alarm based on user input. + * Called when the "Set Alarm" button is clicked. + */ +function setAlarm() { + // Clear any existing interval + if (alarmInterval) { + clearInterval(alarmInterval); + document.body.classList.remove("flash"); + } + + const input = document.getElementById("alarmSet"); + const inputValue = parseInt(input.value); + + // Validate input + if (isNaN(inputValue) || inputValue < 0) { + return; + } + + timeRemaining = inputValue; + + // Update display immediately + const title = document.getElementById("timeRemaining"); + title.innerText = formatTime(timeRemaining); + + // Start countdown interval + alarmInterval = setInterval(function () { + updateTime(); + }, 1000); +} // DO NOT EDIT BELOW HERE From 895d8c6b5ad02399c46d12d8504b56e388b996d4 Mon Sep 17 00:00:00 2001 From: Samuel Tarawally <41825140+Tarawally@users.noreply.github.com> Date: Fri, 12 Dec 2025 17:54:15 +0000 Subject: [PATCH 04/11] refactor: improving comments for clarity and readability --- Sprint-3/alarmclock/alarmclock.js | 105 ++++++++++++++++++++---------- 1 file changed, 69 insertions(+), 36 deletions(-) diff --git a/Sprint-3/alarmclock/alarmclock.js b/Sprint-3/alarmclock/alarmclock.js index cead57428..c077d59f0 100644 --- a/Sprint-3/alarmclock/alarmclock.js +++ b/Sprint-3/alarmclock/alarmclock.js @@ -1,75 +1,108 @@ -// Variables to track state -let timeRemaining = 0; -let alarmInterval = null; +// Use a constant for the one-second interval to make the code easier to read. +const ONE_SECOND_IN_MILLISECONDS = 1000; + +// Defines variables to track the state of the alarm clock. +// Uses 'let' because these values will change as the timer runs. +let timeRemainingInSeconds = 0; +let alarmTimerIdentifier = null; // DOM Elements (will be fetched dynamically in functions to avoid load issues) /** - * Formats a number of seconds into "MM:SS" format. - * @param totalSeconds - The total number of seconds. - * @return A string formatted as "MM:SS". + * Formats a number of seconds into a standard "MM:SS" string. + * This helps the user read the time easily (e.g., "01:30" instead of "90"). + * + * @param {number} totalSeconds - The total number of seconds to format. + * @returns {string} A string formatted as "MM:SS". */ function formatTime(totalSeconds) { + // Calculates the number of full minutes. const minutes = Math.floor(totalSeconds / 60); + + // Calculates the remaining seconds after removing the minutes. const seconds = totalSeconds % 60; - // Pad with leading zeros - const formattedMinutes = minutes < 10 ? "0" + minutes : minutes; - const formattedSeconds = seconds < 10 ? "0" + seconds : seconds; + // Adds a leading zero if the minutes are less than 10. + // This ensures the clock always looks like "09:00" rather than "9:00". + let formattedMinutes = `${minutes}`; + if (minutes < 10) { + formattedMinutes = `0${minutes}`; + } + + // Adds a leading zero if the seconds are less than 10. + let formattedSeconds = `${seconds}`; + if (seconds < 10) { + formattedSeconds = `0${seconds}`; + } - return "Time Remaining: " + formattedMinutes + ":" + formattedSeconds; + return `Time Remaining: ${formattedMinutes}:${formattedSeconds}`; } /** - * Updates the display and handles the alarm trigger logic. - * Called every second by the interval. + * Updates the display and checks if the alarm should sound. + * This function runs every second. */ function updateTime() { - // Update display - const title = document.getElementById("timeRemaining"); - title.innerText = formatTime(timeRemaining); + // Finds the title element on the web page to update the text. + const titleElement = document.getElementById("timeRemaining"); + + // Updates the text inside the title element with the new formatted time. + titleElement.innerText = formatTime(timeRemainingInSeconds); - // Check if alarm should trigger - if (timeRemaining === 0) { + // Checks if the countdown has finished. + if (timeRemainingInSeconds === 0) { + // Plays the alarm sound to alert the user. playAlarm(); - // Change background color to flash + // Changes the background colour to red (visual alert) by adding a CSS class. document.body.classList.add("flash"); } else { - // Decrement time - timeRemaining = timeRemaining - 1; + // If time is not up, decreases the remaining time by exactly one second. + timeRemainingInSeconds = timeRemainingInSeconds - 1; } } /** - * Sets the alarm based on user input. - * Called when the "Set Alarm" button is clicked. + * Starts the alarm countdown based on the time the user entered. + * This function runs when the "Set Alarm" button is clicked. */ function setAlarm() { - // Clear any existing interval - if (alarmInterval) { - clearInterval(alarmInterval); + // check if a timer is already active. + // If so, stops the current timer to prevent two timers running at once. + if (alarmTimerIdentifier) { + clearInterval(alarmTimerIdentifier); + + // Resets the background colour in case it was already flashing. document.body.classList.remove("flash"); } - const input = document.getElementById("alarmSet"); - const inputValue = parseInt(input.value); + // Finds the input box where the user typed the number of seconds. + const timeInput = document.getElementById("alarmSet"); + + // Converts the text input into a whole number (integer). + const startingTime = parseInt(timeInput.value); + + // Validates the input: ensuring it is a number. + if (isNaN(startingTime)) { + return; + } - // Validate input - if (isNaN(inputValue) || inputValue < 0) { + // Validates the input: ensuring it is not negative. + if (startingTime < 0) { return; } - timeRemaining = inputValue; + // Updates the state variable with the new start time. + timeRemainingInSeconds = startingTime; - // Update display immediately - const title = document.getElementById("timeRemaining"); - title.innerText = formatTime(timeRemaining); + // Updates the screen immediately so the user sees the start time without delay. + const titleElement = document.getElementById("timeRemaining"); + titleElement.innerText = formatTime(timeRemainingInSeconds); - // Start countdown interval - alarmInterval = setInterval(function () { + // Starts a repeating timer that calls 'updateTime' every second (1000ms). + alarmTimerIdentifier = setInterval(() => { updateTime(); - }, 1000); + }, ONE_SECOND_IN_MILLISECONDS); } // DO NOT EDIT BELOW HERE From 1aff7c84735d90fde9208790c571ca3a24a0895f Mon Sep 17 00:00:00 2001 From: Samuel Tarawally <41825140+Tarawally@users.noreply.github.com> Date: Fri, 12 Dec 2025 17:54:18 +0000 Subject: [PATCH 05/11] style: revert to standard basic ui layout --- Sprint-3/alarmclock/style.css | 78 +++++++++++++++-------------------- 1 file changed, 34 insertions(+), 44 deletions(-) diff --git a/Sprint-3/alarmclock/style.css b/Sprint-3/alarmclock/style.css index a2ddb3d2c..ee911db46 100644 --- a/Sprint-3/alarmclock/style.css +++ b/Sprint-3/alarmclock/style.css @@ -1,94 +1,84 @@ body { - background-color: #1a1a1a; - font-family: 'Courier New', Courier, monospace; - color: #00ff00; + background-color: #f0f0f0; + font-family: Arial, Helvetica, sans-serif; + color: #333; display: flex; justify-content: center; align-items: center; min-height: 100vh; margin: 0; - transition: background-color 0.5s ease; } .flash { - animation: flash-bg 0.5s infinite alternate; -} - -@keyframes flash-bg { - from { background-color: #ff0000; } - to { background-color: #330000; } + background-color: #ffcccc !important; /* Pastel red for alarm */ } .container { - background-color: #000; - border: 4px solid #333; - border-radius: 20px; - padding: 40px; - box-shadow: 0 0 20px rgba(0, 255, 0, 0.2); + background-color: #ffffff; + border: 1px solid #ccc; + border-radius: 8px; + padding: 30px; + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); text-align: center; max-width: 500px; width: 90%; } h1 { - font-size: 3rem; - margin-bottom: 30px; - text-shadow: 0 0 10px #00ff00; + font-size: 2.5rem; + margin-bottom: 20px; + color: #333; } .input-group { - margin-bottom: 25px; + margin-bottom: 20px; } label { display: block; - margin-bottom: 10px; - font-size: 1.2rem; + margin-bottom: 8px; + font-size: 1.1rem; } input { - background-color: #111; - border: 2px solid #00ff00; - color: #00ff00; padding: 10px; - font-size: 1.5rem; - border-radius: 5px; - width: 120px; + font-size: 1.2rem; + border: 1px solid #ccc; + border-radius: 4px; + width: 100px; text-align: center; - font-family: inherit; } input:focus { outline: none; - box-shadow: 0 0 15px rgba(0, 255, 0, 0.3); + border-color: #007bff; } .controls { display: flex; - gap: 15px; + gap: 10px; justify-content: center; } button { - background-color: #1a1a1a; - color: #00ff00; - border: 2px solid #00ff00; + background-color: #007bff; + color: white; + border: none; padding: 10px 20px; - font-size: 1.1rem; + font-size: 1rem; cursor: pointer; - border-radius: 5px; - font-family: inherit; - font-weight: bold; - transition: all 0.2s; - text-transform: uppercase; + border-radius: 4px; + transition: background-color 0.2s; } button:hover { - background-color: #00ff00; - color: #000; - box-shadow: 0 0 15px #00ff00; + background-color: #0056b3; +} + +button#stop { + background-color: #dc3545; } -button:active { - transform: translateY(2px); +button#stop:hover { + background-color: #a71d2a; } From f08fbfc06dcae3637192c7fc9f7b78d37177342c Mon Sep 17 00:00:00 2001 From: Samuel Tarawally <41825140+Tarawally@users.noreply.github.com> Date: Sat, 13 Dec 2025 01:34:47 +0000 Subject: [PATCH 06/11] feat: implement core functionality and UI enhancements --- Sprint-3/alarmclock/alarmclock.js | 58 +++++++++---------------------- Sprint-3/alarmclock/index.html | 2 +- Sprint-3/alarmclock/style.css | 17 +++++++-- 3 files changed, 33 insertions(+), 44 deletions(-) diff --git a/Sprint-3/alarmclock/alarmclock.js b/Sprint-3/alarmclock/alarmclock.js index c077d59f0..09ce0ba29 100644 --- a/Sprint-3/alarmclock/alarmclock.js +++ b/Sprint-3/alarmclock/alarmclock.js @@ -1,35 +1,20 @@ -// Use a constant for the one-second interval to make the code easier to read. const ONE_SECOND_IN_MILLISECONDS = 1000; -// Defines variables to track the state of the alarm clock. -// Uses 'let' because these values will change as the timer runs. let timeRemainingInSeconds = 0; let alarmTimerIdentifier = null; -// DOM Elements (will be fetched dynamically in functions to avoid load issues) - /** - * Formats a number of seconds into a standard "MM:SS" string. - * This helps the user read the time easily (e.g., "01:30" instead of "90"). - * - * @param {number} totalSeconds - The total number of seconds to format. - * @returns {string} A string formatted as "MM:SS". + * Formats seconds into "MM:SS". */ function formatTime(totalSeconds) { - // Calculates the number of full minutes. const minutes = Math.floor(totalSeconds / 60); - - // Calculates the remaining seconds after removing the minutes. const seconds = totalSeconds % 60; - // Adds a leading zero if the minutes are less than 10. - // This ensures the clock always looks like "09:00" rather than "9:00". let formattedMinutes = `${minutes}`; if (minutes < 10) { formattedMinutes = `0${minutes}`; } - // Adds a leading zero if the seconds are less than 10. let formattedSeconds = `${seconds}`; if (seconds < 10) { formattedSeconds = `0${seconds}`; @@ -40,71 +25,62 @@ function formatTime(totalSeconds) { /** * Updates the display and checks if the alarm should sound. - * This function runs every second. */ function updateTime() { - // Finds the title element on the web page to update the text. const titleElement = document.getElementById("timeRemaining"); - // Updates the text inside the title element with the new formatted time. + timeRemainingInSeconds = timeRemainingInSeconds - 1; titleElement.innerText = formatTime(timeRemainingInSeconds); - // Checks if the countdown has finished. if (timeRemainingInSeconds === 0) { - // Plays the alarm sound to alert the user. playAlarm(); - - // Changes the background colour to red (visual alert) by adding a CSS class. document.body.classList.add("flash"); - } else { - // If time is not up, decreases the remaining time by exactly one second. - timeRemainingInSeconds = timeRemainingInSeconds - 1; + clearInterval(alarmTimerIdentifier); } } /** - * Starts the alarm countdown based on the time the user entered. - * This function runs when the "Set Alarm" button is clicked. + * Initialises the alarm countdown. */ function setAlarm() { - // check if a timer is already active. - // If so, stops the current timer to prevent two timers running at once. if (alarmTimerIdentifier) { clearInterval(alarmTimerIdentifier); - - // Resets the background colour in case it was already flashing. document.body.classList.remove("flash"); } - // Finds the input box where the user typed the number of seconds. const timeInput = document.getElementById("alarmSet"); + const startingTime = parseInt(timeInput.value, 10); - // Converts the text input into a whole number (integer). - const startingTime = parseInt(timeInput.value); - - // Validates the input: ensuring it is a number. if (isNaN(startingTime)) { return; } - // Validates the input: ensuring it is not negative. if (startingTime < 0) { return; } - // Updates the state variable with the new start time. timeRemainingInSeconds = startingTime; - // Updates the screen immediately so the user sees the start time without delay. + // Initialise the audio context to enable autoplay. + audio.play(); + audio.pause(); + const titleElement = document.getElementById("timeRemaining"); titleElement.innerText = formatTime(timeRemainingInSeconds); - // Starts a repeating timer that calls 'updateTime' every second (1000ms). alarmTimerIdentifier = setInterval(() => { updateTime(); }, ONE_SECOND_IN_MILLISECONDS); } +// Add a listener to stop the flashing effect without modifying the protected pauseAlarm function below. +const stopButton = document.getElementById("stop"); +if (stopButton) { + stopButton.addEventListener("click", () => { + document.body.classList.remove("flash"); + }); +} + // DO NOT EDIT BELOW HERE var audio = new Audio("alarmsound.mp3"); diff --git a/Sprint-3/alarmclock/index.html b/Sprint-3/alarmclock/index.html index 887f5559e..c0ae6b482 100644 --- a/Sprint-3/alarmclock/index.html +++ b/Sprint-3/alarmclock/index.html @@ -4,7 +4,7 @@ - Title here + Alarm clock app
diff --git a/Sprint-3/alarmclock/style.css b/Sprint-3/alarmclock/style.css index ee911db46..785e85f58 100644 --- a/Sprint-3/alarmclock/style.css +++ b/Sprint-3/alarmclock/style.css @@ -10,11 +10,24 @@ body { } .flash { - background-color: #ffcccc !important; /* Pastel red for alarm */ + animation: flash-animation 1s infinite; +} + +/* Flashing background colour animation */ +@keyframes flash-animation { + 0% { + background-color: #ffcccc; + } + 50% { + background-color: #ff0000; + } + 100% { + background-color: #ffcccc; + } } .container { - background-color: #ffffff; + background-color: #fff; border: 1px solid #ccc; border-radius: 8px; padding: 30px; From 734208260ab40d94cdfecd7a504935329fa89a1f Mon Sep 17 00:00:00 2001 From: Samuel Tarawally <41825140+Tarawally@users.noreply.github.com> Date: Mon, 15 Dec 2025 20:43:38 +0000 Subject: [PATCH 07/11] refactor: simplify time formatting with padStart --- Sprint-3/alarmclock/alarmclock.js | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/Sprint-3/alarmclock/alarmclock.js b/Sprint-3/alarmclock/alarmclock.js index 09ce0ba29..5266d19dc 100644 --- a/Sprint-3/alarmclock/alarmclock.js +++ b/Sprint-3/alarmclock/alarmclock.js @@ -10,15 +10,8 @@ function formatTime(totalSeconds) { const minutes = Math.floor(totalSeconds / 60); const seconds = totalSeconds % 60; - let formattedMinutes = `${minutes}`; - if (minutes < 10) { - formattedMinutes = `0${minutes}`; - } - - let formattedSeconds = `${seconds}`; - if (seconds < 10) { - formattedSeconds = `0${seconds}`; - } + const formattedMinutes = String(minutes).padStart(2, '0'); + const formattedSeconds = String(seconds).padStart(2, '0'); return `Time Remaining: ${formattedMinutes}:${formattedSeconds}`; } From 8f1a66774434809ef6f47f13809876fe7a7c0e3b Mon Sep 17 00:00:00 2001 From: Samuel Tarawally <41825140+Tarawally@users.noreply.github.com> Date: Mon, 15 Dec 2025 20:59:58 +0000 Subject: [PATCH 08/11] fix: reset timer identifier after alarm completes --- Sprint-3/alarmclock/alarmclock.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Sprint-3/alarmclock/alarmclock.js b/Sprint-3/alarmclock/alarmclock.js index 5266d19dc..395e4aae8 100644 --- a/Sprint-3/alarmclock/alarmclock.js +++ b/Sprint-3/alarmclock/alarmclock.js @@ -1,3 +1,5 @@ +const titleElement = document.getElementById("timeRemaining"); + const ONE_SECOND_IN_MILLISECONDS = 1000; let timeRemainingInSeconds = 0; @@ -20,8 +22,6 @@ function formatTime(totalSeconds) { * Updates the display and checks if the alarm should sound. */ function updateTime() { - const titleElement = document.getElementById("timeRemaining"); - timeRemainingInSeconds = timeRemainingInSeconds - 1; titleElement.innerText = formatTime(timeRemainingInSeconds); @@ -29,6 +29,7 @@ function updateTime() { playAlarm(); document.body.classList.add("flash"); clearInterval(alarmTimerIdentifier); + alarmTimerIdentifier = null; // ← reset to null for proper state management } } @@ -58,7 +59,6 @@ function setAlarm() { audio.play(); audio.pause(); - const titleElement = document.getElementById("timeRemaining"); titleElement.innerText = formatTime(timeRemainingInSeconds); alarmTimerIdentifier = setInterval(() => { From fbc7a5606c64c802bbf8fcf4dd5ca3e30d90cb87 Mon Sep 17 00:00:00 2001 From: Samuel Tarawally <41825140+Tarawally@users.noreply.github.com> Date: Mon, 15 Dec 2025 21:05:09 +0000 Subject: [PATCH 09/11] refactor: extract display update logic into separate function --- Sprint-3/alarmclock/alarmclock.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/Sprint-3/alarmclock/alarmclock.js b/Sprint-3/alarmclock/alarmclock.js index 395e4aae8..3d9948ac8 100644 --- a/Sprint-3/alarmclock/alarmclock.js +++ b/Sprint-3/alarmclock/alarmclock.js @@ -23,16 +23,24 @@ function formatTime(totalSeconds) { */ function updateTime() { timeRemainingInSeconds = timeRemainingInSeconds - 1; - titleElement.innerText = formatTime(timeRemainingInSeconds); + displayTime(); if (timeRemainingInSeconds === 0) { playAlarm(); document.body.classList.add("flash"); clearInterval(alarmTimerIdentifier); - alarmTimerIdentifier = null; // ← reset to null for proper state management + alarmTimerIdentifier = null; // Reset to null for proper state management } } +/** + * Displays the remaining time. + */ +function displayTime() { + const titleElement = document.getElementById("timeRemaining"); + titleElement.innerText = formatTime(timeRemainingInSeconds); +} + /** * Initialises the alarm countdown. */ @@ -59,7 +67,7 @@ function setAlarm() { audio.play(); audio.pause(); - titleElement.innerText = formatTime(timeRemainingInSeconds); + displayTime(); alarmTimerIdentifier = setInterval(() => { updateTime(); From 548ef162d838d62e631d29d522f1b6a06fd46563 Mon Sep 17 00:00:00 2001 From: Samuel Tarawally <41825140+Tarawally@users.noreply.github.com> Date: Mon, 15 Dec 2025 21:08:10 +0000 Subject: [PATCH 10/11] fix: handle zero-second alarm edge case --- Sprint-3/alarmclock/alarmclock.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Sprint-3/alarmclock/alarmclock.js b/Sprint-3/alarmclock/alarmclock.js index 3d9948ac8..888d37a48 100644 --- a/Sprint-3/alarmclock/alarmclock.js +++ b/Sprint-3/alarmclock/alarmclock.js @@ -26,11 +26,15 @@ function updateTime() { displayTime(); if (timeRemainingInSeconds === 0) { + titleElement.innerText = formatTime(0); playAlarm(); document.body.classList.add("flash"); - clearInterval(alarmTimerIdentifier); - alarmTimerIdentifier = null; // Reset to null for proper state management + return; } + + alarmTimerIdentifier = setInterval(() => { + updateTime(); + }, ONE_SECOND_IN_MILLISECONDS); } /** From 426f1fb09f7400aba7defd6010ac8c8f64492d5d Mon Sep 17 00:00:00 2001 From: Samuel Tarawally <41825140+Tarawally@users.noreply.github.com> Date: Mon, 15 Dec 2025 22:10:20 +0000 Subject: [PATCH 11/11] fix: correct timer logic and prevent multiple intervals --- Sprint-3/alarmclock/alarmclock.js | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/Sprint-3/alarmclock/alarmclock.js b/Sprint-3/alarmclock/alarmclock.js index 888d37a48..9372aa9eb 100644 --- a/Sprint-3/alarmclock/alarmclock.js +++ b/Sprint-3/alarmclock/alarmclock.js @@ -18,6 +18,13 @@ function formatTime(totalSeconds) { return `Time Remaining: ${formattedMinutes}:${formattedSeconds}`; } +/** + * Displays the remaining time. + */ +function displayTime() { + titleElement.innerText = formatTime(timeRemainingInSeconds); +} + /** * Updates the display and checks if the alarm should sound. */ @@ -26,23 +33,11 @@ function updateTime() { displayTime(); if (timeRemainingInSeconds === 0) { - titleElement.innerText = formatTime(0); playAlarm(); document.body.classList.add("flash"); - return; + clearInterval(alarmTimerIdentifier); + alarmTimerIdentifier = null; } - - alarmTimerIdentifier = setInterval(() => { - updateTime(); - }, ONE_SECOND_IN_MILLISECONDS); -} - -/** - * Displays the remaining time. - */ -function displayTime() { - const titleElement = document.getElementById("timeRemaining"); - titleElement.innerText = formatTime(timeRemainingInSeconds); } /** @@ -73,6 +68,13 @@ function setAlarm() { displayTime(); + // Handle zero-second edge case + if (timeRemainingInSeconds === 0) { + playAlarm(); + document.body.classList.add("flash"); + return; + } + alarmTimerIdentifier = setInterval(() => { updateTime(); }, ONE_SECOND_IN_MILLISECONDS);