Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 56 additions & 2 deletions Sprint-3/alarmclock/alarmclock.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,59 @@
function setAlarm() {}
let countdown;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider renaming countdown to countdownInterval or intervalId since this stores the interval ID, not the countdown value.


function setAlarm() {
clearInterval(countdown);
document.body.style.backgroundColor = "white";
Comment on lines +4 to +5
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently when starting a new countdown, the application does not always return to a clean initial state,
which can lead to inconsistent behavior between runs.

Hint: a user may not click the "Stop" button first before starting a new count down.

You can also consider introducing a dedicated reset function to return the app to a clean initial state to help ensure consistency. There are few places in this script you can call this reset function instead of repeating the reset logic.


let inputTime = Number(document.getElementById("alarmSet").value);

if (isNaN(inputTime) || inputTime <= 0) {
alert("Please type or select your time 👇⏰");
return;
}
Comment on lines +7 to +12
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What type of numbers should inputTime be? (Currently some input value can corrupt the timer display)


updateDisplay(inputTime);

countdown = setInterval(() => {
inputTime--;

if (inputTime <= 0) {
clearInterval(countdown);
updateDisplay(0);
playAlarm();

let repetitions = 0;
countdown = setInterval(() => {
document.body.style.backgroundColor = `rgb(
${Math.floor(Math.random() * 256)},
${Math.floor(Math.random() * 256)},
${Math.floor(Math.random() * 256)})`;
repetitions++;

if (repetitions > 100) {
clearInterval(countdown);
}
Comment on lines +24 to +34
Copy link
Copy Markdown
Contributor

@cjyuan cjyuan Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is best practice to separate presentation logic from application logic.
Can you either implementing the background animation in CSS or move the code that perform the animation into a separate function?

Note: CSS random() function is still in experimental stage. With pure CSS, we can only cycle through a pre-defined set of colors (e.g. https://codepen.io/beben-koben/pen/eYPNew)

If you are implementing this purely in CSS, you can consider defining a CSS class, and use classList.toggle() to apply/remove the style. For example,

document.body.classList.toggle("alarm-activated", true);  // apply style
document.body.classList.toggle("alarm-activated", false); // remove style

}, 200);
} else {
updateDisplay(inputTime);
}
}, 1000);
}

function updateDisplay(seconds) {
let minutes = Math.floor(seconds / 60);
let remainingSeconds = seconds % 60;

let display = `Time Remaining: ${minutes
.toString()
.padStart(2, "0")}:${remainingSeconds.toString().padStart(2, "0")}`;
Comment on lines +46 to +48
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having a long expression within a template string literal can make the code harder to read.
Better to use an inline function to perform the repeated task, or to store the formatted
values in variables first.


document.getElementById("timeRemaining").innerText = display;
}

// DO NOT EDIT BELOW HERE

var audio = new Audio("alarmsound.mp3");
let audio = new Audio("assets/trebolClan.mp3");
let stopAudio = new Audio("assets/stopAlarm.mp3");

function setup() {
document.getElementById("set").addEventListener("click", () => {
Expand All @@ -20,6 +71,9 @@ function playAlarm() {

function pauseAlarm() {
audio.pause();
stopAudio.play();
audio.currentTime = 0;
clearInterval(countdown);
}

window.onload = setup;
Binary file added Sprint-3/alarmclock/assets/favicon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Sprint-3/alarmclock/assets/stopAlarm.mp3
Binary file not shown.
Binary file added Sprint-3/alarmclock/assets/trebolClan.mp3
Binary file not shown.
10 changes: 8 additions & 2 deletions Sprint-3/alarmclock/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,19 @@
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="style.css" />
<title>Title here</title>
<meta
name="description"
content="This page is an alarm clock with an alert to aware the user type or
select the time. This include two sound effects"
/>
<link rel="icon" type="image/png" href="assets/favicon.png" />
<title>Alarm clock app</title>
</head>
<body>
<div class="centre">
<h1 id="timeRemaining">Time Remaining: 00:00</h1>
<label for="alarmSet">Set time to:</label>
<input id="alarmSet" type="number" />
<input id="alarmSet" type="number" placeholder="Type or select the time -->" min="0" step="1"/>

<button id="set" type="button">Set Alarm</button>
<button id="stop" type="button">Stop Alarm</button>
Expand Down
62 changes: 56 additions & 6 deletions Sprint-3/alarmclock/style.css
Original file line number Diff line number Diff line change
@@ -1,15 +1,65 @@


body{
background-color: #f7f3f2;
color: #333;
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}

.centre {
position: fixed;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
padding: 2rem 2rem;
border-radius: 12px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.8);
text-align: center;
}

/* Input Field */
#alarmSet {
margin: 20px;
margin: 1rem ;
padding: 1rem;
border: 1px solid #ccc;
border-radius: 6px;
font-size: 1rem;
max-width: 300px;
box-sizing: border-box;
}

#alarmSet::placeholder {
color: #888;
font-style: italic;
font-family: 'Arial', sans-serif;
font-size: 0.8rem;
}

h1 {
text-align: center;
}

/* Button */
button {
background-color: #6c63ff;
color: white;
border: none;
border-radius: 6px;
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
transition: background-color 0.3s ease, transform 0.2s ease;
}

button:hover {
background-color: #dedee8;
color: #6c63ff;
transform: translateY(-2px);
}

button:active {
background-color: #4b47b0;
transform: translateY(0);
}
Loading