Step-by-Step Implementation of the Project
Step-by-Step Implementation of the Countdown Timer
This module shows how to build the app step by step.
Set up the environment.
First, open a terminal or command prompt. We use create-react-app (CRA) to scaffold the project, which handles all configuration. Run:
npx create-react-app countdown-timer– this creates a new folder countdown-timer with a React project.cd countdown-timer– move into the project directory.npm start– this starts the development server; you should see the app running at http://localhost:3000/ in your browser.
These commands set up the React app with no extra config. The npm start command runs the app in development mode. You’ll see the default React welcome page; we will replace its contents.
Create Application Structure (Directory Structure).
The create-react-app command generated a folder structure like this:
countdown-timer/
├── README.md
├── node_modules/
├── package.json
├── public/
│ ├── favicon.ico
│ ├── index.html
│ └── ...
└── src/
├── App.css
├── App.js
├── index.css
├── index.js
└── …
- public/index.html: The main HTML file, contains a <div id="root"> where React inserts our app. We generally don’t need to modify this much.
- src/index.js: The JavaScript entry point. It renders the <App /> component into the page.
- src/App.js: The main React component file. We’ll write our countdown logic and UI here.
- src/App.css (and other .css files): Styling for the components. We can style our timer and layout here.
- package.json: Lists project dependencies (like React) and scripts (start, build, etc.).
Steps needed (Implementation)
Now we implement the countdown logic. We will edit the files in src/ as follows:
1. src/App.css: Add some basic styles to make our app look nice. For example:
/* Full-page background with gradient */
body {
margin: 0;
padding: 0;
background: linear-gradient(135deg, #667eea, #764ba2);
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
color: #fff;
}
/* Center content */
.container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
text-align: center;
}
/* Title */
h1 {
font-size: 3rem;
margin-bottom: 20px;
text-shadow: 2px 2px 6px rgba(0, 0, 0, 0.4);
}
/* Input + button row */
.inputs {
background: rgba(255, 255, 255, 0.1);
padding: 20px;
border-radius: 16px;
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.3);
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 10px;
}
/* Inputs */
input {
width: 100px;
padding: 10px;
border: none;
border-radius: 8px;
font-size: 16px;
text-align: center;
outline: none;
transition: 0.2s;
}
input:focus {
transform: scale(1.05);
box-shadow: 0 0 8px rgba(255, 255, 255, 0.8);
}
/* Button */
button {
padding: 10px 20px;
border: none;
border-radius: 8px;
font-size: 16px;
background: #ff6b6b;
color: white;
cursor: pointer;
transition: background 0.3s, transform 0.2s;
}
button:hover {
background: #ff4757;
transform: translateY(-2px);
}
button:active {
transform: translateY(0);
}
/* Countdown display */
.timer-display {
margin-top: 30px;
font-size: 2rem;
font-weight: bold;
background: rgba(0, 0, 0, 0.25);
padding: 20px 40px;
border-radius: 12px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4);
display: inline-block;
}
/* Finished message */
.timer-display span {
color: #ffd32a;
font-size: 1.8rem;
}Here we center the content, set a pleasing background gradient, and style the inputs and timer text. This CSS class .timer-display will format the countdown text.
2. src/App.js: Implement the main component with state and timer logic. Below is a complete code with comments:
import React, { useState, useEffect } from 'react';
import './App.css';
function App() {
// States for input fields
const [days, setDays] = useState(0);
const [hours, setHours] = useState(0);
const [minutes, setMinutes] = useState(0);
const [seconds, setSeconds] = useState(0);
// States for countdown
const [timeLeft, setTimeLeft] = useState(0);
const [running, setRunning] = useState(false);
const [started, setStarted] = useState(false); // tracks if countdown has started at least once
// Handle Start Button
const handleStart = () => {
const total =
days * 24 * 60 * 60 +
hours * 60 * 60 +
minutes * 60 +
seconds;
if (total > 0) {
setTimeLeft(total);
setRunning(true);
setStarted(true); // mark that countdown has begun
}
};
// Effect for timer countdown
useEffect(() => {
if (!running) return;
const intervalId = setInterval(() => {
setTimeLeft((prev) => {
if (prev <= 1) {
clearInterval(intervalId);
setRunning(false);
return 0;
}
return prev - 1;
});
}, 1000);
return () => clearInterval(intervalId);
}, [running]);
// Convert seconds into d:h:m:s
const d = Math.floor(timeLeft / (24 * 3600));
const h = Math.floor((timeLeft % (24 * 3600)) / 3600);
const m = Math.floor((timeLeft % 3600) / 60);
const s = timeLeft % 60;
return (
<div className="container">
<h1>Countdown Timer</h1>
<div className="inputs">
<input
type="number"
min="0"
placeholder="Days"
onChange={(e) => setDays(parseInt(e.target.value) || 0)}
/>
<input
type="number"
min="0"
placeholder="Hours"
onChange={(e) => setHours(parseInt(e.target.value) || 0)}
/>
<input
type="number"
min="0"
placeholder="Minutes"
onChange={(e) => setMinutes(parseInt(e.target.value) || 0)}
/>
<input
type="number"
min="0"
placeholder="Seconds"
onChange={(e) => setSeconds(parseInt(e.target.value) || 0)}
/>
<button onClick={handleStart}>Start</button>
</div>
<div className="timer-display">
{running && timeLeft > 0 ? (
`${d} days : ${h} hours : ${m} minutes : ${s} seconds`
) : !running && started && timeLeft === 0 ? (
<span>Countdown finished!</span>
) : (
<span>Start the countdown!</span>
)}
</div>
</div>
);
}
export default App;- Imports: We import React, the useState and useEffect hooks, and our CSS.
- State Variables: We have state for each input (days, hours, minutes, seconds) and also timeLeft (total seconds remaining) and running (a boolean to know if the timer is active).
- handleStart(): When the user clicks Start, we compute the total seconds (total) from the four inputs. We then set timeLeft = total and set running = true to begin the timer.
- useEffect: This hook watches running. When running is true, it sets up a setInterval that runs every 1000 ms (1 second). Each tick it decrements timeLeft. If timeLeft hits 0 or less, we clear the interval, stop running, and ensure timeLeft is 0. The cleanup function clears the interval if the component is unmounted or if running changes.
- Display: We compute the days/hours/minutes/seconds remaining from timeLeft. If timeLeft > 0, we show the countdown (d days : h hours : m minutes : s seconds). Once timeLeft is 0, we display “Countdown finished!”. (If the timer was running and just hit 0, running becomes false, so we show the finished message.)
This completes the main functionality: the user inputs a duration, clicks Start, and sees the countdown update every second with styled formatting.











