From 35fceee933fcb2aea8936ed5e6e2c76ee40ffc4a Mon Sep 17 00:00:00 2001 From: cywong Date: Wed, 29 Jul 2026 14:36:37 +0100 Subject: [PATCH 1/6] Fix console log to access houseNumber in address object Updated console log to correctly access houseNumber property. --- Sprint-2/debug/address.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Sprint-2/debug/address.js b/Sprint-2/debug/address.js index 940a6af83..8ae16a9f3 100644 --- a/Sprint-2/debug/address.js +++ b/Sprint-2/debug/address.js @@ -12,4 +12,9 @@ const address = { postcode: "XYZ 123", }; -console.log(`My house number is ${address[0]}`); +console.log(`My house number is ${address.houseNumber}`); + +// "My house number is undefined" +// The reason is that it is an object and not array +// The correct statement is to use the dot operator to access the related field. +// In this case, the property/field name should be houseNumber in the object address From 93943228c74d5e96c9099159be83a1b814144b08 Mon Sep 17 00:00:00 2001 From: cywong Date: Wed, 29 Jul 2026 14:40:59 +0100 Subject: [PATCH 2/6] Fix iteration over author object Replace for...of loop with for...in loop to iterate over object properties. --- Sprint-2/debug/author.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Sprint-2/debug/author.js b/Sprint-2/debug/author.js index 8c2125977..b4e617d69 100644 --- a/Sprint-2/debug/author.js +++ b/Sprint-2/debug/author.js @@ -11,6 +11,11 @@ const author = { alive: true, }; -for (const value of author) { - console.log(value); +for (const key in author) { + console.log(author[key]); } + +//TypeError: author is not iterable +// The for...of loop only works on iterable objects in JavaScript—such as Arrays, Strings, Sets, and Maps. +// Plain JavaScript objects ({}) are not iterable by default because they don't have a built-in [Symbol.iterator] method. +// use a for...in loop to step through the keys, then access each value using bracket notation From 637ccab6be8fd211fcec253f33522fb7685115bd Mon Sep 17 00:00:00 2001 From: cywong Date: Wed, 29 Jul 2026 15:11:37 +0100 Subject: [PATCH 3/6] Fix access method for house number in address object Updated console log to access house number using array notation. --- Sprint-2/debug/address.js | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/Sprint-2/debug/address.js b/Sprint-2/debug/address.js index 8ae16a9f3..940a6af83 100644 --- a/Sprint-2/debug/address.js +++ b/Sprint-2/debug/address.js @@ -12,9 +12,4 @@ const address = { postcode: "XYZ 123", }; -console.log(`My house number is ${address.houseNumber}`); - -// "My house number is undefined" -// The reason is that it is an object and not array -// The correct statement is to use the dot operator to access the related field. -// In this case, the property/field name should be houseNumber in the object address +console.log(`My house number is ${address[0]}`); From b7494f786cb052cc0966475214db93cc73ce4063 Mon Sep 17 00:00:00 2001 From: cywong Date: Wed, 29 Jul 2026 15:13:31 +0100 Subject: [PATCH 4/6] Fix iteration method for author object Replaced for...in loop with for...of loop to iterate over author object values. --- Sprint-2/debug/author.js | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/Sprint-2/debug/author.js b/Sprint-2/debug/author.js index b4e617d69..2b17b5fae 100644 --- a/Sprint-2/debug/author.js +++ b/Sprint-2/debug/author.js @@ -11,11 +11,6 @@ const author = { alive: true, }; -for (const key in author) { - console.log(author[key]); +for (const value of author) { + console.log(value); } - -//TypeError: author is not iterable -// The for...of loop only works on iterable objects in JavaScript—such as Arrays, Strings, Sets, and Maps. -// Plain JavaScript objects ({}) are not iterable by default because they don't have a built-in [Symbol.iterator] method. -// use a for...in loop to step through the keys, then access each value using bracket notation From 42e07b83e8695a09ee12b4a195749f2d00b9622e Mon Sep 17 00:00:00 2001 From: cywong Date: Mon, 3 Aug 2026 15:18:59 +0100 Subject: [PATCH 5/6] Change title to 'Alarm clock app' --- 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..ff2d3b453 100644 --- a/Sprint-3/alarmclock/index.html +++ b/Sprint-3/alarmclock/index.html @@ -4,7 +4,7 @@ - Title here + Alarm clock app
From 0a19a38dbef8bddbb4df65a236ecede1f5fe9b21 Mon Sep 17 00:00:00 2001 From: cywong Date: Mon, 3 Aug 2026 15:22:10 +0100 Subject: [PATCH 6/6] Implement countdown timer and alarm functionality --- Sprint-3/alarmclock/alarmclock.js | 133 ++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) diff --git a/Sprint-3/alarmclock/alarmclock.js b/Sprint-3/alarmclock/alarmclock.js index 6ca81cd3b..e894db38d 100644 --- a/Sprint-3/alarmclock/alarmclock.js +++ b/Sprint-3/alarmclock/alarmclock.js @@ -1,3 +1,4 @@ +/* function setAlarm() {} // DO NOT EDIT BELOW HERE @@ -23,3 +24,135 @@ function pauseAlarm() { } window.onload = setup; +*/ + + +let countdownInterval = null; +let flashInterval = null; +let timeRemaining = 0; +let isPaused = false; + +function formatTime(totalSeconds) { + const minutes = Math.floor(totalSeconds / 60); + const seconds = totalSeconds % 60; + + const padMinutes = String(minutes).padStart(2, "0"); + const padSeconds = String(seconds).padStart(2, "0"); + + return `${padMinutes}:${padSeconds}`; +} + +function updateDisplay() { + const timeRemainingElement = document.getElementById("timeRemaining"); + if (timeRemainingElement) { + timeRemainingElement.innerText = `Time Remaining: ${formatTime(timeRemaining)}`; + } +} + +function startFlashingBackground() { + let isRed = false; + flashInterval = setInterval(() => { + document.body.style.backgroundColor = isRed ? "#ffffff" : "#ff4d4d"; + isRed = !isRed; + }, 500); +} + +function stopFlashingBackground() { + if (flashInterval) { + clearInterval(flashInterval); + flashInterval = null; + } + document.body.style.backgroundColor = ""; +} + +function setAlarm() { + const alarmInput = document.getElementById("alarmSet"); + + // If currently paused, resume countdown + if (isPaused) { + isPaused = false; + startCountdown(); + return; + } + + // If an active alarm is already running, toggle pause state + if (countdownInterval !== null) { + isPaused = true; + clearInterval(countdownInterval); + countdownInterval = null; + return; + } + + // Read time from input field + const inputSeconds = parseInt(alarmInput.value, 10); + if (isNaN(inputSeconds) || inputSeconds <= 0) { + alert("Please enter a valid number of seconds."); + return; + } + + timeRemaining = inputSeconds; + stopFlashingBackground(); + updateDisplay(); + startCountdown(); +} + +function startCountdown() { + // Clear any existing timer before starting a new one + if (countdownInterval) { + clearInterval(countdownInterval); + } + + countdownInterval = setInterval(() => { + timeRemaining -= 1; + updateDisplay(); + + if (timeRemaining <= 0) { + clearInterval(countdownInterval); + countdownInterval = null; + playAlarm(); + startFlashingBackground(); + } + }, 1000); +} + +// Override pauseAlarm to also clear screen effects and reset timers +const originalPauseAlarm = pauseAlarm; +pauseAlarm = function () { + if (typeof originalPauseAlarm === "function") { + originalPauseAlarm(); + } else { + audio.pause(); + } + + // Reset state + if (countdownInterval) { + clearInterval(countdownInterval); + countdownInterval = null; + } + isPaused = false; + stopFlashingBackground(); +}; + +// DO NOT EDIT BELOW HERE + +var audio = new Audio("alarmsound.mp3"); + +function setup() { + document.getElementById("set").addEventListener("click", () => { + setAlarm(); + }); + + document.getElementById("stop").addEventListener("click", () => { + pauseAlarm(); + }); +} + +function playAlarm() { + audio.play(); +} + +function pauseAlarm() { + audio.pause(); +} + +window.onload = setup;