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;
Source