@@ -10,12 +10,18 @@ interface CountDownProps {
10
10
className ?: string
11
11
timeLeftLabels : TimeLeftLabels
12
12
expiredLabel : string
13
+ dateTime : string
14
+ hideZeroUnits ?: boolean
15
+ onExpired ?: ( ) => void
13
16
}
14
17
15
18
const CountDown = ( {
16
19
className,
17
20
timeLeftLabels,
18
21
expiredLabel,
22
+ dateTime,
23
+ hideZeroUnits = false ,
24
+ onExpired,
19
25
} : CountDownProps ) => {
20
26
const [ timeLeft , setTimeLeft ] = useState ( {
21
27
days : 0 ,
@@ -26,7 +32,7 @@ const CountDown = ({
26
32
const [ isExpired , setIsExpired ] = useState ( false )
27
33
28
34
useEffect ( ( ) => {
29
- const targetDate = new Date ( "2025-07-30T15:44:00Z" )
35
+ const targetDate = new Date ( dateTime )
30
36
31
37
const calculateTimeLeft = ( ) => {
32
38
const now = new Date ( )
@@ -41,7 +47,10 @@ const CountDown = ({
41
47
seconds : Math . floor ( ( difference / 1000 ) % 60 ) ,
42
48
} )
43
49
} else {
44
- setIsExpired ( true )
50
+ if ( ! isExpired ) {
51
+ setIsExpired ( true )
52
+ onExpired ?.( )
53
+ }
45
54
}
46
55
}
47
56
@@ -51,74 +60,81 @@ const CountDown = ({
51
60
const timer = setInterval ( calculateTimeLeft , 1000 )
52
61
53
62
return ( ) => clearInterval ( timer )
54
- } , [ ] )
63
+ } , [ isExpired , onExpired , dateTime ] )
55
64
56
65
if ( isExpired ) {
57
66
return < div className = "text-center text-2xl font-bold" > { expiredLabel } </ div >
58
67
}
59
68
60
69
return (
61
- < div className = "flex items-center justify-center gap-10" >
62
- < div
63
- className = { cn (
64
- "flex h-20 w-20 flex-col items-center justify-center rounded-2xl border text-center [box-shadow:-2.372px_2.372px_14.234px_1.186px_rgba(52,43,64,0.02),-18.979px_18.979px_14.234px_-3.559px_rgba(52,43,64,0.02),-37.958px_37.958px_28.469px_-7.117px_rgba(52,43,64,0.02),-47.448px_47.448px_47.448px_-14.234px_rgba(88,55,131,0.04)] dark:bg-[#171717]" ,
65
- className
66
- ) }
67
- >
68
- < div className = "font-mono text-4xl font-bold text-accent-a" >
69
- { timeLeft . days }
70
+ < div className = "flex items-center justify-center gap-10 text-accent-a" >
71
+ { ( ! hideZeroUnits || timeLeft . days > 0 ) && (
72
+ < div
73
+ className = { cn (
74
+ "flex h-20 w-20 flex-col items-center justify-center rounded-2xl border text-center [box-shadow:-2.372px_2.372px_14.234px_1.186px_rgba(52,43,64,0.02),-18.979px_18.979px_14.234px_-3.559px_rgba(52,43,64,0.02),-37.958px_37.958px_28.469px_-7.117px_rgba(52,43,64,0.02),-47.448px_47.448px_47.448px_-14.234px_rgba(88,55,131,0.04)] dark:bg-[#171717]" ,
75
+ className
76
+ ) }
77
+ >
78
+ < div className = "font-mono text-4xl font-bold" > { timeLeft . days } </ div >
79
+ < div className = "font-mono text-xs" >
80
+ { timeLeft . days === 1
81
+ ? timeLeftLabels . days . singular
82
+ : timeLeftLabels . days . plural }
83
+ </ div >
70
84
</ div >
71
- < div className = "font-mono text-xs text-accent-a" >
72
- { timeLeft . days === 1
73
- ? timeLeftLabels . days . singular
74
- : timeLeftLabels . days . plural }
85
+ ) }
86
+ { ( ! hideZeroUnits || timeLeft . days > 0 || timeLeft . hours > 0 ) && (
87
+ < div
88
+ className = { cn (
89
+ "flex h-20 w-20 flex-col items-center justify-center rounded-2xl border text-center [box-shadow:-2.372px_2.372px_14.234px_1.186px_rgba(52,43,64,0.02),-18.979px_18.979px_14.234px_-3.559px_rgba(52,43,64,0.02),-37.958px_37.958px_28.469px_-7.117px_rgba(52,43,64,0.02),-47.448px_47.448px_47.448px_-14.234px_rgba(88,55,131,0.04)] dark:bg-[#171717]" ,
90
+ className
91
+ ) }
92
+ >
93
+ < div className = "font-mono text-4xl font-bold" > { timeLeft . hours } </ div >
94
+ < div className = "font-mono text-xs" >
95
+ { timeLeft . hours === 1
96
+ ? timeLeftLabels . hours . singular
97
+ : timeLeftLabels . hours . plural }
98
+ </ div >
75
99
</ div >
76
- </ div >
77
- < div
78
- className = { cn (
79
- "flex h-20 w-20 flex-col items-center justify-center rounded-2xl border text-center [box-shadow:-2.372px_2.372px_14.234px_1.186px_rgba(52,43,64,0.02),-18.979px_18.979px_14.234px_-3.559px_rgba(52,43,64,0.02),-37.958px_37.958px_28.469px_-7.117px_rgba(52,43,64,0.02),-47.448px_47.448px_47.448px_-14.234px_rgba(88,55,131,0.04)] dark:bg-[#171717]" ,
80
- className
81
- ) }
82
- >
83
- < div className = "font-mono text-4xl font-bold text-accent-a" >
84
- { timeLeft . hours }
100
+ ) }
101
+ { ( ! hideZeroUnits ||
102
+ timeLeft . days > 0 ||
103
+ timeLeft . hours > 0 ||
104
+ timeLeft . minutes > 0 ) && (
105
+ < div
106
+ className = { cn (
107
+ "flex h-20 w-20 flex-col items-center justify-center rounded-2xl border text-center [box-shadow:-2.372px_2.372px_14.234px_1.186px_rgba(52,43,64,0.02),-18.979px_18.979px_14.234px_-3.559px_rgba(52,43,64,0.02),-37.958px_37.958px_28.469px_-7.117px_rgba(52,43,64,0.02),-47.448px_47.448px_47.448px_-14.234px_rgba(88,55,131,0.04)] dark:bg-[#171717]" ,
108
+ className
109
+ ) }
110
+ >
111
+ < div className = "font-mono text-4xl font-bold" > { timeLeft . minutes } </ div >
112
+ < div className = "font-mono text-xs" >
113
+ { timeLeft . minutes === 1
114
+ ? timeLeftLabels . minutes . singular
115
+ : timeLeftLabels . minutes . plural }
116
+ </ div >
85
117
</ div >
86
- < div className = "font-mono text-xs text-accent-a" >
87
- { timeLeft . hours === 1
88
- ? timeLeftLabels . hours . singular
89
- : timeLeftLabels . hours . plural }
118
+ ) }
119
+ { ( ! hideZeroUnits ||
120
+ timeLeft . days > 0 ||
121
+ timeLeft . hours > 0 ||
122
+ timeLeft . minutes > 0 ||
123
+ timeLeft . seconds > 0 ) && (
124
+ < div
125
+ className = { cn (
126
+ "hidden h-20 w-20 flex-col items-center justify-center rounded-2xl border text-center [box-shadow:-2.372px_2.372px_14.234px_1.186px_rgba(52,43,64,0.02),-18.979px_18.979px_14.234px_-3.559px_rgba(52,43,64,0.02),-37.958px_37.958px_28.469px_-7.117px_rgba(52,43,64,0.02),-47.448px_47.448px_47.448px_-14.234px_rgba(88,55,131,0.04)] lg:flex dark:bg-[#171717]" ,
127
+ className
128
+ ) }
129
+ >
130
+ < div className = "font-mono text-4xl font-bold" > { timeLeft . seconds } </ div >
131
+ < div className = "font-mono text-xs" >
132
+ { timeLeft . seconds === 1
133
+ ? timeLeftLabels . seconds . singular
134
+ : timeLeftLabels . seconds . plural }
135
+ </ div >
90
136
</ div >
91
- </ div >
92
- < div
93
- className = { cn (
94
- "flex h-20 w-20 flex-col items-center justify-center rounded-2xl border text-center [box-shadow:-2.372px_2.372px_14.234px_1.186px_rgba(52,43,64,0.02),-18.979px_18.979px_14.234px_-3.559px_rgba(52,43,64,0.02),-37.958px_37.958px_28.469px_-7.117px_rgba(52,43,64,0.02),-47.448px_47.448px_47.448px_-14.234px_rgba(88,55,131,0.04)] dark:bg-[#171717]" ,
95
- className
96
- ) }
97
- >
98
- < div className = "font-mono text-4xl font-bold text-accent-a" >
99
- { timeLeft . minutes }
100
- </ div >
101
- < div className = "font-mono text-xs text-accent-a" >
102
- { timeLeft . minutes === 1
103
- ? timeLeftLabels . minutes . singular
104
- : timeLeftLabels . minutes . plural }
105
- </ div >
106
- </ div >
107
- < div
108
- className = { cn (
109
- "hidden h-20 w-20 flex-col items-center justify-center rounded-2xl border text-center [box-shadow:-2.372px_2.372px_14.234px_1.186px_rgba(52,43,64,0.02),-18.979px_18.979px_14.234px_-3.559px_rgba(52,43,64,0.02),-37.958px_37.958px_28.469px_-7.117px_rgba(52,43,64,0.02),-47.448px_47.448px_47.448px_-14.234px_rgba(88,55,131,0.04)] lg:flex dark:bg-[#171717]" ,
110
- className
111
- ) }
112
- >
113
- < div className = "font-mono text-4xl font-bold text-accent-a" >
114
- { timeLeft . seconds }
115
- </ div >
116
- < div className = "font-mono text-xs text-accent-a" >
117
- { timeLeft . seconds === 1
118
- ? timeLeftLabels . seconds . singular
119
- : timeLeftLabels . seconds . plural }
120
- </ div >
121
- </ div >
137
+ ) }
122
138
</ div >
123
139
)
124
140
}
0 commit comments