Source

pages/Authentication/Signup/VerifyModal.jsx

import { Button, Modal } from "antd";
import React from "react";
import { useRef } from "react";
import { useNavigate } from "react-router-dom";
import { useVerifyOtpFirstUser } from "../../../apis/Login";
import { toast } from "react-toastify";
/**
 * VerifyModal component for OTP verification.
 * @module SignUp/VerifyModal
 * @param {Object} props - Component props.
 * @param {boolean} props.otpModal - Boolean to determine if the modal is open.
 * @param {function} props.setOtpModal - Function to set the modal's open/close state.
 * @param {string} props.token - Token for verification.
 * @returns {JSX.Element} The VerifyModal component.
 */
const VerifyModal = ({ otpModal, setOtpModal, token }) => {
  const { mutate: verifyMutate, isLoading: verifyLoading } =
    useVerifyOtpFirstUser();
  const formRef = useRef(null);
  const inputRefs = [
    useRef(null),
    useRef(null),
    useRef(null),
    useRef(null),
    // Add more refs for additional input fields
  ];
  const navigate = useNavigate();
  /**
   * Handles the submission of the OTP form.
   * @method handleOtpSubmit
   * @param {Event} event - The form submit event.
   */
  const handleOtpSubmit = (event) => {
    event.preventDefault();
    const formData = new FormData(formRef.current);
    const formValues = Object.fromEntries(formData.entries());
    const otp = String(
      `${formValues.input1}${formValues.input2}${formValues.input3}${formValues.input4}`
    );
    verifyMutate(
      { otp, token },
      {
        onSuccess: (res) => {
          setOtpModal(false);
          localStorage.setItem("token", token);
          navigate("../dashboard");
          toast.success("Otp verified successfully.");
        },
      }
    );
  };
  /**
   * Handles key down events for input fields to navigate between them.
   * @function handleKeyDown
   * @param {Event} event - The keydown event.
   * @param {number} currentIndex - Index of the current input field.
   */
  const handleKeyDown = (event, currentIndex) => {
    const { key } = event;
    if (key === "ArrowRight") {
      event.preventDefault();
      const nextIndex = currentIndex + 1;
      if (nextIndex < inputRefs.length) {
        inputRefs[nextIndex].current.focus();
      }
    } else if (key === "ArrowLeft") {
      event.preventDefault();
      const prevIndex = currentIndex - 1;
      if (prevIndex >= 0) {
        inputRefs[prevIndex].current.focus();
      }
    }
  };
  /**
   * Handles input for the first digit and moves focus to the next input field.
   * @function handleInput1
   * @param {Event} e - The input change event.
   */
  const handleInput1 = (e) => {
    const value = e.target.value;
    if (value.length === 1) {
      inputRefs[1].current.focus();
    }
  };
  /**
   * Handles input for the second digit and moves focus to the next input field.
   * @function handleInput2
   * @param {Event} e - The input change event.
   */
  const handleInput2 = (e) => {
    const value = e.target.value;
    if (value.length === 1) {
      inputRefs[2].current.focus();
    }
  };
  /**
   * Handles input for the third digit and moves focus to the next input field.
   * @function handleInput3
   * @param {Event} e - The input change event.
   */
  const handleInput3 = (e) => {
    const value = e.target.value;
    if (value.length === 1) {
      inputRefs[3].current.focus();
    }
  };

  return (
    <Modal
      centered
      open={otpModal}
      okText="Verify"
      okButtonProps={{
        style: {
          display: "none",
        },
      }}
      cancelButtonProps={{
        style: {
          display: "none",
        },
      }}
      width={"fit-content"}
      onCancel={() => setOtpModal(false)}
    >
      <div className="otp_container">
        <form ref={formRef} className="form" onSubmit={handleOtpSubmit}>
          {" "}
          <div className="title">OTP</div>{" "}
          <div className="title">Verification Code</div>{" "}
          <p className="message">
            We have sent a verification code to your email
          </p>{" "}
          <div className="otp_inputs">
            <input
              id="input1"
              name="input1"
              type="text"
              min={0}
              max={9}
              pattern="[0-9]"
              maxLength={1}
              ref={inputRefs[0]}
              onChange={handleInput1}
              onKeyDown={(e) => handleKeyDown(e, 0)}
              required
            />{" "}
            <input
              id="input2"
              name="input2"
              type="text"
              min={0}
              max={9}
              pattern="[0-9]"
              maxLength={1}
              ref={inputRefs[1]}
              onChange={handleInput2}
              onKeyDown={(e) => handleKeyDown(e, 1)}
              required
            />{" "}
            <input
              id="input3"
              name="input3"
              type="text"
              min={0}
              max={9}
              pattern="[0-9]"
              maxLength={1}
              ref={inputRefs[2]}
              onChange={handleInput3}
              onKeyDown={(e) => handleKeyDown(e, 2)}
              required
            />{" "}
            <input
              id="input4"
              name="input4"
              type="text"
              min={0}
              max={9}
              pattern="[0-9]"
              maxLength={1}
              ref={inputRefs[3]}
              onKeyDown={(e) => handleKeyDown(e, 3)}
              required
            />{" "}
          </div>{" "}
          <div className="submit_buttons mt-3 flex justify-end gap-2 w-100">
            <Button onClick={() => setOtpModal(false)}>Cancel</Button>
            <Button
              className="send_btn"
              type="primary"
              htmlType="submit"
              loading={verifyLoading}
            >
              verify me
            </Button>
          </div>
        </form>
      </div>
    </Modal>
  );
};

export default VerifyModal;