Skip to content

Qr Scanner

Copy the component

typescript
"use client";
import { useEffect, useState } from "react";

interface IReaderProps {
  onData?: (data: QrUserQRData) => void;
  debug?: boolean;
}

// Change this to your QR code format
export type QrUserQRData = {
  id: string;
  name: string;
  lastName: string;
  company: string;
};
export const parseQrCode = (code: string): QrUserQRData => {
  // Change this to your QR code format
  const splitData = code.split(/\^|\&/);
  if (splitData[0] && splitData[1]) {
    return {
      id: splitData[0],
      name: splitData[1],
      lastName: splitData[2],
      company: splitData[3],
    };
  } else {
    throw new Error("Sorry we do not recognize this QR code: " + code);
  }
};

export default function BarCodeScanner({ onData, debug }: IReaderProps) {
  const [focus, setFocus] = useState<boolean>(true);

  useEffect(() => {
    const exclude = [
      "Shift",
      "Control",
      "Alt",
      "NumLock",
      "CapsLock",
      "Tab",
      "Clear",
      "Enter",
    ];
    let reading = false;
    let code = "";
    // let timeoutHandler: NodeJS.Timeout | null = null;
    const keyDownHandler = (e: any) => {
      reading = true;
      const textInput = e.key;
      if (!exclude.includes(textInput)) {
        code += textInput;
      }
      if (e.keyCode === 13) {
        console.log("you pressed enter: ", code);
        if (code.split("^").length === 5) {
          const cachedCode = code + "";
          code = "";
          reading = false;
          try {
            const parsedQrData = parseQrCode(cachedCode);
            console.log(parsedQrData);
            if (onData) onData(parsedQrData);
          } catch (err) {
            console.log(err);
          }
        } else {
          console.log("invalid code");
          code = "";
          reading = false;
        }
      }
      if (!reading) {
        reading = true;
        setTimeout(() => {
          code = "";
          reading = false;
        }, 200);
      }
    };

    document.addEventListener("keydown", keyDownHandler);

    return () => {
      document.removeEventListener("keydown", keyDownHandler);
    };
  }, [onData]);

  //check if the document has focus so the USB scanner can read correctly
  useEffect(() => {
    const onFocus = () => {
      setFocus(true);
    };
    const onBlur = () => {
      setFocus(false);
    };
    setFocus(document.hasFocus());
    window.addEventListener("focus", onFocus);
    window.addEventListener("blur", onBlur);
    return () => {
      window.removeEventListener("focus", onFocus);
      window.removeEventListener("blur", onBlur);
    };
  }, []);
  if (debug && !focus) {
    return (
      <div className="fixed bg-red-600 text-[30px] text-white bottom-1 right-1 z-20 py-1 px-20 rounded-full">
        Page is not focused
      </div>
    );
  }
  return null;
}