Skip to content

Commit df5a7b4

Browse files
committed
feat: add Countdown component and integrate it into Weeding route for displaying elapsed time
1 parent b4e3bca commit df5a7b4

File tree

2 files changed

+65
-10
lines changed

2 files changed

+65
-10
lines changed

src/components/CountDown.tsx

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { Duration } from 'date-fns';
2+
3+
// Helper function to format numbers with leading zeros (e.g., 5 -> 05)
4+
const formatTime = (time: number | undefined) => {
5+
return time && time < 10 ? `0${time}` : (time ?? 0);
6+
};
7+
8+
// Main Countdown component
9+
const Countdown = ({ duration }: { duration: Duration }) => {
10+
return (
11+
<div className="p-3">
12+
<div className="grid grid-cols-[repeat(3,minmax(100px,1fr))] gap-4 text-center ">
13+
<div className="transform rounded-xl bg-purple-800 p-4 shadow-md transition-transform duration-200 hover:-translate-y-1">
14+
<div className="text-7xl font-bold text-yellow-300">
15+
{formatTime(duration.years ?? 0)}
16+
</div>
17+
<div className="text-lg text-gray-300">Years</div>
18+
</div>
19+
20+
<div className="transform rounded-xl bg-purple-800 p-4 shadow-md transition-transform duration-200 hover:-translate-y-1">
21+
<div className="text-7xl font-bold text-blue-300">
22+
{formatTime(duration.months ?? 0)}
23+
</div>
24+
<div className="text-lg text-gray-300">Months</div>
25+
</div>
26+
27+
<div className="transform rounded-xl bg-purple-800 p-4 shadow-md transition-transform duration-200 hover:-translate-y-1">
28+
<div className="text-7xl font-bold text-green-300">
29+
{formatTime(duration.days)}
30+
</div>
31+
<div className="text-lg text-gray-300">Days</div>
32+
</div>
33+
</div>
34+
</div>
35+
);
36+
};
37+
export default Countdown;

src/routes/Weeding.tsx

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,38 @@
1+
import { Duration, intervalToDuration } from 'date-fns';
12
import { useEffect, useState } from 'react';
23
import ConfettiExplosion from 'react-confetti-explosion';
34

45
import Button from '#components/Button';
6+
import Countdown from '#components/CountDown';
57

68
const Weeding = () => {
7-
const [password, setPassword] = useState('');
9+
const [password, setPassword] = useState('280795');
810
const [isSecret, setIsSecret] = useState(false);
911
const [errorMessage, setErrorMessage] = useState('');
10-
const [daysLeft, setDaysLeft] = useState(0);
12+
const [duration, setDuration] = useState<Duration | null>(null);
13+
const [weedingDate] = useState(new Date(import.meta.env.VITE_WEEDING_DATE));
14+
15+
useEffect(() => {
16+
const timer = setInterval(() => {
17+
const now = new Date();
18+
19+
const duration = intervalToDuration({
20+
start: weedingDate,
21+
end: now,
22+
});
23+
24+
setDuration(duration);
25+
}, 1000);
26+
27+
return () => clearInterval(timer);
28+
}, [weedingDate]);
1129

1230
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
1331
e.preventDefault();
1432
setErrorMessage('');
1533
const secret = import.meta.env.VITE_SECRET;
1634
if (password === secret) {
1735
setIsSecret(true);
18-
const days =
19-
new Date(import.meta.env.VITE_WEEDING_DATE).getTime() -
20-
new Date().getTime();
21-
setDaysLeft(Math.floor(days / (1000 * 60 * 60 * 24)));
2236
} else {
2337
setErrorMessage('Oh no! Wrong key. Try again!');
2438
setIsSecret(false);
@@ -34,7 +48,7 @@ const Weeding = () => {
3448

3549
return (
3650
<div className="grid h-dvh w-screen place-items-center bg-purple-400 p-6">
37-
<div className="w-full max-w-md rounded-xl bg-purple-500 p-6 shadow-xl">
51+
<div className="w-full max-w-screen-sm rounded-xl bg-purple-500 p-6 shadow-xl">
3852
{!isSecret ? (
3953
<form className="space-y-6" onSubmit={handleSubmit}>
4054
<input
@@ -57,10 +71,14 @@ const Weeding = () => {
5771
)}
5872
</form>
5973
) : (
60-
<div className="grid h-[300px] w-full place-content-center overflow-hidden text-center text-5xl font-bold text-purple-800">
74+
<div className="grid h-[300px] text-5xl font-bold text-purple-800">
6175
<ConfettiExplosion particleCount={500} duration={5000} force={1} />
62-
<span className="text-9xl drop-shadow-lg">{daysLeft}</span>
63-
days left
76+
{duration && (
77+
<div className="text-center">
78+
<h3 className="mb-5 text-5xl text-white">Days Past</h3>
79+
<Countdown duration={duration} />
80+
</div>
81+
)}
6482
</div>
6583
)}
6684
</div>

0 commit comments

Comments
 (0)