vizon-countdown-website/src/Countdown.jsx

99 lines
2.8 KiB
JavaScript

import React from 'react';
import moment from 'moment-timezone';
import PropTypes from 'prop-types';
import DigitBlock from './DigitBlock';
import ProgressCircle from './ProgressCircle';
import style from './Countdown.sass';
export default class Countdown extends React.Component {
static propTypes = {
date: PropTypes.instanceOf(moment).isRequired,
locale: PropTypes.string,
minimumIntegerDigits: PropTypes.number,
useGrouping: PropTypes.bool,
getNow: PropTypes.func,
};
static defaultProps = {
locale: undefined,
minimumIntegerDigits: 2,
useGrouping: false,
getNow: () => moment(),
}
componentDidMount() {
this.tick();
this.interval = setInterval(this.tick.bind(this), 100);
}
componentWillUnmount() {
clearInterval(this.interval);
}
calculateDiff() {
const { getNow, date } = this.props;
return date.diff(getNow());
}
tick() {
this.setState({ duration: this.calculateDiff() });
}
render() {
if (!this.state) {
return null;
}
const { duration } = this.state;
const durationMoment = moment.duration(duration);
const milliseconds = durationMoment.asMilliseconds();
const seconds = (milliseconds / 1000) % 60;
const minutes = (milliseconds / (60 * 1000)) % 60;
const hours = (milliseconds / (60 * 60 * 1000)) % 24;
const days = (milliseconds / (24 * 60 * 60 * 1000));
const size = 160; // @HACK
const { locale, minimumIntegerDigits, useGrouping } = this.props;
return (
<div className={style.countdown}>
<ProgressCircle size={size} max={3} progress={days} stroke="rgb(76,114,163)">
<DigitBlock suffix="d">
{Math.floor(days).toLocaleString(locale, {
minimumIntegerDigits,
useGrouping,
})}
</DigitBlock>
</ProgressCircle>
<ProgressCircle size={size} max={24} progress={hours} stroke="rgb(60, 144, 60)">
<DigitBlock suffix="h">
{Math.floor(hours).toLocaleString(locale, {
minimumIntegerDigits,
useGrouping,
})}
</DigitBlock>
</ProgressCircle>
<ProgressCircle size={size} max={60} progress={minutes} stroke="rgb(160, 154, 40)">
<DigitBlock suffix="m">
{Math.floor(minutes).toLocaleString(locale, {
minimumIntegerDigits,
useGrouping,
})}
</DigitBlock>
</ProgressCircle>
<ProgressCircle size={size} max={60} progress={seconds} stroke="rgb(193,63,88)">
<DigitBlock suffix="s">
{Math.floor(seconds).toLocaleString(locale, {
minimumIntegerDigits,
useGrouping,
})}
</DigitBlock>
</ProgressCircle>
</div>
);
}
}