import React, { useState, useEffect, useRef, useContext } from 'react'; import { useHistory } from 'react-router-dom'; import PropTypes from 'prop-types'; import Button from '../../components/ui/button'; import { SECOND } from '../../../shared/constants/time'; import Typography from '../../components/ui/typography'; import { I18nContext } from '../../contexts/i18n'; import IconDesktopPairing from '../../components/ui/icon/icon-desktop-pairing'; import { TEXT_ALIGN, TypographyVariant, DISPLAY, AlignItems, FLEX_DIRECTION, } from '../../helpers/constants/design-system'; import Box from '../../components/ui/box/box'; import { useCopyToClipboard } from '../../hooks/useCopyToClipboard'; import Tooltip from '../../components/ui/tooltip'; export default function DesktopPairingPage({ generateDesktopOtp, mostRecentOverviewPage, showLoadingIndication, hideLoadingIndication, }) { const t = useContext(I18nContext); const history = useHistory(); const OTP_DURATION = SECOND * 30; const REFRESH_INTERVAL = SECOND; const time = new Date().getTime(); const [otp, setOtp] = useState(); const [lastOtpTime, setLastOtpTime] = useState(time); const [currentTime, setCurrentTime] = useState(time); const [copied, handleCopy] = useCopyToClipboard(); const generateIntervalRef = useRef(); const refreshIntervalRef = useRef(); const updateCurrentTime = () => { setCurrentTime(new Date().getTime()); }; const getExpireDuration = () => { const timeSinceOtp = currentTime - lastOtpTime; const expireDurationMilliseconds = OTP_DURATION - timeSinceOtp; const expireDurationSeconds = Math.round( expireDurationMilliseconds / SECOND, ); return expireDurationSeconds; }; useEffect(() => { const generate = async () => { setLastOtpTime(new Date().getTime()); const OTP = await generateDesktopOtp(); setOtp(OTP); }; generate(); updateCurrentTime(); generateIntervalRef.current = setInterval(() => generate(), OTP_DURATION); refreshIntervalRef.current = setInterval( () => updateCurrentTime(), REFRESH_INTERVAL, ); return function cleanup() { clearInterval(generateIntervalRef.current); clearInterval(refreshIntervalRef.current); }; }, [OTP_DURATION, REFRESH_INTERVAL, generateDesktopOtp]); const renderIcon = () => { return (
); }; const goBack = () => { history?.push(mostRecentOverviewPage); }; const renderContent = () => { if (!otp) { showLoadingIndication(); return null; } hideLoadingIndication(); return (
{ handleCopy(otp); }} data-testid="desktop-pairing-otp-content" > {otp} {t('desktopPairingExpireMessage', [ {getExpireDuration()} , ])}
{t('desktopPageDescription')}
); }; const renderFooter = () => { return (
); }; return (
{renderIcon()}
{t('desktopPageTitle')}
{t('desktopPageSubTitle')}
{renderContent()}
{renderFooter()}
); } DesktopPairingPage.propTypes = { mostRecentOverviewPage: PropTypes.string, showLoadingIndication: PropTypes.func, hideLoadingIndication: PropTypes.func, generateDesktopOtp: PropTypes.func, };