ComponentsCountdown Timer

Credit goes to alberduris for re-creating this ShipFast component.

Table of Contents:

A countdown timer showing days, hours, minutes, and seconds left. Can be used for counting down till Product Hunt launch.

Countdown Timer Component

Code

/components/CountdownTimer.tsx

1"use client";
2
3import React from "react";
4
5type CountdownTimerProps = {
6  days: number | string;
7  hours: number | string;
8  minutes: number | string;
9  seconds: number | string;
10};
11
12const CountdownTimer = ({
13  initialTimeLeft,
14}: {
15  initialTimeLeft: CountdownTimerProps;
16}) => {
17  const [timeLeft, setTimeLeft] = React.useState(initialTimeLeft);
18
19  const calculateTimeLeft = () => {
20    const difference = +new Date("2024-02-01") - +new Date();
21    let timeLeft = { days: 0, hours: 0, minutes: 0, seconds: 0 };
22
23    if (difference > 0) {
24      timeLeft = {
25        days: Math.floor(difference / (1000 * 60 * 60 * 24)),
26        hours: Math.floor((difference / (1000 * 60 * 60)) % 24),
27        minutes: Math.floor((difference / 1000 / 60) % 60),
28        seconds: Math.floor((difference / 1000) % 60), // Calculate seconds
29      };
30    }
31
32    return timeLeft;
33  };
34
35  React.useEffect(() => {
36    const timer = setTimeout(() => {
37      setTimeLeft(calculateTimeLeft());
38    }, 1000); // Update every second
39    return () => clearTimeout(timer); // Clear the timer on component unmount
40  }, [timeLeft]);
41
42  return (
43    <div>
44      <p className="text-base text-gray-600 dark:text-gray-400 mb-2">
45        The Starter Kit is launching soon...
46      </p>
47      <div className="flex gap-4 text-center bg-white dark:bg-secondary shadow-lg rounded-lg p-3 md:p-4">
48        <div>
49          <p className="text-lg font-extrabold text-gray-900 dark:text-gray-100">
50            {timeLeft.days}
51          </p>
52          <p className="text-primary">Days</p>
53        </div>
54        <div>
55          <p className="text-lg font-extrabold text-gray-900 dark:text-gray-100">
56            {timeLeft.hours}
57          </p>
58          <p className="text-primary">Hours</p>
59        </div>
60        <div>
61          <p className="text-lg font-extrabold text-gray-900 dark:text-gray-100">
62            {timeLeft.minutes}
63          </p>
64          <p className="text-primary">Minutes</p>
65        </div>
66        <div>
67          <p className="text-lg font-extrabold text-gray-900 dark:text-gray-100">
68            {timeLeft.seconds}
69          </p>
70          <p className="text-primary">Seconds</p>
71        </div>
72      </div>
73    </div>
74  );
75};
76
77export default CountdownTimer;

Usage

/components/Pricing.tsx

1import CountdownTimer from "./CountdownTimer";
2
3const Pricing = () => {
4  return (
5    <>
6      <section>
7        ...
8        <CountdownTimer initialTimeLeft={10} />
9        ...
10      </section>
11    </>
12  );
13};
14
15export default Pricing;