Last active
November 13, 2019 14:07
-
-
Save rubensuet-mms/9319753939f9a0271b86f84e480530d0 to your computer and use it in GitHub Desktop.
Countdown With 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 MyState = { | |
days: number | |
hours: number | |
min: number | |
sec: number | |
} | |
class Countdown extends React.Component<MyProps, MyState> { | |
interval: NodeJS.Timer | |
state = { | |
days: 0, | |
hours: 0, | |
min: 0, | |
sec: 0, | |
} | |
componentDidMount() { | |
this.interval = setInterval(() => { | |
const date = this.calculateCountdown(this.props.date) | |
date ? this.setState(date) : this.stop() | |
}, 1000) | |
} | |
componentWillUnmount() { | |
this.stop() | |
} | |
private calculateCountdown(endDate: string) { | |
let diff: number = | |
(Date.parse(new Date(endDate).toString()) - Date.parse(new Date().toString())) / 1000 | |
// clear countdown when date is reached | |
if (diff <= 0) return false | |
const timeLeft: Record<'years' | 'days' | 'hours' | 'min' | 'sec' | 'millisec', number> = { | |
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 | |
} | |
private stop() { | |
clearInterval(this.interval) | |
} | |
private addLeadingZeros(rawValue: number) { | |
let value: string = String(rawValue) | |
while (value.length < 2) { | |
value = '0' + value | |
} | |
return value | |
} | |
render() { | |
const countDown = this.state | |
return ( | |
<div className="Countdown"> | |
<span className="Countdown-col"> | |
<span className="Countdown-col-element"> | |
<strong>{this.addLeadingZeros(countDown.days)}</strong> | |
<span>{countDown.days === 1 ? 'Day' : 'Days'}</span> | |
</span> | |
</span> | |
<span className="Countdown-col"> | |
<span className="Countdown-col-element"> | |
<strong>{this.addLeadingZeros(countDown.hours)}</strong> | |
<span>Hours</span> | |
</span> | |
</span> | |
<span className="Countdown-col"> | |
<span className="Countdown-col-element"> | |
<strong>{this.addLeadingZeros(countDown.min)}</strong> | |
<span>Min</span> | |
</span> | |
</span> | |
<span className="Countdown-col"> | |
<span className="Countdown-col-element"> | |
<strong>{this.addLeadingZeros(countDown.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