Skip to content

Instantly share code, notes, and snippets.

@rubensuet-mms
Last active November 13, 2019 14:43
Show Gist options
  • Save rubensuet-mms/2d6b799db3ad45fd13d763daa787a99a to your computer and use it in GitHub Desktop.
Save rubensuet-mms/2d6b799db3ad45fd13d763daa787a99a to your computer and use it in GitHub Desktop.
Countdown with Hooks and Typescript
import * as React from 'react'
type MyProps = {
date: string
}
type TimeLeft = Record<'years' | 'days' | 'hours' | 'min' | 'sec' | 'millisec', number>
const Countdown: React.FC<MyProps> = ({ date }) => {
const [remainingDate, setRemainingDate] = React.useState({
days: 0,
hours: 0,
min: 0,
sec: 0,
})
const calculateCountdown = (): TimeLeft | false => {
let diff: number =
(Date.parse(new Date(date).toString()) - Date.parse(new Date().toString())) / 1000
// clear countdown when date is reached
if (diff <= 0) return false
const timeLeft: TimeLeft = {
years: 0,
days: 0,
hours: 0,
min: 0,
sec: 0,
millisec: 0,
}
// calculate time difference between now and expected date
if (diff >= 365.25 * 86400) {
// 365.25 * 24 * 60 * 60
timeLeft.years = Math.floor(diff / (365.25 * 86400))
diff -= timeLeft.years * 365.25 * 86400
}
if (diff >= 86400) {
// 24 * 60 * 60
timeLeft.days = Math.floor(diff / 86400)
diff -= timeLeft.days * 86400
}
if (diff >= 3600) {
// 60 * 60
timeLeft.hours = Math.floor(diff / 3600)
diff -= timeLeft.hours * 3600
}
if (diff >= 60) {
timeLeft.min = Math.floor(diff / 60)
diff -= timeLeft.min * 60
}
timeLeft.sec = diff
return timeLeft
}
const addLeadingZeros = (rawValue: number): string => {
let value: string = String(rawValue)
while (value.length < 2) {
value = '0' + value
}
return value
}
React.useEffect(() => {
const interval = setInterval(() => {
console.log('hello')
const newRemainigDate = calculateCountdown()
return newRemainigDate ? setRemainingDate(newRemainigDate) : clearInterval(interval)
}, 1000)
return () => {
clearInterval(interval)
}
},[])
return (
<div className="Countdown">
<span className="Countdown-col">
<span className="Countdown-col-element">
<strong>{addLeadingZeros(remainingDate.days)}</strong>
<span>{remainingDate.days === 1 ? 'Day' : 'Days'}</span>
</span>
</span>
<span className="Countdown-col">
<span className="Countdown-col-element">
<strong>{addLeadingZeros(remainingDate.hours)}</strong>
<span>Hours</span>
</span>
</span>
<span className="Countdown-col">
<span className="Countdown-col-element">
<strong>{addLeadingZeros(remainingDate.min)}</strong>
<span>Min</span>
</span>
</span>
<span className="Countdown-col">
<span className="Countdown-col-element">
<strong>{addLeadingZeros(remainingDate.sec)}</strong>
<span>Sec</span>
</span>
</span>
</div>
)
}
export default Countdown
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment