All files PinCode.js

95.65% Statements 44/46
71.42% Branches 10/14
88.23% Functions 15/17
100% Lines 44/44

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 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96                1x 1x   1x 1x   1x     1x 2x   2x     1x 10x         1x 8x 8x 8x   8x 1x 1x 1x         8x 2x 2x 2x 2x 2x         8x 1x 1x 1x     8x 2x 2x 2x 1x 1x       8x 1x 1x 1x     8x 1x 1x 2x 1x     8x                              
/* eslint jsx-a11y/aria-role: 0 */
 
import { useCallback, useState } from "react";
import axios from 'axios';
import useWebSocket from 'react-use-websocket';
import 'bootstrap-icons/font/bootstrap-icons.css';
import './PinCode.css';
 
const websocketUrl = `${process.env.REACT_APP_WS_URL}/ws`;
const PinCodeUpdateValue = 255;
 
const apiFetchPinCode = async () => {
  return await axios.get(
    `${process.env.REACT_APP_BASE_URL}/pin_code`,
  ).then(res => res.data);
}
 
const apiFetchQrCode = async () => {
  return await axios.get(
    `${process.env.REACT_APP_BASE_URL}/pin_code/qr_code`,
  ).then(res => res.data);
}
 
const Animate = ({ children, on, transition }) => {
  return (on === undefined)
    ? <>{children}</>
    : <span className={transition} key={on}>{children}</span>
}
 
export const PinCode = () => {
  const [ pinCode, setPinCode ] = useState();
  const [ qrCode, setQrCode ] = useState();
  const [ pinCodeCopied, setPinCodeCopied ] = useState(false);
 
  const fetchPinCode = useCallback(async () => {
    const data = await apiFetchPinCode().catch(error => console.log(error));
    Eif (data) {
      setPinCode(data.pin);
    }
  }, [setPinCode]
  );
 
  const fetchQrCode = useCallback(async () => {
    const data = await apiFetchQrCode().catch(error => console.log(error));
    Eif (data) {
      let parser = new DOMParser();
      let qr_code = parser.parseFromString(data, "image/svg+xml").documentElement.outerHTML;
      setQrCode(qr_code);
    }
  }, [setQrCode]
  );
 
  const onWsOpen = () => {
    console.log('websocket opened');
    fetchPinCode();
    fetchQrCode();
  };
 
  const onWsMessage = (event) => {
    const message = JSON.parse(event.data);
    console.log(`websocket message ${message.pin_code}`);
    if (message.cmd === PinCodeUpdateValue) {
      setPinCode(message.pin_code);
      fetchQrCode();
    }
  };
 
  const onClipboardClick = async () => {
    await navigator.clipboard.writeText(pinCode);
    setPinCodeCopied(true);
    console.log(`Pin Code ${pinCode} copied to clipboard`);
  };
 
  useWebSocket(websocketUrl, {
    onOpen: () => onWsOpen(),
    onClose: () => console.log("websocket closed"),
    onMessage: (event) => onWsMessage(event),
    shouldReconnect: (event) => true,
  });
 
  return (
    <div className="PinCode" role="PinCode">
      {qrCode &&
      <Animate on={qrCode} transition="FadeIn">
        <div role="QrCode" className="Pop" dangerouslySetInnerHTML={{ __html: qrCode }} />
      </Animate>
      }
      {pinCode &&
      <p>
        Pin Code: <Animate on={pinCode} transition="FadeIn">{pinCode}</Animate>&nbsp;<button className="Button" type="button" onClick={onClipboardClick}><i className={`bi ${pinCodeCopied ? "bi-clipboard-check": "bi-clipboard"}`}></i></button>
      </p>
      }
    </div>
  );
}