Skip to content

Commit 5d3f414

Browse files
committed
Update countdown timer
1 parent 7a25b15 commit 5d3f414

File tree

2 files changed

+91
-37
lines changed

2 files changed

+91
-37
lines changed
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import { Fragment, useEffect, useState } from "react";
2+
3+
interface CountdownProps {
4+
targetDate: string; // YYYY-MM-DD format
5+
}
6+
7+
interface TimeLeft {
8+
days: number;
9+
hours: number;
10+
minutes: number;
11+
seconds: number;
12+
}
13+
14+
function calculateTimeLeft(targetDate: string): TimeLeft {
15+
const target = new Date(`${targetDate}T00:00:00-08:00`);
16+
const now = new Date();
17+
const difference = +target - +now;
18+
19+
if (difference <= 0) {
20+
return {
21+
days: 0,
22+
hours: 0,
23+
minutes: 0,
24+
seconds: 0,
25+
};
26+
}
27+
28+
return {
29+
days: Math.floor(difference / (1000 * 60 * 60 * 24)),
30+
hours: Math.floor((difference / (1000 * 60 * 60)) % 24),
31+
minutes: Math.floor((difference / 1000 / 60) % 60),
32+
seconds: Math.floor((difference / 1000) % 60),
33+
};
34+
}
35+
36+
const formatNumber = (number: number) => number.toString().padStart(2, "0");
37+
38+
const Countdown: React.FC<CountdownProps> = ({ targetDate }) => {
39+
const [timeLeft, setTimeLeft] = useState<TimeLeft>(
40+
calculateTimeLeft(targetDate)
41+
);
42+
43+
useEffect(() => {
44+
const timer = setInterval(() => {
45+
const newTimeLeft = calculateTimeLeft(targetDate);
46+
setTimeLeft(newTimeLeft);
47+
if (
48+
newTimeLeft.days === 0 &&
49+
newTimeLeft.hours === 0 &&
50+
newTimeLeft.minutes === 0 &&
51+
newTimeLeft.seconds === 0
52+
) {
53+
clearInterval(timer);
54+
}
55+
}, 1000);
56+
57+
return () => clearInterval(timer);
58+
}, [targetDate]);
59+
60+
if (
61+
timeLeft.days === 0 &&
62+
timeLeft.hours === 0 &&
63+
timeLeft.minutes === 0 &&
64+
timeLeft.seconds === 0
65+
) {
66+
return null;
67+
}
68+
69+
return (
70+
<div className="countdown flex gap-2 justify-center">
71+
{["days", "hours", "minutes", "seconds"].map((unit, index) => (
72+
<Fragment key={unit}>
73+
{index > 0 && <span className="h-[2rem] grid place-content-center">:</span>}
74+
<div className={`${unit} grid grid-cols-2 gap-x-1 gap-y-1.5`}>
75+
<span className="h-[2.3rem] aspect-square grid place-content-center rounded-sm bg-brand-beige bg-opacity-10 font-semibold">
76+
{formatNumber(timeLeft[unit as keyof TimeLeft]).charAt(0)}
77+
</span>
78+
<span className="h-[2.3rem] aspect-square grid place-content-center rounded-sm bg-brand-beige bg-opacity-10 font-semibold">
79+
{formatNumber(timeLeft[unit as keyof TimeLeft]).charAt(1)}
80+
</span>
81+
<p className="col-span-full text-xs">{unit}</p>
82+
</div>
83+
</Fragment>
84+
))}
85+
</div>
86+
);
87+
};
88+
89+
export default Countdown;

usehooks.com/src/components/QueryGGBanner.astro

Lines changed: 2 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
---
22
import Button from "./Button.astro";
3+
import CountdownTimer from "./CountdownTimer";
34
---
45

56
<aside class="mx-auto max-w-[1300px] pb-8 flex items-center">
@@ -31,43 +32,7 @@ import Button from "./Button.astro";
3132
>
3233
<div class="my-2 uppercase text-center place-self-center text-[1.1rem]">
3334
<h2 class="mb-3 font-semibold">Launch sale happening now</h2>
34-
<div class="countdown flex gap-2 justify-center">
35-
<div class="days grid grid-cols-2 gap-x-1 gap-y-1.5">
36-
<span
37-
class="h-[2.3rem] aspect-square grid place-content-center rounded-sm bg-brand-beige bg-opacity-10 font-semibold"
38-
>0</span
39-
>
40-
<span
41-
class="h-[2.3rem] aspect-square grid place-content-center rounded-sm bg-brand-beige bg-opacity-10 font-semibold"
42-
>3</span
43-
>
44-
<p class="col-span-full text-xs">days</p>
45-
</div>
46-
<span class="h-[2rem] grid place-content-center">:</span>
47-
<div class="hours grid grid-cols-2 gap-x-1 gap-y-1.5">
48-
<span
49-
class="h-[2.3rem] aspect-square grid place-content-center rounded-sm bg-brand-beige bg-opacity-10 font-semibold"
50-
>2</span
51-
>
52-
<span
53-
class="h-[2.3rem] aspect-square grid place-content-center rounded-sm bg-brand-beige bg-opacity-10 font-semibold"
54-
>1</span
55-
>
56-
<p class="col-span-full text-xs">hours</p>
57-
</div>
58-
<span class="h-[2rem] grid place-content-center">:</span>
59-
<div class="minutes grid grid-cols-2 gap-x-1 gap-y-1.5">
60-
<span
61-
class="h-[2.3rem] aspect-square grid place-content-center rounded-sm bg-brand-beige bg-opacity-10 font-semibold"
62-
>1</span
63-
>
64-
<span
65-
class="h-[2.3rem] aspect-square grid place-content-center rounded-sm bg-brand-beige bg-opacity-10 font-semibold"
66-
>4</span
67-
>
68-
<p class="col-span-full text-xs">minutes</p>
69-
</div>
70-
</div>
35+
<CountdownTimer client:only targetDate="2024-06-05" />
7136
<Button
7237
text="Join Now"
7338
size="small"

0 commit comments

Comments
 (0)