Description:
I recently completed my first JavaScript project, a Pomodoro clock, without relying on tutorials. I’d like feedback on my code to improve my skills further. Here’s a detailed overview of how I implemented it:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Pomodoro Clock</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<div class="app-title">
<div class="double-line"></div>
<p>Pomodoro Clock</p>
<div class="double-line"></div>
</div>
<div class="adjustment-div">
<div class="break-length-div">
<p class="heading">Break Length</p>
<div class="value-adjustment">
<button class="minus">-</button>
<div class="minutes"></div>
<button class="plus">+</button>
</div>
</div>
<div class="session-length-div">
<p class="heading">Session Length</p>
<div class="value-adjustment">
<button class="minus">-</button>
<div class="minutes"></div>
<button class="plus">+</button>
</div>
</div>
</div>
<div class="session">
<div class="heading">
Start
</div>
<div class="time">
00:00
</div>
</div>
<div class="controls">
<div class="reset-button">
<button>Reset</button>
</div>
<div class="start-button">
<button>Start</button>
</div>
</div>
<div class="remarks">
Designed based on a pen by <u>Edd Yerburgh</u> and code by <u>Crying Wolfe</u>
</div>
</div>
<script src="main.js"></script>
</body>
</html>
The CSS of the clock
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
background-color: #0e9aa7;
font-family: sans-serif;
height: 100%;
margin: 0;
padding-top: 40px;
display: flex;
justify-content: center;
}
.container {
width: 100vh;
height: 90vh;
display: flex;
flex-direction: column;
align-items: center;
}
.app-title {
display: flex;
align-items: center;
}
.double-line {
height: 5px;
width: 200px;
border-top: 2px solid white;
border-bottom: 2px solid white;
}
.app-title p {
color: white;
font-size: 26px;
font-weight: bold;
padding: 0 15px 0 15px;
}
.adjustment-div {
display: flex;
justify-content: space-between;
width: 80%;
}
.break-length-div,
.session-length-div {
display: flex;
flex-direction: column;
align-items: center;
margin-top: 40px;
width: 130px;
}
.break-length-div .heading,
.session-length-div .heading {
color: white;
font-size: 15px;
font-weight: 600;
}
.value-adjustment {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 8px;
width: 90%;
}
.minus,
.plus {
background: transparent;
height: 30px;
width: 30px;
color: #3db9c5;
border: 1px #3db9c5 solid;
border-radius: 3px;
cursor: pointer;
}
.minus:hover,
.plus:hover {
color: #2dd6e6;
border-color: #2dd6e6;
}
.value-adjustment .minutes {
background-color: white;
height: 38px;
width: 38px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
.session {
margin-top: 30px;
height: 280px;
width: 280px;
border-radius: 50%;
border: 5px solid #3db9c5;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
color: white;
position: relative;
}
.session .heading {
font-size: 26px;
font-weight: bold;
position: absolute;
top: 60px;
}
.session .time {
font-size: 76px;
font-weight: bolder;
margin-top: 40px;
}
.controls {
display: flex;
justify-content: space-between;
padding: 0 10px;
margin-top: 30px;
width: 200px;
}
.start-button button,
.reset-button button {
width: 80px;
height: 30px;
background: transparent;
color: white;
border: 2px solid #3db9c5;
border-radius: 5px;
font-size: 18px;
cursor: pointer;
}
.start-button button:hover,
.reset-button button:hover {
border-color: #2dd6e6;
}
.remarks {
margin-top: 40px;
color: #80e4eb;
}
This is my JavaScript
console.log("Happy Coding, with Pomodoro Timer!");
const break_time_adjustments = () => {
// Getting all elements to set the length of Break
const increase_break_time_button = document.querySelector(
".break-length-div .value-adjustment .plus"
),
decrease_break_time_button = document.querySelector(
".break-length-div .value-adjustment .minus"
),
break_time_value = document.querySelector(
".break-length-div .value-adjustment .minutes"
);
// Performing Operations on the elements
let break_time = 5;
break_time_value.innerHTML = break_time;
// Getter function to retrieve the current brake time
const get_break_time = () => break_time;
// Setter funtion to set the update the break time and display it
const set_break_time = (new_time) => {
break_time = new_time;
break_time_value.innerHTML = break_time;
};
// Increasing the length of Break
function increase_break_time() {
set_break_time(break_time + 5); // Increasing the break time by 5
}
increase_break_time_button.addEventListener("click", increase_break_time);
// Decreasing the length of Break
function decrease_break_time() {
if (break_time <= 0) {
break_time = 0;
} else {
set_break_time(break_time - 5); // Decreasing the break time by 5
}
}
decrease_break_time_button.addEventListener("click", decrease_break_time);
return { get_break_time, set_break_time };
};
const { get_break_time, set_break_time } = break_time_adjustments();
break_time_adjustments();
const session_time_adjustments = () => {
// Getting all elements to set the length of a session
const increase_session_time_button = document.querySelector(
".session-length-div .value-adjustment .plus"
),
decrease_session_time_button = document.querySelector(
".session-length-div .value-adjustment .minus"
),
session_time_value = document.querySelector(
".session-length-div .value-adjustment .minutes"
);
// Performing Operations on the elements
let session_time = 25;
session_time_value.innerHTML = session_time;
// Getter function to retrieve the current session time
const get_session_time = () => session_time;
// Setter function to update the session time and display it
const set_session_time = (newTime) => {
session_time = newTime;
session_time_value.innerHTML = session_time;
};
// Increasing the length of Session
function increase_session_time() {
set_session_time(session_time + 5); // Increasing length of Session time by 5
}
increase_session_time_button.addEventListener("click", increase_session_time);
// Decreasing the length of Session
function decrease_session_time() {
if (session_time <= 0) {
session_time = 0;
} else {
set_session_time(session_time - 5); // Decreasing length of Session time by 5
}
}
decrease_session_time_button.addEventListener("click", decrease_session_time);
// Return getter and setter functions
return { get_session_time, set_session_time };
};
const { get_session_time, set_session_time } = session_time_adjustments();
// Initializing a variable to store session interval id
let session_interval_id;
const update_time = (session_duration) => {
// Getting elements to update the Time
const Time = document.querySelector(".time");
const heading = document.querySelector(".session .heading");
heading.innerHTML = "Session";
let minutes = session_duration;
let seconds = 0;
// Updating Time
const timer = setInterval(() => {
if (minutes === 0 && seconds === 0) {
clearInterval(timer); // Stop the timer when it reaches 0
break_time(get_break_time()); // Start the break
// break_time(1); // For testing
return;
}
if (seconds === 0) {
minutes--;
seconds = 59;
} else {
seconds--;
}
Time.innerHTML = `${minutes}:${seconds < 10 ? "0" : ""}${seconds}`;
}, 1000);
session_interval_id = timer;
return timer;
};
// Initializing a varibale to store break time interval id
let break_interval_id;
const break_time = (break_duration_time) => {
//Getting elements to start break time
const Time = document.querySelector(".time");
const heading = document.querySelector(".session .heading");
heading.innerHTML = "Break";
// Starting Break time
let break_duration = break_duration_time;
let minutes = break_duration;
let seconds = 0;
const break_timer = setInterval(() => {
if (minutes === 0 && seconds === 0) {
clearInterval(break_timer); // Stop the timer when it reaches 0
update_time(get_session_time());
// update_time(1); // For Testing
return;
}
if (seconds === 0) {
minutes--;
seconds = 59;
} else {
seconds--;
}
Time.innerHTML = `${minutes}:${seconds < 10 ? "0" : ""}${seconds}`;
}, 1000);
break_interval_id = break_timer;
return break_timer;
};
const start = () => {
// Getting elements to start the clock
const start_button = document.querySelector(".controls .start-button button");
// Flag to check if previous session is already running
let is_session_running = false;
// Starting the clock
function start_clock() {
if (is_session_running) {
clearInterval(session_interval_id); // Clearing previous session
clearInterval(break_interval_id); // Clearing previous break
}
update_time(get_session_time());
// update_time(1); // For Testing
is_session_running = true;
}
start_button.addEventListener("click", start_clock);
};
start();
const stop = () => {
// Getting Elements to stop the clock
const reset_button = document.querySelector(".controls .reset-button button");
const heading = document.querySelector(".session .heading");
const Timer = document.querySelector(".session .time");
// Adding funcionality to stop button
function reset_the_timer() {
clearInterval(session_interval_id);
clearInterval(break_interval_id);
heading.innerHTML = "Start";
Timer.innerHTML = "00:00";
}
reset_button.addEventListener("click", reset_the_timer);
};
stop();
Key Features:
Modularization: I modularized my code by breaking it down into functions for adjusting break and session times, updating the time display, starting the session, and stopping/resetting the clock. This approach promotes code reuse and maintainability.
Event Handling: Event listeners are used to handle user interactions, such as increasing/decreasing break and session times, starting the clock, and resetting it, making the application interactive and user-friendly.
Error Handling: I implemented basic error handling to ensure that session and break times do not become negative and are capped at a minimum of 0.
Functionality: The Pomodoro clock alternates between session and break periods based on user-defined times, providing a functional and intuitive experience.
Request for Feedback:
I would appreciate feedback on the overall structure and readability of my code, as well as suggestions for optimization and improvement. Additionally, any advice on best practices or alternative approaches would be valuable for my learning journey.
Thank you for your time and assistance!