-
- {/* User Dropdown */}
-
- {/* Avatar Button */}
-
-
- {user ? (
- {(user?.firstName + " " + user?.lastName).split(' ').map((item) => item.slice(0, 1)).join("").toUpperCase()}
- ) : (
-
- )}
-
-
-
- {/* Enhanced Dropdown */}
- {open && (
-
- {/* User Info Section */}
-
-
-
- {(user) ? (
-
- {(user?.firstName + " " + user?.lastName).split(' ').map((item) => item.slice(0, 1)).join("").toUpperCase()}
- ) : (
-
- )}
-
-
-
{user.firstName + ' ' + user.lastName || '-'}
-
{user.email || '-'}
-
- Account #{user?.account?.name || '-'}
-
-
-
-
-
- {/* Account List Section */}
-
-
-
-
- Switch Account
-
-
-
-
- {/* Accounts Dropdown */}
- {accountsOpen && (
-
- {loadingAccounts ? (
-
-
-
-
- ) : (
-
- {accounts.length > 0 ? (accounts?.map((account) => (
-
handleAccountSwitch(account)}
- className="w-full px-4 py-3 hover:bg-white transition-colors cursor-pointer text-left"
- >
-
-
-
- {account.accountName.slice(0, 2).toUpperCase()}
-
-
-
- {account.accountName}
- {account.status && (
-
- )}
-
-
{account.company}
-
-
-
- {account.role}
-
-
-
- ))) :
No Account... }
-
-
- )}
-
- )}
-
-
- {/* Logout Section */}
-
-
-
- Log Out
-
-
-
- )}
-
+
+
+
+
+ {user ? (
+
+ {(user?.name?.slice(0, 2)).toUpperCase()}
+
+ ) : (
+
+ )}
-
- );
+
+
+ {open && (
+
+
+
+
+ {user ? (
+
+ {(user?.name?.slice(0, 2)).toUpperCase()}
+
+ ) : (
+
+ )}
+
+
+
{user?.name || '-'}
+
{user?.email || '-'}
+
+ Account #{user?.account?.name || '-'}
+
+
+
+
+
+
+
+
+
+ Switch Account
+
+
+
+
+ {accountsOpen && (
+
+ {loadingAccounts ? (
+
+
+
+
+ ) : (
+
+ {accounts?.length > 0 ? (
+ accounts?.map((account) => (
+
handleAccountSwitch(account)}
+ className={`w-full px-4 py-3 hover:bg-white transition-colors cursor-pointer text-left`}
+ >
+
+
+
+ {account.accountName.slice(0, 2).toUpperCase()}
+
+
+
+ {account.accountName}
+ {account.accountId === activeAccountId && (
+
+ )}
+
+
+
+
+ {account.role}
+
+
+
+ ))
+ ) : (
+
No Account...
+ )}
+
+ )}
+
+ )}
+
+
+
+
+
+ Log Out
+
+
+
+ )}
+
+
+
+ );
};
export default CommonNav;
\ No newline at end of file
diff --git a/src/components/accounts/Account.tsx b/src/components/accounts/Account.tsx
index be312fb..d5c7a6a 100644
--- a/src/components/accounts/Account.tsx
+++ b/src/components/accounts/Account.tsx
@@ -67,36 +67,36 @@ const Account = () => {
textColor: 'text-teal-700',
trend: 'up'
},
- {
- title: 'Waiting for Others',
- count: data.waitingForOthers || 0,
- icon:
,
- gradient: 'bg-gradient-to-br from-blue-50 to-blue-100',
- shadowColor: 'shadow-blue-200/50',
- iconBg: 'bg-blue-100 border-blue-200',
- textColor: 'text-blue-700',
- trend: 'down'
- },
- {
- title: 'declined',
- count: data.declined || 0,
- icon:
,
- gradient: 'bg-gradient-to-br from-purple-50 to-purple-100',
- shadowColor: 'shadow-purple-200/50',
- iconBg: 'bg-purple-100 border-purple-200',
- textColor: 'text-purple-700',
- trend: 'down'
- },
- {
- title: 'cancelled',
- count: data.cancelled || 0,
- icon:
,
- gradient: 'bg-gradient-to-br from-green-50 to-green-100',
- shadowColor: 'shadow-green-200/50',
- iconBg: 'bg-green-100 border-green-200',
- textColor: 'text-green-700',
- trend: 'down'
- },
+ // {
+ // title: 'Waiting for Others',
+ // count: data.waitingForOthers || 0,
+ // icon:
,
+ // gradient: 'bg-gradient-to-br from-blue-50 to-blue-100',
+ // shadowColor: 'shadow-blue-200/50',
+ // iconBg: 'bg-blue-100 border-blue-200',
+ // textColor: 'text-blue-700',
+ // trend: 'down'
+ // },
+ // {
+ // title: 'declined',
+ // count: data.declined || 0,
+ // icon:
,
+ // gradient: 'bg-gradient-to-br from-purple-50 to-purple-100',
+ // shadowColor: 'shadow-purple-200/50',
+ // iconBg: 'bg-purple-100 border-purple-200',
+ // textColor: 'text-purple-700',
+ // trend: 'down'
+ // },
+ // {
+ // title: 'cancelled',
+ // count: data.cancelled || 0,
+ // icon:
,
+ // gradient: 'bg-gradient-to-br from-green-50 to-green-100',
+ // shadowColor: 'shadow-green-200/50',
+ // iconBg: 'bg-green-100 border-green-200',
+ // textColor: 'text-green-700',
+ // trend: 'down'
+ // },
{
title: 'draft',
count: data.draft || 0,
@@ -115,7 +115,9 @@ const Account = () => {
JSON.parse(sessionStorage.getItem('activeAccountId') || 'null')
);
- console.log("activeAccountId Trans.",activeAccountId)
+ const [currentEmailId, setCurrentEmailId] = useState
('null');
+
+ console.log("activeAccountId Trans.", activeAccountId)
// const { accountId } = useParams<{ accountId: string }>();
const [transactions, setTransactions] = useState([]);
const [selectedTransactions, setSelectedTransactions] = useState([]);
@@ -141,32 +143,38 @@ const Account = () => {
// getUserDetails()
// }, [])
+ useEffect(() => {
+ const userDetails = JSON.parse(sessionStorage.getItem('userDetails'));
+ setCurrentEmailId(userDetails?.email)
+ }, []);
+
+
// Listen for sessionStorage changes
- useEffect(() => {
- const handleStorageChange = (e: StorageEvent) => {
- if (e.key === 'activeAccountId') {
- const newActiveAccountId = e.newValue ? JSON.parse(e.newValue) : null;
- setActiveAccountId(newActiveAccountId);
- }
- };
-
- // Listen for storage events (works for changes from other tabs)
- window.addEventListener('storage', handleStorageChange);
-
- // Custom event listener for same-tab changes
- const handleCustomStorageChange = (e: CustomEvent) => {
- if (e.detail.key === 'activeAccountId') {
- setActiveAccountId(e.detail.newValue);
- }
- };
-
- window.addEventListener('sessionStorageChange', handleCustomStorageChange as EventListener);
-
- return () => {
- window.removeEventListener('storage', handleStorageChange);
- window.removeEventListener('sessionStorageChange', handleCustomStorageChange as EventListener);
- };
- }, []);
+ useEffect(() => {
+ const handleStorageChange = (e: StorageEvent) => {
+ if (e.key === 'activeAccountId') {
+ const newActiveAccountId = e.newValue ? JSON.parse(e.newValue) : null;
+ setActiveAccountId(newActiveAccountId);
+ }
+ };
+
+ // Listen for storage events (works for changes from other tabs)
+ window.addEventListener('storage', handleStorageChange);
+
+ // Custom event listener for same-tab changes
+ const handleCustomStorageChange = (e: CustomEvent) => {
+ if (e.detail.key === 'activeAccountId') {
+ setActiveAccountId(e.detail.newValue);
+ }
+ };
+
+ window.addEventListener('sessionStorageChange', handleCustomStorageChange as EventListener);
+
+ return () => {
+ window.removeEventListener('storage', handleStorageChange);
+ window.removeEventListener('sessionStorageChange', handleCustomStorageChange as EventListener);
+ };
+ }, []);
const getDashboardData = async () => {
@@ -281,7 +289,8 @@ const Account = () => {
Active
Last Change
Expire After (days)
-
+ Sign
+ Action
@@ -318,6 +327,9 @@ const Account = () => {
{tx.expireAfter ?? "-"}
+
+ {tx?.createdBy?.email === currentEmailId ? Sign now : "-"}
+
diff --git a/src/components/dashboard/Dashboard.tsx b/src/components/dashboard/Dashboard.tsx
index 5865246..b35173f 100644
--- a/src/components/dashboard/Dashboard.tsx
+++ b/src/components/dashboard/Dashboard.tsx
@@ -103,32 +103,32 @@ function Dashboard() {
}, [documentSignType])
- useEffect(() => {
- if (showConfetti) {
- const duration = 3000;
- const end = Date.now() + duration;
+ useEffect(() => {
+ if (showConfetti) {
+ const duration = 3000;
+ const end = Date.now() + duration;
- const interval = setInterval(() => {
- if (Date.now() > end) {
- clearInterval(interval);
- return;
- }
+ const interval = setInterval(() => {
+ if (Date.now() > end) {
+ clearInterval(interval);
+ return;
+ }
- confetti({
- particleCount: 80, // more particles
- angle: Math.random() * 360, // fire in random direction
- spread: 220, // wider spread
- startVelocity: 15, // more power
- scalar: 1.2, // bigger pieces (default is 1)
- origin: {
- x: Math.random(),
- y: Math.random() * 0.6,
- },
- zIndex: 9999,
- });
- }, 350); // fire every 150ms
- }
- }, [showConfetti]);
+ confetti({
+ particleCount: 80, // more particles
+ angle: Math.random() * 360, // fire in random direction
+ spread: 220, // wider spread
+ startVelocity: 15, // more power
+ scalar: 1.2, // bigger pieces (default is 1)
+ origin: {
+ x: Math.random(),
+ y: Math.random() * 0.6,
+ },
+ zIndex: 9999,
+ });
+ }, 350); // fire every 150ms
+ }
+ }, [showConfetti]);
diff --git a/src/components/process/CompletionScreen/DocumentCompletionScreen.tsx b/src/components/process/CompletionScreen/DocumentCompletionScreen.tsx
new file mode 100644
index 0000000..17c961c
--- /dev/null
+++ b/src/components/process/CompletionScreen/DocumentCompletionScreen.tsx
@@ -0,0 +1,354 @@
+import React, { useEffect } from "react";
+import {
+ FaCheck,
+ FaFileAlt,
+ FaUsers,
+ FaEnvelope,
+ FaClock,
+ FaDownload,
+ FaShare,
+ FaShieldAlt,
+ FaLock,
+ FaPen,
+ FaCheckCircle
+} from 'react-icons/fa';
+import { fetchRecipients } from "../../../store/slices/selectedRecipientsSlice";
+import { fetchDocuments } from "../../../store/slices/documentSlice";
+import { useDispatch, useSelector } from "react-redux";
+import { Link, useNavigate, useParams } from "react-router-dom";
+import Loader from "../../dashboard/Loader";
+import confetti from 'canvas-confetti'
+import { IoClose } from "react-icons/io5";
+import { IoMdHome } from "react-icons/io";
+
+type Signer = {
+ id: number;
+ name: string;
+ email: string;
+ routingOrder: number;
+ completed: boolean;
+};
+
+// Signers List Component
+const SignersList: React.FC<{ signers: Signer[] }> = ({ signers }) => {
+ return (
+
+
+
+
+
+ Signature Status
+
+
+ {signers.filter(s => s.completed).length} of {signers.length} signed
+
+
+
+
+ {signers.map((signer) => (
+
+
+ {signer.name.split(" ").map(n => n[0].toUpperCase()).join("")}
+
+
+
{signer.name}
+
{signer.email}
+
Order: {signer.routingOrder}
+
+
+ {signer.completed ? (
+
+
+ Signed
+
+ ) : (
+
+
+ Pending
+
+ )}
+
+
+ ))}
+
+
+
+ );
+};
+
+// Fixed Signing Order Diagram Component
+const SigningOrderDiagram: React.FC<{ signers: Signer[] }> = ({ signers }) => {
+ const groupByRoutingOrder = (data: Signer[]) => {
+ const grouped: Record = {};
+ data.forEach((signer) => {
+ if (!grouped[signer.routingOrder]) {
+ grouped[signer.routingOrder] = [];
+ }
+ grouped[signer.routingOrder].push(signer);
+ });
+ return grouped;
+ };
+
+ const getInitials = (name: string) => {
+ return name
+ .split(" ")
+ .map((n) => n[0].toUpperCase())
+ .join("");
+ };
+
+ const grouped = groupByRoutingOrder(signers);
+ const sortedOrders = Object.keys(grouped)
+ .map(Number)
+ .sort((a, b) => a - b);
+
+ const currentProcessingOrder =
+ sortedOrders.find((order) =>
+ grouped[order].some((signer) => !signer.completed)
+ ) || -1;
+
+ return (
+
+
+
Signing Flow
+
+
+ {/* Mail icon */}
+
+
+ {/* Dotted line */}
+
+
+ {/* Signers by routing order */}
+
+ {sortedOrders.map((order, index) => (
+
+
+
+ Step {order}
+
+
+ {grouped[order].map((signer) => {
+ let bgColor = "";
+ let icon = null;
+
+ if (signer.completed) {
+ bgColor = "bg-[var(--primary)]";
+ icon =
;
+ } else if (order === currentProcessingOrder) {
+ bgColor = "bg-yellow-500";
+ icon =
;
+ } else {
+ bgColor = "bg-gray-400";
+ icon =
;
+ }
+
+ return (
+
+
+ {getInitials(signer.name)}
+
+ {icon}
+
+
+
+ {signer.name.split(" ")[0]}
+
+
+ );
+ })}
+
+
+
+ {index < sortedOrders.length - 1 && (
+
+ )}
+
+ ))}
+
+
+
+
+
+ );
+};
+
+// Main DocumentCompletionScreen Component
+const DocumentCompletionScreen = () => {
+ const documentList = [
+ { title: 'Document 1', pages: 12 },
+ { title: 'Document 2', pages: 8 },
+ { title: 'Document 3', pages: 5 },
+ { title: 'Document 4', pages: 22 },
+ { title: 'Document 5', pages: 10 },
+ { title: 'Document 6', pages: 15 },
+ { title: 'Document 7', pages: 7 },
+ { title: 'Document 8', pages: 9 },
+ { title: 'Document 9', pages: 6 },
+ { title: 'Document 10', pages: 11 },
+ { title: 'Document 11', pages: 4 }, // Won't be shown due to slice
+ ];
+
+ const { accountId, transactionId } = useParams<{ accountId: string, transactionId: string }>();
+ const [showConfetti, setShowConfetti] = React.useState(true)
+ if (!accountId || !transactionId) {
+ window.location.href = "/";
+ return null;
+ }
+
+ // const transactionId = useSelector((state: RootState) => state.transaction.transactionId)
+ const navigate = useNavigate();
+ const dispatch = useDispatch();
+
+ const selectedRecipients = useSelector((state: RootState) => state.selectedRecipients.recipients);
+ // const selectedDocuments = useSelector((state: RootState) => state.selectedDocuments.selectedDocuments)
+ const selectedDocuments = useSelector((state: RootState) => state.documents.documents)
+
+
+ useEffect(() => {
+ selectedRecipients.length === 0 && dispatch(fetchRecipients({ accountId, transactionId }));
+ selectedDocuments.length === 0 && dispatch(fetchDocuments({ accountId, transactionId }));
+ }, [])
+
+ useEffect(() => {
+ if (showConfetti) {
+ const duration = 3000;
+ const end = Date.now() + duration;
+
+ const interval = setInterval(() => {
+ if (Date.now() > end) {
+ clearInterval(interval);
+ return;
+ }
+
+ confetti({
+ particleCount: 80, // more particles
+ angle: Math.random() * 360, // fire in random direction
+ spread: 220, // wider spread
+ startVelocity: 15, // more power
+ scalar: 1.2, // bigger pieces (default is 1)
+ origin: {
+ x: Math.random(),
+ y: Math.random() * 0.6,
+ },
+ zIndex: 9999,
+ });
+ }, 350); // fire every 150ms
+ }
+ }, [showConfetti]);
+
+ return (
+ <>
+ <>
+ {
+ showConfetti && (
+
+ {/*
*/}
+
+
+ {/* Close Icon */}
+
setShowConfetti(false)} // or whatever logic hides the modal
+ className="absolute top-2 right-2 text-gray-500 hover:text-gray-700"
+ aria-label="Close"
+ >
+
+
+
+ {/* Success Icon */}
+
+
+ {/* Message */}
+
Transaction Successful
+
Your transaction has been created and saved successfully.
+
+
+ )
+ }
+ >
+
+ {/* Top Banner */}
+
+
+
+
+
+
+
+
+
+
+
+
+
Awesome! Your document is sent for signature
+
+
+
+
+
Edit
+
+
+
+
+ {(selectedRecipients.length > 0 && selectedDocuments.length > 0) ?
+
+
+ {/* Header */}
+
+ {/* Left Section - Document Details */}
+
+ {/* Document Preview Card */}
+
+
+ {selectedDocuments?.map((item, index) => (
+
+
+
+ {/*
*/}
+
+
+
+
+ Name : {item.name ?? '--'}
+
+
+ Status : {item.status ?? '--'}
+
+
+
+
+
+ ))}
+
+
+
+
+ {/* Right Section - Signer Components */}
+
+ {/* Signing Order Diagram */}
+
+
+ {/* Signers List */}
+
+
+
+
+
+ :
}
+
+ >
+ );
+};
+
+export default DocumentCompletionScreen;
\ No newline at end of file
diff --git a/src/components/process/processStepTwo/NavTwo.tsx b/src/components/process/processStepTwo/NavTwo.tsx
index 19d652a..d6b2268 100644
--- a/src/components/process/processStepTwo/NavTwo.tsx
+++ b/src/components/process/processStepTwo/NavTwo.tsx
@@ -10,7 +10,7 @@ import { MdKeyboardArrowDown } from 'react-icons/md'
import { RiResetLeftLine, RiResetRightLine } from 'react-icons/ri'
import { fetchRecipients } from '../../../store/slices/selectedRecipientsSlice'
import { fetchDocuments } from '../../../store/slices/documentSlice'
-import { useParams } from 'react-router-dom'
+import { useNavigate, useParams } from 'react-router-dom'
interface NavTwoProps {
isFields: boolean;
@@ -57,6 +57,8 @@ const NavTwo: React.FC = ({ isFields, setIsFields, isSend, setIsSen
const [isFitDd, setIsFitDd] = useState(false)
const [selFitIndx, setSelFitIndx] = useState(0);
+ const navigate = useNavigate()
+
const selectedRecipients = useSelector((state: RootState) => state.selectedRecipients.recipients)
const selectedDocuments = useSelector((state: RootState) => state.documents.documents)
@@ -76,6 +78,7 @@ const NavTwo: React.FC = ({ isFields, setIsFields, isSend, setIsSen
setIsSend(false);
}
setIsSend(!isSend)
+ navigate(`/document-completion-screen/${accountId}/${transactionId}`)
}
const handleSetIsFields = (setTo: boolean) => {
diff --git a/src/components/process/processStepTwo/rightSideBar/DirectionalControls.tsx b/src/components/process/processStepTwo/rightSideBar/DirectionalControls.tsx
index 4644623..95bb714 100644
--- a/src/components/process/processStepTwo/rightSideBar/DirectionalControls.tsx
+++ b/src/components/process/processStepTwo/rightSideBar/DirectionalControls.tsx
@@ -101,7 +101,7 @@ const DirectionalControls: React.FC = ({
handleMove('right')} disabled={disabled} className={buttonClass} title="Move right" type="button">
- Right: {Math.round(right)}px
+ {/* Right: {Math.round(right)}px */}
{/* Bottom Row */}
@@ -110,7 +110,7 @@ const DirectionalControls: React.FC = ({
handleMove('down')} disabled={disabled} className={buttonClass} title="Move down" type="button">
- Bottom: {Math.round(bottom)}px
+ {/* Bottom: {Math.round(bottom)}px */}
diff --git a/src/components/setting/Setting.tsx b/src/components/setting/Setting.tsx
index 000d1d0..623cc53 100644
--- a/src/components/setting/Setting.tsx
+++ b/src/components/setting/Setting.tsx
@@ -19,8 +19,7 @@ interface Account {
interface UserData {
id: string;
- firstName: string;
- lastName: string;
+ name: string;
email: string;
language: string;
account: Account;
@@ -43,32 +42,35 @@ interface AccountOption {
const Setting = () => {
const { page1 } = useParams<{ page1: string }>();
- console.log("page1" , page1)
+ console.log("page1", page1)
const location = useLocation();
- console.log("location",location)
+ console.log("location", location)
const navigate = useNavigate();
+ const [activeAccountId, setActiveAccountId] = useState(
+ JSON.parse(sessionStorage.getItem('activeAccountId') || 'null')
+ );
+
// Refs for subsections within each main tab
const subSectionRefs = useRef<{ [key: string]: HTMLDivElement | null }>({});
const scrollContainerRef = useRef(null);
const [activeTab, setActiveTab] = useState("userProfile");
const [activeSubSection, setActiveSubSection] = useState("");
- const [user, setUser] = useState({
- id: "",
- firstName: "",
- lastName: "",
- email: "",
- language: "",
+ const [user, setUser] = useState({
+ id: '',
+ name: '',
+ email: '',
+ language: '',
account: {
id: 0,
isDefault: false,
- name: "",
+ name: '',
},
});
const [createAndInviteLoader, setCreateAndInviteLoader] = useState(false);
-
+
// Dropdown data states
const [accountOptions, setAccountOptions] = useState([]);
const [accountOptionsLoading, setAccountOptionsLoading] = useState(false);
@@ -203,8 +205,8 @@ const Setting = () => {
return ;
case "create and invite":
return (
- {
{ id: "contactShare", label: "Share Contact", type: "contact" },
];
- const getUserDetails = async () => {
- try {
- let res = await api.get(`/api/user/details`)
- console.log("getuser", res)
- setUser(res?.data)
- } catch (error) {
- console.error("Error fetching user details:", error);
+
+ // Listen for sessionStorage changes
+ useEffect(() => {
+ const handleStorageChange = (e: StorageEvent) => {
+ if (e.key === 'activeAccountId') {
+ const newActiveAccountId = e.newValue ? JSON.parse(e.newValue) : null;
+ setActiveAccountId(newActiveAccountId);
+ }
+ };
+
+ // Listen for storage events (works for changes from other tabs)
+ window.addEventListener('storage', handleStorageChange);
+
+ // Custom event listener for same-tab changes
+ const handleCustomStorageChange = (e: CustomEvent) => {
+ if (e.detail.key === 'activeAccountId') {
+ setActiveAccountId(e.detail.newValue);
+ }
+ };
+
+ window.addEventListener('sessionStorageChange', handleCustomStorageChange as EventListener);
+
+ return () => {
+ window.removeEventListener('storage', handleStorageChange);
+ window.removeEventListener('sessionStorageChange', handleCustomStorageChange as EventListener);
+ };
+ }, []);
+
+ // Re-fetch dashboard data when activeAccountId changes
+ useEffect(() => {
+ const rawUser = JSON.parse(sessionStorage.getItem('userDetails') || 'null');
+
+ if (rawUser) {
+ const userData: UserData = {
+ id: String(rawUser.id || ''),
+ name: rawUser.name || '',
+ email: rawUser.email || '',
+ language: rawUser.language || '',
+ account: {
+ id: rawUser.account?.id || 0,
+ isDefault: rawUser.account?.isDefault || false,
+ name: rawUser.account?.name || '',
+ },
+ };
+
+ setUser(userData);
}
- }
+ }, [activeAccountId]);
+
+
useEffect(() => {
- getUserDetails()
// Fetch account list when component mounts
getAccountList()
}, [])
@@ -259,7 +301,7 @@ const Setting = () => {
// Set initial subsection when component mounts or activeTab changes
useEffect(() => {
const subSections = getSubSections(activeTab);
- console.log("subSections",subSections)
+ console.log("subSections", subSections)
const hash = location.hash.replace('#', '');
if (subSections.length > 0) {
@@ -292,7 +334,7 @@ const Setting = () => {
setCreateAndInviteLoader(true)
try {
let res;
- let toastMesaage ;
+ let toastMesaage;
if (action === 'create') {
console.log('Creating account:', data);
const payloadAccount = {
@@ -310,10 +352,10 @@ const Setting = () => {
role: data.role
}
res = await api.post(`/api/accounts/${data.i_accountName}/invite`, payloadInvite)
- console.log("InviteNAme",res)
+ console.log("InviteNAme", res)
toastMesaage = "Invite Successfull...!"
}
-
+
if (res?.data) {
toast.success(toastMesaage, {
position: "top-center",
@@ -326,7 +368,7 @@ const Setting = () => {
theme: "light",
transition: Bounce,
});
-
+
// Refetch account list after successful submission
await getAccountList();
}
@@ -340,7 +382,7 @@ const Setting = () => {
return (
<>
{/* */}
-
+ {/* */}
{/* Main Navigation Tabs */}
@@ -364,7 +406,7 @@ const Setting = () => {
{/* Content with Aside Navigation */}
-
+
{/* Fixed Aside Navigation - Shows subsections of active tab */}
{activeTab === 'userProfile' &&
diff --git a/src/components/setting/Signature/AddSignatureModal.tsx b/src/components/setting/Signature/AddSignatureModal.tsx
index a92c172..285a997 100644
--- a/src/components/setting/Signature/AddSignatureModal.tsx
+++ b/src/components/setting/Signature/AddSignatureModal.tsx
@@ -1,6 +1,6 @@
import React, { useEffect, useState } from 'react';
import { AiOutlineUpload, AiOutlineEdit } from 'react-icons/ai';
-import { MdCloudUpload } from 'react-icons/md';
+import { MdCloudUpload } from 'react-icons/md';
import api from '../../../config/api';
import DrawSignatureCanvas from './DrawSignatureCanvas';
import { FaSpinner } from "react-icons/fa";
@@ -54,7 +54,7 @@ const AddSignatureModal: React.FC = ({
getAllSignatures,
editingSignature
}) => {
- const [activeTab, setActiveTab] = useState<'SELECT' | 'DRAW' | 'UPLOAD'>('SELECT');
+ const [activeTab, setActiveTab] = useState<'TYPE' | 'DRAW' | 'UPLOAD' | 'SELECT'>('TYPE');
const [fullName, setFullName] = useState('');
const [initials, setInitials] = useState('');
const [isSubmitting, setIsSubmitting] = useState(false);
@@ -102,9 +102,10 @@ const AddSignatureModal: React.FC = ({
// Navigation items
const navigationItems = [
- { id: 'SELECT', label: 'SELECT', icon: },
+ { id: 'TYPE', label: 'TYPE', icon: },
{ id: 'DRAW', label: 'DRAW', icon: },
{ id: 'UPLOAD', label: 'UPLOAD', icon: },
+ { id: 'SELECT', label: 'SELECT', icon: },
];
// Initialize form with editing signature data
@@ -112,7 +113,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 'SELECT' | 'DRAW' | 'UPLOAD');
+ setActiveTab(editingSignature.signatureType as 'TYPE' | 'DRAW' | 'UPLOAD');
// Set font for SELECT tab
const fontOption = signatureOptions.find(option => option.style === editingSignature.font);
@@ -262,7 +263,7 @@ const AddSignatureModal: React.FC = ({
const renderContent = () => {
switch (activeTab) {
- case 'SELECT':
+ case 'TYPE':
return (
@@ -383,6 +384,16 @@ const AddSignatureModal: React.FC
= ({
);
+
+
+ case 'SELECT':
+ return (
+
+ );
default:
return null;
}
@@ -462,7 +473,7 @@ const AddSignatureModal: React.FC
= ({
{navigationItems.map((item) => (
setActiveTab(item.id as 'SELECT' | 'DRAW' | 'UPLOAD')}
+ onClick={() => setActiveTab(item.id as 'TYPE' | 'DRAW' | 'UPLOAD')}
className={`w-full flex items-center space-x-3 px-2 py-2 text-sm font-medium rounded-lg cursor-pointer transition-colors ${activeTab === item.id
? 'bg-blue-50 text-blue-700 border border-blue-200'
: 'text-gray-600 hover:bg-gray-100 hover:text-gray-900'
diff --git a/src/components/setting/Signature/Signature.tsx b/src/components/setting/Signature/Signature.tsx
index 2b0b901..45074b7 100644
--- a/src/components/setting/Signature/Signature.tsx
+++ b/src/components/setting/Signature/Signature.tsx
@@ -175,7 +175,7 @@ const SignatureManager: React.FC = () => {
{/* Label */}
- DS
+ Initials
{/* Signature Image */}
@@ -186,6 +186,10 @@ const SignatureManager: React.FC = () => {
alt="DS Signature"
/>
+ {/* Initial ID */}
+
+ {signature.initialsHash}
+
diff --git a/src/components/setting/UserProfile.tsx b/src/components/setting/UserProfile.tsx
index ce58abd..95b0412 100644
--- a/src/components/setting/UserProfile.tsx
+++ b/src/components/setting/UserProfile.tsx
@@ -6,9 +6,8 @@ interface Account {
}
interface UserData {
- id: string;
- firstName: string;
- lastName: string;
+ id: number;
+ name:string
email: string;
language: string;
account: Account;
@@ -26,7 +25,7 @@ const UserProfile: React.FC
= ({ userData }) => {
{/* Profile Picture */}
- {getInitials(userData.firstName, userData.lastName)}
+ {userData.name.slice(0,2).toUpperCase()}
@@ -36,7 +35,7 @@ const UserProfile: React.FC = ({ userData }) => {
Name
- {userData.firstName} {userData.lastName}
+ {userData.name}
diff --git a/src/components/transactions/TransactionView.tsx b/src/components/transactions/TransactionView.tsx
index 9f1bbe3..5ec0c86 100644
--- a/src/components/transactions/TransactionView.tsx
+++ b/src/components/transactions/TransactionView.tsx
@@ -64,13 +64,14 @@ const TransactionView = () => {
{/* Header */}
- Complete with Forms Made Easy: { transactionDetails.transaction.name ?? "Untitled"}
+ Complete with Forms Made Easy: { transactionDetails?.transaction?.subject ?? "Untitled"}
+ {/* new Date(transactionDetails?.transaction?.lastModifiedAt * 1000) */}
From Shanu.R
-
Last Change on 12/02/25
-
Sent on 11/02/25
+
Last Change on {new Date(transactionDetails?.transaction?.lastModifiedAt * 1000).toISOString()}
+
Created at {new Date(transactionDetails?.transaction?.createdAt * 1000).toISOString()}
Draft
@@ -139,7 +140,7 @@ const TransactionView = () => {
Message
-
No Message Found
+
{ transactionDetails?.transaction?.message ?? "No Message Found...!"}
diff --git a/vite.config.ts b/vite.config.ts
index 70397db..0472e82 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -12,7 +12,8 @@ export default defineConfig({
'officially-powerful-goat.ngrok-free.app',
'89f0-49-36-189-120.ngrok-free.app',
'c8ee-49-36-191-130.ngrok-free.app',
- 'c76f1251c173.ngrok-free.app'
+ 'c76f1251c173.ngrok-free.app',
+ 'enabled-upright-boxer.ngrok-free.app'
],
},
build: {