All files / src/features/profile PairingCodeDisplay.tsx

90% Statements 18/20
75% Branches 3/4
83.33% Functions 5/6
93.75% Lines 15/16

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66                              3x 3x 3x   3x   3x 3x 3x   3x 2x     1x 3x   3x 3x     3x     3x                                                    
/**
 * PairingCodeDisplay Component
 * Story W2.1: Pairing Code Backend & Web Frontend — AC1
 * Shows 6-digit pairing code with live 24h countdown timer.
 */
 
import React, { useState, useEffect } from 'react';
import { Alert, Box, Typography } from '@mui/material';
import type { PendingPairingCode } from '@/types/watch';
 
interface PairingCodeDisplayProps {
  pendingCode: PendingPairingCode;
}
 
function formatCountdown(expiresAt: string): string {
  const now = new Date();
  const expiry = new Date(expiresAt);
  const diffMs = expiry.getTime() - now.getTime();
 
  Iif (diffMs <= 0) return 'Expired';
 
  const totalMinutes = Math.floor(diffMs / 60000);
  const hours = Math.floor(totalMinutes / 60);
  const minutes = totalMinutes % 60;
 
  if (hours > 0) return `Expires in ${hours}h ${minutes}m`;
  return `Expires in ${minutes}m`;
}
 
const PairingCodeDisplay: React.FC<PairingCodeDisplayProps> = ({ pendingCode }) => {
  const [countdown, setCountdown] = useState(() => formatCountdown(pendingCode.expiresAt));
 
  useEffect(() => {
    const interval = setInterval(() => {
      setCountdown(formatCountdown(pendingCode.expiresAt));
    }, 1000);
    return () => clearInterval(interval);
  }, [pendingCode.expiresAt]);
 
  return (
    <Alert severity="info" data-testid="pairing-code-display">
      <Typography variant="subtitle2" gutterBottom>
        Your pairing code
      </Typography>
      <Typography
        variant="h4"
        component="span"
        sx={{ fontFamily: 'monospace', letterSpacing: 4, fontWeight: 'bold' }}
        data-testid="pairing-code-value"
      >
        {pendingCode.code}
      </Typography>
      <Box sx={{ mt: 1 }}>
        <Typography variant="caption" color="text.secondary" data-testid="pairing-code-countdown">
          {countdown}
        </Typography>
      </Box>
      <Typography variant="body2" sx={{ mt: 1 }}>
        Open BATbern Watch app, swipe right, and enter this code.
      </Typography>
    </Alert>
  );
};
 
export default PairingCodeDisplay;