Source

pages/Dashboard/Sharetransfer/Sharetransfer.jsx

import React, { useMemo, useRef, useState } from "react";
import "../Sharetransfer/sharetransfer.css";
import { useParams } from "react-router-dom";
import { DownloadOutlined } from "@ant-design/icons";
import {
  useGetSingleShareTransferRequest,
  useShareTransferRequest,
} from "../../../apis/ShareTransfer";
import { useNavigate } from "react-router-dom";
import LoadingAnimation from "../Loading/LoadingAnimation";
import { useGetShareHoldersList } from "../../../apis/ShareHolders";
import { useQueryClient } from "@tanstack/react-query";
import { Button, InputNumber, Select } from "antd";
import { toast } from "react-toastify";
import html2canvas from "html2canvas";
import jsPDF from "jspdf";
import ContractTemplate from "../../../component/ContractTemplate/ContractTemplate";

/**
 * Represents Sharetransfer page component
 * @module Sharetransfer
 * @param user {object} - logged in user details
 * @return {JSX.Element}
 */
const Sharetransfer = ({ user }) => {
  /**
   * React state that holds request letter
   * @type {string}
   * @constant
   * @memberof module:Sharetransfer
   * @name request_letter
   * @default ""
   */
  const [request_letter, setrequest_letter] = useState("");
  /**
   * React state that holds transfer quantity
   * @type {number}
   * @constant
   * @memberof module:Sharetransfer
   * @name transfer_quantity
   * @default 0
   */
  const [transfer_quantity, settransfer_quantity] = useState(0);
  /**
   * React state that holds to shareholder
   * @type {number}
   * @constant
   * @memberof module:Sharetransfer
   * @name to_shareholder
   * @default null
   */
  const [to_shareholder, Setto_shareholder] = useState(null);
  /**
   * React state that holds shareholder name
   * @type {string}
   * @constant
   * @memberof module:Sharetransfer
   * @name shareHolderName
   * @default ""
   */
  const [shareHolderName, setShareHolderName] = useState("");
  /**
   * React useParam hook to get id from url
   * @type {object}
   * @constant  useParams
   *@memberof module:Sharetransfer
   */
  const { id } = useParams();
  const queryClient = useQueryClient();
  const navigate = useNavigate();
  /**
   * React state that holds image
   * @type {string}
   * @constant
   * @memberof module:Sharetransfer
   * @name image
   * @default null
   */
  const [image, setImage] = useState(null);
  /**
   * React state that holds file name
   * @type {string}
   * @constant
   * @memberof module:Sharetransfer
   * @name fileName
   * @default "No selected file"
   */
  const [fileName, setFileName] = useState("No selected file");
  /**
   * React query hook for mutate transfer request
   * @type {object}
   * @constant  useShareTransferRequest
   * @memberof module:Sharetransfer
   */
  const { mutate: requestMutate, isLoading: requestLoading } =
    useShareTransferRequest();
  /**
   * React query hook for getting share holder list
   * @type {object}
   * @constant  useGetShareHoldersList
   * @memberof module:Sharetransfer
   */
  const { data: shareHolder, isLoading: holderLoading } =
    useGetShareHoldersList();
  /**
   * React query hook for getting single share transfer request
   * @type {object}
   * @constant  useGetSingleShareTransferRequest
   * @memberof module:Sharetransfer
   */
  const { data: share, isLoading: shareLoading } =
    useGetSingleShareTransferRequest(id);
  /**
   * React memo hook for getting share holder list
   * @type {object}
   * @constant  shareHolderList
   * @memberof module:Sharetransfer
   * @type {{label: *, value: *}[]}
   */
  const shareHolderList = useMemo(() => {
    let temp = shareHolder?.data?.data?.results || [];
    return temp.map((shareHolder) => ({
      label: shareHolder?.full_name,
      value: shareHolder?.id,
    }));
  }, [shareHolder?.data]);
  /**
   * React ref hook for getting div element
   * @constant  divToConvert
   * @type {React.MutableRefObject<null>}
   * @memberof module:Sharetransfer
   */
  const divToConvert = useRef(null);
  // Getting share type
  /**
   * React memo hook for getting share type
   * @type {boolean}
   * @constant  isTransferrable
   * @memberof module:Sharetransfer
   */
  const isTransferrable = useMemo(() => {
    if (share?.data?.data?.share_type === "BONUS") {
      return true;
    }
    return false;
  }, [share?.data]);
  /**
   * React event handler function that handle file change
   * @memberof module:Sharetransfer
   * @function handleFileChange
   *
   * @param e {Event} Html event object
   */
  const handleFileChange = (e) => {
    const files = e.target.files;
    if (files && files[0]) {
      setFileName(files[0].name);
      setImage(URL.createObjectURL(files[0]));
      setrequest_letter(files[0]);
    }
  };
  /**
   * React event handler function that handle submit
   * @memberof module:Sharetransfer
   * @function handleSubmit
   * @param event {Event} Html event object
   */
  const handleSubmit = (event) => {
    try {
      event.preventDefault();

      const formData = new FormData();
      formData.append("transfer_quantity", transfer_quantity);
      formData.append("sharehistory", parseInt(id));
      formData.append("to_shareholder", to_shareholder);
      formData.append("request_letter", request_letter);
      if (isTransferrable) {
        requestMutate(formData, {
          onSuccess: (res) => {
            queryClient.invalidateQueries(["share-history-list"]);
            navigate("../sharetransferrequest");
          },
        });
      } else {
        toast.error("Sorry, Share type should be Bonus.");
      }
    } catch (err) {
      console.log(err.message);
    }
  };

  /**
   * React event handler function that handle download document
   * @memberof module:Sharetransfer
   * @function downloadDocument
   * @return {Promise<void>}
   */
  async function downloadDocument() {
    try {
      const canvas = await html2canvas(divToConvert.current, {
        useCORS: true, // Enable CORS for images
      });
      const imgData = canvas.toDataURL("image/png", 1); // Increase quality (1 = max quality)
      const pdf = new jsPDF("p", "mm", "a4"); // Create PDF instance
      const imgProps = pdf.getImageProperties(imgData);
      // Set margins (adjust these values as needed)
      const marginTop = 10; // mm
      const marginLeft = 10; // mm
      const pdfWidth = pdf.internal.pageSize.getWidth() - 2 * marginLeft;
      const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width;

      pdf.addImage(imgData, "PNG", marginLeft, marginTop, pdfWidth, pdfHeight);
      pdf.save("contract-pdf.pdf"); // Trigger the download
    } catch (err) {
      console.log(err.message);
    }
  }

  /**
   * React event handler function that handle select change
   * @memberof module:Sharetransfer
   * @function handleSelectChange
   * @param value {number} shareholder id
   * @param values {object} shareholder object data
   */
  const handleSelectChange = (value, values) => {
    Setto_shareholder(parseInt(value));
    setShareHolderName(values.label);
  };
  if (requestLoading || holderLoading) {
    return <LoadingAnimation />;
  }
  return (
    <>
      <div className="share_transfer_container">
        <div className="sharetransfer_heading flex gap-3 justify-between">
          <h3>Share Transfer Request</h3>
          <Button
            className={
              transfer_quantity && to_shareholder ? "download_btn" : ""
            }
            type="primary"
            icon={<DownloadOutlined />}
            disabled={transfer_quantity && to_shareholder ? false : true}
            onClick={() => downloadDocument()}
          >
            Download template
          </Button>
        </div>
        <div className="sharetransfer_form">
          <form onSubmit={handleSubmit}>
            <div className="sharetransfer_form_group">
              <label>Enter quantity</label>
              <InputNumber
                style={{
                  width: "100%",
                }}
                type="number"
                placeholder=""
                min={0}
                onChange={(e) => settransfer_quantity(parseInt(e))}
              />
            </div>
            <div className="sharetransfer_form_group">
              <Select
                placeholder="Select a shareholder."
                showSearch
                filterOption={true}
                optionFilterProp="label"
                onChange={handleSelectChange}
                options={shareHolderList}
              />
            </div>
            <div className="sharetransfer_form_group_img">
              <input
                type="file"
                accept=".pdf"
                className="image_field"
                hidden
                onChange={handleFileChange}
              />
              {image ? (
                <img
                  src={image}
                  alt={fileName}
                  onClick={() => document.querySelector(".image_field").click()}
                />
              ) : (
                <ion-icon
                  name="cloud-upload-outline"
                  onClick={() => document.querySelector(".image_field").click()}
                ></ion-icon>
              )}
            </div>
            <div className="sharetransfer_form_group">
              <button className="sharetransfer_button">Transfer Share</button>
            </div>
          </form>
        </div>
        <ContractTemplate
          componentRef={divToConvert}
          data={share?.data?.data}
          kitta={transfer_quantity}
          target_name={shareHolderName}
        />
      </div>
    </>
  );
};
export default Sharetransfer;