diff --git a/src/App.tsx b/src/App.tsx index 0486a18..6a6a7e3 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -22,7 +22,6 @@ import Templates from "./components/templates/Templates"; import DocumentCompletionScreen from "./components/process/CompletionScreen/DocumentCompletionScreen"; import JoyrideController from "./utlity/JoyRideTour"; import Contacts from "./components/contacts/Contacts"; - const App = () => { return ( diff --git a/src/SigningOrderDiagram .tsx b/src/SigningOrderDiagram .tsx index c9fe0b5..f04f611 100644 --- a/src/SigningOrderDiagram .tsx +++ b/src/SigningOrderDiagram .tsx @@ -1,5 +1,5 @@ import React from "react"; -import { FaCheck, FaLock, FaClock, FaEnvelope, FaTimes } from "react-icons/fa"; +import { FaCheck, FaLock, FaClock, FaEnvelope, FaTimes, FaUserTimes } from "react-icons/fa"; import { IoCloseOutline } from "react-icons/io5"; type Signer = { @@ -48,8 +48,10 @@ const groupByRoutingOrder = (data: Signer[]) => { }; const getInitials = (name: string) => { + if (!name.trim()) return ""; return name .split(" ") + .filter(n => n) .map((n) => n[0].toUpperCase()) .join(""); }; @@ -63,6 +65,8 @@ const SigningOrderDiagram : React.FC = (signers) => { .map(Number) .sort((a, b) => a - b); + console.log("sortedOrders",sortedOrders,grouped) + const currentProcessingOrder = sortedOrders.find((order) => grouped[order].some((signer) => !signer.completed) @@ -109,14 +113,14 @@ const SigningOrderDiagram : React.FC = (signers) => {
- {getInitials(signer.name)} + {(signer?.name !== '' || signer?.roleName) ? getInitials(signer?.name || signer?.roleName) : ""} {icon}
-

{signer.name.split(" ")[0]}

+

{(signer?.name?.split(" ")[0] || signer?.roleName)}

); })} diff --git a/src/components/client/SignCompletionScreen.tsx b/src/components/client/SignCompletionScreen.tsx index 2038f29..31a2d33 100644 --- a/src/components/client/SignCompletionScreen.tsx +++ b/src/components/client/SignCompletionScreen.tsx @@ -17,6 +17,32 @@ const SignCompletionScreen: React.FC = () => { const [showDownloadModal, setShowDownloadModal] = useState(false); const [animationPhase, setAnimationPhase] = useState(0); + + useEffect(() => { + const currentPath = window.location.pathname; + + const handlePopState = (event) => { + // Show warning + // alert("Back navigation is blocked on this screen."); + + // Push the current URL back to prevent navigating away + window.history.pushState(null, "", currentPath); + }; + + // Push extra states to build history buffer + for (let i = 0; i < 50; i++) { + window.history.pushState(null, "", currentPath); + } + + // Add popstate listener + window.addEventListener("popstate", handlePopState); + + // Cleanup on unmount + return () => { + window.removeEventListener("popstate", handlePopState); + }; + }, []); + useEffect(() => { // Trigger animation phases sequentially const timers = [ @@ -321,7 +347,7 @@ const SignCompletionScreen: React.FC = () => { {/* Additional Info */}

- Your document is signed and ready. You can download it or return to the sign made easy. + Your document is signed and saved. Download it or return to Sign Made Easy to continue โ€” navigation is paused until an action is taken.

diff --git a/src/components/client/SignDocument.tsx b/src/components/client/SignDocument.tsx index 8fb09d8..d731e3d 100644 --- a/src/components/client/SignDocument.tsx +++ b/src/components/client/SignDocument.tsx @@ -157,6 +157,7 @@ const SignDocument = () => { const [stamp, setStamp] = useState({ open: false, blob: "" }); + console.log(recSignStatus, "recSignStatus") // Handling Date Opacity const [dateValues, setDateValues] = useState<{ [key: string]: string }>({}); @@ -259,6 +260,8 @@ const SignDocument = () => { } }, [saved]) + + const handleSignClick = (index: number, id: number) => { setSignTagId(id) if (saved.save) { @@ -303,6 +306,35 @@ const SignDocument = () => { } } + // Step 2: Prevent browser back when status === 'COMPLETED' + // useEffect(() => { + // if (recSignStatus !== "COMPLETED") return; + + // const currentPath = window.location.pathname; + + // const handlePopState = (event) => { + // // Show warning + // alert("Back navigation is blocked on this screen."); + + // // Push the current URL back to prevent navigating away + // window.history.pushState(null, "", currentPath); + // }; + + // // Push extra states to build history buffer + // for (let i = 0; i < 50; i++) { + // window.history.pushState(null, "", currentPath); + // } + + // // Add popstate listener + // window.addEventListener("popstate", handlePopState); + + // // Cleanup on unmount + // return () => { + // window.removeEventListener("popstate", handlePopState); + // }; + // }, [recSignStatus]); + + const fetchData = (isSign: boolean = false) => { axios.get(`${import.meta.env.VITE_BASE_URI}/api/sign?recipientId=${recipientId}`, { @@ -313,17 +345,17 @@ const SignDocument = () => { if (res.status === 200) { - setSelectedDocuments(res.data.documents) - setRecipient(res.data.details) - setDroppedItems(res.data.tagJsons) - setTransaction(res.data.transaction) - setRecSignStatus(res.data.status) + setSelectedDocuments(res?.data?.documents) + setRecipient(res?.data?.details) + setDroppedItems(res?.data?.tagJsons) + setTransaction(res?.data?.transaction) + setRecSignStatus(res?.data?.status) - if ("provideOwnTags" in res.data.details && res.data.details.provideOwnTags) { + if ("provideOwnTags" in res?.data?.details && res?.data?.details.provideOwnTags) { setProvideTags(true) } - if (res.data.status === "COMPLETED") { + if (res?.data?.status === "COMPLETED") { setShowCompletionScreen(true) } @@ -335,6 +367,7 @@ const SignDocument = () => { }) .catch((err) => { + console.log(err) }); } @@ -866,6 +899,8 @@ const SignDocument = () => { }; + + // const [showTerms, setShowTerms] = useState(true); return (
diff --git a/src/components/contacts/Contacts.tsx b/src/components/contacts/Contacts.tsx index 655e92e..ff45d09 100644 --- a/src/components/contacts/Contacts.tsx +++ b/src/components/contacts/Contacts.tsx @@ -134,7 +134,7 @@ const Contacts = () => {
-
+
@@ -162,7 +162,7 @@ const Contacts = () => { ) : ( - contacts.map((contact) => ( + contacts.map((contact, index) => ( @@ -181,7 +181,7 @@ const Contacts = () => { {openMenuId === contact.id && ( -
+
*/} - -
+ {/* Header */} +
+ + + +
+

๐ŸŽ‰ Awesome! The documentโ€™s been sent for signature. ๐ŸŽ‰

+
+ {/* Left Panel - Configuration */} +
+ {/* Action Selection */} +
+
+

+ Choose an action after a signer completes the document. +

+
+ {options.map((option) => { + const Icon = option.icon; + const isSelected = selectedOption === option.id; - {(selectedRecipients.length > 0 && selectedDocuments.length > 0) ? -
-
- {/* Header */} -
- {/* Left Section - Document Details */} -
- {/* Document Preview Card */} -
-
- {selectedDocuments?.map((item, index) => ( -
-
-
- {/* */} - document -
-
-

- Name : {item.name ?? '--'} -

-
- Status : {item.status ?? '--'} -
- + return ( +
setSelectedOption(option.id)} + className={` + relative cursor-pointer p-4 rounded-xl border-2 transition-all duration-200 group + ${isSelected + ? 'border-[var(--primary)] bg-blue-50 shadow-md scale-[1.02]' + : option.color + ' border-2' + } + hover:shadow-md hover:scale-[1.01] transform + `} + > +
+
+ +
+
+
+

+ {option.title} +

+ {option.isPremium && ( + โ˜… + )}
+

+ {option.description} +

- ))} -
-
-
+ {/* Selection indicator */} + {isSelected && ( +
+
+ +
+
+ )} +
+ ); + })}
+
+
- {/* Right Section - Signer Components */} -
- {/* Signing Order Diagram */} - + {/* Custom Image Section */} +
- {/* Signers List */} + {/* Right Panel - Preview */} +
+
+
+

Live Preview

+

See how your users will experience the completion

+
+
+
+ {getPreviewContent()}
- : } +
- +
); }; -export default DocumentCompletionScreen; \ No newline at end of file +export default DocumentSubmissionOptions; \ No newline at end of file diff --git a/src/components/process/processStepOne/ProcessStepOne.tsx b/src/components/process/processStepOne/ProcessStepOne.tsx index a250747..0be9217 100644 --- a/src/components/process/processStepOne/ProcessStepOne.tsx +++ b/src/components/process/processStepOne/ProcessStepOne.tsx @@ -60,6 +60,7 @@ const ProcessStepOne = () => { 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('') console.log() const userData = useSelector((state: RootState) => state.user) @@ -142,7 +143,8 @@ const ProcessStepOne = () => { let formError = { documents: false, recipients: false, - subject: false + subject: false, + recipientEmailAndLastName:false } if (transactionTemplateToggle !== TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES) { @@ -150,20 +152,32 @@ const ProcessStepOne = () => { formError.documents = true } if (!selectedRecipients.length) { - formError.recipients = true + 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) { + if (formError.documents || formError.recipients || formError.subject || formError.recipientEmailAndLastName) { console.log(selectedDocuments, 'line 193') 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", @@ -434,7 +448,8 @@ const ProcessStepOne = () => { { (signType !== SignTypeEnum.selfSign || showSelfSignWarnModal) &&
- + + {/* {signType !== "self-sign" && } */}
{ className={`relative w-full bg-[var(--mainViewBg)] ${globalLoader.isLoading ? 'pointer-events-none h-screen overflow-hidden' : ''}`} > - +
diff --git a/src/components/process/processStepOne/RecipientAddCard.tsx b/src/components/process/processStepOne/RecipientAddCard.tsx index a691704..02fd656 100644 --- a/src/components/process/processStepOne/RecipientAddCard.tsx +++ b/src/components/process/processStepOne/RecipientAddCard.tsx @@ -22,10 +22,11 @@ interface ContactType { export interface ContactTypeObj { type: string; contacts: ContactType[]; + setEditRecipientCurrentEmail: any } -const RecipientAddCard = ({ transactionTemplateToggle, editRecipient, editCase, setEditRecipient, setEditCase, topRef }) => { +const RecipientAddCard = ({ transactionTemplateToggle, editRecipient, editCase, setEditRecipient, setEditCase, topRef, setEditRecipientCurrentEmail }) => { const [activeAccountId, setActiveAccountId] = useState( JSON.parse(sessionStorage.getItem('activeAccountId') || 'null') ); @@ -112,7 +113,7 @@ const RecipientAddCard = ({ transactionTemplateToggle, editRecipient, editCase, hostName: editRecipient.hostName || "", hostEmail: editRecipient.hostEmail || "", roleName: editRecipient.roleName || "", - type: editRecipient.type || recipientType.SIGNER, + type: editRecipient.type, allowSenderToEdit: editRecipient.allowSenderToEdit ?? true, allowSenderToDelete: editRecipient.allowSenderToDelete ?? true, uuid: String(editRecipient?.id ?? editRecipient?.uuid ?? ''), @@ -209,11 +210,22 @@ const RecipientAddCard = ({ transactionTemplateToggle, editRecipient, editCase, submitForm(); function submitForm() { - if (editCase === 'Edit') { - dispatch(updateRecipient(recipient)); + let updatedRecipient = { ...recipient }; + + // Clear hostName and hostEmail if type is SIGNER or CC + if ( + updatedRecipient.type === recipientType.SIGNER || + updatedRecipient.type === recipientType.CC + ) { + updatedRecipient.hostName = ""; + updatedRecipient.hostEmail = ""; + } + + if (editCase === "Edit") { + dispatch(updateRecipient(updatedRecipient)); } else { dispatch(addRecipient({ - ...recipient, + ...updatedRecipient, uuid: uuidv4(), newOne: true, })); @@ -241,6 +253,7 @@ const RecipientAddCard = ({ transactionTemplateToggle, editRecipient, editCase, type: false, }); + setEditRecipientCurrentEmail("") setEditCase(""); setManualFocusTriggered(false); formRef.current?.reset(); @@ -578,7 +591,7 @@ const RecipientAddCard = ({ transactionTemplateToggle, editRecipient, editCase, type="radio" name="recipient-type" value={option.value} - defaultChecked={option.value === recipientType.SIGNER} + checked={recipient.type === option.value} onClick={(e) => setRecipients({ ...recipient, type: e.target.value })} className="accent-[var(--primary)] cursor-pointer" /> diff --git a/src/components/process/processStepOne/RecipientCards.tsx b/src/components/process/processStepOne/RecipientCards.tsx index 2bff2bd..581107b 100644 --- a/src/components/process/processStepOne/RecipientCards.tsx +++ b/src/components/process/processStepOne/RecipientCards.tsx @@ -30,12 +30,17 @@ type CardsData = { setEditRecipient: (recipient: any) => void; // Replace `any` with the actual type if known setEditCase: (string: any) => void; transactionTemplateToggle: string + editRecipient: any + setEditRecipientCurrentEmail: any, + editRecipientCurrentEmail: string }; -const RecipientCards = ({ editRecipient, setEditRecipient, setEditCase, transactionTemplateToggle }: CardsData) => { + +const RecipientCards = ({ setEditRecipient, setEditCase, transactionTemplateToggle, editRecipient, editCase, setEditRecipientCurrentEmail, editRecipientCurrentEmail }: CardsData) => { const templateId = useParams<{ templateId: string }>().templateId; let { accountId, transactionId } = useParams<{ accountId: string, transactionId: string }>(); + const dispatch = useDispatch(); if (!transactionId) { @@ -57,6 +62,11 @@ const RecipientCards = ({ editRecipient, setEditRecipient, setEditCase, transact // alert(JSON.stringify(recipient)) setEditCase('Edit') setEditRecipient(recipient) + if (recipient.uuid) { + setEditRecipientCurrentEmail(recipient.uuid) + }else{ + setEditRecipientCurrentEmail(recipient.id) + } } const handleRemoveRecipient = (recipient) => { @@ -128,40 +138,36 @@ const RecipientCards = ({ editRecipient, setEditRecipient, setEditCase, transact )}
- {recipients.map((recipient, idx) => { - // if(recipient.id === editRecipient.id) return - - return ( -
-
- {/* {signingOrder && ( */} - {recipients.length > 1 ?
- - handleOrderChange(recipient.id || recipient.email, Number(e.target.value)) - } - className="w-10 h-6 text-center rounded text-sm text-gray-600 focus:outline-none focus:ring-[var(--primary)] border border-dashed border-gray-400 bg-slate-100" - /> - {/* */} -
- : - handleOrderChange(recipient.id || recipient.email, Number(e.target.value)) - } - className="w-8 text-center rounded text-sm text-gray-700 border-none focus:outline-none focus:ring-[var(--primary)]" - />} - {/* )} */} - + {recipients.map((recipient, idx) => ( +
+
+ {/* {signingOrder && ( */} + {recipients.length > 1 ?
+ + handleOrderChange(recipient.id || recipient.email, Number(e.target.value)) + } + className="w-10 h-6 text-center rounded text-sm text-gray-600 focus:outline-none focus:ring-[var(--primary)] border border-dashed border-gray-400 bg-slate-100" + /> + {/* */} +
+ : + handleOrderChange(recipient.id || recipient.email, Number(e.target.value)) + } + className="w-8 text-center rounded text-sm text-gray-700 border-none focus:outline-none focus:ring-[var(--primary)]" + />} +
{getInitials(`${recipient.firstName} ${recipient.lastName || ""}`)}
@@ -219,7 +225,7 @@ const RecipientCards = ({ editRecipient, setEditRecipient, setEditCase, transact )}
) - })} + )}
) : ( diff --git a/src/components/process/processStepTwo/NavTwo.tsx b/src/components/process/processStepTwo/NavTwo.tsx index ba94dba..2845fd0 100644 --- a/src/components/process/processStepTwo/NavTwo.tsx +++ b/src/components/process/processStepTwo/NavTwo.tsx @@ -63,6 +63,7 @@ const NavTwo: React.FC = ({ transactionSaving, isFields, setIsField return null; } + // const [transactionSaving, setTransactionSaving] = useState(false); const [dotCount, setDotCount] = useState(0); @@ -125,10 +126,10 @@ const NavTwo: React.FC = ({ transactionSaving, isFields, setIsField setTimeout(() => { if (transactionTemplateToggle === TRANSACTION_TEMPLATE_TOGGLE.TRANSACTIONS) { if (isSignSend) { - navigate(`./../../../sign/${selfUserSign.recipientId}`); + navigate(`./../../../sign/${selfUserSign.recipientId}`,{ replace: true }); } - else { - navigate(`/document-completion-screen/${accountId}/${transactionId}`) + else { + navigate(`/document-completion-screen/${accountId}/${transactionId}`, { replace: true }) } } else { navigate(`/templates`); @@ -311,7 +312,7 @@ const NavTwo: React.FC = ({ transactionSaving, isFields, setIsField return (

-

{recipient.firstName} {recipient.lastName} segfsdtzgszrdtgrs serdgvsrdgs dtrgv

+

{recipient.firstName} {recipient.lastName}

) })} diff --git a/src/components/process/processStepTwo/ProcessStepTwo.tsx b/src/components/process/processStepTwo/ProcessStepTwo.tsx index 58043dd..b411753 100644 --- a/src/components/process/processStepTwo/ProcessStepTwo.tsx +++ b/src/components/process/processStepTwo/ProcessStepTwo.tsx @@ -9,6 +9,7 @@ import { RootState } from '../../../store/store'; import Loader from '../../dashboard/Loader'; import { hideLoader } from '../../../store/slices/loaderSlice'; import { useNavigate } from 'react-router-dom'; +import api from '../../../config/api'; export interface IsSendInterface { send: boolean | null; @@ -25,7 +26,7 @@ const ProcessStepTwo = () => { const [isSend, setIsSend] = useState(null); const globalLoader = useSelector((state: RootState) => state.loader) const dispatch = useDispatch(); - const navigate = useNavigate(); + const navigate = useNavigate(); useEffect(() => { setTimeout(() => { @@ -33,6 +34,8 @@ const ProcessStepTwo = () => { }, 800) }, []) + + return (
diff --git a/src/components/setting/Signature/AddSignatureModal.tsx b/src/components/setting/Signature/AddSignatureModal.tsx index 9478964..9a7fb94 100644 --- a/src/components/setting/Signature/AddSignatureModal.tsx +++ b/src/components/setting/Signature/AddSignatureModal.tsx @@ -55,7 +55,7 @@ const AddSignatureModal: React.FC = ({ getAllSignatures, editingSignature }) => { - const [activeTab, setActiveTab] = useState<'TYPE' | 'DRAW' | 'UPLOAD' >('TYPE'); + const [activeTab, setActiveTab] = useState<'SELECT' | 'DRAW' | 'UPLOAD'>('SELECT'); const [fullName, setFullName] = useState(''); const [initials, setInitials] = useState(''); const [isSubmitting, setIsSubmitting] = useState(false); @@ -107,7 +107,7 @@ const AddSignatureModal: React.FC = ({ // Navigation items const navigationItems = [ - { id: 'TYPE', label: 'TYPE', icon: }, + { id: 'SELECT', label: 'SELECT', icon: }, { id: 'DRAW', label: 'DRAW', icon: }, { id: 'UPLOAD', label: 'UPLOAD', icon: }, // { id: 'SELECT', label: 'SELECT', icon: }, @@ -118,7 +118,7 @@ const AddSignatureModal: React.FC = ({ if (editingSignature) { setFullName(`${editingSignature.firstName} ${editingSignature.lastName}`); setInitials(`${editingSignature.firstName.slice(0, 1)}${editingSignature.lastName.slice(0, 1)}`); - setActiveTab(editingSignature.signatureType as 'TYPE' | 'DRAW' | 'UPLOAD'); + setActiveTab(editingSignature.signatureType as 'SELECT' | 'DRAW' | 'UPLOAD'); // Set font for SELECT tab const fontOption = signatureOptions.find(option => option.style === editingSignature.font); @@ -193,10 +193,12 @@ const AddSignatureModal: React.FC = ({ const handleSubmit = async () => { setIsSubmitting(true); - if (!signatures.fullSignature || !signatures.initials) { - alert('Please provide both signature and initials'); - setIsSubmitting(false); - return; + if (activeTab === 'DRAW' || activeTab === 'UPLOAD') { + if (!signatures.fullSignature || !signatures.initials) { + alert('Please provide both signature and initials'); + setIsSubmitting(false); + return; + } } try { @@ -207,7 +209,7 @@ const AddSignatureModal: React.FC = ({ firstName: fullName.split(' ')[0] || user.firstName, lastName: fullName.split(' ')[1] || user.lastName, font: selectedSignature.style, - default:checked + default: checked }; let res; @@ -273,7 +275,7 @@ const AddSignatureModal: React.FC = ({ const renderContent = () => { switch (activeTab) { - case 'TYPE': + case 'SELECT': return (
@@ -481,7 +483,7 @@ const AddSignatureModal: React.FC = ({ {navigationItems.map((item) => (

- {checked - ? 'Signature will be used by default.' - : 'Signature will not be used by default.'} + + Signature will be used by default. +

diff --git a/src/components/templates/Templates.tsx b/src/components/templates/Templates.tsx index 72830bd..e16d0e1 100644 --- a/src/components/templates/Templates.tsx +++ b/src/components/templates/Templates.tsx @@ -90,6 +90,22 @@ const Templates = () => { navigate(`/process-step-one/${accountId}/template/${templateId}`); } + function formatTimestamp(isoString, options = { timeZone: 'local' }) { + // Parse the ISO string to a Date object + const date = new Date(isoString); + + if (isNaN(date)) { + return 'Invalid date'; + } + + // Return formatted date string + if (options.timeZone === 'UTC') { + return date.toUTCString(); // e.g. "Mon, 04 Aug 2025 13:46:46 GMT" + } else { + return date.toLocaleString(); // e.g. "8/4/2025, 9:46:46 AM" (based on local time zone) + } + } + return (
{/* Header */} @@ -159,8 +175,8 @@ const Templates = () => {
- - + + {/* Dropdown Trigger + Tooltip */}
{contact.firstName} {contact.lastName}{item.name || 'Untitled'}{formatDate(item.createdAt)}{formatDate(item.lastModifiedAt)}{formatTimestamp(item.createdAt)}{formatTimestamp(item.lastModifiedAt)} handleUseClick(item)}>Use @@ -173,7 +189,7 @@ const Templates = () => { {showMenu === index && (
{ // Ensure it only closes if focus truly leaves the container @@ -183,7 +199,7 @@ const Templates = () => { }} > +
+ + {/* Content */} +
+ +
+
TODAY
+ + {statusHistory.slice(0, 2).map((item) => ( +
+
+ {item.icon} +
+
+

{item.title}

+
+ By {item.author} + {item.role && ( + <> + โ€ข + ({item.role}) + + )} +
+
+ {item.time} +
+ + {item.fromStatus} + + โ†’ + + {item.toStatus} + +
+
+
+
+ ))} + + +
+ +
+ + {/* Footer */} +
+ +
+ + + ); +}; + +export default AuditModal; diff --git a/src/components/transactions/TransactionView.tsx b/src/components/transactions/TransactionView.tsx index b31dc69..dfb154c 100644 --- a/src/components/transactions/TransactionView.tsx +++ b/src/components/transactions/TransactionView.tsx @@ -1,5 +1,5 @@ import { AiFillSignature } from 'react-icons/ai'; -import { Link, useNavigate, useParams } from 'react-router-dom'; +import { Link, useLocation, useNavigate, useParams, useSearchParams } from 'react-router-dom'; import { LuGitGraph } from 'react-icons/lu'; import AccountNav from '../accounts/AccountNav'; import { useEffect, useState } from 'react'; @@ -10,6 +10,7 @@ import { MdEditDocument } from "react-icons/md"; import { useSelector } from 'react-redux'; import { RootState } from '../../store/store'; import { SignTypeEnum } from '../../utlity/types'; +import AuditModal from './AuditModal'; // Sample recipient data โ€” you can replace this with actual API data later const recipients = [ @@ -44,6 +45,35 @@ const TransactionView = () => { const [transactionDetails, setTransactionDetails] = useState(null); const [signingOrderModal, setSigningOrderModal] = useState({ open: false }); const user = useSelector((state: RootState) => state.user) + const location = useLocation(); + const [isModalOpen, setIsModalOpen] = useState(false); + + useEffect(() => { + // update whenever location changes + setIsModalOpen(location.search.includes("auditStatus")); + }, [location]); + + const handleOpenAuditModal = () => { + const { pathname, search } = location; + let newSearch = search + ? search.includes("auditStatus") + ? search + : `${search}&auditStatus` + : "?auditStatus"; + + window.history.pushState({}, "", pathname + newSearch); + setIsModalOpen(true); // โœ… update state immediately + }; + + const closeModal = () => { + let search = location.search + .replace(/[?&]auditStatus\b/, "") + .replace(/^&/, "?") + .replace(/\?$/, ""); + + window.history.pushState({}, "", location.pathname + search); + setIsModalOpen(false); // โœ… update state immediately + }; console.log(transactionDetails, "line 37"); @@ -99,9 +129,13 @@ const TransactionView = () => { More - + {/* Edit - + */} + +
@@ -138,7 +172,7 @@ const TransactionView = () => { {recipient.email === user.email && recipient.status !== "COMPLETED" &&

handleNavigateToSign(recipient.id)} + onClick={() => handleNavigateToSign(recipient.id)} className='text-white rounded-sm bg-[var(--primary)] px-3 py-1 font-semibold cursor-pointer'> Sign

} @@ -207,6 +241,8 @@ const TransactionView = () => { } + + {isModalOpen && } }