From 7b448558c02ee9450b660c25a8339d7a0f051da9 Mon Sep 17 00:00:00 2001 From: =bhagwanSingh <=bhagwan.r@hicglobalsolutions.com> Date: Thu, 24 Jul 2025 12:31:44 +0530 Subject: [PATCH] API UPdate --- src/App.tsx | 6 + src/components/client/DocumentPages.tsx | 6 +- src/components/client/SignDocument.tsx | 35 ++-- src/components/dashboard/SendForSign.tsx | 75 +++++--- src/components/home/StartSection.tsx | 4 +- .../DocumentCompletionScreen.tsx | 2 +- .../process/processStepOne/ProcessStepOne.tsx | 89 +++++++--- .../processStepTwo/DocumentContainer.tsx | 4 +- .../process/processStepTwo/LeftSideBar.tsx | 6 +- src/components/signature/SignCon.tsx | 6 +- src/store/slices/selectedDocsSlice.ts | 6 +- src/store/slices/selectedRecipientsSlice.tsx | 1 + src/utlity/types.tsx | 164 +++++++++--------- 13 files changed, 247 insertions(+), 157 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index eeccb2a..4a9fe56 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -54,6 +54,12 @@ const App = () => { } /> + + + + } /> + diff --git a/src/components/client/DocumentPages.tsx b/src/components/client/DocumentPages.tsx index 7b97f2f..035398c 100644 --- a/src/components/client/DocumentPages.tsx +++ b/src/components/client/DocumentPages.tsx @@ -23,10 +23,10 @@ const DocumentPages = ({ selectedDocuments, setDropDownTogglePage, dropDownToggl onClick={() => (`${(dropDownTogglePage === 'pageDropDown' + indx) ? '' : 'pageDropDown' + indx}`)} className={`p-2 ${(dropDownTogglePage === 'pageDropDown' + indx) ? "bg-[var(--primary)]" : "bg-slate-200"} flex flex-col justify-center items-center gap-2 rounded`}> { - document.images != undefined && } @@ -41,7 +41,7 @@ const DocumentPages = ({ selectedDocuments, setDropDownTogglePage, dropDownToggl { dropDownTogglePage === 'pageDropDown' + indx &&
- {document.images != undefined && document.images.map((img, indx) => ( + {document.pages != undefined && document.pages.map((img, indx) => ( { @@ -525,18 +525,19 @@ const SignDocument = () => { return null; } - useEffect(() => { - (async () => { - if (droppedItems) { - for (const tag of droppedItems) { - if (tag.type === "SIGNATURE" && "value" in tag) { - const signatureData = await fetchSignatureData(tag.value); - console.log("Currnet Signature",signatureData); - } - } - } - })() - }, [droppedItems]) + // useEffect(() => { + // (async () => { + // if (droppedItems) { + // for (const tag of droppedItems) { + // if (tag.type === "SIGNATURE" && "value" in tag) { + // console.log(tag, "line 533") + // const signatureData = await fetchSignatureData(tag["value"]); + // console.log("Currnet Signature",signatureData); + // } + // } + // } + // })() + // }, [droppedItems]) const handleTagUpdate = (updateIndx: number, updateValue: string) => { @@ -890,7 +891,7 @@ const SignDocument = () => {
{ - doc.images && doc.images.length > 0 && doc.images.map((page, indx) => { + doc.pages && doc.pages.length > 0 && doc.pages.map((page, indx) => { const key = `${doc.documentId}_${page.index}`; console.log(droppedItems, "line 820") // const tagJsonData = [...droppedItems]; @@ -1222,7 +1223,7 @@ const SignDocument = () => { {/* Side details of documents Pages and document Name - START */}

- page {indx + 1} of {doc.images && doc.images.length} + page {indx + 1} of {doc.pages && doc.pages.length}

{/* Side details of documents Pages and document Name - END */} diff --git a/src/components/dashboard/SendForSign.tsx b/src/components/dashboard/SendForSign.tsx index e30d913..6629539 100644 --- a/src/components/dashboard/SendForSign.tsx +++ b/src/components/dashboard/SendForSign.tsx @@ -2,10 +2,14 @@ import React, { useEffect, useRef } from 'react' import { IoMdArrowDropdown } from "react-icons/io"; import { IoIosSend } from "react-icons/io"; import { useDispatch, useSelector } from 'react-redux'; -import { setSignType } from '../../store/slices/selectedDocsSlice'; +import { setSignType, SignType } from '../../store/slices/selectedDocsSlice'; import { RootState } from '../../store/store'; import { useNavigate } from 'react-router-dom'; import { Bounce, toast } from 'react-toastify'; +import api from '../../config/api'; +import { StartCard } from '../home/StartSection'; +import { setTransactionId, TRANSACTION_STATUS_ENUMS, updateTransactionStatus } from '../../store/slices/transactionSlice'; +import { SignTypeEnum } from '../../utlity/types'; // import { IoMdArrowDropright } from "react-icons/io"; interface Props { @@ -22,32 +26,55 @@ const SendForSign: React.FC = ({ showSideBar }) => { sendForSignDropdown && dropDownRef.current?.focus(); }, [sendForSignDropdown]) + const user = useSelector((state: RootState) => state.user); + if (!user.account || user.account === null) { + window.location.href = "/login"; + return; + } + + const defaultAccountId = user.account.id; + const selectedDocuments = useSelector((state: RootState) => state.selectedDocuments.selectedDocuments); - const handleSendSignDispatch: (type: "self-sign" | "multiple-sign") => void = (signType) => { - if (selectedDocuments === null || !selectedDocuments.length) { - if (selectedDocuments === null || !selectedDocuments.length) { - toast.dismiss(); - toast.error("Select 📄 Documents first!", { - position: "bottom-right", - autoClose: 5000, - hideProgressBar: false, - closeOnClick: false, - pauseOnHover: true, - draggable: true, - progress: undefined, - theme: "light", - transition: Bounce, - }); - return - } - } + const handleStartSectionClick = (signType: SignTypeEnum) => { - if (selectedDocuments.length) { - dispatch(setSignType(signType)); - } + api.post(`/api/accounts/${defaultAccountId}/transactions`) + .then(res => { + if (res.status === 200 || res.status === 201) { + dispatch(updateTransactionStatus(TRANSACTION_STATUS_ENUMS.TRANSACTION_INITIATED)); + dispatch(setTransactionId(res.data)); + let navigateUrl = `/process-step-one/${defaultAccountId}/${res.data}`; + if (signType === SignTypeEnum.selfSign) navigateUrl = `/process-step-one/${defaultAccountId}/${res.data}/self_sign`; + setTimeout(() => navigate(navigateUrl), 0) + } + }) + .catch(err => console.log(err)) } + // const handleSendSignDispatch: (type: "self-sign" | "multiple-sign") => void = (signType) => { + // if (selectedDocuments === null || !selectedDocuments.length) { + // if (selectedDocuments === null || !selectedDocuments.length) { + // toast.dismiss(); + // toast.error("Select 📄 Documents first!", { + // position: "bottom-right", + // autoClose: 5000, + // hideProgressBar: false, + // closeOnClick: false, + // pauseOnHover: true, + // draggable: true, + // progress: undefined, + // theme: "light", + // transition: Bounce, + // }); + // return + // } + // } + + // if (selectedDocuments.length) { + // dispatch(setSignType(signType)); + // } + // } + return (
= ({ showSideBar }) => { { sendForSignDropdown &&
-
handleSendSignDispatch('self-sign')}> +
handleStartSectionClick(SignTypeEnum.selfSign)}>

Self Sign

You're the only signer.

-
handleSendSignDispatch('multiple-sign')}> +
handleStartSectionClick(SignTypeEnum.multipleSign)}>

Send for Sign

You and other need to sign.

diff --git a/src/components/home/StartSection.tsx b/src/components/home/StartSection.tsx index 70b989b..392f15a 100644 --- a/src/components/home/StartSection.tsx +++ b/src/components/home/StartSection.tsx @@ -8,7 +8,7 @@ import api from '../../config/api'; import { setTransactionId, TRANSACTION_STATUS_ENUMS, updateTransactionStatus } from '../../store/slices/transactionSlice'; -interface StartCard { +export interface StartCard { icon: ReactNode; title: string; description: string; @@ -57,7 +57,7 @@ const StartSection = () => { if (res.status === 200 || res.status === 201) { dispatch(updateTransactionStatus(TRANSACTION_STATUS_ENUMS.TRANSACTION_INITIATED)); dispatch(setTransactionId(res.data)); - setTimeout(() => navigate(`/process-step-one/${defaultAccountId}/${res.data}`), 0) + setTimeout(() => navigate(`/process-step-one/${defaultAccountId}/${res.data.id}`), 0) } }) .catch(err => console.log(err)) diff --git a/src/components/process/CompletionScreen/DocumentCompletionScreen.tsx b/src/components/process/CompletionScreen/DocumentCompletionScreen.tsx index 5c19737..706c76e 100644 --- a/src/components/process/CompletionScreen/DocumentCompletionScreen.tsx +++ b/src/components/process/CompletionScreen/DocumentCompletionScreen.tsx @@ -316,7 +316,7 @@ const DocumentCompletionScreen = () => {
{/* */} - document + document

diff --git a/src/components/process/processStepOne/ProcessStepOne.tsx b/src/components/process/processStepOne/ProcessStepOne.tsx index 94a8027..9c0274d 100644 --- a/src/components/process/processStepOne/ProcessStepOne.tsx +++ b/src/components/process/processStepOne/ProcessStepOne.tsx @@ -15,6 +15,7 @@ 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 { @@ -23,8 +24,8 @@ const ProcessStepOne = () => { } let transactionTemplateToggle = TRANSACTION_TEMPLATE_TOGGLE.TRANSACTIONS; - console.log("transactionTemplateToggle1", transactionTemplateToggle) - console.log() + + const signType = useParams<{ signType: string }>().signType; const templateId = useParams<{ templateId: string }>().templateId; let { accountId, transactionId } = useParams<{ accountId: string, transactionId: string }>(); @@ -33,11 +34,11 @@ const ProcessStepOne = () => { if (!transactionId) { transactionTemplateToggle = TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES; - console.log("transactionTemplateToggle2", transactionTemplateToggle) + transactionId = templateId; dispatch(toggleToTemplates()); } - console.log("ProcessStepOne called with accountId:", accountId, "and transactionId:", transactionId); + // if (!accountId || !transactionId) { // window.location.href = "/"; // return null; @@ -48,10 +49,10 @@ const ProcessStepOne = () => { const selectedDocuments = useSelector((state: RootState) => state.documents.documents) const selectedRecipients = useSelector((state: RootState) => state.selectedRecipients.recipients) + const userData = useSelector((state: RootState) => state.user) console.log("selectedRecipients", selectedRecipients) - useEffect(() => { selectedRecipients.length === 0 && dispatch(fetchRecipients({ accountId, transactionId })); selectedDocuments.length === 0 && dispatch(fetchDocuments({ accountId, transactionId })); @@ -85,6 +86,8 @@ const ProcessStepOne = () => { formError.subject = true } + if(SignTypeEnum.selfSign === signType) formError.recipients = false; + if (formError.documents || formError.recipients || formError.subject) { console.log(selectedDocuments, 'line 193') toast.dismiss(); @@ -149,11 +152,38 @@ const ProcessStepOne = () => { roleName: recipient.roleName })); - dispatch(addRecipientAsync({ recipientsData, accountId, transactionId })); + let recipientsDataTemp = recipientsData; + + 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: "" + }] + } + + 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" @@ -202,6 +232,15 @@ const ProcessStepOne = () => { navigate('/') } + + const handleSelfSignCb = (e: React.ChangeEvent) => { + if (e.currentTarget.checked) { + navigate("self_sign"); + } else { + navigate("./../"); + } + } + const globalLoader = useSelector((state: RootState) => state.loader) return ( @@ -219,12 +258,15 @@ const ProcessStepOne = () => {

- +
+ 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" + /> + + +
{globalLoader.isLoading && } -
+
); } diff --git a/src/components/process/processStepTwo/DocumentContainer.tsx b/src/components/process/processStepTwo/DocumentContainer.tsx index b25a20c..ecaa313 100644 --- a/src/components/process/processStepTwo/DocumentContainer.tsx +++ b/src/components/process/processStepTwo/DocumentContainer.tsx @@ -778,7 +778,7 @@ const DocumentContainer: React.FC = ({ isSend }) => {
{ - doc.images && doc.images.length > 0 && doc.images.map((page, indx) => { + doc.pages && doc.pages.length > 0 && doc.pages.map((page, indx) => { const key = `${doc.id}_${page.index}`; return (
= ({ isSend }) => { {/* Side details of documents Pages and document Name - START */}

- page {indx + 1} of {doc.images && doc.images.length} + page {indx + 1} of {doc.pages && doc.pages.length}

{/*

Document {indxDoc + 1} {doc.name} diff --git a/src/components/process/processStepTwo/LeftSideBar.tsx b/src/components/process/processStepTwo/LeftSideBar.tsx index 6a97bc1..a687121 100644 --- a/src/components/process/processStepTwo/LeftSideBar.tsx +++ b/src/components/process/processStepTwo/LeftSideBar.tsx @@ -133,10 +133,10 @@ const LeftSideBar: React.FC = ({ isFields, selectedRecipientIn onClick={() => setDropDownTogglePage(`${(dropDownTogglePage === 'pageDropDown' + indx) ? '' : 'pageDropDown' + indx}`)} className={`p-2 ${(dropDownTogglePage === 'pageDropDown' + indx) ? "bg-[var(--primary)]" : "bg-slate-200"} flex flex-col justify-center items-center gap-2 rounded`}> { - document.images != undefined && } @@ -151,7 +151,7 @@ const LeftSideBar: React.FC = ({ isFields, selectedRecipientIn { dropDownTogglePage === 'pageDropDown' + indx &&

- {document.images != undefined && document.images.map((img, indx) => ( + {document.pages != undefined && document.pages.map((img, indx) => ( = ({ const getUserDetails = async () => { try { - let res = await api.get(`/api/user/details`); + let res = await axios.get(`/api/user/details`, { + headers: { + "ngrok-skip-browser-warning": "69420", + } + }); console.log("getuser", res); let currUser = res?.data; setUser(currUser); diff --git a/src/store/slices/selectedDocsSlice.ts b/src/store/slices/selectedDocsSlice.ts index 5006788..477854a 100644 --- a/src/store/slices/selectedDocsSlice.ts +++ b/src/store/slices/selectedDocsSlice.ts @@ -21,7 +21,7 @@ export interface SelectedDocument { extension: string; original: boolean; corrupted?: boolean; - images?: Image[]; + pages?: Image[]; } export interface PayloadSelectedDocument { @@ -30,7 +30,7 @@ export interface PayloadSelectedDocument { extension: string; original: boolean; corrupted?: boolean; - images?: Image[]; + pages?: Image[]; } interface SelectedDocumentsState { @@ -87,7 +87,7 @@ const selectedDocumentsSlice = createSlice({ const docId = document.documentId; for (const [index, selDoc] of state.selectedDocuments.entries()) { if (selDoc.id === docId) { - state.selectedDocuments[index].images = document.images; + state.selectedDocuments[index].pages = document.pages; break; } } diff --git a/src/store/slices/selectedRecipientsSlice.tsx b/src/store/slices/selectedRecipientsSlice.tsx index 87ac190..9b5855d 100644 --- a/src/store/slices/selectedRecipientsSlice.tsx +++ b/src/store/slices/selectedRecipientsSlice.tsx @@ -352,6 +352,7 @@ export interface Recipient { type: recipientType; color?: string; roleName:string + provideOwnTags?: boolean; } export interface SelectedRecipientInt { diff --git a/src/utlity/types.tsx b/src/utlity/types.tsx index eb4cc7a..cd7ffd1 100644 --- a/src/utlity/types.tsx +++ b/src/utlity/types.tsx @@ -1,61 +1,61 @@ import { JSX } from "react"; export interface DroppedItem { - id?: string; - icon: JSX.Element; - focusElementIndx?: number; - label?: string; - type: string; - subType?: string; - dimensions: { - left: number; - top: number; - width: number; - height: number; - } - recipientId: number; - // mask?: { - // type: string; - // character: string; - // } + id?: string; + icon: JSX.Element; + focusElementIndx?: number; + label?: string; + type: string; + subType?: string; + dimensions: { + left: number; + top: number; + width: number; + height: number; + } + recipientId: number; + // mask?: { + // type: string; + // character: string; + // } - maskType?: string; - maskCharacter?: string; + maskType?: string; + maskCharacter?: string; - required?: boolean; - format?: string; - radioGroups?: DroppedItem[]; - // documentIndex: number; - documentId: string; - pageIndex: number; - options?: string[] - selectedValue?: string | null; - radioPosition?: { - topMin: number; - topMax: number; - leftMin: number; - leftMax: number; - width?: number; - height?: number - }; - value?: string | number; - validation?: { - minLength: number; - maxLength: number; - error: string; - regex: string[]; - }; - isDeleted: boolean; + required?: boolean; + format?: string; + radioGroups?: DroppedItem[]; + // documentIndex: number; + documentId: string; + pageIndex: number; + options?: string[] + selectedValue?: string | null; + radioPosition?: { + topMin: number; + topMax: number; + leftMin: number; + leftMax: number; + width?: number; + height?: number + }; + value?: string | number; + validation?: { + minLength: number; + maxLength: number; + error: string; + regex: string[]; + }; + isDeleted: boolean; } export interface DroppedItemsObj { - [key: string]: DroppedItem[] + [key: string]: DroppedItem[] } export enum OpenType { - TYPED, - DRAW, - UPLOADED + TYPED, + DRAW, + UPLOADED } // types/account.ts @@ -81,39 +81,45 @@ export interface AccountData { } export interface TagsProperties { - "editable": boolean; - "required": boolean; - "navigationOrder": number; - "type": string; - "lastName"?: boolean; - "firstName"?: boolean; - "maxLength"?: number; - "minLength"?: number; - "readOnly"?: boolean; - "multiLine"?: boolean; - "regex"?: string[]; - "format"?: string; - "dateFormat"?: string; - "currentTimeStamp"?: boolean; - "decimalPlace"?: number; - "multiSelect"?: boolean; + "editable": boolean; + "required": boolean; + "navigationOrder": number; + "type": string; + "lastName"?: boolean; + "firstName"?: boolean; + "maxLength"?: number; + "minLength"?: number; + "readOnly"?: boolean; + "multiLine"?: boolean; + "regex"?: string[]; + "format"?: string; + "dateFormat"?: string; + "currentTimeStamp"?: boolean; + "decimalPlace"?: number; + "multiSelect"?: boolean; } export enum TagsTypes { - TEXT= "text", - SIGNATURE= "signature", - INITIALS= "initials", - TEMPORAL= "temporal", - NUMBER= "number", - IMAGE= "image", - STAMP= "stamp", - CHECKBOX= "checkbox", - SELECT= "select", - FILE= "file", - ATTACHMENT= "attachment", - RADIO= "radio", - EMAIL= "email", - NAME= "name", - COMPANY= "company", - } + TEXT = "text", + SIGNATURE = "signature", + INITIALS = "initials", + TEMPORAL = "temporal", + NUMBER = "number", + IMAGE = "image", + STAMP = "stamp", + CHECKBOX = "checkbox", + SELECT = "select", + FILE = "file", + ATTACHMENT = "attachment", + RADIO = "radio", + EMAIL = "email", + NAME = "name", + COMPANY = "company", +} + + +export enum SignTypeEnum { + selfSign = "self_sign", + multipleSign = "multi_sign" +} \ No newline at end of file