import React from 'react'; import moment, { Duration } from 'moment-timezone'; import * as Styles from './countdown.styles'; import { CountdownProps, CountdownState } from './countdown.types'; export default class Countdown extends React.Component { timer: any; now?: string; cutOff?: string; timeLeft?: Duration; state = { time: '', showCountdown: true }; componentWillUnmount(): void { clearInterval(this.timer); this.setState({ showCountdown: false }); } componentDidUpdate(prevProps: CountdownProps) { if (prevProps.time !== this.props.time) { this.calculateTimeLeft(); } } componentDidMount(): void { this.calculateTimeLeft(); } calculateTimeLeft = () => { this.now = moment().tz(this.props.timezone).format("DD/MM/YYYY HH:mm:ss"); this.cutOff = moment(this.props.time).utc().format("DD/MM/YYYY HH:mm:ss"); this.timeLeft = this.difference(); if (this.timeLeft.asMilliseconds() > 0) { const intervalFunction = () => { const difference = this.timeLeft!.asMilliseconds(); this.timeLeft = moment.duration(difference - 1000, 'milliseconds'); if (difference > 0) { this.setState({ time: moment(difference).utc().format('HH:mm:ss'), showCountdown: true }); } else { clearInterval(this.timer); this.props.onTimeOut(); this.setState({ showCountdown: false }); } } intervalFunction(); this.timer = setInterval((): void => intervalFunction(), 1000); } } difference = () => { var localTime = moment(this.now, "DD/MM/YYYY HH:mm:ss"); var cutoffTime = moment(this.cutOff, "DD/MM/YYYY HH:mm:ss"); return moment.duration(cutoffTime.diff(localTime)); }; intervalFunction = () => { const difference = this.timeLeft!.asMilliseconds(); this.timeLeft = moment.duration(difference - 1000, 'milliseconds'); if (difference > 0) { this.setState({ time: moment(difference).utc().format('HH:mm:ss'), showCountdown: true }); } else { clearInterval(this.timer); this.props.onTimeOut(); this.setState({ showCountdown: false }); } } addPlural = (time: string) => { return parseInt(time) === 1 ? '' : 's' } formatTime = (timeleft: string): JSX.Element => { const time = timeleft.split(':'); return ( { !!parseInt(time[0]) && ( <>{time[0]} Hour{this.addPlural(time[0])}{' '} )} {time[1]} Min{this.addPlural(time[1])}{' '} {time[2]} Sec{this.addPlural(time[2])}{' '} ); } buildCopy = (countdown: JSX.Element) => { switch (true) { case this.props.isSameDay: return ( Need it today? Order within {countdown} ) case moment().add(1, 'days').day() === moment(this.props.time).utc().day(): return ( Need it Tomorrow? Order within
{countdown}
) default: return 'Add to basket to see available delivery dates'; } } render(): JSX.Element | null { const countdown = this.formatTime(this.state.time); return ( <> {this.state.showCountdown && {this.buildCopy(countdown)} } ); } }