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, useSearchParams } from "react-router-dom"; import { setImages } from "../../../store/slices/selectedDocsSlice"; import { addRecipient, addRecipientAsync, fetchRecipients, recipientType, removeAllRecipients, removeRecipientAsync, 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"; import { RiPencilFill } from "react-icons/ri"; import SelfSignWarnModal from "./SelfSignWarnModal"; 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 [searchParams] = useSearchParams(); const isTamplate = searchParams.get('useTemplate') const navigate = useNavigate(); const dispatch = useDispatch(); if (!transactionId) { transactionTemplateToggle = TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES; transactionId = templateId; dispatch(toggleToTemplates()); } const [editCase, setEditCase] = useState("") const [editRecipient, setEditRecipient] = useState({}) const selectedDocuments = useSelector((state: RootState) => state.documents.documents) const selectedRecipients = useSelector((state: RootState) => state.selectedRecipients.recipients) const [showSelfSignWarnModal, setShowSelfSignWarnModal] = useState(false) const [editRecipientCurrentEmail, setEditRecipientCurrentEmail] = useState('') const userData = useSelector((state: RootState) => state.user) // ProcessStepOne.tsx const topRef = useRef(null); const [templateName, setTemplateName] = useState('Untitled'); const [isTyping, setIsTyping] = useState(false); // Optional: use a timer to detect pause in typing let typingTimeout = null; const handleChange = (e) => { setTemplateName(e.target.value); setIsTyping(true); clearTimeout(typingTimeout); typingTimeout = setTimeout(() => { setIsTyping(false); }, 5000); // hide icon while typing, show it again after 500ms of no input }; const [transactionDetails, setTransactionDetails] = useState([]); useEffect(() => { (async () => { try { const res = await api.get(`/api/accounts/${accountId}/${transactionTemplateToggle}/${transactionId}`); setTransactionDetails(res.data) if (transactionTemplateToggle === TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES) { setTemplateName(res.data.name) } setEmailDtls( { subject: res.data.subject ? res.data.subject : "Documents for Signature", message: res.data.message ? res.data.message : "" } ) } catch (e) { } })() selectedRecipients.length === 0 && dispatch(fetchRecipients({ accountId, transactionId })); selectedDocuments.length === 0 && dispatch(fetchDocuments({ accountId, transactionId })); }, []) const [emailDtls, setEmailDtls] = useState({ subject: "Documents for Signature", message: "" }); useEffect(() => { dispatch(hideLoader()); }, []) const getMinRoutingOrder = () => { return selectedRecipients.reduce((min, recipient) => { return Math.min(min, recipient.routingOrder ?? Infinity); }, Infinity); }; const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); const handleNextClick = async (saveAndClose: boolean = false) => { let formError = { documents: false, recipients: false, subject: false, recipientEmailAndLastName: false } if (transactionTemplateToggle !== TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES) { if (!selectedDocuments.length) { formError.documents = true } if (!selectedRecipients.length) { formError.recipients = true; } else { // Check if all recipients have email and lastName const isValid = selectedRecipients.every( (item) => item.email?.trim() !== '' && item.lastName?.trim() !== '' ); if (!isValid) { // alert('All recipients must have both Email and Last Name filled.'); formError.recipientEmailAndLastName = true; } } if (!emailDtls.subject.length) { formError.subject = true } if (SignTypeEnum.selfSign === signType) formError.recipients = false; if (formError.documents || formError.recipients || formError.subject || formError.recipientEmailAndLastName) { toast.dismiss(); toast.error(`${formError.documents ? "Add Document" : ""} ${(formError.documents && formError.recipients) ? " | " : ""} ${formError.recipients ? "Add Recipient" : ""} ${formError.recipientEmailAndLastName ? "All recipients must have both Email and Last Name." : ""} ${(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...")); let minRoutingOrder = getMinRoutingOrder(); // selectedRecipients.forEach((recipient) => { // if (recipient.routingOrder ?? 1 < minRoutingOrder) { // minRoutingOrder = recipient.routingOrder ?? 1; // } // }); const recipientsData = selectedRecipients.map((recipient, index) => ({ id: "id" in recipient ? recipient.id : null, routingOrder: "routingOrder" in recipient && recipient.routingOrder ? recipient.routingOrder : 1, provideOwnTags: userData.email === recipient.email && (recipient.routingOrder ?? 1) === minRoutingOrder ? true : false, 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) { dispatch(removeAllRecipients()); await Promise.all( selectedRecipients.map((recipient) => dispatch(removeRecipientAsync({ recipientId: recipient.id, accountId, transactionId, email: recipient.email, }))) ); 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: userData.language ? userData.language : "en", name: `${userData.firstName} ${userData.lastName}`, roleName: "", allowSenderToEdit: true, allowSenderToDelete: true, }] 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 { if(!accountId || !transactionId) return; dispatch(addRecipientAsync({ recipientsData: recipientsDataTemp, accountId, transactionId })); } dispatch(showLoader("Processing Message...")); let res = await api.put(`/api/accounts/${accountId}/${transactionTemplateToggle}/${transactionId}`, { name: templateName, subject: emailDtls.subject, message: emailDtls.message, status: "CREATED" }) dispatch(resetDocuments()) dispatch(resetRecipients()) if (transactionTemplateToggle === TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES) { dispatch(hideLoader()); if (!saveAndClose) { navigate(`/process-step-two/${accountId}/template/${transactionId}`) } else { navigate(`/templates`) } } else { if (signType === SignTypeEnum.selfSign) { dispatch(showLoader("Processing eSignature...")); (async () => { try { await api.put(`/api/accounts/${accountId}/${transactionTemplateToggle}/${transactionId}`, { status: "SENT" }) dispatch(hideLoader()); navigate(`/sign/${recipientId}/self_sign`); } 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) => { if (e.currentTarget.checked) { navigate("self_sign"); setShowSelfSignWarnModal((prev) => !prev) } else { navigate("./../"); } } const globalLoader = useSelector((state: RootState) => state.loader) return ( <>
{/* Top Navigation - Fixed */}

{transactionTemplateToggle === TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES ? <> {!isTyping && ( )} : "Add Recipient and Message" }

{transactionTemplateToggle === TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES && }
{/* Main Content - Scrollable */}
{/* Documents */}

Documents

{/* Recipients */}

{!isTamplate && transactionTemplateToggle !== TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES &&

Signers

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" />
} { (signType !== SignTypeEnum.selfSign || showSelfSignWarnModal) &&
}
{/* Email */}

Email

{/* Subject */}
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)]" />
{/* Message */}