Last active
November 13, 2019 14:43
-
-
Save rubensuet-mms/2d6b799db3ad45fd13d763daa787a99a to your computer and use it in GitHub Desktop.
Countdown with Hooks and Typescript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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