270 lines
9.6 KiB
TypeScript
270 lines
9.6 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, useState } from "react";
|
|
import { useNavigate, useParams } from "react-router-dom";
|
|
import { setImages } from "../../../store/slices/selectedDocsSlice";
|
|
import { addRecipient, addRecipientAsync, fetchRecipients, recipientType, resetRecipients, 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";
|
|
|
|
const ProcessStepOne = () => {
|
|
interface EmailDtls {
|
|
subject: string;
|
|
message: string;
|
|
}
|
|
|
|
const { accountId, transactionId } = useParams<{ accountId: string, transactionId: string }>();
|
|
if (!accountId || !transactionId) {
|
|
window.location.href = "/";
|
|
return null;
|
|
}
|
|
|
|
const navigate = useNavigate();
|
|
const dispatch = useDispatch();
|
|
|
|
// 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)
|
|
|
|
|
|
useEffect(() => {
|
|
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 handleNextClick = async (isSendNow: boolean) => {
|
|
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 (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}/transactions/${transactionId}/documents`, { "documents": documentsData });
|
|
|
|
await api.get(`/api/accounts/${accountId}/transactions/${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) => ({
|
|
// index,
|
|
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}`
|
|
}));
|
|
|
|
dispatch(addRecipientAsync({ recipientsData, accountId, transactionId }));
|
|
|
|
dispatch(showLoader("Processing Message..."));
|
|
|
|
await api.put(`/api/accounts/${accountId}/transactions/${transactionId}`, { subject: emailDtls.subject, message: emailDtls.message, status: "CREATED" }).then((res) => {
|
|
console.log(res);
|
|
})
|
|
|
|
dispatch(hideLoader());
|
|
|
|
if (isSendNow) {
|
|
dispatch(updateTransactionStatus(TRANSACTION_STATUS_ENUMS.TRANSACTION_SEND_SUCCESS));
|
|
setTimeout(() => {
|
|
// navigate("/");
|
|
}, 1000);
|
|
} else {
|
|
setTimeout(() => {
|
|
dispatch(resetDocuments())
|
|
dispatch(resetRecipients())
|
|
dispatch(hideLoader());
|
|
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 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 className='flex items-center gap-3'>
|
|
<button
|
|
onClick={() => handleNextClick(true)}
|
|
className="text-sm px-4 py-2 rounded border border-gray-300 hover:bg-gray-100 transition"
|
|
>
|
|
Send Now
|
|
</button>
|
|
<button
|
|
onClick={() => handleNextClick(false)}
|
|
className="text-sm px-4 py-2 rounded bg-[var(--primary)] text-white shadow hover:bg-[var(--primaryLight2)] transition"
|
|
>
|
|
Add Tags
|
|
</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 />
|
|
</section>
|
|
|
|
{/* Recipients */}
|
|
<section className="mt-8">
|
|
<h2 className="text-lg font-medium mb-4 pt-6 border-t text-[var(--processStepOneTextHead)]">Signers</h2>
|
|
<div className="flex flex-col gap-4 align-start">
|
|
<RecipientCards />
|
|
{/* {signType !== "self-sign" && <RecipientAddCard />} */}
|
|
<RecipientAddCard />
|
|
</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 |