SME-Web/src/components/process/processStepOne/ProcessStepOne.tsx

428 lines
16 KiB
TypeScript

import { IoMdClose } from "react-icons/io";
import RecipientAddCard from './RecipientAddCard';
import RecipientCards from './RecipientCards';
import SelectedDocuments from "./SelectedDocuments";
import api from "../../../config/api";
import { useDispatch, useSelector } from "react-redux";
import { RootState } from "../../../store/store";
import { useEffect, useRef, useState } from "react";
import { useNavigate, useParams } from "react-router-dom";
import { setImages } from "../../../store/slices/selectedDocsSlice";
import { addRecipient, addRecipientAsync, fetchRecipients, recipientType, resetRecipients, toggleToTemplates, TRANSACTION_TEMPLATE_TOGGLE, updateRecipientIds } from "../../../store/slices/selectedRecipientsSlice";
import { setTransactionId, TRANSACTION_STATUS_ENUMS, updateTransactionStatus } from "../../../store/slices/transactionSlice";
import { hideLoader, showLoader } from "../../../store/slices/loaderSlice";
import Loader from "../../dashboard/Loader";
import { Bounce, toast } from "react-toastify";
import { fetchDocuments, resetDocuments, setDocuments, uploadDocuments } from "../../../store/slices/documentSlice";
import { SignTypeEnum } from "../../../utlity/types";
const ProcessStepOne = () => {
interface EmailDtls {
subject: string;
message: string;
}
let transactionTemplateToggle = TRANSACTION_TEMPLATE_TOGGLE.TRANSACTIONS;
const signType = useParams<{ signType: string }>().signType;
const templateId = useParams<{ templateId: string }>().templateId;
let { accountId, transactionId } = useParams<{ accountId: string, transactionId: string }>();
const navigate = useNavigate();
const dispatch = useDispatch();
if (!transactionId) {
transactionTemplateToggle = TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES;
transactionId = templateId;
dispatch(toggleToTemplates());
}
const [editCase, setEditCase] = useState<string>("")
const [editRecipient, setEditRecipient] = useState({})
// if (!accountId || !transactionId) {
// window.location.href = "/";
// return null;
// }
// const selectedDocuments = useSelector((state: RootState) => state.selectedDocuments.selectedDocuments)
// const { selectedDocuments, signType } = useSelector((state: RootState) => state.selectedDocuments)
const selectedDocuments = useSelector((state: RootState) => state.documents.documents)
const selectedRecipients = useSelector((state: RootState) => state.selectedRecipients.recipients)
const userData = useSelector((state: RootState) => state.user)
// ProcessStepOne.tsx
const topRef = useRef<HTMLDivElement | null>(null);
// const userData = useSelector((state: RootState) => state.user)
const [transactionDetails, setTransactionDetails] = useState<any>([]);
console.log("selectedRecipients", selectedRecipients)
useEffect(() => {
// <<<<<<< HEAD
// Fetching Transaction Details - START
(async () => {
try {
const res = await api.get(`/api/accounts/${accountId}/${transactionTemplateToggle}/${transactionId}`);
setTransactionDetails(res.data)
} catch (e) {
console.log("Error - transactions details")
}
})()
// Fetching Transaction Details - END
// =======
// (async () => {
// const res = await api.get(`/api/accounts/${accountId}/${transactionTemplateToggle}/${transactionId}`)
// console.log(res.data);
// })()
// >>>>>>> origin/main
// (async () => {
// const res = await api.get(`/api/accounts/${accountId}/${transactionTemplateToggle}/${transactionId}`)
// console.log(res.data);
// })()
selectedRecipients.length === 0 && dispatch(fetchRecipients({ accountId, transactionId }));
selectedDocuments.length === 0 && dispatch(fetchDocuments({ accountId, transactionId }));
}, [])
// const signingOrder = useSelector((state: RootState) => state.selectedRecipients.signingOrder)
// const user = useSelector((state: RootState) => state.user)
const [emailDtls, setEmailDtls] = useState<EmailDtls>({ subject: "Documents for Signature", message: "" });
useEffect(() => {
dispatch(hideLoader());
}, [])
const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
const handleNextClick = async (isSendNow: boolean, saveAndClose: boolean = false) => {
let formError = {
documents: false,
recipients: false,
subject: false
}
if (!selectedDocuments.length) {
formError.documents = true
}
if (!selectedRecipients.length) {
formError.recipients = true
}
if (!emailDtls.subject.length) {
formError.subject = true
}
if (SignTypeEnum.selfSign === signType) formError.recipients = false;
if (formError.documents || formError.recipients || formError.subject) {
console.log(selectedDocuments, 'line 193')
toast.dismiss();
toast.error(`${formError.documents ? "Add Document" : ""}
${(formError.documents && formError.recipients) ? " | " : ""}
${formError.recipients ? "Add Recipient" : ""}
${(formError.documents || formError.recipients) ? " | " : ""}
${formError.subject ? "Add Subject" : ""}`, {
position: "top-center",
autoClose: 5000,
hideProgressBar: false,
closeOnClick: false,
pauseOnHover: true,
draggable: true,
progress: undefined,
theme: "light",
transition: Bounce,
});
return;
}
try {
dispatch(showLoader("Processing Documents..."));
const documentsData = selectedDocuments.map((doc, index) => ({
name: doc.name,
documentId: doc.id,
order: index,
}));
await api.patch(`/api/accounts/${accountId}/${transactionTemplateToggle}/${transactionId}/documents`, { "documents": documentsData });
await api.get(`/api/accounts/${accountId}/${transactionTemplateToggle}/${transactionId}/documents?include_images=true`).then(res => {
if (res.status === 200) {
dispatch(setDocuments(res.data));
}
}).catch((err) => {
console.error(err)
});
dispatch(showLoader("Processing Recipients..."));
const recipientsData = selectedRecipients.map((recipient, index) => ({
id: "id" in recipient ? recipient.id : null,
routingOrder: "routingOrder" in recipient && recipient.routingOrder ? recipient.routingOrder : 1,
type: recipient.type,
firstName: recipient.firstName,
lastName: recipient.lastName,
authType: "NONE",
deliveryMethod: "EMAIL",
email: recipient.email,
hostName: recipient.hostName,
hostEmail: recipient.hostEmail,
company: "",
title: "",
website: "",
phone: "",
accessCode: "",
accessCodeDelivery: true,
language: "en",
name: `${recipient.firstName} ${recipient.lastName}`,
roleName: recipient.roleName,
allowSenderToEdit: recipient.allowSenderToEdit,
allowSenderToDelete: recipient.allowSenderToDelete,
}));
let recipientsDataTemp = recipientsData;
let recipientId = null;
if (signType === SignTypeEnum.selfSign) {
recipientsDataTemp = [{
id: null,
routingOrder: 1,
provideOwnTags: true,
type: recipientType.SIGNER,
firstName: userData.firstName,
lastName: userData.lastName,
authType: "NONE",
deliveryMethod: "EMAIL",
email: userData.email,
hostName: "",
hostEmail: "",
company: "",
title: "",
website: "",
phone: "",
accessCode: "",
accessCodeDelivery: true,
language: "en",
name: `${userData.firstName} ${userData.lastName}`,
roleName: ""
}]
try {
const basePath = `/api/accounts/${accountId}/transactions/${transactionId}/recipients`;
const res = await api.post(basePath, recipientsDataTemp)
recipientId = res.data[0].id;
} catch (error) {
console.log("Error Creating Self Sign Recipient", error.message)
}
} else {
dispatch(addRecipientAsync({ recipientsData: recipientsDataTemp, accountId, transactionId }));
}
dispatch(showLoader("Processing Message..."));
console.log(`1/api/accounts/${accountId}/${transactionTemplateToggle}/${transactionId}`)
let res = await api.put(`/api/accounts/${accountId}/${transactionTemplateToggle}/${transactionId}`, {
subject: emailDtls.subject, message: emailDtls.message,
status: "CREATED"
})
console.log("Line 158", res.data)
if (isSendNow) {
dispatch(updateTransactionStatus(TRANSACTION_STATUS_ENUMS.TRANSACTION_SEND_SUCCESS));
setTimeout(() => {
// navigate("/");
}, 1000);
}
else {
setTimeout(() => {
dispatch(resetDocuments())
dispatch(resetRecipients())
dispatch(hideLoader());
if (transactionTemplateToggle === TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES) {
console.log(`/process-step-two/${accountId}/template/${transactionId}`)
if(!saveAndClose) {
navigate(`/process-step-two/${accountId}/template/${transactionId}`)
} else {
navigate(`/templates`)
}
} else {
if (signType === SignTypeEnum.selfSign) {
(async () => {
try {
const res = await api.put(`/api/accounts/${accountId}/${transactionTemplateToggle}/${transactionId}`, { status: "SENT" })
console.log(res, "Check123");
navigate(`/sign/${recipientId}`);
} catch (err) {
console.log("Error Transaction Sent", err.message);
}
})()
} else {
navigate(`/process-step-two/${accountId}/${transactionId}`);
}
}
}, 1000);
}
} catch (error) {
dispatch(hideLoader());
console.error("Error submitting data step-by-step:", error);
toast.error("Something went wrong. Please try again.", {
position: "top-center",
autoClose: 5000,
theme: "light",
transition: Bounce,
});
}
};
useEffect(() => {
dispatch(updateTransactionStatus(TRANSACTION_STATUS_ENUMS.TRANSACTION_INITIATED))
}, [])
const handleClose = () => {
dispatch(resetDocuments())
navigate('/')
}
const handleSelfSignCb = (e: React.ChangeEvent<HTMLInputElement>) => {
if (e.currentTarget.checked) {
navigate("self_sign");
} else {
navigate("./../");
}
}
const globalLoader = useSelector((state: RootState) => state.loader)
return (
<>
<div className={`relative w-full bg-[var(--mainViewBg)] ${globalLoader.isLoading ? 'pointer-events-none h-screen overflow-hidden' : ''}`}>
{/* Top Navigation */}
<div className='fixed top-0 w-full flex items-center justify-between bg-white shadow z-50 px-4 py-3'>
<div className='flex items-center gap-2'>
<IoMdClose
onClick={handleClose}
className='text-2xl text-slate-500 cursor-pointer hover:text-[var(--primary)] transition'
/>
<p className="text-base font-normal text-gray-700 border-l pl-4">Add Recipient and Message</p>
</div>
<div
id="add-tags-btn-step-one"
className='flex items-center gap-3'>
{transactionTemplateToggle === TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES && <button
onClick={() => handleNextClick(false, true)}
className="text-sm px-4 py-2 rounded bg-[var(--primary)] text-white shadow hover:bg-[var(--primaryLight2)] transition cursor-pointer"
>
Save & Close
</button>}
<button
onClick={() => handleNextClick(false)}
className="text-sm px-4 py-2 rounded bg-[var(--primary)] text-white shadow hover:bg-[var(--primaryLight2)] transition cursor-pointer"
>
{signType === SignTypeEnum.selfSign ? "Sign" : "Next"}
</button>
</div>
</div>
{/* Main Content */}
<div className="relative max-w-4xl mx-auto pt-[80px] px-4 pb-10">
{/* Documents */}
<section>
<h2 className="text-lg font-medium mb-4 text-[var(--processStepOneTextHead)]">Documents</h2>
<SelectedDocuments transactionTemplateToggle={transactionTemplateToggle} />
</section>
{/* Recipients */}
<section className="mt-8">
{
transactionTemplateToggle !== TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES &&
<div className="flex justify-between items-center">
<h2 className="text-lg font-medium mb-4 pt-6 border-t text-[var(--processStepOneTextHead)]">Signers</h2>
<div className="flex items-center mr-2">
<input
checked={signType === SignTypeEnum.selfSign}
onChange={(e) => handleSelfSignCb(e)}
id="default-checkbox" type="checkbox" value="" className="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded-sm outline-none"
/>
<label htmlFor="default-checkbox" className="ms-2 text-sm text-slate-600">SELF SIGN</label>
</div>
</div>
}
{
signType !== SignTypeEnum.selfSign &&
<div className="flex flex-col gap-4 align-start">
<RecipientCards transactionTemplateToggle={transactionTemplateToggle} setEditRecipient={setEditRecipient} setEditCase={setEditCase} />
{/* {signType !== "self-sign" && <RecipientAddCard />} */}
<div
ref={topRef}
className={`relative w-full bg-[var(--mainViewBg)] ${globalLoader.isLoading ? 'pointer-events-none h-screen overflow-hidden' : ''}`}
>
<RecipientAddCard transactionTemplateToggle={transactionTemplateToggle} editRecipient={editRecipient} editCase={editCase} setEditRecipient={setEditRecipient} setEditCase={setEditCase} topRef={topRef} />
</div>
</div>
}
</section>
{/* Email */}
<section className="mt-8">
<h2 className="text-lg font-medium mb-4 pt-6 border-t text-[var(--processStepOneTextHead)]">Email</h2>
{/* Subject */}
<div className='flex flex-col mb-4'>
<label className='text-sm font-medium text-[var(--greyTextCol)] mb-1'>Subject</label>
<input
type="text"
required
value={emailDtls.subject}
onChange={(e) => setEmailDtls({ ...emailDtls, subject: e.target.value })}
placeholder="Email Subject"
className="w-full px-3 py-2 rounded border border-gray-300 focus:outline-none focus:ring-2 focus:ring-[var(--primary)]"
/>
</div>
{/* Message */}
<div className='flex flex-col'>
<label className='text-sm font-medium text-[var(--greyTextCol)] mb-1'>Message for Signers</label>
<textarea
rows={4}
value={emailDtls.message}
onChange={(e) => setEmailDtls({ ...emailDtls, message: e.target.value })}
placeholder="Message"
className="w-full px-3 py-2 rounded border border-gray-300 focus:outline-none focus:ring-2 focus:ring-[var(--primary)]"
/>
</div>
</section>
</div>
{globalLoader.isLoading && <Loader />}
</div >
</>
);
}
export default ProcessStepOne