Compare commits
2 Commits
a7b7be491e
...
f045674055
| Author | SHA1 | Date |
|---|---|---|
|
|
f045674055 | |
|
|
f2b17edb13 |
10
src/App.tsx
10
src/App.tsx
|
|
@ -60,31 +60,31 @@ const App = () => {
|
||||||
<Route path="/s/:page1" element={<Setting />} />
|
<Route path="/s/:page1" element={<Setting />} />
|
||||||
</Route>
|
</Route>
|
||||||
|
|
||||||
<Route path="/process-step-one/:accountId/:transactionId" element={
|
<Route path="/setup-transaction/:accountId/:transactionId" element={
|
||||||
<ProtectedRoute>
|
<ProtectedRoute>
|
||||||
<ProcessStepOne />
|
<ProcessStepOne />
|
||||||
</ProtectedRoute>
|
</ProtectedRoute>
|
||||||
} />
|
} />
|
||||||
|
|
||||||
<Route path="/process-step-one/:accountId/:transactionId/:signType" element={
|
<Route path="/setup-transaction/:accountId/:transactionId/:signType" element={
|
||||||
<ProtectedRoute>
|
<ProtectedRoute>
|
||||||
<ProcessStepOne />
|
<ProcessStepOne />
|
||||||
</ProtectedRoute>
|
</ProtectedRoute>
|
||||||
} />
|
} />
|
||||||
|
|
||||||
<Route path="/process-step-one/:accountId/template/:templateId" element={
|
<Route path="/setup-transaction/:accountId/template/:templateId" element={
|
||||||
<ProtectedRoute>
|
<ProtectedRoute>
|
||||||
<ProcessStepOne />
|
<ProcessStepOne />
|
||||||
</ProtectedRoute>
|
</ProtectedRoute>
|
||||||
} />
|
} />
|
||||||
|
|
||||||
<Route path="/process-step-two/:accountId/template/:templateId" element={
|
<Route path="/review-and-tag/:accountId/template/:templateId" element={
|
||||||
<ProtectedRoute>
|
<ProtectedRoute>
|
||||||
<ProcessStepTwo />
|
<ProcessStepTwo />
|
||||||
</ProtectedRoute>
|
</ProtectedRoute>
|
||||||
} />
|
} />
|
||||||
|
|
||||||
<Route path="/process-step-two/:accountId/:transactionId" element={
|
<Route path="/review-and-tag/:accountId/:transactionId" element={
|
||||||
<ProtectedRoute>
|
<ProtectedRoute>
|
||||||
<ProcessStepTwo />
|
<ProcessStepTwo />
|
||||||
</ProtectedRoute>
|
</ProtectedRoute>
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,7 @@ const SigningOrderDiagram : React.FC<Signer[]> = (signers) => {
|
||||||
if (signer.completed) {
|
if (signer.completed) {
|
||||||
bgColor = "bg-green-500";
|
bgColor = "bg-green-500";
|
||||||
icon = <FaCheck className="text-green-600" />;
|
icon = <FaCheck className="text-green-600" />;
|
||||||
} else if (order === currentProcessingOrder) {
|
} else if (order == currentProcessingOrder) {
|
||||||
bgColor = "bg-yellow-500";
|
bgColor = "bg-yellow-500";
|
||||||
icon = <FaClock className="text-yellow-800" />;
|
icon = <FaClock className="text-yellow-800" />;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -111,7 +111,7 @@ const SigningOrderDiagram : React.FC<Signer[]> = (signers) => {
|
||||||
className={`w-10 h-10 rounded-full flex items-center justify-center text-white text-sm font-semibold ${bgColor}`}
|
className={`w-10 h-10 rounded-full flex items-center justify-center text-white text-sm font-semibold ${bgColor}`}
|
||||||
title={signer?.name}
|
title={signer?.name}
|
||||||
>
|
>
|
||||||
{(signer?.name !== '' || signer?.roleName) ? getInitials(signer?.name || signer?.roleName) : ""}
|
{(signer?.name != '' || signer?.roleName) ? getInitials(signer?.name || signer?.roleName) : ""}
|
||||||
<span className="absolute bottom-[12px] right-[-12px] p-1 rounded-full bg-white shadow">
|
<span className="absolute bottom-[12px] right-[-12px] p-1 rounded-full bg-white shadow">
|
||||||
{icon}
|
{icon}
|
||||||
</span>
|
</span>
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ const CommonNav: React.FC<AccountNavProps> = ({
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (initial !== "") return
|
if (initial != "") return
|
||||||
console.log(userDetailsAsync, 'line 89')
|
console.log(userDetailsAsync, 'line 89')
|
||||||
let initialN = (userDetailsAsync.firstName && userDetailsAsync.firstName[0])
|
let initialN = (userDetailsAsync.firstName && userDetailsAsync.firstName[0])
|
||||||
initialN = initialN + "" + (userDetailsAsync.lastName && userDetailsAsync.lastName[0])
|
initialN = initialN + "" + (userDetailsAsync.lastName && userDetailsAsync.lastName[0])
|
||||||
|
|
@ -121,7 +121,7 @@ const CommonNav: React.FC<AccountNavProps> = ({
|
||||||
if (!accountsOpen) {
|
if (!accountsOpen) {
|
||||||
setLoadingAccounts(true);
|
setLoadingAccounts(true);
|
||||||
|
|
||||||
if (accounts.length === 0 || hasModalBeenClosed) {
|
if (accounts.length == 0 || hasModalBeenClosed) {
|
||||||
await getAccountDetails();
|
await getAccountDetails();
|
||||||
setHasModalBeenClosed(false);
|
setHasModalBeenClosed(false);
|
||||||
}
|
}
|
||||||
|
|
@ -278,7 +278,7 @@ const CommonNav: React.FC<AccountNavProps> = ({
|
||||||
|
|
||||||
// Special case: if first segment is 's' and next is 'settings', remove 's'
|
// Special case: if first segment is 's' and next is 'settings', remove 's'
|
||||||
const pathnames =
|
const pathnames =
|
||||||
rawPathnames[0] === "s" && rawPathnames[1] === "settings"
|
rawPathnames[0] == "s" && rawPathnames[1] == "settings"
|
||||||
? rawPathnames.slice(1)
|
? rawPathnames.slice(1)
|
||||||
: rawPathnames;
|
: rawPathnames;
|
||||||
|
|
||||||
|
|
@ -298,7 +298,7 @@ const CommonNav: React.FC<AccountNavProps> = ({
|
||||||
const accIndex = pathnames.indexOf("accounts");
|
const accIndex = pathnames.indexOf("accounts");
|
||||||
const txnIndex = pathnames.indexOf("transactions");
|
const txnIndex = pathnames.indexOf("transactions");
|
||||||
|
|
||||||
if (accIndex !== -1 && txnIndex !== -1 && txnIndex > accIndex) {
|
if (accIndex != -1 && txnIndex != -1 && txnIndex > accIndex) {
|
||||||
// keep only "transactions" and everything after it
|
// keep only "transactions" and everything after it
|
||||||
filteredPathnames = pathnames.slice(txnIndex);
|
filteredPathnames = pathnames.slice(txnIndex);
|
||||||
}
|
}
|
||||||
|
|
@ -336,13 +336,13 @@ const CommonNav: React.FC<AccountNavProps> = ({
|
||||||
|
|
||||||
{/* Breadcrumb Navigation */}
|
{/* Breadcrumb Navigation */}
|
||||||
<nav className="text-md font-medium text-gray-800 capitalize flex items-center flex-wrap">
|
<nav className="text-md font-medium text-gray-800 capitalize flex items-center flex-wrap">
|
||||||
{filteredPathnames.length === 0 ? (
|
{filteredPathnames.length == 0 ? (
|
||||||
<span className="hidden sm:block text-sm ml-4">Welcome <span className='text-white ml-1 bg-[#34BEFF] px-2.5 py-1 rounded-2xl'>{user.firstName ? user.firstName : user.lastName}!</span></span>
|
<span className="hidden sm:block text-sm ml-4">Welcome <span className='text-white ml-1 bg-[#34BEFF] px-2.5 py-1 rounded-2xl'>{user.firstName ? user.firstName : user.lastName}!</span></span>
|
||||||
) : (
|
) : (
|
||||||
filteredPathnames.map((segment, index) => {
|
filteredPathnames.map((segment, index) => {
|
||||||
const label = labelMap[segment] || formatSegment(segment);
|
const label = labelMap[segment] || formatSegment(segment);
|
||||||
const to = "/" + filteredPathnames.slice(0, index + 1).join("/");
|
const to = "/" + filteredPathnames.slice(0, index + 1).join("/");
|
||||||
const isLast = index === filteredPathnames.length - 1;
|
const isLast = index == filteredPathnames.length - 1;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span key={to} className="flex items-center">
|
<span key={to} className="flex items-center">
|
||||||
|
|
@ -485,7 +485,7 @@ const CommonNav: React.FC<AccountNavProps> = ({
|
||||||
<div className="flex-1 min-w-0">
|
<div className="flex-1 min-w-0">
|
||||||
<div className="flex items-center space-x-2">
|
<div className="flex items-center space-x-2">
|
||||||
<span className="font-medium text-gray-900 text-sm">{account.accountName}</span>
|
<span className="font-medium text-gray-900 text-sm">{account.accountName}</span>
|
||||||
{account.accountId === activeAccountId && (
|
{account.accountId == activeAccountId && (
|
||||||
<FaCheck className="text-green-600 text-xs" />
|
<FaCheck className="text-green-600 text-xs" />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,7 @@ const Account = () => {
|
||||||
// Listen for sessionStorage changes
|
// Listen for sessionStorage changes
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleStorageChange = (e: StorageEvent) => {
|
const handleStorageChange = (e: StorageEvent) => {
|
||||||
if (e.key === 'activeAccountId') {
|
if (e.key == 'activeAccountId') {
|
||||||
const newActiveAccountId = e.newValue ? JSON.parse(e.newValue) : null;
|
const newActiveAccountId = e.newValue ? JSON.parse(e.newValue) : null;
|
||||||
setActiveAccountId(newActiveAccountId);
|
setActiveAccountId(newActiveAccountId);
|
||||||
}
|
}
|
||||||
|
|
@ -123,7 +123,7 @@ const Account = () => {
|
||||||
|
|
||||||
// Custom event listener for same-tab changes
|
// Custom event listener for same-tab changes
|
||||||
const handleCustomStorageChange = (e: CustomEvent) => {
|
const handleCustomStorageChange = (e: CustomEvent) => {
|
||||||
if (e.detail.key === 'activeAccountId') {
|
if (e.detail.key == 'activeAccountId') {
|
||||||
setActiveAccountId(e.detail.newValue);
|
setActiveAccountId(e.detail.newValue);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ const AccountNav: React.FC<AccountNavProps> = ({ accountName = null, transaction
|
||||||
if (!accountsOpen) {
|
if (!accountsOpen) {
|
||||||
setLoadingAccounts(true);
|
setLoadingAccounts(true);
|
||||||
|
|
||||||
if (accounts.length === 0 || hasModalBeenClosed) {
|
if (accounts.length == 0 || hasModalBeenClosed) {
|
||||||
await getAccountDetails();
|
await getAccountDetails();
|
||||||
setHasModalBeenClosed(false);
|
setHasModalBeenClosed(false);
|
||||||
}
|
}
|
||||||
|
|
@ -187,7 +187,7 @@ const AccountNav: React.FC<AccountNavProps> = ({ accountName = null, transaction
|
||||||
|
|
||||||
// Special case: if first segment is 's' and next is 'settings', remove 's'
|
// Special case: if first segment is 's' and next is 'settings', remove 's'
|
||||||
const pathnames =
|
const pathnames =
|
||||||
rawPathnames[0] === "s" && rawPathnames[1] === "settings"
|
rawPathnames[0] == "s" && rawPathnames[1] == "settings"
|
||||||
? rawPathnames.slice(1)
|
? rawPathnames.slice(1)
|
||||||
: rawPathnames;
|
: rawPathnames;
|
||||||
|
|
||||||
|
|
@ -256,13 +256,13 @@ const AccountNav: React.FC<AccountNavProps> = ({ accountName = null, transaction
|
||||||
return (
|
return (
|
||||||
<header className="w-full px-6 py-2 flex justify-between items-center bg-white border-b rounded-sm border-gray-200">
|
<header className="w-full px-6 py-2 flex justify-between items-center bg-white border-b rounded-sm border-gray-200">
|
||||||
<nav className="text-md font-medium text-gray-800 capitalize flex items-center flex-wrap">
|
<nav className="text-md font-medium text-gray-800 capitalize flex items-center flex-wrap">
|
||||||
{pathnames.length === 0 ? (
|
{pathnames.length == 0 ? (
|
||||||
<span className="text-gray-900 font-semibold">Dashboard</span>
|
<span className="text-gray-900 font-semibold">Dashboard</span>
|
||||||
) : (
|
) : (
|
||||||
pathnames.map((segment, index) => {
|
pathnames.map((segment, index) => {
|
||||||
const label = labelMap[segment] || formatSegment(segment);
|
const label = labelMap[segment] || formatSegment(segment);
|
||||||
const to = "/" + pathnames.slice(0, index + 1).join("/");
|
const to = "/" + pathnames.slice(0, index + 1).join("/");
|
||||||
const isLast = index === pathnames.length - 1;
|
const isLast = index == pathnames.length - 1;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span key={to} className="flex items-center">
|
<span key={to} className="flex items-center">
|
||||||
|
|
@ -361,7 +361,7 @@ const AccountNav: React.FC<AccountNavProps> = ({ accountName = null, transaction
|
||||||
<div className="flex-1 min-w-0">
|
<div className="flex-1 min-w-0">
|
||||||
<div className="flex items-center space-x-2">
|
<div className="flex items-center space-x-2">
|
||||||
<span className="font-medium text-gray-900 text-sm">{account.accountName}</span>
|
<span className="font-medium text-gray-900 text-sm">{account.accountName}</span>
|
||||||
{account.accountId === activeAccountId && (
|
{account.accountId == activeAccountId && (
|
||||||
<FaCheck className="text-green-600 text-xs" />
|
<FaCheck className="text-green-600 text-xs" />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,11 @@ const getStatusLabel = (
|
||||||
status: AccountStatus,
|
status: AccountStatus,
|
||||||
role: UserRole
|
role: UserRole
|
||||||
): { text: string; color: string } => {
|
): { text: string; color: string } => {
|
||||||
if (status === AccountStatus.ACTIVE && role !== UserRole.OWNER)
|
if (status == AccountStatus.ACTIVE && role != UserRole.OWNER)
|
||||||
return { text: "Accepted", color: "text-green-600 bg-green-100" };
|
return { text: "Accepted", color: "text-green-600 bg-green-100" };
|
||||||
if (status === AccountStatus.REJECTED)
|
if (status == AccountStatus.REJECTED)
|
||||||
return { text: "Rejected", color: "text-red-600 bg-red-100" };
|
return { text: "Rejected", color: "text-red-600 bg-red-100" };
|
||||||
if (status === AccountStatus.INVITED)
|
if (status == AccountStatus.INVITED)
|
||||||
return { text: "Pending", color: "text-yellow-600 bg-yellow-100" };
|
return { text: "Pending", color: "text-yellow-600 bg-yellow-100" };
|
||||||
return { text: "Active", color: "text-blue-600 bg-blue-100" };
|
return { text: "Active", color: "text-blue-600 bg-blue-100" };
|
||||||
};
|
};
|
||||||
|
|
@ -83,13 +83,13 @@ const Accounts = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleMenuToggle = (accountId: string) => {
|
const handleMenuToggle = (accountId: string) => {
|
||||||
setOpenMenuId(openMenuId === accountId ? null : accountId);
|
setOpenMenuId(openMenuId == accountId ? null : accountId);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleAction = async (accountId: string, action: 'accept' | 'reject') => {
|
const handleAction = async (accountId: string, action: 'accept' | 'reject') => {
|
||||||
try {
|
try {
|
||||||
let response = await api.post(`/api/v1/accounts/${accountId}/accept/invite`)
|
let response = await api.post(`/api/v1/accounts/${accountId}/accept/invite`)
|
||||||
if (response.data.status === 202) {
|
if (response.data.status == 202) {
|
||||||
toast.success("Login Successful", {
|
toast.success("Login Successful", {
|
||||||
position: "top-center",
|
position: "top-center",
|
||||||
autoClose: 5000,
|
autoClose: 5000,
|
||||||
|
|
@ -171,7 +171,7 @@ const Accounts = () => {
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
{/* Dropdown menu */}
|
{/* Dropdown menu */}
|
||||||
{openMenuId === account.accountId && (
|
{openMenuId == account.accountId && (
|
||||||
<div
|
<div
|
||||||
className="absolute right-13 top-6 mt-1 w-18 bg-white border text-[13px] font-bold border-gray-300 rounded-md shadow-lg z-10"
|
className="absolute right-13 top-6 mt-1 w-18 bg-white border text-[13px] font-bold border-gray-300 rounded-md shadow-lg z-10"
|
||||||
onClick={(e) => e.stopPropagation()} // prevent row click closing
|
onClick={(e) => e.stopPropagation()} // prevent row click closing
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,7 @@ const TransactionDataTable = ({ activeAccountId }) => {
|
||||||
return (
|
return (
|
||||||
<div className="bg-white rounded-xl shadow-sm border border-gray-200 overflow-hidden p-5">
|
<div className="bg-white rounded-xl shadow-sm border border-gray-200 overflow-hidden p-5">
|
||||||
{/* Table Header */}
|
{/* Table Header */}
|
||||||
{location.pathname !== "/transactions" && (
|
{location.pathname != "/transactions" && (
|
||||||
<div className="flex justify-between items-center pb-3">
|
<div className="flex justify-between items-center pb-3">
|
||||||
<h2 className="text-lg font-semibold text-gray-800">Recent Transactions</h2>
|
<h2 className="text-lg font-semibold text-gray-800">Recent Transactions</h2>
|
||||||
<span
|
<span
|
||||||
|
|
@ -104,7 +104,7 @@ const TransactionDataTable = ({ activeAccountId }) => {
|
||||||
|
|
||||||
{/* Table */}
|
{/* Table */}
|
||||||
<div
|
<div
|
||||||
className={`overflow-auto rounded-lg ${location.pathname === "/transactions"
|
className={`overflow-auto rounded-lg ${location.pathname == "/transactions"
|
||||||
? "min-h-[70vh] max-h-[70vh]"
|
? "min-h-[70vh] max-h-[70vh]"
|
||||||
: "min-h-[30vh] max-h-[50vh]"
|
: "min-h-[30vh] max-h-[50vh]"
|
||||||
}`}
|
}`}
|
||||||
|
|
@ -134,7 +134,7 @@ const TransactionDataTable = ({ activeAccountId }) => {
|
||||||
{transactions.map((tx, idx) => (
|
{transactions.map((tx, idx) => (
|
||||||
<tr
|
<tr
|
||||||
key={tx.id}
|
key={tx.id}
|
||||||
className={`${idx % 2 !== 0 ? "bg-gray-50" : "bg-white"} border-b border-gray-300 hover:bg-gray-100 transition`}
|
className={`${idx % 2 != 0 ? "bg-gray-50" : "bg-white"} border-b border-gray-300 hover:bg-gray-100 transition`}
|
||||||
>
|
>
|
||||||
<td
|
<td
|
||||||
onClick={() => navigate(`/accounts/${activeAccountId}/transactions/${tx.id}`)}
|
onClick={() => navigate(`/accounts/${activeAccountId}/transactions/${tx.id}`)}
|
||||||
|
|
@ -205,8 +205,8 @@ const TransactionDataTable = ({ activeAccountId }) => {
|
||||||
|
|
||||||
<button
|
<button
|
||||||
onClick={() => setPage((prev) => Math.max(prev - 1, 0))}
|
onClick={() => setPage((prev) => Math.max(prev - 1, 0))}
|
||||||
disabled={page === 0}
|
disabled={page == 0}
|
||||||
className={`px-3 py-1 rounded border ${page === 0 ? "bg-gray-100 text-gray-400 cursor-not-allowed" : "bg-white hover:bg-gray-50"
|
className={`px-3 py-1 rounded border ${page == 0 ? "bg-gray-100 text-gray-400 cursor-not-allowed" : "bg-white hover:bg-gray-50"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
Prev
|
Prev
|
||||||
|
|
|
||||||
|
|
@ -115,15 +115,15 @@ const LoginForm = ({ onSwitchToRegister }) => {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
if (res.status === 200) {
|
if (res.status == 200) {
|
||||||
TokenStorage.setTokens(res.data.accessToken, res.data.refreshToken)
|
TokenStorage.setTokens(res.data.accessToken, res.data.refreshToken)
|
||||||
formErrorRef.current = { message: "Login Successfully", error: false }
|
formErrorRef.current = { message: "Login Successfully", error: false }
|
||||||
navigate("/");
|
navigate("/");
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err.response?.status === 400 || err.response?.status === 401) {
|
if (err.response?.status == 400 || err.response?.status == 401) {
|
||||||
formErrorRef.current = { message: "The email or password you entered is invalid.", error: true }
|
formErrorRef.current = { message: "The email or password you entered is invalid.", error: true }
|
||||||
} else if(err.response?.status === 404) {
|
} else if(err.response?.status == 404) {
|
||||||
formErrorRef.current = { message: "Email not found. Please sign up to continue.", error: true }
|
formErrorRef.current = { message: "Email not found. Please sign up to continue.", error: true }
|
||||||
} else {
|
} else {
|
||||||
formErrorRef.current = { message: "Something went wrong. Please refresh and try again.", error: true }
|
formErrorRef.current = { message: "Something went wrong. Please refresh and try again.", error: true }
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ const OAuthGoogle: React.FC<OAuthGoogleProps> = ({ isLogin }) => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.status === 200 || res.status === 201) {
|
if (res.status == 200 || res.status == 201) {
|
||||||
toast.dismiss();
|
toast.dismiss();
|
||||||
|
|
||||||
dispatch(updateUser({ ...res.data, authorized: true, accessToken: res.headers.authorization }));
|
dispatch(updateUser({ ...res.data, authorized: true, accessToken: res.headers.authorization }));
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,7 @@ const RegisterForm = ({ onSwitchToLogin }) => {
|
||||||
|
|
||||||
const validateConfirmPassword = (confirmPassword: string, password: string) => {
|
const validateConfirmPassword = (confirmPassword: string, password: string) => {
|
||||||
if (!confirmPassword) return "Please confirm your password";
|
if (!confirmPassword) return "Please confirm your password";
|
||||||
if (confirmPassword !== password) return "Passwords do not match";
|
if (confirmPassword != password) return "Passwords do not match";
|
||||||
return "";
|
return "";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -105,7 +105,7 @@ const RegisterForm = ({ onSwitchToLogin }) => {
|
||||||
if (errors[field]) setErrors({ ...errors, [field]: "" });
|
if (errors[field]) setErrors({ ...errors, [field]: "" });
|
||||||
|
|
||||||
// If password changes, check confirm password
|
// If password changes, check confirm password
|
||||||
if (field === "password" && formData.confirmPassword && errors.confirmPassword) {
|
if (field == "password" && formData.confirmPassword && errors.confirmPassword) {
|
||||||
const confirmError = validateConfirmPassword(formData.confirmPassword, value);
|
const confirmError = validateConfirmPassword(formData.confirmPassword, value);
|
||||||
if (!confirmError) setErrors({ ...errors, password: "", confirmPassword: "" });
|
if (!confirmError) setErrors({ ...errors, password: "", confirmPassword: "" });
|
||||||
}
|
}
|
||||||
|
|
@ -121,7 +121,7 @@ const RegisterForm = ({ onSwitchToLogin }) => {
|
||||||
const newErrors = { firstName: firstNameError, lastName: lastNameError, email: emailError, password: passwordError, confirmPassword: confirmPasswordError };
|
const newErrors = { firstName: firstNameError, lastName: lastNameError, email: emailError, password: passwordError, confirmPassword: confirmPasswordError };
|
||||||
setErrors(newErrors);
|
setErrors(newErrors);
|
||||||
|
|
||||||
if (Object.values(newErrors).some(e => e !== "")) return;
|
if (Object.values(newErrors).some(e => e != "")) return;
|
||||||
|
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
|
|
||||||
|
|
@ -137,12 +137,12 @@ const RegisterForm = ({ onSwitchToLogin }) => {
|
||||||
{ withCredentials: true }
|
{ withCredentials: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
if (res.status === 201) {
|
if (res.status == 201) {
|
||||||
TokenStorage.setTokens(res.data.accessToken, res.data.refreshToken);
|
TokenStorage.setTokens(res.data.accessToken, res.data.refreshToken);
|
||||||
navigate("/");
|
navigate("/");
|
||||||
}
|
}
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
if (err.response?.status === 409) {
|
if (err.response?.status == 409) {
|
||||||
formErrorRef.current = { message: 'Email already exists. Try logging in.', error: true };
|
formErrorRef.current = { message: 'Email already exists. Try logging in.', error: true };
|
||||||
} else {
|
} else {
|
||||||
formErrorRef.current = { message: 'Something went wrong. Please refresh and try again.', error: true };
|
formErrorRef.current = { message: 'Something went wrong. Please refresh and try again.', error: true };
|
||||||
|
|
|
||||||
|
|
@ -18,9 +18,9 @@ function UserAuthUI() {
|
||||||
// Sync isLogin state with the current route
|
// Sync isLogin state with the current route
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const path = location.pathname;
|
const path = location.pathname;
|
||||||
if (path === "/login") {
|
if (path == "/login") {
|
||||||
setIsLogin(true);
|
setIsLogin(true);
|
||||||
} else if (path === "/register") {
|
} else if (path == "/register") {
|
||||||
setIsLogin(false);
|
setIsLogin(false);
|
||||||
}
|
}
|
||||||
}, [location.pathname]);
|
}, [location.pathname]);
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ const ClientAuditModal: React.FC<ClientAuditModalProps> = ({ open, onClose, reci
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
// let res = await api.get(`/api/v1/accounts/${accountId}/transactions/${transactionId}/audit?lang=hi`)
|
// let res = await api.get(`/api/v1/accounts/${accountId}/transactions/${transactionId}/audit?lang=hi`)
|
||||||
if (res?.status === 200) {
|
if (res?.status == 200) {
|
||||||
// console.log(res?.data?.events)
|
// console.log(res?.data?.events)
|
||||||
// let auditResponse = res?.data?.events
|
// let auditResponse = res?.data?.events
|
||||||
setAuditStatus(res.data.events || []);
|
setAuditStatus(res.data.events || []);
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ export default function DeclineModal({
|
||||||
type="radio"
|
type="radio"
|
||||||
name="declineReason"
|
name="declineReason"
|
||||||
value={r}
|
value={r}
|
||||||
checked={reason === r}
|
checked={reason == r}
|
||||||
onChange={() => setReason(r)}
|
onChange={() => setReason(r)}
|
||||||
className="h-4 w-4 text-red-500 border-gray-300 focus:ring-red-500"
|
className="h-4 w-4 text-red-500 border-gray-300 focus:ring-red-500"
|
||||||
/>
|
/>
|
||||||
|
|
@ -69,7 +69,7 @@ export default function DeclineModal({
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Comments (only for Other) */}
|
{/* Comments (only for Other) */}
|
||||||
{reason === "Other" && (
|
{reason == "Other" && (
|
||||||
<div className="mb-6">
|
<div className="mb-6">
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||||
Additional Comments
|
Additional Comments
|
||||||
|
|
|
||||||
|
|
@ -14,93 +14,94 @@ const DocumentPages = ({ selectedDocuments, setDropDownTogglePage, dropDownToggl
|
||||||
const [currentPage, setCurrentPage] = useState(0);
|
const [currentPage, setCurrentPage] = useState(0);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-2 pb-[6rem]">
|
<div className="flex flex-col gap-2 pb-[6rem]">
|
||||||
{selectedDocuments && selectedDocuments.length && selectedDocuments.map((document, indx) => {
|
{selectedDocuments && selectedDocuments.length && selectedDocuments.map((document, indx) => {
|
||||||
return (
|
return (
|
||||||
|
<div
|
||||||
|
key={indx}
|
||||||
|
|
||||||
|
// tabIndex={1}
|
||||||
|
// onBlur={() => setDropDownTogglePage('')}
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
key={indx}
|
onClick={() => {
|
||||||
|
setDropDownTogglePage(`${(dropDownTogglePage == 'pageDropDown' + indx) ? '' : 'pageDropDown' + indx}`);
|
||||||
// tabIndex={1}
|
window.location.hash = document.documentId + "" + 0;
|
||||||
// onBlur={() => setDropDownTogglePage('')}
|
}
|
||||||
>
|
}
|
||||||
<div
|
className={`p-2 ${(dropDownTogglePage == 'pageDropDown' + indx) ? "bg-[var(--primary)]" : "bg-slate-200"} flex flex-col justify-center items-center gap-2 rounded`}>
|
||||||
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.pages != undefined && <img
|
|
||||||
key={indx}
|
|
||||||
className='rounded-sm shadow'
|
|
||||||
src={document.pages[0].src}
|
|
||||||
alt="" />
|
|
||||||
}
|
|
||||||
|
|
||||||
<div
|
|
||||||
className={`flex items-center justify-between w-full text-xs rounded-sm cursor-pointer ${(dropDownTogglePage === 'pageDropDown' + indx) ? "text-slate-100" : "text-slate-600"}`}>
|
|
||||||
<p className={`whitespace-nowrap overflow-hidden text-ellipsis max-w-[18ch]`}>{document.name}</p>
|
|
||||||
<MdKeyboardArrowDown className={`${(dropDownTogglePage === 'pageDropDown' + indx) ? 'rotate-180' : ''}`} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
dropDownTogglePage === 'pageDropDown' + indx &&
|
document.pages != undefined && <img
|
||||||
<div className="my-1 flex justify-center items-center gap-2 flex-wrap">
|
key={indx}
|
||||||
{/* Prev Button */}
|
className='rounded-sm shadow'
|
||||||
<a
|
src={document.pages[0].src}
|
||||||
href={"#" + document.documentId + (currentPage - 1)}
|
alt="" />
|
||||||
className={`cursor-pointer px-2 py-1 shadow rounded-sm text-sm bg-slate-200 hover:border-[var(--primary)] transition-all duration-300 ${currentPage === 0 ? "pointer-events-none opacity-50" : ""
|
|
||||||
}`}
|
|
||||||
onClick={(e) => {
|
|
||||||
if (currentPage === 0) e.preventDefault();
|
|
||||||
else setCurrentPage(currentPage - 1);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<GrFormPrevious />
|
|
||||||
</a>
|
|
||||||
|
|
||||||
{/* Page Selector */}
|
|
||||||
<select
|
|
||||||
className="w-[58px] py-1 text-xs text-slate-400 outline-none"
|
|
||||||
value={currentPage}
|
|
||||||
onChange={(e) => {
|
|
||||||
const newPage = Number(e.target.value);
|
|
||||||
setCurrentPage(newPage);
|
|
||||||
window.location.hash = document.documentId + "" + newPage;
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{document.pages != undefined && document.pages.map((_, pageIndex) => (
|
|
||||||
<option key={pageIndex} value={pageIndex}>
|
|
||||||
{pageIndex + 1}
|
|
||||||
</option>
|
|
||||||
))}
|
|
||||||
</select>
|
|
||||||
|
|
||||||
<span className="text-xs text-slate-600">
|
|
||||||
/ {document.pages?.length}
|
|
||||||
</span>
|
|
||||||
|
|
||||||
{/* Next Button */}
|
|
||||||
<a
|
|
||||||
href={"#" + document.documentId + (currentPage + 1)}
|
|
||||||
className={`cursor-pointer px-2 py-1 shadow rounded-sm text-sm bg-slate-200 hover:border-[var(--primary)] transition-all duration-300 ${currentPage === document.pages?.length - 1 ? "pointer-events-none opacity-50" : ""
|
|
||||||
}`}
|
|
||||||
onClick={(e) => {
|
|
||||||
if (currentPage === document.pages?.length - 1) e.preventDefault();
|
|
||||||
else setCurrentPage(currentPage + 1);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<MdOutlineNavigateNext />
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<div
|
||||||
|
className={`flex items-center justify-between w-full text-xs rounded-sm cursor-pointer ${(dropDownTogglePage == 'pageDropDown' + indx) ? "text-slate-100" : "text-slate-600"}`}>
|
||||||
|
<p className={`whitespace-nowrap overflow-hidden text-ellipsis max-w-[18ch]`}>{document.name}</p>
|
||||||
|
<MdKeyboardArrowDown className={`${(dropDownTogglePage == 'pageDropDown' + indx) ? 'rotate-180' : ''}`} />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
|
||||||
})}
|
|
||||||
</div>
|
{
|
||||||
|
dropDownTogglePage == 'pageDropDown' + indx &&
|
||||||
|
<div className="my-1 flex justify-center items-center gap-2 flex-wrap">
|
||||||
|
{/* Prev Button */}
|
||||||
|
<a
|
||||||
|
href={"#" + document.documentId + (currentPage - 1)}
|
||||||
|
className={`cursor-pointer px-2 py-1 shadow rounded-sm text-sm bg-slate-200 hover:border-[var(--primary)] transition-all duration-300 ${currentPage == 0 ? "pointer-events-none opacity-50" : ""
|
||||||
|
}`}
|
||||||
|
onClick={(e) => {
|
||||||
|
if (currentPage == 0) e.preventDefault();
|
||||||
|
else setCurrentPage(currentPage - 1);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<GrFormPrevious />
|
||||||
|
</a>
|
||||||
|
|
||||||
|
{/* Page Selector */}
|
||||||
|
<select
|
||||||
|
className="w-[58px] py-1 text-xs text-slate-400 outline-none"
|
||||||
|
value={currentPage}
|
||||||
|
onChange={(e) => {
|
||||||
|
const newPage = Number(e.target.value);
|
||||||
|
setCurrentPage(newPage);
|
||||||
|
window.location.hash = document.documentId + "" + newPage;
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{document.pages != undefined && document.pages.map((_, pageIndex) => (
|
||||||
|
<option key={pageIndex} value={pageIndex}>
|
||||||
|
{pageIndex + 1}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<span className="text-xs text-slate-600">
|
||||||
|
/ {document.pages?.length}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
{/* Next Button */}
|
||||||
|
<a
|
||||||
|
href={"#" + document.documentId + (currentPage + 1)}
|
||||||
|
className={`cursor-pointer px-2 py-1 shadow rounded-sm text-sm bg-slate-200 hover:border-[var(--primary)] transition-all duration-300 ${currentPage == document.pages?.length - 1 ? "pointer-events-none opacity-50" : ""
|
||||||
|
}`}
|
||||||
|
onClick={(e) => {
|
||||||
|
if (currentPage == document.pages?.length - 1) e.preventDefault();
|
||||||
|
else setCurrentPage(currentPage + 1);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<MdOutlineNavigateNext />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ export default function ReassignModal({ open, onClose, onConfirm }: ReassignModa
|
||||||
if (!email.trim()) newErrors.email = "Email is required.";
|
if (!email.trim()) newErrors.email = "Email is required.";
|
||||||
else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) newErrors.email = "Enter a valid email.";
|
else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) newErrors.email = "Enter a valid email.";
|
||||||
setErrors(newErrors);
|
setErrors(newErrors);
|
||||||
return Object.keys(newErrors).length === 0;
|
return Object.keys(newErrors).length == 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSubmit = () => {
|
const handleSubmit = () => {
|
||||||
|
|
|
||||||
|
|
@ -319,7 +319,7 @@ const SignCompletionScreen: React.FC = () => {
|
||||||
<FiDownload className="w-5 h-5 mr-3" />
|
<FiDownload className="w-5 h-5 mr-3" />
|
||||||
Download Signed Document
|
Download Signed Document
|
||||||
</button>
|
</button>
|
||||||
{signType === SignTypeEnum.selfSign ? <a
|
{signType == SignTypeEnum.selfSign ? <a
|
||||||
href="http://localhost:5173/"
|
href="http://localhost:5173/"
|
||||||
// target="_blank"
|
// target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
|
|
|
||||||
|
|
@ -90,6 +90,7 @@ export enum SaveTypeEnum {
|
||||||
DRAW = "DRAW",
|
DRAW = "DRAW",
|
||||||
TYPE = "TEXT",
|
TYPE = "TEXT",
|
||||||
UPLOAD = "IMAGE",
|
UPLOAD = "IMAGE",
|
||||||
|
SELECT = "SELECT",
|
||||||
}
|
}
|
||||||
export interface SaveType {
|
export interface SaveType {
|
||||||
signatureId: string | null
|
signatureId: string | null
|
||||||
|
|
@ -98,6 +99,7 @@ export interface SaveType {
|
||||||
signature: string | null;
|
signature: string | null;
|
||||||
initial: string | null;
|
initial: string | null;
|
||||||
isDefaultAndClicked?: boolean;
|
isDefaultAndClicked?: boolean;
|
||||||
|
font?: string;
|
||||||
}
|
}
|
||||||
interface TagsSubmitDataObj {
|
interface TagsSubmitDataObj {
|
||||||
tags: TagSubmitData[];
|
tags: TagSubmitData[];
|
||||||
|
|
@ -237,7 +239,7 @@ const SignDocument = () => {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let indx = fitObj[selFitIndx].value
|
let indx = fitObj[selFitIndx].value
|
||||||
if (indx === "FIT") {
|
if (indx == "FIT") {
|
||||||
indx = "100";
|
indx = "100";
|
||||||
}
|
}
|
||||||
zoom(Number(indx), 'zoom-con')
|
zoom(Number(indx), 'zoom-con')
|
||||||
|
|
@ -270,11 +272,11 @@ const SignDocument = () => {
|
||||||
setFocusElement({ ...droppedItems[0], focusElementIndx: 0 });
|
setFocusElement({ ...droppedItems[0], focusElementIndx: 0 });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (focusElement === null || !("focusElementIndx" in focusElement)) return;
|
if (focusElement == null || !("focusElementIndx" in focusElement)) return;
|
||||||
|
|
||||||
// const docCon = document.getElementById("doc-con");
|
// const docCon = document.getElementById("doc-con");
|
||||||
// document.addEventListener("keydown", (e) => {
|
// document.addEventListener("keydown", (e) => {
|
||||||
// if (e.key === "Tab") {
|
// if (e.key == "Tab") {
|
||||||
// e.preventDefault();
|
// e.preventDefault();
|
||||||
|
|
||||||
// console.log("Listening Tab Key Press")
|
// console.log("Listening Tab Key Press")
|
||||||
|
|
@ -318,7 +320,7 @@ const SignDocument = () => {
|
||||||
}, [showConfetti]);
|
}, [showConfetti]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (recSignStatus === "COMPLETED") {
|
if (recSignStatus == "COMPLETED") {
|
||||||
// setHideTags(true);
|
// setHideTags(true);
|
||||||
setTransparentTags(true);
|
setTransparentTags(true);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -329,7 +331,7 @@ const SignDocument = () => {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (saved.save && Object.keys(signConfObj).length) {
|
if (saved.save && Object.keys(signConfObj).length) {
|
||||||
const keys = Object.keys(signConfObj)
|
const keys = Object.keys(signConfObj)
|
||||||
const index = Number(keys[0])
|
const index = keys[0]
|
||||||
|
|
||||||
const newObj = {
|
const newObj = {
|
||||||
accepted: true,
|
accepted: true,
|
||||||
|
|
@ -351,11 +353,11 @@ const SignDocument = () => {
|
||||||
{ "ngrok-skip-browser-warning": "69420", }
|
{ "ngrok-skip-browser-warning": "69420", }
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.status === 200) {
|
if (res.status == 200) {
|
||||||
setSelectedDocuments(res?.data?.documents)
|
setSelectedDocuments(res?.data?.documents)
|
||||||
setRecipient(res?.data?.details)
|
setRecipient(res?.data?.details)
|
||||||
|
|
||||||
const sortedDroppedItems = res?.data?.tagJsons.sort((a, b) => a.navigationOrder - b.navigationOrder);
|
const sortedDroppedItems = res?.data?.tags.sort((a, b) => a.navigationOrder - b.navigationOrder);
|
||||||
setDroppedItems(sortedDroppedItems)
|
setDroppedItems(sortedDroppedItems)
|
||||||
|
|
||||||
setFocusElement({ ...sortedDroppedItems[0], focusElementIndx: 0 });
|
setFocusElement({ ...sortedDroppedItems[0], focusElementIndx: 0 });
|
||||||
|
|
@ -374,16 +376,16 @@ const SignDocument = () => {
|
||||||
setIsFields(false)
|
setIsFields(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res?.data?.status === "COMPLETED" || res?.data?.status === "DECLINED" || res?.data?.details.type == "CC") {
|
if (res?.data?.status == "COMPLETED" || res?.data?.status == "DECLINED" || res?.data?.details.type == "CC") {
|
||||||
// setShowCompletionScreen(true)
|
// setShowCompletionScreen(true)
|
||||||
setTransparentTags(true)
|
setTransparentTags(true)
|
||||||
setHideTags(true)
|
setHideTags(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (res?.data?.tagJsons && res?.data?.tagJsons.length > 0) {
|
if (res?.data?.tags && res?.data?.tags.length > 0) {
|
||||||
for (const tag of res?.data?.tagJsons) {
|
for (const tag of res?.data?.tags) {
|
||||||
if (tag.type === "SIGNATURE" && "value" in tag && tag.value) {
|
if (tag.type == "SIGNATURE" && "value" in tag && tag.value) {
|
||||||
|
|
||||||
axiosInstance.get(`/api/v1/sign/${recipientId}/signatures/${tag.value}`).then((res) => {
|
axiosInstance.get(`/api/v1/sign/${recipientId}/signatures/${tag.value}`).then((res) => {
|
||||||
console.log(res, "line 386")
|
console.log(res, "line 386")
|
||||||
|
|
@ -400,7 +402,7 @@ const SignDocument = () => {
|
||||||
// });
|
// });
|
||||||
|
|
||||||
|
|
||||||
} else if (tag.type === "INITIALS") {
|
} else if (tag.type == "INITIALS") {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -425,7 +427,7 @@ const SignDocument = () => {
|
||||||
signatureId: saved.signatureId
|
signatureId: saved.signatureId
|
||||||
});
|
});
|
||||||
|
|
||||||
if (res.status === 201 || res.status === 202) {
|
if (res.status == 201 || res.status == 202) {
|
||||||
newSignatureIdForCreateDefault = res.data.id;
|
newSignatureIdForCreateDefault = res.data.id;
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|
@ -444,23 +446,23 @@ const SignDocument = () => {
|
||||||
|
|
||||||
let signInitialsCount = 0;
|
let signInitialsCount = 0;
|
||||||
for (let i = 0; i < droppedItems.length; i++) {
|
for (let i = 0; i < droppedItems.length; i++) {
|
||||||
if (droppedItems[i].type === "SIGNATURE" || droppedItems[i].type === "INITIALS") {
|
if (droppedItems[i].type == "SIGNATURE" || droppedItems[i].type == "INITIALS") {
|
||||||
signInitialsCount += 1;
|
signInitialsCount += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (signInitialsCount !== Object.keys(signConfObj).length) {
|
if (signInitialsCount != Object.keys(signConfObj).length) {
|
||||||
// handleToastError("Please ensure all signature and initials are signed")
|
// handleToastError("Please ensure all signature and initials are signed")
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let tag of droppedItems) {
|
for (let tag of droppedItems) {
|
||||||
if ("required" in tag && tag.required && ((tag.type !== "SIGNATURE" && tag.type !== "INITIALS") && (tag.value === undefined || tag.value === null || tag.value === "" || !("value" in tag)))) {
|
if ("required" in tag && tag.required && ((tag.type != "SIGNATURE" && tag.type != "INITIALS") && (tag.value == undefined || tag.value == null || tag.value == "" || !("value" in tag)))) {
|
||||||
// handleToastError(`${tag.label} is required`)
|
// handleToastError(`${tag.label} is required`)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("id" in tag && (tag.type === "SIGNATURE" || tag.type === "INITIALS")) {
|
if ("id" in tag && (tag.type == "SIGNATURE" || tag.type == "INITIALS")) {
|
||||||
const tagData: TagSubmitData = {
|
const tagData: TagSubmitData = {
|
||||||
id: tag.id as string,
|
id: tag.id as string,
|
||||||
type: tag.type,
|
type: tag.type,
|
||||||
|
|
@ -478,10 +480,10 @@ const SignDocument = () => {
|
||||||
value: tag.value ? tag.value as string : ""
|
value: tag.value ? tag.value as string : ""
|
||||||
}
|
}
|
||||||
submitData.tags.push(tagData);
|
submitData.tags.push(tagData);
|
||||||
} else if (tag.type === "SIGNATURE" || tag.type === "INITIALS") {
|
} else if (tag.type == "SIGNATURE" || tag.type == "INITIALS") {
|
||||||
// Not getting recipient id in details it is undefined - not working self sign
|
// Not getting recipient id in details it is undefined - not working self sign
|
||||||
tag.recipientId = recipient.id;
|
tag.recipientId = recipient.id;
|
||||||
tag.documentId = Number(tag.documentId)
|
tag.documentId = tag.documentId
|
||||||
|
|
||||||
createTagsAndSubmit.tags.push(
|
createTagsAndSubmit.tags.push(
|
||||||
{
|
{
|
||||||
|
|
@ -493,7 +495,7 @@ const SignDocument = () => {
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
tag.recipientId = recipient.id
|
tag.recipientId = recipient.id
|
||||||
tag.documentId = Number(tag.documentId)
|
tag.documentId = tag.documentId
|
||||||
createTagsAndSubmit.tags.push(
|
createTagsAndSubmit.tags.push(
|
||||||
{
|
{
|
||||||
...tag,
|
...tag,
|
||||||
|
|
@ -517,7 +519,7 @@ const SignDocument = () => {
|
||||||
|
|
||||||
const signRes = await axiosInstance.post(`/api/v1/sign/${recipientId}`, {}, { headers: { "ngrok-skip-browser-warning": "69420", } })
|
const signRes = await axiosInstance.post(`/api/v1/sign/${recipientId}`, {}, { headers: { "ngrok-skip-browser-warning": "69420", } })
|
||||||
dispatch(hideLoader());
|
dispatch(hideLoader());
|
||||||
if (signRes.status === 200) {
|
if (signRes.status == 200) {
|
||||||
dispatch(hideLoader());
|
dispatch(hideLoader());
|
||||||
setTransparentTags(true)
|
setTransparentTags(true)
|
||||||
// setShowConfetti(true)
|
// setShowConfetti(true)
|
||||||
|
|
@ -550,8 +552,8 @@ const SignDocument = () => {
|
||||||
|
|
||||||
// If FocusElement is present updating in Based on Next and Prev
|
// If FocusElement is present updating in Based on Next and Prev
|
||||||
const currFocusElemIndx = focusElement.focusElementIndx;
|
const currFocusElemIndx = focusElement.focusElementIndx;
|
||||||
if (currFocusElemIndx === undefined) return;
|
if (currFocusElemIndx == undefined) return;
|
||||||
let updIndx = (action === "N") ? (currFocusElemIndx + 1) : (currFocusElemIndx - 1)
|
let updIndx = (action == "N") ? (currFocusElemIndx + 1) : (currFocusElemIndx - 1)
|
||||||
|
|
||||||
if (updIndx >= droppedItems.length || updIndx < 0 || !droppedItems[updIndx].id) updIndx = 0;
|
if (updIndx >= droppedItems.length || updIndx < 0 || !droppedItems[updIndx].id) updIndx = 0;
|
||||||
|
|
||||||
|
|
@ -628,7 +630,7 @@ const SignDocument = () => {
|
||||||
|
|
||||||
|
|
||||||
(
|
(
|
||||||
(item.id !== null && item.id !== undefined && item.id !== "")
|
(item.id != null && item.id != undefined && item.id != "")
|
||||||
? (
|
? (
|
||||||
(`${item.id}`) in signConfObj && signConfObj[`${item.id}`].accepted
|
(`${item.id}`) in signConfObj && signConfObj[`${item.id}`].accepted
|
||||||
) : (
|
) : (
|
||||||
|
|
@ -685,7 +687,7 @@ const SignDocument = () => {
|
||||||
width: dragElemData.width,
|
width: dragElemData.width,
|
||||||
height: dragElemData.height,
|
height: dragElemData.height,
|
||||||
},
|
},
|
||||||
styles: dragElemData.label === "text" ? {
|
styles: dragElemData.label == "text" ? {
|
||||||
"font": "Great Vibes",
|
"font": "Great Vibes",
|
||||||
"italic": false,
|
"italic": false,
|
||||||
"bold": false,
|
"bold": false,
|
||||||
|
|
@ -697,12 +699,12 @@ const SignDocument = () => {
|
||||||
pageIndex: pageIndex,
|
pageIndex: pageIndex,
|
||||||
recipientId: dragElemData.recipientId,
|
recipientId: dragElemData.recipientId,
|
||||||
recipientIndx: dragElemData.recipientIndx,
|
recipientIndx: dragElemData.recipientIndx,
|
||||||
required: (dragElemData.label !== TagsTypes.SIGNATURE && dragElemData.label !== TagsTypes.INITIALS) ? false : true,
|
required: (dragElemData.label != TagsTypes.SIGNATURE && dragElemData.label != TagsTypes.INITIALS) ? false : true,
|
||||||
update: true,
|
update: true,
|
||||||
isDeleted: false
|
isDeleted: false
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prepData.type === "NAME") {
|
if (prepData.type == "NAME") {
|
||||||
prepData.firstName = true
|
prepData.firstName = true
|
||||||
prepData.lastName = true
|
prepData.lastName = true
|
||||||
}
|
}
|
||||||
|
|
@ -712,18 +714,18 @@ const SignDocument = () => {
|
||||||
prepData.isGroupExist = false;
|
prepData.isGroupExist = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prepData.type.toLowerCase() === "temporal") {
|
if (prepData.type.toLowerCase() == "temporal") {
|
||||||
prepData.currentTimeStamp = true;
|
prepData.currentTimeStamp = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prepData.type.toLowerCase() === "number") {
|
if (prepData.type.toLowerCase() == "number") {
|
||||||
prepData.decimalPlace = 0;
|
prepData.decimalPlace = 0;
|
||||||
prepData.isCurrency = false;
|
prepData.isCurrency = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prepData.type.toLowerCase() === TagsTypes.SIGNATURE || prepData.type.toLowerCase() === TagsTypes.INITIALS) {
|
if (prepData.type.toLowerCase() == TagsTypes.SIGNATURE || prepData.type.toLowerCase() == TagsTypes.INITIALS) {
|
||||||
|
|
||||||
const currDocTags = droppedItems.filter((val) => val.pageIndex === prepData.pageIndex)
|
const currDocTags = droppedItems.filter((val) => val.pageIndex == prepData.pageIndex)
|
||||||
setSignConfObj({
|
setSignConfObj({
|
||||||
...signConfObj,
|
...signConfObj,
|
||||||
[currDocTags.length]: {
|
[currDocTags.length]: {
|
||||||
|
|
@ -742,7 +744,7 @@ const SignDocument = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSetIsFields = (setTo: boolean) => {
|
const handleSetIsFields = (setTo: boolean) => {
|
||||||
if (setTo !== isFields) setIsFields(setTo);
|
if (setTo != isFields) setIsFields(setTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleOnConsent = () => {
|
const handleOnConsent = () => {
|
||||||
|
|
@ -770,7 +772,7 @@ const SignDocument = () => {
|
||||||
language: "en"
|
language: "en"
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.status === 202) {
|
if (res.status == 202) {
|
||||||
// setShowCompletionScreen(true);
|
// setShowCompletionScreen(true);
|
||||||
// navigate("/transaction-reassigned")
|
// navigate("/transaction-reassigned")
|
||||||
window.location.href = `/transaction-reassigned`
|
window.location.href = `/transaction-reassigned`
|
||||||
|
|
@ -837,9 +839,9 @@ const SignDocument = () => {
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// if (showCompletionScreen) {
|
// if (showCompletionScreen) {
|
||||||
// if (recSignStatus === "COMPLETED") {
|
// if (recSignStatus == "COMPLETED") {
|
||||||
// return <CompletionScreen />
|
// return <CompletionScreen />
|
||||||
// } else if (recSignStatus === "DECLINED") {
|
// } else if (recSignStatus == "DECLINED") {
|
||||||
// return <CompletionScreen hit="Action Canceled! " title="Maybe Next Time!" message={"Your request has been declined successfully. You can revisit anytime if you change your mind."} textColorSuccess={false} />
|
// return <CompletionScreen hit="Action Canceled! " title="Maybe Next Time!" message={"Your request has been declined successfully. You can revisit anytime if you change your mind."} textColorSuccess={false} />
|
||||||
// } else {
|
// } else {
|
||||||
// return <CompletionScreen />
|
// return <CompletionScreen />
|
||||||
|
|
@ -868,7 +870,7 @@ const SignDocument = () => {
|
||||||
|
|
||||||
{/* Documnt Nav */}
|
{/* Documnt Nav */}
|
||||||
<>
|
<>
|
||||||
{selectedDocuments !== null &&
|
{selectedDocuments != null &&
|
||||||
<div
|
<div
|
||||||
className=""
|
className=""
|
||||||
tabIndex={1}
|
tabIndex={1}
|
||||||
|
|
@ -931,11 +933,11 @@ const SignDocument = () => {
|
||||||
onDeclineClick={() => setDeclineOpen(true)}
|
onDeclineClick={() => setDeclineOpen(true)}
|
||||||
onReassignClick={() => setReassignOpen(true)}
|
onReassignClick={() => setReassignOpen(true)}
|
||||||
onAuditHistoryClick={() => setAuditHistoryOpen(true)}
|
onAuditHistoryClick={() => setAuditHistoryOpen(true)}
|
||||||
showDecAndReassign={recipient?.type !== "CC"}
|
showDecAndReassign={recipient?.type != "CC"}
|
||||||
transactionId={"1"}
|
transactionId={"1"}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{!transparentTags && recipient?.type !== "CC" && (
|
{!transparentTags && recipient?.type != "CC" && (
|
||||||
<div
|
<div
|
||||||
className={`absolute z-50 left-0 bottom-0 bg-[var(--primary)] w-full flex justify-around items-center
|
className={`absolute z-50 left-0 bottom-0 bg-[var(--primary)] w-full flex justify-around items-center
|
||||||
px-2.5 transition-all duration-500 ease-in-out
|
px-2.5 transition-all duration-500 ease-in-out
|
||||||
|
|
@ -964,7 +966,7 @@ const SignDocument = () => {
|
||||||
|
|
||||||
|
|
||||||
{/* Horizontal Loader */}
|
{/* Horizontal Loader */}
|
||||||
{horizontalFormLoader.totalRequired !== null && !transparentTags && (
|
{horizontalFormLoader.totalRequired != null && !transparentTags && (
|
||||||
<div className="w-full h-[4px] bg-slate-400 relative">
|
<div className="w-full h-[4px] bg-slate-400 relative">
|
||||||
<div
|
<div
|
||||||
className="h-full bg-yellow-300 transition-all duration-300"
|
className="h-full bg-yellow-300 transition-all duration-300"
|
||||||
|
|
@ -990,11 +992,11 @@ const SignDocument = () => {
|
||||||
{/* <div className="lg:col-span-2 bg-slate-100 h-full p-4 overflow-y-auto"></div> */}
|
{/* <div className="lg:col-span-2 bg-slate-100 h-full p-4 overflow-y-auto"></div> */}
|
||||||
<div
|
<div
|
||||||
id="tags-list-client-side"
|
id="tags-list-client-side"
|
||||||
className={`absolute w-[220px] left-0 top-[42px] border-r-2 sm:border-none border-slate-200 z-10 sm:static sm:w-auto sm:col-span-2 h-full p-4 overflow-y-auto ${recipient?.type !== "CC" ? "bg-white" : ""} ${!provideTags && isFields ? "hidden" : ""}`}>
|
className={`absolute w-[220px] left-0 top-[42px] border-r-2 sm:border-none border-slate-200 z-10 sm:static sm:w-auto sm:col-span-2 h-full p-4 overflow-y-auto ${recipient?.type != "CC" ? "bg-white" : ""} ${!provideTags && isFields ? "hidden" : ""}`}>
|
||||||
|
|
||||||
|
|
||||||
{!transparentTags && <div className='flex flex-col md:flex-row justify-between items-center bg-slate-100 p-1.5 rounded-2xl border-1 border-gray-200 mb-3'>
|
{!transparentTags && <div className='flex flex-col md:flex-row justify-between items-center bg-slate-100 p-1.5 rounded-2xl border-1 border-gray-200 mb-3'>
|
||||||
{provideTags && recipient?.type !== "CC" && <div
|
{provideTags && recipient?.type != "CC" && <div
|
||||||
onClick={() => handleSetIsFields(true)}
|
onClick={() => handleSetIsFields(true)}
|
||||||
className={`flex items-center gap-1 cursor-pointer text-xs w-full justify-center py-1.5 rounded-2xl ${isFields ? 'bg-[var(--primary)] text-white' : ''} transition-all duration-300'}`}
|
className={`flex items-center gap-1 cursor-pointer text-xs w-full justify-center py-1.5 rounded-2xl ${isFields ? 'bg-[var(--primary)] text-white' : ''} transition-all duration-300'}`}
|
||||||
>
|
>
|
||||||
|
|
@ -1013,7 +1015,7 @@ const SignDocument = () => {
|
||||||
{/* <p className="hidden sm:block text-xs text-white">Hi! {recipient && recipient.firstName} {recipient && recipient.lastName}</p> */}
|
{/* <p className="hidden sm:block text-xs text-white">Hi! {recipient && recipient.firstName} {recipient && recipient.lastName}</p> */}
|
||||||
</div>}
|
</div>}
|
||||||
|
|
||||||
{!transparentTags && isFields && recipientId && provideTags && recipient?.type !== "CC" && <FieldList color={"#8f87f1"} recipientId={Number(recipientId)} recipientIndx={0} acntId={"1"} />}
|
{!transparentTags && isFields && recipientId && provideTags && recipient?.type != "CC" && <FieldList color={"#8f87f1"} recipientId={recipientId} recipientIndx={0} acntId={"1"} />}
|
||||||
|
|
||||||
{!isFields && <DocumentPages
|
{!isFields && <DocumentPages
|
||||||
selectedDocuments={selectedDocuments}
|
selectedDocuments={selectedDocuments}
|
||||||
|
|
@ -1026,7 +1028,7 @@ const SignDocument = () => {
|
||||||
{/* Main container */}
|
{/* Main container */}
|
||||||
<div
|
<div
|
||||||
id="doc-con"
|
id="doc-con"
|
||||||
className={`zoom-con relative ${provideTags ? (isFields && selectedTag !== null ? "col-span-8" : "col-span-10") : (isFields ? "col-span-12" : "col-span-10")} sm:px-4 bg-slate-100 h-full w-full overflow-auto scroll-smooth transition-all duration-200 pb-[4rem]`}
|
className={`zoom-con relative ${provideTags ? (isFields && selectedTag != null ? "col-span-8" : "col-span-10") : (isFields ? "col-span-12" : "col-span-10")} sm:px-4 bg-slate-100 h-full w-full overflow-auto scroll-smooth transition-all duration-200 pb-[4rem]`}
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
selectedDocuments && selectedDocuments.length > 0 && selectedDocuments.map((doc) => {
|
selectedDocuments && selectedDocuments.length > 0 && selectedDocuments.map((doc) => {
|
||||||
|
|
@ -1041,7 +1043,7 @@ const SignDocument = () => {
|
||||||
doc.pages && doc.pages.length > 0 && doc.pages.map((page, indx) => {
|
doc.pages && doc.pages.length > 0 && doc.pages.map((page, indx) => {
|
||||||
const key = `${doc.documentId}_${page.index}`;
|
const key = `${doc.documentId}_${page.index}`;
|
||||||
// const tagJsonData = [...droppedItems];
|
// const tagJsonData = [...droppedItems];
|
||||||
const currDocTags = droppedItems.filter((val) => val.pageIndex === page.index)
|
const currDocTags = droppedItems.filter((val) => val.pageIndex == page.index)
|
||||||
let scale: { x: number | null, y: number | null } = { x: null, y: null }
|
let scale: { x: number | null, y: number | null } = { x: null, y: null }
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
|
@ -1105,7 +1107,7 @@ const SignDocument = () => {
|
||||||
{/* Side details of documents Pages and document Name - END */}
|
{/* Side details of documents Pages and document Name - END */}
|
||||||
|
|
||||||
|
|
||||||
{!transparentTags && focusElement !== null && focusElement.documentId == doc.documentId && focusElement.pageIndex == page.index &&
|
{!transparentTags && focusElement != null && focusElement.documentId == doc.documentId && focusElement.pageIndex == page.index &&
|
||||||
<div
|
<div
|
||||||
id="tag-navigation-btn"
|
id="tag-navigation-btn"
|
||||||
className={`absolute right-0 translate-x-[100%] flex justify-center gap-0 items-center z-50 cursor-pointer transition-all duration-300`}
|
className={`absolute right-0 translate-x-[100%] flex justify-center gap-0 items-center z-50 cursor-pointer transition-all duration-300`}
|
||||||
|
|
@ -1137,24 +1139,24 @@ const SignDocument = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
{(navigationTagPos === NavigationTagPosEnum.ABOVE || navigationTagPos === NavigationTagPosEnum.BELOW) &&
|
{(navigationTagPos == NavigationTagPosEnum.ABOVE || navigationTagPos == NavigationTagPosEnum.BELOW) &&
|
||||||
<div
|
<div
|
||||||
onClick={() => scrollToElement(focusElement?.navigationOrder)}
|
onClick={() => scrollToElement(focusElement?.navigationOrder)}
|
||||||
className={`cursor-pointer fixed ${navigationTagPos === NavigationTagPosEnum.ABOVE ? "top-[45px]" : "bottom-[45px]"} right-[8%] flex flex-col items-center`}>
|
className={`cursor-pointer fixed ${navigationTagPos == NavigationTagPosEnum.ABOVE ? "top-[45px]" : "bottom-[45px]"} right-[8%] flex flex-col items-center`}>
|
||||||
{/* Arrow pointing up */}
|
{/* Arrow pointing up */}
|
||||||
{navigationTagPos === NavigationTagPosEnum.ABOVE && <div className="w-0 h-0 border-l-6 border-r-6 border-b-6 border-l-transparent border-r-transparent border-b-[var(--primary)]"></div>}
|
{navigationTagPos == NavigationTagPosEnum.ABOVE && <div className="w-0 h-0 border-l-6 border-r-6 border-b-6 border-l-transparent border-r-transparent border-b-[var(--primary)]"></div>}
|
||||||
|
|
||||||
{/* Label box */}
|
{/* Label box */}
|
||||||
<div
|
<div
|
||||||
className="bg-[var(--primary)] text-white text-sm px-3 py-1 rounded-md shadow-md flex items-center gap-1">
|
className="bg-[var(--primary)] text-white text-sm px-3 py-1 rounded-md shadow-md flex items-center gap-1">
|
||||||
<span className="capitalize">{focusElement?.type.toLowerCase()}</span>
|
<span className="capitalize">{focusElement?.type.toLowerCase()}</span>
|
||||||
</div>
|
</div>
|
||||||
{navigationTagPos === NavigationTagPosEnum.BELOW && <div className="w-0 h-0 border-l-6 border-r-6 border-b-6 border-l-transparent border-r-transparent border-b-[var(--primary)] rotate-[180deg]"></div>}
|
{navigationTagPos == NavigationTagPosEnum.BELOW && <div className="w-0 h-0 border-l-6 border-r-6 border-b-6 border-l-transparent border-r-transparent border-b-[var(--primary)] rotate-[180deg]"></div>}
|
||||||
</div>}
|
</div>}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{provideTags && selectedTag && selectedTag !== null && "key" in selectedTag && "index" in selectedTag &&
|
{provideTags && selectedTag && selectedTag != null && "key" in selectedTag && "index" in selectedTag &&
|
||||||
<div className={`col-span-2 ${provideTags ? "" : "order-first"} h-full ${!isFields ? "bg-white" : isFields && provideTags ? "bg-white" : ""} overflow-y-auto`}>
|
<div className={`col-span-2 ${provideTags ? "" : "order-first"} h-full ${!isFields ? "bg-white" : isFields && provideTags ? "bg-white" : ""} overflow-y-auto`}>
|
||||||
{/* Right Side Attributes Section if providedTags - START */}
|
{/* Right Side Attributes Section if providedTags - START */}
|
||||||
<RightSideBar
|
<RightSideBar
|
||||||
|
|
@ -1173,8 +1175,8 @@ const SignDocument = () => {
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* {showCompletionScreen && recSignStatus === "COMPLETED" && <CompletionScreen />}
|
{/* {showCompletionScreen && recSignStatus == "COMPLETED" && <CompletionScreen />}
|
||||||
{showCompletionScreen && recSignStatus === "DECLINED" && <CompletionScreen title="No worries! you declined the signing request." message={"Your signing request has been declined. No changes were made to the document."} textColorSuccess={false} />} */}
|
{showCompletionScreen && recSignStatus == "DECLINED" && <CompletionScreen title="No worries! you declined the signing request." message={"Your signing request has been declined. No changes were made to the document."} textColorSuccess={false} />} */}
|
||||||
|
|
||||||
<div style={{ display: `${openSign ? 'block' : 'none'}` }}>
|
<div style={{ display: `${openSign ? 'block' : 'none'}` }}>
|
||||||
{recipient &&
|
{recipient &&
|
||||||
|
|
@ -1196,7 +1198,7 @@ const SignDocument = () => {
|
||||||
{globalLoader.isLoading && <Loader />}
|
{globalLoader.isLoading && <Loader />}
|
||||||
|
|
||||||
{
|
{
|
||||||
!transparentTags && selectedDocuments !== null && !showCompletionScreen && !signerConsent.consent && recipient?.type !== "CC" &&
|
!transparentTags && selectedDocuments != null && !showCompletionScreen && !signerConsent.consent && recipient?.type != "CC" &&
|
||||||
<ConsentScreen
|
<ConsentScreen
|
||||||
onConsent={() => handleOnConsent()}
|
onConsent={() => handleOnConsent()}
|
||||||
// onDecline={() => console.log("User declined")}
|
// onDecline={() => console.log("User declined")}
|
||||||
|
|
@ -1224,7 +1226,7 @@ const SignDocument = () => {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{!transparentTags && recipient?.type !== "CC" && <>
|
{!transparentTags && recipient?.type != "CC" && <>
|
||||||
<div className={`w-full shadow-[0_20px_35px_rgba(0,0,0,0.25)] bottom-0 left-0 bg-white px-4 py-2 flex justify-between items-center gap-4`}>
|
<div className={`w-full shadow-[0_20px_35px_rgba(0,0,0,0.25)] bottom-0 left-0 bg-white px-4 py-2 flex justify-between items-center gap-4`}>
|
||||||
<p className='text-sm text-slate-600'>By Signing I agree Sign Made Easy <a href="" className="text-[var(--mainPrimaryBtn)]">Terms & Conditions.</a></p>
|
<p className='text-sm text-slate-600'>By Signing I agree Sign Made Easy <a href="" className="text-[var(--mainPrimaryBtn)]">Terms & Conditions.</a></p>
|
||||||
{/* <div className='flex items-center gap-8 cursor-pointer text-xs px-2 py-1 rounded-sm outline-none'>
|
{/* <div className='flex items-center gap-8 cursor-pointer text-xs px-2 py-1 rounded-sm outline-none'>
|
||||||
|
|
@ -1270,7 +1272,7 @@ const SignDocument = () => {
|
||||||
|
|
||||||
className='flex items-center justify-between w-full'>
|
className='flex items-center justify-between w-full'>
|
||||||
<p className='whitespace-nowrap overflow-hidden text-ellipsis max-w-[12ch]'>{val.label}</p>
|
<p className='whitespace-nowrap overflow-hidden text-ellipsis max-w-[12ch]'>{val.label}</p>
|
||||||
{selFitIndx === indx && <FaCheck className='text-sm text-slate-400' />}
|
{selFitIndx == indx && <FaCheck className='text-sm text-slate-400' />}
|
||||||
</div>
|
</div>
|
||||||
</div>)
|
</div>)
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -115,7 +115,7 @@ const TagsCon: React.FC<TagsConProps> = ({
|
||||||
// Apply the movement to the element
|
// Apply the movement to the element
|
||||||
setDroppedItems(
|
setDroppedItems(
|
||||||
droppedItems.map((item, i) =>
|
droppedItems.map((item, i) =>
|
||||||
i === index ? { ...item, dimensions: { ...item.dimensions, left, top }, update: true } : item
|
i == index ? { ...item, dimensions: { ...item.dimensions, left, top }, update: true } : item
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -140,7 +140,7 @@ const TagsCon: React.FC<TagsConProps> = ({
|
||||||
if ("id" in tag) {
|
if ("id" in tag) {
|
||||||
try {
|
try {
|
||||||
const response = await api.delete(`/api/v1/sign/${recipientId}/tags/`, { data: [{ tagId: tag.id }] })
|
const response = await api.delete(`/api/v1/sign/${recipientId}/tags/`, { data: [{ tagId: tag.id }] })
|
||||||
if (response.status !== 200) throw "Tag Deletion error"
|
if (response.status != 200) throw "Tag Deletion error"
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -155,13 +155,13 @@ const TagsCon: React.FC<TagsConProps> = ({
|
||||||
// Find all items in the same group
|
// Find all items in the same group
|
||||||
const groupItems = droppedItems[key]
|
const groupItems = droppedItems[key]
|
||||||
.map((item, idx) => ({ item, index: idx }))
|
.map((item, idx) => ({ item, index: idx }))
|
||||||
.filter(({ item }) => 'group' in item && item.group === groupId && !item.isDeleted);
|
.filter(({ item }) => 'group' in item && item.group == groupId && !item.isDeleted);
|
||||||
|
|
||||||
// Sort group items by their top position to identify the parent (top-most)
|
// Sort group items by their top position to identify the parent (top-most)
|
||||||
groupItems.sort((a, b) => a.item.dimensions.top - b.item.dimensions.top);
|
groupItems.sort((a, b) => a.item.dimensions.top - b.item.dimensions.top);
|
||||||
|
|
||||||
// Check if the item being removed is the parent (top-most item)
|
// Check if the item being removed is the parent (top-most item)
|
||||||
const isParentItem = groupItems.length > 0 && groupItems[0].index === targetIndex;
|
const isParentItem = groupItems.length > 0 && groupItems[0].index == targetIndex;
|
||||||
|
|
||||||
if (isParentItem && groupItems.length > 1) {
|
if (isParentItem && groupItems.length > 1) {
|
||||||
// If removing the parent and there are child items, mark all items in the group as deleted
|
// If removing the parent and there are child items, mark all items in the group as deleted
|
||||||
|
|
@ -187,17 +187,17 @@ const TagsCon: React.FC<TagsConProps> = ({
|
||||||
setDroppedItems(prevState => ({
|
setDroppedItems(prevState => ({
|
||||||
...prevState,
|
...prevState,
|
||||||
[key]: prevState[key].map((item, index) =>
|
[key]: prevState[key].map((item, index) =>
|
||||||
index === targetIndex ? { ...item, isDeleted: true } : item
|
index == targetIndex ? { ...item, isDeleted: true } : item
|
||||||
)
|
)
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Check if this was the last item in the group after state update
|
// Check if this was the last item in the group after state update
|
||||||
// setTimeout(() => {
|
// setTimeout(() => {
|
||||||
// const remainingGroupItems = droppedItems[key].filter(item =>
|
// const remainingGroupItems = droppedItems[key].filter(item =>
|
||||||
// 'group' in item && item.group === groupId && !item.isDeleted
|
// 'group' in item && item.group == groupId && !item.isDeleted
|
||||||
// );
|
// );
|
||||||
|
|
||||||
// if (remainingGroupItems.length === 0) {
|
// if (remainingGroupItems.length == 0) {
|
||||||
// // Remove group borders if no items left
|
// // Remove group borders if no items left
|
||||||
// removeGroupBorders(groupId);
|
// removeGroupBorders(groupId);
|
||||||
// } else {
|
// } else {
|
||||||
|
|
@ -209,7 +209,7 @@ const TagsCon: React.FC<TagsConProps> = ({
|
||||||
} else {
|
} else {
|
||||||
// Handle non-group item removal (your existing logic)
|
// Handle non-group item removal (your existing logic)
|
||||||
setDroppedItems(prevState => prevState.filter((item, idx) => {
|
setDroppedItems(prevState => prevState.filter((item, idx) => {
|
||||||
return idx !== targetIndex;
|
return idx != targetIndex;
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
})()
|
})()
|
||||||
|
|
@ -218,7 +218,7 @@ const TagsCon: React.FC<TagsConProps> = ({
|
||||||
const handleTagUpdate = (updateIndx: number, updateValue: string) => {
|
const handleTagUpdate = (updateIndx: number, updateValue: string) => {
|
||||||
if (droppedItems && droppedItems.length) {
|
if (droppedItems && droppedItems.length) {
|
||||||
const updatedTag = droppedItems.map((val, indx) => {
|
const updatedTag = droppedItems.map((val, indx) => {
|
||||||
if (indx === updateIndx) {
|
if (indx == updateIndx) {
|
||||||
return {
|
return {
|
||||||
...val,
|
...val,
|
||||||
value: updateValue
|
value: updateValue
|
||||||
|
|
@ -239,7 +239,7 @@ const TagsCon: React.FC<TagsConProps> = ({
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleSignClick = async (index: number, id: number | undefined) => {
|
const handleSignClick = async (index: number, id: number | undefined) => {
|
||||||
id = (id !== undefined && id !== null) ? id : index
|
id = (id != undefined && id != null) ? id : index
|
||||||
setSignTagId(id)
|
setSignTagId(id)
|
||||||
if (saved.save) {
|
if (saved.save) {
|
||||||
if (saved.isDefaultAndClicked) {
|
if (saved.isDefaultAndClicked) {
|
||||||
|
|
@ -249,7 +249,7 @@ const TagsCon: React.FC<TagsConProps> = ({
|
||||||
tagId: id
|
tagId: id
|
||||||
}, { headers: { "ngrok-skip-browser-warning": "69420", } })
|
}, { headers: { "ngrok-skip-browser-warning": "69420", } })
|
||||||
|
|
||||||
if (res.status === 202) {
|
if (res.status == 202) {
|
||||||
setSaved({ ...saved, signatureId: res.data.id, isDefaultAndClicked: false });
|
setSaved({ ...saved, signatureId: res.data.id, isDefaultAndClicked: false });
|
||||||
}
|
}
|
||||||
} catch (error) { }
|
} catch (error) { }
|
||||||
|
|
@ -274,7 +274,7 @@ const TagsCon: React.FC<TagsConProps> = ({
|
||||||
setOpenSign(true);
|
setOpenSign(true);
|
||||||
// setDroppedItems((prev) => {
|
// setDroppedItems((prev) => {
|
||||||
// return prev.map((obj, idx) => {
|
// return prev.map((obj, idx) => {
|
||||||
// if (idx === index && obj.id === id) return { ...obj, valus: saved.signatureId }
|
// if (idx == index && obj.id == id) return { ...obj, valus: saved.signatureId }
|
||||||
// return obj;
|
// return obj;
|
||||||
// })
|
// })
|
||||||
// })
|
// })
|
||||||
|
|
@ -296,18 +296,18 @@ const TagsCon: React.FC<TagsConProps> = ({
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleSignAcknowledgeClick = (index: number) => {
|
const handleSignAcknowledgeClick = (index: number) => {
|
||||||
if (saved.save && signConfObj === null) {
|
if (saved.save && signConfObj == null) {
|
||||||
setSignConfObj([...signConfObj, index])
|
setSignConfObj([...signConfObj, index])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
console.log(signConfObj, "Line 305")
|
console.log(signConfObj, saved, "Line 305")
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{currDocTags.map((item, index) => {
|
{currDocTags.map((item, index) => {
|
||||||
if (item.pageIndex !== pageIndex || Number(item.documentId) !== Number(documentId)) return <></>;
|
if ((item.pageIndex != pageIndex) || (item.documentId != documentId)) return <></>;
|
||||||
console.log('pageWidth:', pageWidth, 'computed left:', (item.dimensions.left / pageWidth) * 100);
|
console.log('pageWidth:', pageWidth, 'computed left:', (item.dimensions.left / pageWidth) * 100);
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
|
@ -326,7 +326,7 @@ const TagsCon: React.FC<TagsConProps> = ({
|
||||||
// top: `${item.dimensions.top}px`,
|
// top: `${item.dimensions.top}px`,
|
||||||
// width: `${item.dimensions.width}px`,
|
// width: `${item.dimensions.width}px`,
|
||||||
// height: `${item.dimensions.height}px`,
|
// height: `${item.dimensions.height}px`,
|
||||||
// border: `${((!hideTags && focusElement) && !transparentTags && focusElement.documentId === item.documentId && focusElement.focusElementIndx === index) ? '2px dashed #1c398e' : 'none'}`,
|
// border: `${((!hideTags && focusElement) && !transparentTags && focusElement.documentId == item.documentId && focusElement.focusElementIndx == index) ? '2px dashed #1c398e' : 'none'}`,
|
||||||
// // display: `${hideTags ? 'none' : 'block'}`
|
// // display: `${hideTags ? 'none' : 'block'}`
|
||||||
// }}
|
// }}
|
||||||
|
|
||||||
|
|
@ -353,7 +353,7 @@ const TagsCon: React.FC<TagsConProps> = ({
|
||||||
</div>}
|
</div>}
|
||||||
|
|
||||||
<>
|
<>
|
||||||
{selectedTag !== null && selectedTag?.key && selectedTag.key === pageIdkey && selectedTag.index === index &&
|
{selectedTag != null && selectedTag?.key && selectedTag.key == pageIdkey && selectedTag.index == index &&
|
||||||
<div className='absolute flex justify-between items-center w-full max-w-max bg-white top-[-22px] shadow z-20 text-sm rounded-t-sm' >
|
<div className='absolute flex justify-between items-center w-full max-w-max bg-white top-[-22px] shadow z-20 text-sm rounded-t-sm' >
|
||||||
<div className='flex justify-center items-center gap-1 bg-white px-2 shadow'>
|
<div className='flex justify-center items-center gap-1 bg-white px-2 shadow'>
|
||||||
{/* <p className='w-2.5 h-2.5 rounded'
|
{/* <p className='w-2.5 h-2.5 rounded'
|
||||||
|
|
@ -374,7 +374,7 @@ const TagsCon: React.FC<TagsConProps> = ({
|
||||||
|
|
||||||
{/* TEXT FIELD - START */}
|
{/* TEXT FIELD - START */}
|
||||||
{
|
{
|
||||||
item.type === "TEXT" &&
|
item.type == "TEXT" &&
|
||||||
<div
|
<div
|
||||||
id={item.navigationOrder}
|
id={item.navigationOrder}
|
||||||
tabIndex={1}
|
tabIndex={1}
|
||||||
|
|
@ -397,7 +397,7 @@ const TagsCon: React.FC<TagsConProps> = ({
|
||||||
handleTagUpdate(index, val as string);
|
handleTagUpdate(index, val as string);
|
||||||
}}
|
}}
|
||||||
onKeyDown={(e) => {
|
onKeyDown={(e) => {
|
||||||
if (e.key === "Enter") e.preventDefault();
|
if (e.key == "Enter") e.preventDefault();
|
||||||
}}
|
}}
|
||||||
contentEditable={true}
|
contentEditable={true}
|
||||||
className="outline-none whitespace-nowrap w-full max-h-max"
|
className="outline-none whitespace-nowrap w-full max-h-max"
|
||||||
|
|
@ -421,14 +421,14 @@ const TagsCon: React.FC<TagsConProps> = ({
|
||||||
// handleTagUpdate(index, val as string);
|
// handleTagUpdate(index, val as string);
|
||||||
// }}
|
// }}
|
||||||
onKeyDown={(e) => {
|
onKeyDown={(e) => {
|
||||||
if (e.key === "Enter") e.preventDefault();
|
if (e.key == "Enter") e.preventDefault();
|
||||||
}}
|
}}
|
||||||
// onFocus={() => {
|
// onFocus={() => {
|
||||||
// }}
|
// }}
|
||||||
onBlur={(e) => {
|
onBlur={(e) => {
|
||||||
let val = e.target.textContent;
|
let val = e.target.textContent;
|
||||||
handleTagUpdate(index, val as string);
|
handleTagUpdate(index, val as string);
|
||||||
if (typeof item.maskType === "string" && typeof val === "string" && item.maskCharacter) {
|
if (typeof item.maskType == "string" && typeof val == "string" && item.maskCharacter) {
|
||||||
val = val.replace(/ /g, "");
|
val = val.replace(/ /g, "");
|
||||||
e.target.textContent = maskUtils(item.maskType, val, item.maskCharacter)
|
e.target.textContent = maskUtils(item.maskType, val, item.maskCharacter)
|
||||||
}
|
}
|
||||||
|
|
@ -443,7 +443,7 @@ const TagsCon: React.FC<TagsConProps> = ({
|
||||||
|
|
||||||
{/* EMAIL FIELD - START */}
|
{/* EMAIL FIELD - START */}
|
||||||
{
|
{
|
||||||
item.type === "EMAIL" &&
|
item.type == "EMAIL" &&
|
||||||
<div
|
<div
|
||||||
id={item.navigationOrder}
|
id={item.navigationOrder}
|
||||||
tabIndex={1}
|
tabIndex={1}
|
||||||
|
|
@ -458,7 +458,7 @@ const TagsCon: React.FC<TagsConProps> = ({
|
||||||
handleTagUpdate(index, val as string);
|
handleTagUpdate(index, val as string);
|
||||||
}}
|
}}
|
||||||
onKeyDown={(e) => {
|
onKeyDown={(e) => {
|
||||||
if (e.key === "Enter") {
|
if (e.key == "Enter") {
|
||||||
const val = e.currentTarget.textContent?.trim() || "";
|
const val = e.currentTarget.textContent?.trim() || "";
|
||||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||||
|
|
||||||
|
|
@ -496,7 +496,7 @@ const TagsCon: React.FC<TagsConProps> = ({
|
||||||
|
|
||||||
{/* NAME FIELD - START */}
|
{/* NAME FIELD - START */}
|
||||||
{
|
{
|
||||||
item.type === "NAME" &&
|
item.type == "NAME" &&
|
||||||
<div
|
<div
|
||||||
id={item.navigationOrder}
|
id={item.navigationOrder}
|
||||||
tabIndex={1}
|
tabIndex={1}
|
||||||
|
|
@ -511,7 +511,7 @@ const TagsCon: React.FC<TagsConProps> = ({
|
||||||
handleTagUpdate(index, val as string);
|
handleTagUpdate(index, val as string);
|
||||||
}}
|
}}
|
||||||
onKeyDown={(e) => {
|
onKeyDown={(e) => {
|
||||||
if (e.key === "Enter") {
|
if (e.key == "Enter") {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
};
|
};
|
||||||
}}
|
}}
|
||||||
|
|
@ -532,7 +532,7 @@ const TagsCon: React.FC<TagsConProps> = ({
|
||||||
|
|
||||||
{/* NUMBER FIELD - START */}
|
{/* NUMBER FIELD - START */}
|
||||||
{
|
{
|
||||||
item.type === "NUMBER" &&
|
item.type == "NUMBER" &&
|
||||||
<div
|
<div
|
||||||
id={item.navigationOrder}
|
id={item.navigationOrder}
|
||||||
tabIndex={1}
|
tabIndex={1}
|
||||||
|
|
@ -556,7 +556,7 @@ const TagsCon: React.FC<TagsConProps> = ({
|
||||||
|
|
||||||
{/* COMPANY FIELD - START */}
|
{/* COMPANY FIELD - START */}
|
||||||
{
|
{
|
||||||
item.type === "COMPANY" &&
|
item.type == "COMPANY" &&
|
||||||
<div
|
<div
|
||||||
id={item.navigationOrder}
|
id={item.navigationOrder}
|
||||||
tabIndex={1}
|
tabIndex={1}
|
||||||
|
|
@ -571,7 +571,7 @@ const TagsCon: React.FC<TagsConProps> = ({
|
||||||
handleTagUpdate(index, val as string);
|
handleTagUpdate(index, val as string);
|
||||||
}}
|
}}
|
||||||
onKeyDown={(e) => {
|
onKeyDown={(e) => {
|
||||||
if (e.key === "Enter") {
|
if (e.key == "Enter") {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
};
|
};
|
||||||
}}
|
}}
|
||||||
|
|
@ -590,7 +590,7 @@ const TagsCon: React.FC<TagsConProps> = ({
|
||||||
|
|
||||||
{/* CHECKBOX FIELD - START */}
|
{/* CHECKBOX FIELD - START */}
|
||||||
{
|
{
|
||||||
item.type === "CHECKBOX" &&
|
item.type == "CHECKBOX" &&
|
||||||
<div
|
<div
|
||||||
id={item.navigationOrder}
|
id={item.navigationOrder}
|
||||||
className={`h-full w-full rounded flex justify-center items-center ${transparentTags || hideTags ? "pointer-events-none" : "bg-slate-200 shadow-sm border-slate-100 opacity-80"}`}
|
className={`h-full w-full rounded flex justify-center items-center ${transparentTags || hideTags ? "pointer-events-none" : "bg-slate-200 shadow-sm border-slate-100 opacity-80"}`}
|
||||||
|
|
@ -608,7 +608,7 @@ const TagsCon: React.FC<TagsConProps> = ({
|
||||||
|
|
||||||
{/* SIGNATURE FIELD - START */}
|
{/* SIGNATURE FIELD - START */}
|
||||||
{
|
{
|
||||||
item.type === "SIGNATURE" &&
|
item.type == "SIGNATURE" &&
|
||||||
<div
|
<div
|
||||||
tabIndex={1}
|
tabIndex={1}
|
||||||
id={item.navigationOrder}
|
id={item.navigationOrder}
|
||||||
|
|
@ -620,7 +620,7 @@ const TagsCon: React.FC<TagsConProps> = ({
|
||||||
{
|
{
|
||||||
(!transparentTags && !hideTags && !(saved.save &&
|
(!transparentTags && !hideTags && !(saved.save &&
|
||||||
(
|
(
|
||||||
(item.id !== null && item.id !== undefined && item.id !== "")
|
(item.id != null && item.id != undefined && item.id != "")
|
||||||
? (
|
? (
|
||||||
(`${item.id}`) in signConfObj && signConfObj[`${item.id}`].accepted
|
(`${item.id}`) in signConfObj && signConfObj[`${item.id}`].accepted
|
||||||
) : (
|
) : (
|
||||||
|
|
@ -629,8 +629,8 @@ const TagsCon: React.FC<TagsConProps> = ({
|
||||||
)
|
)
|
||||||
)) ? (
|
)) ? (
|
||||||
<FaSignature className="text-lg text-slate-600" />
|
<FaSignature className="text-lg text-slate-600" />
|
||||||
) : saved.saveType === "SELECT" ? (
|
) : saved && saved.saveType != null && saved.saveType == "SELECT" ? (
|
||||||
<>{saved.fullName}</>
|
<><span style={{ fontFamily: saved?.font, fontSize: "18px" }}>{saved.signature}</span></>
|
||||||
) : (
|
) : (
|
||||||
<img
|
<img
|
||||||
style={{
|
style={{
|
||||||
|
|
@ -650,7 +650,7 @@ const TagsCon: React.FC<TagsConProps> = ({
|
||||||
|
|
||||||
{/* INITIALS FIELD - START */}
|
{/* INITIALS FIELD - START */}
|
||||||
{
|
{
|
||||||
item.type === "INITIALS" &&
|
item.type == "INITIALS" &&
|
||||||
<div
|
<div
|
||||||
tabIndex={1}
|
tabIndex={1}
|
||||||
id={item.navigationOrder}
|
id={item.navigationOrder}
|
||||||
|
|
@ -660,7 +660,7 @@ const TagsCon: React.FC<TagsConProps> = ({
|
||||||
>
|
>
|
||||||
{((!transparentTags && !hideTags) && !(saved.save &&
|
{((!transparentTags && !hideTags) && !(saved.save &&
|
||||||
(
|
(
|
||||||
(item.id !== null && item.id !== undefined && item.id !== "")
|
(item.id != null && item.id != undefined && item.id != "")
|
||||||
? (
|
? (
|
||||||
(`${item.id}`) in signConfObj && signConfObj[`${item.id}`].accepted
|
(`${item.id}`) in signConfObj && signConfObj[`${item.id}`].accepted
|
||||||
) : (
|
) : (
|
||||||
|
|
@ -669,16 +669,18 @@ const TagsCon: React.FC<TagsConProps> = ({
|
||||||
)
|
)
|
||||||
)) ?
|
)) ?
|
||||||
<TbSignature className="text-lg text-slate-600" />
|
<TbSignature className="text-lg text-slate-600" />
|
||||||
:
|
: saved && saved.saveType != null && saved.saveType == "SELECT" ? (
|
||||||
<img
|
<><span style={{ fontFamily: saved?.font }}>{saved.initial}</span></>
|
||||||
style={{
|
) :
|
||||||
width: `${item.dimensions.width}px`,
|
(<img
|
||||||
height: `${item.dimensions.height}px`,
|
style={{
|
||||||
}}
|
width: `${item.dimensions.width}px`,
|
||||||
className="w-[100%] h-full"
|
height: `${item.dimensions.height}px`,
|
||||||
// src={saved.initial as string}
|
}}
|
||||||
src={`data:image/png;base64,${saved.initial}`}
|
className="w-[100%] h-full"
|
||||||
/>
|
// src={saved.initial as string}
|
||||||
|
src={`data:image/png;base64,${saved.initial}`}
|
||||||
|
/>)
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
@ -687,7 +689,7 @@ const TagsCon: React.FC<TagsConProps> = ({
|
||||||
|
|
||||||
{/* STAMP FIELD - START */}
|
{/* STAMP FIELD - START */}
|
||||||
{
|
{
|
||||||
item.type === "STAMP" &&
|
item.type == "STAMP" &&
|
||||||
<div
|
<div
|
||||||
tabIndex={1}
|
tabIndex={1}
|
||||||
id={item.navigationOrder}
|
id={item.navigationOrder}
|
||||||
|
|
@ -706,7 +708,7 @@ const TagsCon: React.FC<TagsConProps> = ({
|
||||||
|
|
||||||
{/* IMAGE FIELD - START */}
|
{/* IMAGE FIELD - START */}
|
||||||
{
|
{
|
||||||
item.type === "FILE" &&
|
item.type == "FILE" &&
|
||||||
<div
|
<div
|
||||||
tabIndex={1}
|
tabIndex={1}
|
||||||
id={item.navigationOrder}
|
id={item.navigationOrder}
|
||||||
|
|
@ -726,7 +728,7 @@ const TagsCon: React.FC<TagsConProps> = ({
|
||||||
|
|
||||||
{/* SELECT FIELD - START */}
|
{/* SELECT FIELD - START */}
|
||||||
{
|
{
|
||||||
item.type === "SELECT" &&
|
item.type == "SELECT" &&
|
||||||
<div
|
<div
|
||||||
id={item.navigationOrder}
|
id={item.navigationOrder}
|
||||||
tabIndex={1}
|
tabIndex={1}
|
||||||
|
|
@ -763,14 +765,14 @@ const TagsCon: React.FC<TagsConProps> = ({
|
||||||
{/* TEMPORAL FIELD - START */}
|
{/* TEMPORAL FIELD - START */}
|
||||||
|
|
||||||
{
|
{
|
||||||
item.type === "TEMPORAL" &&
|
item.type == "TEMPORAL" &&
|
||||||
<div
|
<div
|
||||||
id={item.navigationOrder}
|
id={item.navigationOrder}
|
||||||
tabIndex={1}
|
tabIndex={1}
|
||||||
className={`flex justify-center items-center h-full w-full rounded cursor-pointer ${transparentTags || hideTags ? "pointer-events-none" : "bg-slate-200 shadow-sm border-slate-100"}`}
|
className={`flex justify-center items-center h-full w-full rounded cursor-pointer ${transparentTags || hideTags ? "pointer-events-none" : "bg-slate-200 shadow-sm border-slate-100"}`}
|
||||||
>
|
>
|
||||||
<p
|
<p
|
||||||
style={{ opacity: `${item.id === isDateOpen ? "0" : "100"}` }}
|
style={{ opacity: `${item.id == isDateOpen ? "0" : "100"}` }}
|
||||||
className="w-full h-full rounded pl-1 pt-1 whitespace-nowrap">
|
className="w-full h-full rounded pl-1 pt-1 whitespace-nowrap">
|
||||||
{(item.id && item.id in dateValues) ? dateValues[item.id] : item.value ? item.value : item.dateFormat?.toLowerCase()}
|
{(item.id && item.id in dateValues) ? dateValues[item.id] : item.value ? item.value : item.dateFormat?.toLowerCase()}
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -784,7 +786,7 @@ const TagsCon: React.FC<TagsConProps> = ({
|
||||||
let val = e.target.value;
|
let val = e.target.value;
|
||||||
|
|
||||||
// Adding dummy time in case of time as it giving Invalid date without that
|
// Adding dummy time in case of time as it giving Invalid date without that
|
||||||
if (item.dateFormat?.toLowerCase() === "time") val = "09/02/2025 " + val
|
if (item.dateFormat?.toLowerCase() == "time") val = "09/02/2025 " + val
|
||||||
|
|
||||||
if (!item.id) return;
|
if (!item.id) return;
|
||||||
setIsDateOpen(null);
|
setIsDateOpen(null);
|
||||||
|
|
@ -797,12 +799,12 @@ const TagsCon: React.FC<TagsConProps> = ({
|
||||||
const val = e.currentTarget.value;
|
const val = e.currentTarget.value;
|
||||||
handleTagUpdate(index, val as string);
|
handleTagUpdate(index, val as string);
|
||||||
}}
|
}}
|
||||||
style={{ opacity: `${item.id === isDateOpen ? "100" : "0"}` }}
|
style={{ opacity: `${item.id == isDateOpen ? "100" : "0"}` }}
|
||||||
className="w-full px-2 outline-none absolute"
|
className="w-full px-2 outline-none absolute"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
|
||||||
}}
|
}}
|
||||||
type={`${item.dateFormat?.toLowerCase() === "date" ? "date" : (item.dateFormat?.toLowerCase() === "time" ? "time" : "datetime-local")}`}
|
type={`${item.dateFormat?.toLowerCase() == "date" ? "date" : (item.dateFormat?.toLowerCase() == "time" ? "time" : "datetime-local")}`}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -813,7 +815,7 @@ const TagsCon: React.FC<TagsConProps> = ({
|
||||||
|
|
||||||
{/* Attachment Field - START */}
|
{/* Attachment Field - START */}
|
||||||
{
|
{
|
||||||
item.type.toLowerCase() === TagsTypes.ATTACHMENT &&
|
item.type.toLowerCase() == TagsTypes.ATTACHMENT &&
|
||||||
<div
|
<div
|
||||||
tabIndex={1}
|
tabIndex={1}
|
||||||
id={item.navigationOrder}
|
id={item.navigationOrder}
|
||||||
|
|
@ -842,7 +844,7 @@ const TagsCon: React.FC<TagsConProps> = ({
|
||||||
|
|
||||||
{/* Focus Show Element */}
|
{/* Focus Show Element */}
|
||||||
{
|
{
|
||||||
(!transparentTags && !hideTags) && (focusElement && focusElement.documentId === item.documentId && focusElement.focusElementIndx === index) &&
|
(!transparentTags && !hideTags) && (focusElement && focusElement.documentId == item.documentId && focusElement.focusElementIndx == index) &&
|
||||||
<>
|
<>
|
||||||
{/* <div
|
{/* <div
|
||||||
className="absolute left-0 z-50 bg-blue-900 text-xs text-slate-100 px-2 py-[2px] rounded-sm whitespace-nowrap"
|
className="absolute left-0 z-50 bg-blue-900 text-xs text-slate-100 px-2 py-[2px] rounded-sm whitespace-nowrap"
|
||||||
|
|
|
||||||
|
|
@ -9,12 +9,12 @@
|
||||||
SME
|
SME
|
||||||
</Link>
|
</Link>
|
||||||
<div className="h-6 sm:h-8 w-px bg-gray-300"></div>
|
<div className="h-6 sm:h-8 w-px bg-gray-300"></div>
|
||||||
{recSignStatus === "COMPLETED" && (
|
{recSignStatus == "COMPLETED" && (
|
||||||
<h1 className="text-sm sm:text-md text-gray-800">
|
<h1 className="text-sm sm:text-md text-gray-800">
|
||||||
🎉 The document has been signed successfully!
|
🎉 The document has been signed successfully!
|
||||||
</h1>
|
</h1>
|
||||||
)}
|
)}
|
||||||
{recSignStatus === "DECLINED" && (
|
{recSignStatus == "DECLINED" && (
|
||||||
<h1 className="text-sm sm:text-md text-gray-800">
|
<h1 className="text-sm sm:text-md text-gray-800">
|
||||||
❌ The document has been declined by you.
|
❌ The document has been declined by you.
|
||||||
</h1>
|
</h1>
|
||||||
|
|
@ -26,23 +26,23 @@
|
||||||
<div className="mx-auto w-full max-w-6xl">
|
<div className="mx-auto w-full max-w-6xl">
|
||||||
{/* Banner */}
|
{/* Banner */}
|
||||||
<div className="flex items-center gap-3 sm:gap-4 mb-4 bg-slate-100 p-4 rounded-md">
|
<div className="flex items-center gap-3 sm:gap-4 mb-4 bg-slate-100 p-4 rounded-md">
|
||||||
{recSignStatus === "COMPLETED" && (
|
{recSignStatus == "COMPLETED" && (
|
||||||
<div className="w-10 h-10 sm:w-12 sm:h-12 bg-gradient-to-br from-teal-500 to-green-400 rounded-full flex items-center justify-center shadow-sm">
|
<div className="w-10 h-10 sm:w-12 sm:h-12 bg-gradient-to-br from-teal-500 to-green-400 rounded-full flex items-center justify-center shadow-sm">
|
||||||
<FaCheck className="text-white text-xl sm:text-2xl" />
|
<FaCheck className="text-white text-xl sm:text-2xl" />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{recSignStatus === "DECLINED" && (
|
{recSignStatus == "DECLINED" && (
|
||||||
<div className="w-10 h-10 sm:w-12 sm:h-12 bg-gradient-to-br from-red-400 to-red-500 rounded-full flex items-center justify-center shadow-sm">
|
<div className="w-10 h-10 sm:w-12 sm:h-12 bg-gradient-to-br from-red-400 to-red-500 rounded-full flex items-center justify-center shadow-sm">
|
||||||
<ImCancelCircle className="text-white text-xl sm:text-2xl" />
|
<ImCancelCircle className="text-white text-xl sm:text-2xl" />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div>
|
<div>
|
||||||
{recSignStatus === "COMPLETED" && (
|
{recSignStatus == "COMPLETED" && (
|
||||||
<p className="text-lg sm:text-2xl font-medium text-[var(--primary)]">
|
<p className="text-lg sm:text-2xl font-medium text-[var(--primary)]">
|
||||||
You have successfully signed the document.
|
You have successfully signed the document.
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
{recSignStatus === "DECLINED" && (
|
{recSignStatus == "DECLINED" && (
|
||||||
<p className="text-lg sm:text-2xl font-medium text-[var(--primary)]">
|
<p className="text-lg sm:text-2xl font-medium text-[var(--primary)]">
|
||||||
You have declined the document.
|
You have declined the document.
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -82,7 +82,7 @@
|
||||||
doc.pages.map((page, indx) => {
|
doc.pages.map((page, indx) => {
|
||||||
const key = `${doc.documentId}_${page.index}`
|
const key = `${doc.documentId}_${page.index}`
|
||||||
const currDocTags = droppedItems.filter(
|
const currDocTags = droppedItems.filter(
|
||||||
(val) => val.pageIndex === page.index
|
(val) => val.pageIndex == page.index
|
||||||
)
|
)
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
|
@ -166,7 +166,7 @@
|
||||||
>
|
>
|
||||||
Visit Sign Made Easy
|
Visit Sign Made Easy
|
||||||
</Link>
|
</Link>
|
||||||
{recSignStatus === "DECLINED" && (
|
{recSignStatus == "DECLINED" && (
|
||||||
<p className="italic text-slate-400 text-center mt-2 cursor-pointer hover:underline">
|
<p className="italic text-slate-400 text-center mt-2 cursor-pointer hover:underline">
|
||||||
Report Sender ?
|
Report Sender ?
|
||||||
</p>
|
</p>
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ const Contacts = () => {
|
||||||
}, [activeAccountId]);
|
}, [activeAccountId]);
|
||||||
|
|
||||||
const handleEdit = (contactId) => {
|
const handleEdit = (contactId) => {
|
||||||
let jsonEditData = contacts.find((prev) => prev.id === contactId)
|
let jsonEditData = contacts.find((prev) => prev.id == contactId)
|
||||||
setEditJsonData(jsonEditData)
|
setEditJsonData(jsonEditData)
|
||||||
setActionStatus("Edit")
|
setActionStatus("Edit")
|
||||||
setShowModal((prev) => !prev)
|
setShowModal((prev) => !prev)
|
||||||
|
|
@ -74,7 +74,7 @@ const Contacts = () => {
|
||||||
const toggleMenu = (contactId) => {
|
const toggleMenu = (contactId) => {
|
||||||
// Cancel any pending blur timeout (prevents blinking)
|
// Cancel any pending blur timeout (prevents blinking)
|
||||||
clearTimeout(blurTimeoutRef.current);
|
clearTimeout(blurTimeoutRef.current);
|
||||||
setOpenMenuId((prevId) => (prevId === contactId ? null : contactId));
|
setOpenMenuId((prevId) => (prevId == contactId ? null : contactId));
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleBlur = () => {
|
const handleBlur = () => {
|
||||||
|
|
@ -87,12 +87,12 @@ const Contacts = () => {
|
||||||
try {
|
try {
|
||||||
let res;
|
let res;
|
||||||
setCreateAndInviteLoader(true);
|
setCreateAndInviteLoader(true);
|
||||||
if (type === 'Edit') {
|
if (type == 'Edit') {
|
||||||
res = await api.put(`/api/v1/accounts/${activeAccountId}/contacts`, {contacts: [data], empty: true})
|
res = await api.put(`/api/v1/accounts/${activeAccountId}/contacts`, {contacts: [data], empty: true})
|
||||||
} else {
|
} else {
|
||||||
res = await api.post(`/api/v1/accounts/${activeAccountId}/contacts`, {contacts: [data], empty: true});
|
res = await api.post(`/api/v1/accounts/${activeAccountId}/contacts`, {contacts: [data], empty: true});
|
||||||
}
|
}
|
||||||
if (res.status === 200) {
|
if (res.status == 200) {
|
||||||
// toast.success('Contact created successfully!', {
|
// toast.success('Contact created successfully!', {
|
||||||
// position: "top-center",
|
// position: "top-center",
|
||||||
// autoClose: 1500,
|
// autoClose: 1500,
|
||||||
|
|
@ -149,7 +149,7 @@ const Contacts = () => {
|
||||||
<Loader />
|
<Loader />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
) : contacts.length === 0 ? (
|
) : contacts.length == 0 ? (
|
||||||
<tr>
|
<tr>
|
||||||
<td colSpan="4" className="text-center py-10 text-gray-500">
|
<td colSpan="4" className="text-center py-10 text-gray-500">
|
||||||
<div className="flex flex-col items-center justify-center">
|
<div className="flex flex-col items-center justify-center">
|
||||||
|
|
@ -183,9 +183,9 @@ const Contacts = () => {
|
||||||
<FaEllipsisV />
|
<FaEllipsisV />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
{openMenuId === contact.id && (
|
{openMenuId == contact.id && (
|
||||||
<div
|
<div
|
||||||
className={`absolute mt-1 bg-white border border-gray-200 rounded-lg shadow-lg z-20 min-w-[100px] ${contacts.length - 1 === index
|
className={`absolute mt-1 bg-white border border-gray-200 rounded-lg shadow-lg z-20 min-w-[100px] ${contacts.length - 1 == index
|
||||||
? "bottom-1 right-4"
|
? "bottom-1 right-4"
|
||||||
: "bottom-0 right-5"
|
: "bottom-0 right-5"
|
||||||
}`}
|
}`}
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ const ContactFormModal = ({
|
||||||
const [errors, setErrors] = useState<{ [key: string]: string }>({});
|
const [errors, setErrors] = useState<{ [key: string]: string }>({});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (actionStatus === "Edit" && editJsonData) {
|
if (actionStatus == "Edit" && editJsonData) {
|
||||||
setFormData({
|
setFormData({
|
||||||
email: editJsonData.email,
|
email: editJsonData.email,
|
||||||
firstName: editJsonData.firstName,
|
firstName: editJsonData.firstName,
|
||||||
|
|
@ -78,7 +78,7 @@ const ContactFormModal = ({
|
||||||
// };
|
// };
|
||||||
|
|
||||||
// const removePhoneField = (index: number) => {
|
// const removePhoneField = (index: number) => {
|
||||||
// const updatedPhones = formData.phones.filter((_, i) => i !== index);
|
// const updatedPhones = formData.phones.filter((_, i) => i != index);
|
||||||
// setFormData((prev) => ({ ...prev, phones: updatedPhones }));
|
// setFormData((prev) => ({ ...prev, phones: updatedPhones }));
|
||||||
// };
|
// };
|
||||||
|
|
||||||
|
|
@ -141,7 +141,7 @@ const ContactFormModal = ({
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
if (actionStatus === "Edit") {
|
if (actionStatus == "Edit") {
|
||||||
type = "Edit";
|
type = "Edit";
|
||||||
payload = {
|
payload = {
|
||||||
...formData,
|
...formData,
|
||||||
|
|
|
||||||
|
|
@ -37,13 +37,13 @@ function Dashboard() {
|
||||||
|
|
||||||
// Check if cookie already exists - Redirect to Dashboard
|
// Check if cookie already exists - Redirect to Dashboard
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
if (transactionStatus === TRANSACTION_STATUS_ENUMS.TRANSACTION_SEND_SUCCESS || transactionStatus === TRANSACTION_STATUS_ENUMS.TRANSACTION_INITIATED || transactionStatus === TRANSACTION_STATUS_ENUMS.TRANSACTION_SEND_FAILURE) {
|
if (transactionStatus == TRANSACTION_STATUS_ENUMS.TRANSACTION_SEND_SUCCESS || transactionStatus == TRANSACTION_STATUS_ENUMS.TRANSACTION_INITIATED || transactionStatus == TRANSACTION_STATUS_ENUMS.TRANSACTION_SEND_FAILURE) {
|
||||||
|
|
||||||
dispatch(resetSelDoc())
|
dispatch(resetSelDoc())
|
||||||
dispatch(resetSelRecipient())
|
dispatch(resetSelRecipient())
|
||||||
dispatch(clearTransaction())
|
dispatch(clearTransaction())
|
||||||
|
|
||||||
if (transactionStatus === TRANSACTION_STATUS_ENUMS.TRANSACTION_SEND_SUCCESS) {
|
if (transactionStatus == TRANSACTION_STATUS_ENUMS.TRANSACTION_SEND_SUCCESS) {
|
||||||
setShowConfetti(true)
|
setShowConfetti(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -52,22 +52,22 @@ function Dashboard() {
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (transactionStatus === TRANSACTION_STATUS_ENUMS.TRANSACTION_SEND_SUCCESS || transactionStatus === TRANSACTION_STATUS_ENUMS.TRANSACTION_INITIATED) return;
|
if (transactionStatus == TRANSACTION_STATUS_ENUMS.TRANSACTION_SEND_SUCCESS || transactionStatus == TRANSACTION_STATUS_ENUMS.TRANSACTION_INITIATED) return;
|
||||||
|
|
||||||
if (selectedDocuments === null || (Array.isArray(selectedDocuments) && !selectedDocuments.length)) {
|
if (selectedDocuments == null || (Array.isArray(selectedDocuments) && !selectedDocuments.length)) {
|
||||||
dispatch(resetSelDoc())
|
dispatch(resetSelDoc())
|
||||||
}
|
}
|
||||||
dispatch(showLoader("Loading ..."));
|
dispatch(showLoader("Loading ..."));
|
||||||
|
|
||||||
if (documentSignType && transactionStatus === TRANSACTION_STATUS_ENUMS.TRANSACTION_NOT_INITIATED) {
|
if (documentSignType && transactionStatus == TRANSACTION_STATUS_ENUMS.TRANSACTION_NOT_INITIATED) {
|
||||||
if (documentSignType === 'self-sign') {
|
if (documentSignType == 'self-sign') {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
navigate('/process-step-one');
|
navigate('/setup-transaction');
|
||||||
}, 1000)
|
}, 1000)
|
||||||
return
|
return
|
||||||
} else if (documentSignType === 'multiple-sign') {
|
} else if (documentSignType == 'multiple-sign') {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
navigate('/process-step-one');
|
navigate('/setup-transaction');
|
||||||
}, 1000)
|
}, 1000)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ interface NavLinkProps {
|
||||||
const NavLink: React.FC<NavLinkProps> = ({ to, icon, label, showSideBar, menuPathMap }) => {
|
const NavLink: React.FC<NavLinkProps> = ({ to, icon, label, showSideBar, menuPathMap }) => {
|
||||||
|
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const isActive = menuPathMap[location.pathname] === label;
|
const isActive = menuPathMap[location.pathname] == label;
|
||||||
|
|
||||||
// const [transactionFilter, setTransationFilter] = useState<TransactionFilterEnum>(TransactionFilterEnum.ALL)
|
// const [transactionFilter, setTransationFilter] = useState<TransactionFilterEnum>(TransactionFilterEnum.ALL)
|
||||||
|
|
||||||
|
|
@ -47,7 +47,7 @@ const NavLink: React.FC<NavLinkProps> = ({ to, icon, label, showSideBar, menuPat
|
||||||
export default NavLink;
|
export default NavLink;
|
||||||
|
|
||||||
|
|
||||||
// {label === "Transactions" ? <div>
|
// {label == "Transactions" ? <div>
|
||||||
// <Link
|
// <Link
|
||||||
// to={to + "/all"}
|
// to={to + "/all"}
|
||||||
// className={`${isActive ? 'text-[var(--menuTextColActive)] bg-[var(--menuBgColActive)]' : 'text-[var(--menuTextCol)]'}
|
// className={`${isActive ? 'text-[var(--menuTextColActive)] bg-[var(--menuBgColActive)]' : 'text-[var(--menuTextCol)]'}
|
||||||
|
|
@ -63,77 +63,77 @@ export default NavLink;
|
||||||
// >
|
// >
|
||||||
// <Link
|
// <Link
|
||||||
// to={to + "/all"}
|
// to={to + "/all"}
|
||||||
// className={`px-2 py-1 mt-1 ${transactionFilter === TransactionFilterEnum.ALL ? 'text-[var(--menuTextColActive)] bg-[var(--menuBgColActive)]' : 'text-[var(--menuTextCol)]'} rounded-md flex justify-between gap-2 items-center transition-all duration-300 ${showSideBar ? 'text-lg' : 'text-lg max-w-max'}`}
|
// className={`px-2 py-1 mt-1 ${transactionFilter == TransactionFilterEnum.ALL ? 'text-[var(--menuTextColActive)] bg-[var(--menuBgColActive)]' : 'text-[var(--menuTextCol)]'} rounded-md flex justify-between gap-2 items-center transition-all duration-300 ${showSideBar ? 'text-lg' : 'text-lg max-w-max'}`}
|
||||||
// onClick={() => setTransationFilter(TransactionFilterEnum.ALL)}
|
// onClick={() => setTransationFilter(TransactionFilterEnum.ALL)}
|
||||||
// >
|
// >
|
||||||
// {showSideBar && <p className="text-[0.8rem]">All</p>}
|
// {showSideBar && <p className="text-[0.8rem]">All</p>}
|
||||||
// {transactionFilter === TransactionFilterEnum.ALL && <IoIosArrowRoundForward />}
|
// {transactionFilter == TransactionFilterEnum.ALL && <IoIosArrowRoundForward />}
|
||||||
// </Link>
|
// </Link>
|
||||||
|
|
||||||
// <Link
|
// <Link
|
||||||
// to={to + "/draft"}
|
// to={to + "/draft"}
|
||||||
// className={`px-2 py-1 mt-1 ${transactionFilter === TransactionFilterEnum.DRAFT ? 'text-[var(--menuTextColActive)] bg-[var(--menuBgColActive)]' : 'text-[var(--menuTextCol)]'} rounded-md flex justify-between gap-2 items-center transition-all duration-300 ${showSideBar ? 'text-lg' : 'text-lg max-w-max'}`}
|
// className={`px-2 py-1 mt-1 ${transactionFilter == TransactionFilterEnum.DRAFT ? 'text-[var(--menuTextColActive)] bg-[var(--menuBgColActive)]' : 'text-[var(--menuTextCol)]'} rounded-md flex justify-between gap-2 items-center transition-all duration-300 ${showSideBar ? 'text-lg' : 'text-lg max-w-max'}`}
|
||||||
// onClick={() => setTransationFilter(TransactionFilterEnum.DRAFT)}
|
// onClick={() => setTransationFilter(TransactionFilterEnum.DRAFT)}
|
||||||
// >
|
// >
|
||||||
// {showSideBar && <p className="text-[0.8rem]">Draft</p>}
|
// {showSideBar && <p className="text-[0.8rem]">Draft</p>}
|
||||||
// {transactionFilter === TransactionFilterEnum.DRAFT && <IoIosArrowRoundForward />}
|
// {transactionFilter == TransactionFilterEnum.DRAFT && <IoIosArrowRoundForward />}
|
||||||
// </Link>
|
// </Link>
|
||||||
|
|
||||||
// <Link
|
// <Link
|
||||||
// to={to + "/sent"}
|
// to={to + "/sent"}
|
||||||
// className={`px-2 py-1 mt-1 ${transactionFilter === TransactionFilterEnum.SENT ? 'text-[var(--menuTextColActive)] bg-[var(--menuBgColActive)]' : 'text-[var(--menuTextCol)]'} rounded-md flex justify-between gap-2 items-center transition-all duration-300 ${showSideBar ? 'text-lg' : 'text-lg max-w-max'}`}
|
// className={`px-2 py-1 mt-1 ${transactionFilter == TransactionFilterEnum.SENT ? 'text-[var(--menuTextColActive)] bg-[var(--menuBgColActive)]' : 'text-[var(--menuTextCol)]'} rounded-md flex justify-between gap-2 items-center transition-all duration-300 ${showSideBar ? 'text-lg' : 'text-lg max-w-max'}`}
|
||||||
// onClick={() => setTransationFilter(TransactionFilterEnum.SENT)}
|
// onClick={() => setTransationFilter(TransactionFilterEnum.SENT)}
|
||||||
// >
|
// >
|
||||||
// {showSideBar && <p className="text-[0.8rem]">Sent</p>}
|
// {showSideBar && <p className="text-[0.8rem]">Sent</p>}
|
||||||
// {transactionFilter === TransactionFilterEnum.SENT && <IoIosArrowRoundForward />}
|
// {transactionFilter == TransactionFilterEnum.SENT && <IoIosArrowRoundForward />}
|
||||||
// </Link>
|
// </Link>
|
||||||
|
|
||||||
// <Link
|
// <Link
|
||||||
// to={to + "/complete"}
|
// to={to + "/complete"}
|
||||||
// className={`px-2 py-1 my-1 ${transactionFilter === TransactionFilterEnum.COMPLETE ? 'text-[var(--menuTextColActive)] bg-[var(--menuBgColActive)]' : 'text-[var(--menuTextCol)]'} rounded-md flex justify-between gap-2 items-center transition-all duration-300 ${showSideBar ? 'text-lg' : 'text-lg max-w-max'}`}
|
// className={`px-2 py-1 my-1 ${transactionFilter == TransactionFilterEnum.COMPLETE ? 'text-[var(--menuTextColActive)] bg-[var(--menuBgColActive)]' : 'text-[var(--menuTextCol)]'} rounded-md flex justify-between gap-2 items-center transition-all duration-300 ${showSideBar ? 'text-lg' : 'text-lg max-w-max'}`}
|
||||||
// onClick={() => setTransationFilter(TransactionFilterEnum.COMPLETE)}
|
// onClick={() => setTransationFilter(TransactionFilterEnum.COMPLETE)}
|
||||||
// >
|
// >
|
||||||
// {showSideBar && <p className="text-[0.8rem]">Completed</p>}
|
// {showSideBar && <p className="text-[0.8rem]">Completed</p>}
|
||||||
// {transactionFilter === TransactionFilterEnum.COMPLETE && <IoIosArrowRoundForward />}
|
// {transactionFilter == TransactionFilterEnum.COMPLETE && <IoIosArrowRoundForward />}
|
||||||
// </Link>
|
// </Link>
|
||||||
|
|
||||||
// <Link
|
// <Link
|
||||||
// to={to + "/declined"}
|
// to={to + "/declined"}
|
||||||
// className={`px-2 py-1 my-1 ${transactionFilter === TransactionFilterEnum.DECLINED ? 'text-[var(--menuTextColActive)] bg-[var(--menuBgColActive)]' : 'text-[var(--menuTextCol)]'} rounded-md flex justify-between gap-2 items-center transition-all duration-300 ${showSideBar ? 'text-lg' : 'text-lg max-w-max'}`}
|
// className={`px-2 py-1 my-1 ${transactionFilter == TransactionFilterEnum.DECLINED ? 'text-[var(--menuTextColActive)] bg-[var(--menuBgColActive)]' : 'text-[var(--menuTextCol)]'} rounded-md flex justify-between gap-2 items-center transition-all duration-300 ${showSideBar ? 'text-lg' : 'text-lg max-w-max'}`}
|
||||||
// onClick={() => setTransationFilter(TransactionFilterEnum.DECLINED)}
|
// onClick={() => setTransationFilter(TransactionFilterEnum.DECLINED)}
|
||||||
// >
|
// >
|
||||||
// {showSideBar && <p className="text-[0.8rem]">Declined</p>}
|
// {showSideBar && <p className="text-[0.8rem]">Declined</p>}
|
||||||
// {transactionFilter === TransactionFilterEnum.DECLINED && <IoIosArrowRoundForward />}
|
// {transactionFilter == TransactionFilterEnum.DECLINED && <IoIosArrowRoundForward />}
|
||||||
// </Link>
|
// </Link>
|
||||||
|
|
||||||
|
|
||||||
// <Link
|
// <Link
|
||||||
// to={to + "/discarded"}
|
// to={to + "/discarded"}
|
||||||
// className={`px-2 py-1 my-1 ${transactionFilter === TransactionFilterEnum.DISCARDED ? 'text-[var(--menuTextColActive)] bg-[var(--menuBgColActive)]' : 'text-[var(--menuTextCol)]'} rounded-md flex justify-between gap-2 items-center transition-all duration-300 ${showSideBar ? 'text-lg' : 'text-lg max-w-max'}`}
|
// className={`px-2 py-1 my-1 ${transactionFilter == TransactionFilterEnum.DISCARDED ? 'text-[var(--menuTextColActive)] bg-[var(--menuBgColActive)]' : 'text-[var(--menuTextCol)]'} rounded-md flex justify-between gap-2 items-center transition-all duration-300 ${showSideBar ? 'text-lg' : 'text-lg max-w-max'}`}
|
||||||
// onClick={() => setTransationFilter(TransactionFilterEnum.DISCARDED)}
|
// onClick={() => setTransationFilter(TransactionFilterEnum.DISCARDED)}
|
||||||
// >
|
// >
|
||||||
// {showSideBar && <p className="text-[0.8rem]">Discarded</p>}
|
// {showSideBar && <p className="text-[0.8rem]">Discarded</p>}
|
||||||
// {transactionFilter === TransactionFilterEnum.DISCARDED && <IoIosArrowRoundForward />}
|
// {transactionFilter == TransactionFilterEnum.DISCARDED && <IoIosArrowRoundForward />}
|
||||||
// </Link>
|
// </Link>
|
||||||
|
|
||||||
|
|
||||||
// <Link
|
// <Link
|
||||||
// to={to + "/canceled"}
|
// to={to + "/canceled"}
|
||||||
// className={`px-2 py-1 my-1 ${transactionFilter === TransactionFilterEnum.CANCELED ? 'text-[var(--menuTextColActive)] bg-[var(--menuBgColActive)]' : 'text-[var(--menuTextCol)]'} rounded-md flex justify-between gap-2 items-center transition-all duration-300 ${showSideBar ? 'text-lg' : 'text-lg max-w-max'}`}
|
// className={`px-2 py-1 my-1 ${transactionFilter == TransactionFilterEnum.CANCELED ? 'text-[var(--menuTextColActive)] bg-[var(--menuBgColActive)]' : 'text-[var(--menuTextCol)]'} rounded-md flex justify-between gap-2 items-center transition-all duration-300 ${showSideBar ? 'text-lg' : 'text-lg max-w-max'}`}
|
||||||
// onClick={() => setTransationFilter(TransactionFilterEnum.CANCELED)}
|
// onClick={() => setTransationFilter(TransactionFilterEnum.CANCELED)}
|
||||||
// >
|
// >
|
||||||
// {showSideBar && <p className="text-[0.8rem]">Canceled</p>}
|
// {showSideBar && <p className="text-[0.8rem]">Canceled</p>}
|
||||||
// {transactionFilter === TransactionFilterEnum.CANCELED && <IoIosArrowRoundForward />}
|
// {transactionFilter == TransactionFilterEnum.CANCELED && <IoIosArrowRoundForward />}
|
||||||
// </Link>
|
// </Link>
|
||||||
|
|
||||||
|
|
||||||
// <Link
|
// <Link
|
||||||
// to={to + "/expired"}
|
// to={to + "/expired"}
|
||||||
// className={`px-2 py-1 my-1 ${transactionFilter === TransactionFilterEnum.EXPIRED ? 'text-[var(--menuTextColActive)] bg-[var(--menuBgColActive)]' : 'text-[var(--menuTextCol)]'} rounded-md flex justify-between gap-2 items-center transition-all duration-300 ${showSideBar ? 'text-lg' : 'text-lg max-w-max'}`}
|
// className={`px-2 py-1 my-1 ${transactionFilter == TransactionFilterEnum.EXPIRED ? 'text-[var(--menuTextColActive)] bg-[var(--menuBgColActive)]' : 'text-[var(--menuTextCol)]'} rounded-md flex justify-between gap-2 items-center transition-all duration-300 ${showSideBar ? 'text-lg' : 'text-lg max-w-max'}`}
|
||||||
// onClick={() => setTransationFilter(TransactionFilterEnum.EXPIRED)}
|
// onClick={() => setTransationFilter(TransactionFilterEnum.EXPIRED)}
|
||||||
// >
|
// >
|
||||||
// {showSideBar && <p className="text-[0.8rem]">Expired</p>}
|
// {showSideBar && <p className="text-[0.8rem]">Expired</p>}
|
||||||
// {transactionFilter === TransactionFilterEnum.EXPIRED && <IoIosArrowRoundForward />}
|
// {transactionFilter == TransactionFilterEnum.EXPIRED && <IoIosArrowRoundForward />}
|
||||||
// </Link>
|
// </Link>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ const SendForSign: React.FC<Props> = ({ showSideBar }) => {
|
||||||
const user = useSelector((state: RootState) => state.user);
|
const user = useSelector((state: RootState) => state.user);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!user.account || user.account === null) {
|
if (!user.account || user.account == null) {
|
||||||
window.location.href = "/login";
|
window.location.href = "/login";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -40,11 +40,11 @@ const SendForSign: React.FC<Props> = ({ showSideBar }) => {
|
||||||
|
|
||||||
api.post(`/api/v1/accounts/${defaultAccountId}/transactions`)
|
api.post(`/api/v1/accounts/${defaultAccountId}/transactions`)
|
||||||
.then(res => {
|
.then(res => {
|
||||||
if (res.status === 200 || res.status === 201) {
|
if (res.status == 200 || res.status == 201) {
|
||||||
dispatch(updateTransactionStatus(TRANSACTION_STATUS_ENUMS.TRANSACTION_INITIATED));
|
dispatch(updateTransactionStatus(TRANSACTION_STATUS_ENUMS.TRANSACTION_INITIATED));
|
||||||
dispatch(setTransactionId(res.data.id));
|
dispatch(setTransactionId(res.data.id));
|
||||||
let navigateUrl = `/process-step-one/${defaultAccountId}/${res.data.id}`;
|
let navigateUrl = `/setup-transaction/${defaultAccountId}/${res.data.id}`;
|
||||||
if (signType === SignTypeEnum.selfSign) navigateUrl = `/process-step-one/${defaultAccountId}/${res.data.id}/self_sign`;
|
if (signType == SignTypeEnum.selfSign) navigateUrl = `/setup-transaction/${defaultAccountId}/${res.data.id}/self_sign`;
|
||||||
setTimeout(() => navigate(navigateUrl), 0)
|
setTimeout(() => navigate(navigateUrl), 0)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -52,8 +52,8 @@ const SendForSign: React.FC<Props> = ({ showSideBar }) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
// const handleSendSignDispatch: (type: "self-sign" | "multiple-sign") => void = (signType) => {
|
// const handleSendSignDispatch: (type: "self-sign" | "multiple-sign") => void = (signType) => {
|
||||||
// if (selectedDocuments === null || !selectedDocuments.length) {
|
// if (selectedDocuments == null || !selectedDocuments.length) {
|
||||||
// if (selectedDocuments === null || !selectedDocuments.length) {
|
// if (selectedDocuments == null || !selectedDocuments.length) {
|
||||||
// toast.dismiss();
|
// toast.dismiss();
|
||||||
// toast.error("Select 📄 Documents first!", {
|
// toast.error("Select 📄 Documents first!", {
|
||||||
// position: "bottom-right",
|
// position: "bottom-right",
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,7 @@ const Cards: React.FC<CardsProps> = ({ type = 'dashboard', onOpenModal, onDateRa
|
||||||
// useEffect(() => {
|
// useEffect(() => {
|
||||||
// setIsLoading(true);
|
// setIsLoading(true);
|
||||||
// setTimeout(() => {
|
// setTimeout(() => {
|
||||||
// if (type === 'account') {
|
// if (type == 'account') {
|
||||||
// setShowCards(AccountData);
|
// setShowCards(AccountData);
|
||||||
// } else {
|
// } else {
|
||||||
// setShowCards(cards);
|
// setShowCards(cards);
|
||||||
|
|
@ -117,7 +117,7 @@ const Cards: React.FC<CardsProps> = ({ type = 'dashboard', onOpenModal, onDateRa
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
||||||
if (type === 'dashboard') {
|
if (type == 'dashboard') {
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
let fromDate = new Date();
|
let fromDate = new Date();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -120,7 +120,7 @@ const Home = () => {
|
||||||
// Listen for sessionStorage changes
|
// Listen for sessionStorage changes
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleStorageChange = (e: StorageEvent) => {
|
const handleStorageChange = (e: StorageEvent) => {
|
||||||
if (e.key === 'activeAccountId') {
|
if (e.key == 'activeAccountId') {
|
||||||
const newActiveAccountId = e.newValue ? JSON.parse(e.newValue) : null;
|
const newActiveAccountId = e.newValue ? JSON.parse(e.newValue) : null;
|
||||||
setActiveAccountId(newActiveAccountId);
|
setActiveAccountId(newActiveAccountId);
|
||||||
}
|
}
|
||||||
|
|
@ -131,7 +131,7 @@ const Home = () => {
|
||||||
|
|
||||||
// Custom event listener for same-tab changes
|
// Custom event listener for same-tab changes
|
||||||
const handleCustomStorageChange = (e: CustomEvent) => {
|
const handleCustomStorageChange = (e: CustomEvent) => {
|
||||||
if (e.detail.key === 'activeAccountId') {
|
if (e.detail.key == 'activeAccountId') {
|
||||||
setActiveAccountId(e.detail.newValue);
|
setActiveAccountId(e.detail.newValue);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ const ShowDocs = () => {
|
||||||
// Handle checkbox selection
|
// Handle checkbox selection
|
||||||
const handleSelect = (docId: string) => {
|
const handleSelect = (docId: string) => {
|
||||||
setSelectedDocs((prev) =>
|
setSelectedDocs((prev) =>
|
||||||
prev.includes(docId) ? prev.filter((id) => id !== docId) : [...prev, docId]
|
prev.includes(docId) ? prev.filter((id) => id != docId) : [...prev, docId]
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -37,7 +37,7 @@ const ShowDocs = () => {
|
||||||
// Updating Redux State When Anywhere Sign Type is set ["self-sign" | "multiple-sign"]
|
// Updating Redux State When Anywhere Sign Type is set ["self-sign" | "multiple-sign"]
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// if (signTypeGlobalState === null) return;
|
// if (signTypeGlobalState == null) return;
|
||||||
handleUpdateSelectedDocs()
|
handleUpdateSelectedDocs()
|
||||||
}, [selectedDocs])
|
}, [selectedDocs])
|
||||||
|
|
||||||
|
|
@ -45,7 +45,7 @@ const ShowDocs = () => {
|
||||||
// useEffect(() => {
|
// useEffect(() => {
|
||||||
// setTimeout(async () => {
|
// setTimeout(async () => {
|
||||||
// const res = await dispatch(fetchDocuments());
|
// const res = await dispatch(fetchDocuments());
|
||||||
// if (res.meta.requestStatus === "rejected") {
|
// if (res.meta.requestStatus == "rejected") {
|
||||||
// Object.keys(localStorage).forEach((key) => {
|
// Object.keys(localStorage).forEach((key) => {
|
||||||
// if (key.startsWith("persist:root-")) {
|
// if (key.startsWith("persist:root-")) {
|
||||||
// localStorage.removeItem(key);
|
// localStorage.removeItem(key);
|
||||||
|
|
@ -70,7 +70,7 @@ const ShowDocs = () => {
|
||||||
onChange={() => handleSelect(doc.id)}
|
onChange={() => handleSelect(doc.id)}
|
||||||
/>
|
/>
|
||||||
<div className="flex gap-2 items-center">
|
<div className="flex gap-2 items-center">
|
||||||
{doc.extension === "pdf" ? (
|
{doc.extension == "pdf" ? (
|
||||||
<BsFiletypePdf className="text-lg text-red-400" />
|
<BsFiletypePdf className="text-lg text-red-400" />
|
||||||
) : (
|
) : (
|
||||||
<BsFiletypeDocx className="text-lg text-blue-400" />
|
<BsFiletypeDocx className="text-lg text-blue-400" />
|
||||||
|
|
@ -118,7 +118,7 @@ const ShowDocs = () => {
|
||||||
</td>
|
</td>
|
||||||
<td className="px-4 py-3">
|
<td className="px-4 py-3">
|
||||||
<label htmlFor={doc.name + idx} className="flex items-center gap-2 cursor-pointer">
|
<label htmlFor={doc.name + idx} className="flex items-center gap-2 cursor-pointer">
|
||||||
{doc.extension === "pdf" ? (
|
{doc.extension == "pdf" ? (
|
||||||
<BsFiletypePdf className="text-xl text-red-500" />
|
<BsFiletypePdf className="text-xl text-red-500" />
|
||||||
) : (
|
) : (
|
||||||
<BsFiletypeDocx className="text-xl text-blue-500" />
|
<BsFiletypeDocx className="text-xl text-blue-500" />
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ const StartNow = () => {
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
// toast.dismiss();
|
// toast.dismiss();
|
||||||
setFiles([]);
|
setFiles([]);
|
||||||
navigate(`/process-step-one/${accountId}/${transactionId}`);
|
navigate(`/setup-transaction/${accountId}/${transactionId}`);
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.error("Upload failed", err);
|
console.error("Upload failed", err);
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ const StartSection = () => {
|
||||||
);
|
);
|
||||||
|
|
||||||
const user = useSelector((state: RootState) => state.user);
|
const user = useSelector((state: RootState) => state.user);
|
||||||
if (!user.account || user.account === null) {
|
if (!user.account || user.account == null) {
|
||||||
window.location.href = "/login";
|
window.location.href = "/login";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -60,13 +60,13 @@ const StartSection = () => {
|
||||||
const defaultAccountId = user.account.id;
|
const defaultAccountId = user.account.id;
|
||||||
|
|
||||||
const handleStartSectionClick = (link: string) => {
|
const handleStartSectionClick = (link: string) => {
|
||||||
// if ("buttonText" in card && card.buttonText === "Start Now") {
|
// if ("buttonText" in card && card.buttonText == "Start Now") {
|
||||||
// api.post(`/api/v1/accounts/${defaultAccountId}/transactions`)
|
// api.post(`/api/v1/accounts/${defaultAccountId}/transactions`)
|
||||||
// .then(res => {
|
// .then(res => {
|
||||||
// if (res.status === 200 || res.status === 201) {
|
// if (res.status == 200 || res.status == 201) {
|
||||||
// dispatch(updateTransactionStatus(TRANSACTION_STATUS_ENUMS.TRANSACTION_INITIATED));
|
// dispatch(updateTransactionStatus(TRANSACTION_STATUS_ENUMS.TRANSACTION_INITIATED));
|
||||||
// dispatch(setTransactionId(res.data));
|
// dispatch(setTransactionId(res.data));
|
||||||
// setTimeout(() => navigate(`/process-step-one/${defaultAccountId}/${res.data.id}`), 0)
|
// setTimeout(() => navigate(`/setup-transaction/${defaultAccountId}/${res.data.id}`), 0)
|
||||||
// }
|
// }
|
||||||
// })
|
// })
|
||||||
// .catch(err => console.log(err))
|
// .catch(err => console.log(err))
|
||||||
|
|
@ -89,7 +89,7 @@ const StartSection = () => {
|
||||||
// Listen for sessionStorage changes
|
// Listen for sessionStorage changes
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleStorageChange = (e: StorageEvent) => {
|
const handleStorageChange = (e: StorageEvent) => {
|
||||||
if (e.key === 'activeAccountId') {
|
if (e.key == 'activeAccountId') {
|
||||||
const newActiveAccountId = e.newValue ? JSON.parse(e.newValue) : null;
|
const newActiveAccountId = e.newValue ? JSON.parse(e.newValue) : null;
|
||||||
setActiveAccountId(newActiveAccountId);
|
setActiveAccountId(newActiveAccountId);
|
||||||
}
|
}
|
||||||
|
|
@ -100,7 +100,7 @@ const StartSection = () => {
|
||||||
|
|
||||||
// Custom event listener for same-tab changes
|
// Custom event listener for same-tab changes
|
||||||
const handleCustomStorageChange = (e: CustomEvent) => {
|
const handleCustomStorageChange = (e: CustomEvent) => {
|
||||||
if (e.detail.key === 'activeAccountId') {
|
if (e.detail.key == 'activeAccountId') {
|
||||||
setActiveAccountId(e.detail.newValue);
|
setActiveAccountId(e.detail.newValue);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ const UploadDoc: React.FC = () => {
|
||||||
>
|
>
|
||||||
<span className="truncate text-sm text-gray-800 max-w-[85%]">{file.name}</span>
|
<span className="truncate text-sm text-gray-800 max-w-[85%]">{file.name}</span>
|
||||||
<MdCancel
|
<MdCancel
|
||||||
onClick={() => setFiles(files.filter((_, i) => i !== index))}
|
onClick={() => setFiles(files.filter((_, i) => i != index))}
|
||||||
className="text-gray-400 hover:text-red-500 cursor-pointer transition"
|
className="text-gray-400 hover:text-red-500 cursor-pointer transition"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -157,7 +157,7 @@ const SigningOrderDiagram: React.FC<{ signers: Signer[] }> = ({ signers }) => {
|
||||||
if (signer.completed) {
|
if (signer.completed) {
|
||||||
bgColor = "bg-[var(--primary)]";
|
bgColor = "bg-[var(--primary)]";
|
||||||
icon = <FaCheck className="text-green-600" />;
|
icon = <FaCheck className="text-green-600" />;
|
||||||
} else if (order === currentProcessingOrder) {
|
} else if (order == currentProcessingOrder) {
|
||||||
bgColor = "bg-yellow-500";
|
bgColor = "bg-yellow-500";
|
||||||
icon = <FaClock className="text-yellow-800" />;
|
icon = <FaClock className="text-yellow-800" />;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -221,8 +221,8 @@ const DocumentSubmissionOptions = () => {
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
selectedRecipients.length === 0 && dispatch(fetchRecipients({ accountId, transactionId }));
|
selectedRecipients.length == 0 && dispatch(fetchRecipients({ accountId, transactionId }));
|
||||||
selectedDocuments.length === 0 && dispatch(fetchDocuments({ accountId, transactionId }));
|
selectedDocuments.length == 0 && dispatch(fetchDocuments({ accountId, transactionId }));
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -275,9 +275,9 @@ const DocumentSubmissionOptions = () => {
|
||||||
}
|
}
|
||||||
}, [accountId, transactionId]);
|
}, [accountId, transactionId]);
|
||||||
|
|
||||||
// Step 2: Prevent browser back when status === 'SENT'
|
// Step 2: Prevent browser back when status == 'SENT'
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (status === "SENT") {
|
if (status == "SENT") {
|
||||||
|
|
||||||
const currentPath = window.location.pathname;
|
const currentPath = window.location.pathname;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ export const SignersList: React.FC<{ signers: Signer[] }> = ({ signers }) => {
|
||||||
|
|
||||||
<div className="overflow-y-auto no-scrollbar">
|
<div className="overflow-y-auto no-scrollbar">
|
||||||
{signers.map((signer, indx) => (
|
{signers.map((signer, indx) => (
|
||||||
<div key={signer.id} className={`text-sm flex items-center gap-4 ${indx !== signers.length-1 ? "border-b-1 border-gray-200" : ""} py-4`}>
|
<div key={signer.id} className={`text-sm flex items-center gap-4 ${indx != signers.length-1 ? "border-b-1 border-gray-200" : ""} py-4`}>
|
||||||
<div className="w-10 h-10 bg-blue-100 rounded-full flex items-center justify-center text-blue-600 font-medium">
|
<div className="w-10 h-10 bg-blue-100 rounded-full flex items-center justify-center text-blue-600 font-medium">
|
||||||
{/* {signer.name.split(" ").length > 2 ? signer.name.split(" ").map(n => n[0].toUpperCase()).join("") : signer.name[0].toUpperCase()} */}
|
{/* {signer.name.split(" ").length > 2 ? signer.name.split(" ").map(n => n[0].toUpperCase()).join("") : signer.name[0].toUpperCase()} */}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ export const SigningOrderDiagram: React.FC<{ signers: Signer[] }> = ({ signers }
|
||||||
if (signer.completed) {
|
if (signer.completed) {
|
||||||
bgColor = "bg-[var(--primary)]";
|
bgColor = "bg-[var(--primary)]";
|
||||||
icon = <FaCheck className="text-green-600" />;
|
icon = <FaCheck className="text-green-600" />;
|
||||||
} else if (order === currentProcessingOrder) {
|
} else if (order == currentProcessingOrder) {
|
||||||
bgColor = "bg-yellow-500";
|
bgColor = "bg-yellow-500";
|
||||||
icon = <FaClock className="text-yellow-800" />;
|
icon = <FaClock className="text-yellow-800" />;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -28,13 +28,13 @@ const TransactionSentSuccess = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
selectedRecipients.length === 0 && dispatch(fetchRecipients({ accountId, transactionId }))
|
selectedRecipients.length == 0 && dispatch(fetchRecipients({ accountId, transactionId }))
|
||||||
selectedDocuments.length === 0 && dispatch(fetchDocuments({ accountId, transactionId }))
|
selectedDocuments.length == 0 && dispatch(fetchDocuments({ accountId, transactionId }))
|
||||||
setIsVisible(true)
|
setIsVisible(true)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedRecipients.length === 0) return
|
if (selectedRecipients.length == 0) return
|
||||||
|
|
||||||
let minRoutingOrder: number = Infinity
|
let minRoutingOrder: number = Infinity
|
||||||
let userEmailPresent = {
|
let userEmailPresent = {
|
||||||
|
|
@ -50,19 +50,19 @@ const TransactionSentSuccess = () => {
|
||||||
minRoutingOrder = recipient.routingOrder
|
minRoutingOrder = recipient.routingOrder
|
||||||
}
|
}
|
||||||
|
|
||||||
if (recipient.email === userDetails.email) {
|
if (recipient.email == userDetails.email) {
|
||||||
userEmailPresent.present = true
|
userEmailPresent.present = true
|
||||||
userEmailPresent.routingOrder = recipient.routingOrder
|
userEmailPresent.routingOrder = recipient.routingOrder
|
||||||
userEmailPresent.recipientId = Number(recipient.id)
|
userEmailPresent.recipientId = recipient.id
|
||||||
userEmailPresent.type = recipient.type
|
userEmailPresent.type = recipient.type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
userEmailPresent.present &&
|
userEmailPresent.present &&
|
||||||
userEmailPresent.routingOrder === minRoutingOrder &&
|
userEmailPresent.routingOrder == minRoutingOrder &&
|
||||||
userEmailPresent.type !== recipientType.CC &&
|
userEmailPresent.type != recipientType.CC &&
|
||||||
userEmailPresent.type !== recipientType.INPERSONSIGNER
|
userEmailPresent.type != recipientType.INPERSONSIGNER
|
||||||
) {
|
) {
|
||||||
setSelfUserSign({ sign: true, recipientId: userEmailPresent.recipientId })
|
setSelfUserSign({ sign: true, recipientId: userEmailPresent.recipientId })
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ const AdvancedOptions: React.FC<AdvancedOptionsProps> = ({ accountId, setShowAdv
|
||||||
|
|
||||||
let changes : any = {}
|
let changes : any = {}
|
||||||
for (const [key, val] of Object.entries(transactionDetails)) {
|
for (const [key, val] of Object.entries(transactionDetails)) {
|
||||||
if(transactionFormData[key as keyof TransactionDetailsInt] === transactionDetails[key as keyof TransactionDetailsInt]) continue
|
if(transactionFormData[key as keyof TransactionDetailsInt] == transactionDetails[key as keyof TransactionDetailsInt]) continue
|
||||||
changes[key as keyof TransactionDetailsInt] = val
|
changes[key as keyof TransactionDetailsInt] = val
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ const highlightText = (text: string, searchTerm: string, shouldHighlight: boolea
|
||||||
const textLower = text.toLowerCase();
|
const textLower = text.toLowerCase();
|
||||||
const index = textLower.indexOf(searchTermLower);
|
const index = textLower.indexOf(searchTermLower);
|
||||||
|
|
||||||
if (index === -1) {
|
if (index == -1) {
|
||||||
return <span>{text}</span>;
|
return <span>{text}</span>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -67,7 +67,7 @@ const ContactModal: React.FC<ContactDataProps> = ({
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleKeyDown = (event: React.KeyboardEvent, indx: number) => {
|
const handleKeyDown = (event: React.KeyboardEvent, indx: number) => {
|
||||||
if (event.key === 'Enter' || event.key === ' ') {
|
if (event.key == 'Enter' || event.key == ' ') {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
handleContactClick(indx);
|
handleContactClick(indx);
|
||||||
}
|
}
|
||||||
|
|
@ -101,14 +101,14 @@ const ContactModal: React.FC<ContactDataProps> = ({
|
||||||
{highlightText(
|
{highlightText(
|
||||||
contact.firstName,
|
contact.firstName,
|
||||||
inpFirstName,
|
inpFirstName,
|
||||||
contactData.type === "firstName"
|
contactData.type == "firstName"
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
<p className="text-sm font-semibold text-gray-900 truncate">
|
<p className="text-sm font-semibold text-gray-900 truncate">
|
||||||
{highlightText(
|
{highlightText(
|
||||||
contact.lastName,
|
contact.lastName,
|
||||||
inpLastName,
|
inpLastName,
|
||||||
contactData.type === "lastName"
|
contactData.type == "lastName"
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -116,7 +116,7 @@ const ContactModal: React.FC<ContactDataProps> = ({
|
||||||
{highlightText(
|
{highlightText(
|
||||||
contact.email,
|
contact.email,
|
||||||
inpEmail,
|
inpEmail,
|
||||||
contactData.type === "email"
|
contactData.type == "email"
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -124,7 +124,7 @@ const ContactModal: React.FC<ContactDataProps> = ({
|
||||||
))}
|
))}
|
||||||
|
|
||||||
{/* No results message */}
|
{/* No results message */}
|
||||||
{contactData.contacts.length === 0 && (
|
{contactData.contacts.length == 0 && (
|
||||||
<div className="px-3 py-4 text-center text-gray-500 text-sm">
|
<div className="px-3 py-4 text-center text-gray-500 text-sm">
|
||||||
No contacts found
|
No contacts found
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ const DocumentCard: React.FC<DocumentCardProps> = ({ id, name, isCompleted, tran
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const res = await api.delete(`/api/v1/accounts/${accountId}/${transactionTemplateToggle}/${transactionId}/documents/${docId}`)
|
const res = await api.delete(`/api/v1/accounts/${accountId}/${transactionTemplateToggle}/${transactionId}/documents/${docId}`)
|
||||||
if (res.status === 202) {
|
if (res.status == 202) {
|
||||||
dispatch(deleteDocument(docId));
|
dispatch(deleteDocument(docId));
|
||||||
setDocumentDel({ docId: null, isDel: false });
|
setDocumentDel({ docId: null, isDel: false });
|
||||||
}
|
}
|
||||||
|
|
@ -171,7 +171,7 @@ const DocumentCard: React.FC<DocumentCardProps> = ({ id, name, isCompleted, tran
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
documentDel.docId !== null && <div className="fixed inset-0 backdrop-blur-sm flex items-center justify-center z-50">
|
documentDel.docId != null && <div className="fixed inset-0 backdrop-blur-sm flex items-center justify-center z-50">
|
||||||
<div className="bg-white rounded-lg p-6 w-80">
|
<div className="bg-white rounded-lg p-6 w-80">
|
||||||
<h3 className="text-lg font-medium text-gray-800 mb-4">Confirm Delete</h3>
|
<h3 className="text-lg font-medium text-gray-800 mb-4">Confirm Delete</h3>
|
||||||
<p className="text-gray-600 mb-6">Are you sure you want to delete?</p>
|
<p className="text-gray-600 mb-6">Are you sure you want to delete?</p>
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ const MessageCon: React.FC<MessageConIntProps> = ({ transactionTemplateToggle, a
|
||||||
try {
|
try {
|
||||||
const res = await api.get(`/api/v1/accounts/${accountId}/${transactionTemplateToggle}/${transactionId}`);
|
const res = await api.get(`/api/v1/accounts/${accountId}/${transactionTemplateToggle}/${transactionId}`);
|
||||||
|
|
||||||
if (transactionTemplateToggle === TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES) {
|
if (transactionTemplateToggle == TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES) {
|
||||||
setTemplateName(res.data.name)
|
setTemplateName(res.data.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -107,9 +107,15 @@ const ProcessStepOne = () => {
|
||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
const res = await api.get(`/api/v1/accounts/${accountId}/${transactionTemplateToggle}/${transactionId}`);
|
const res = await api.get(`/api/v1/accounts/${accountId}/${transactionTemplateToggle}/${transactionId}`);
|
||||||
|
|
||||||
|
if (res.data.status === "COMPLETED" || res.data.status === "SENT") {
|
||||||
|
navigate("/")
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
setTransactionDetails(res.data)
|
setTransactionDetails(res.data)
|
||||||
|
|
||||||
if (transactionTemplateToggle === TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES) {
|
if (transactionTemplateToggle == TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES) {
|
||||||
setTemplateName(res.data.name)
|
setTemplateName(res.data.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -121,8 +127,8 @@ const ProcessStepOne = () => {
|
||||||
}
|
}
|
||||||
})()
|
})()
|
||||||
|
|
||||||
selectedRecipients.length === 0 && dispatch(fetchRecipients({ accountId, transactionId }));
|
selectedRecipients.length == 0 && dispatch(fetchRecipients({ accountId, transactionId }));
|
||||||
selectedDocuments.length === 0 && dispatch(fetchDocuments({ accountId, transactionId }));
|
selectedDocuments.length == 0 && dispatch(fetchDocuments({ accountId, transactionId }));
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const [emailDtls, setEmailDtls] = useState<EmailDtls>({ subject: "Documents for Signature", message: "" });
|
const [emailDtls, setEmailDtls] = useState<EmailDtls>({ subject: "Documents for Signature", message: "" });
|
||||||
|
|
@ -156,7 +162,7 @@ const ProcessStepOne = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (transactionTemplateToggle !== TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES) {
|
if (transactionTemplateToggle != TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES) {
|
||||||
if (!selectedDocuments.length) {
|
if (!selectedDocuments.length) {
|
||||||
formError.documents = true
|
formError.documents = true
|
||||||
}
|
}
|
||||||
|
|
@ -195,7 +201,7 @@ const ProcessStepOne = () => {
|
||||||
formError.subject = true
|
formError.subject = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SignTypeEnum.selfSign === signType) formError.recipients = false;
|
if (SignTypeEnum.selfSign == signType) formError.recipients = false;
|
||||||
|
|
||||||
if (formError.documents || formError.recipients || formError.subject || formError.invalidRecipientLastName || formError.invalidRecipientEmail || formError.duplicateEmailSameRoutingOrder) {
|
if (formError.documents || formError.recipients || formError.subject || formError.invalidRecipientLastName || formError.invalidRecipientEmail || formError.duplicateEmailSameRoutingOrder) {
|
||||||
setSubmitError({ ...formError, allValid: false })
|
setSubmitError({ ...formError, allValid: false })
|
||||||
|
|
@ -208,7 +214,7 @@ const ProcessStepOne = () => {
|
||||||
|
|
||||||
|
|
||||||
const handleNextClick = async (saveAndClose: boolean = false) => {
|
const handleNextClick = async (saveAndClose: boolean = false) => {
|
||||||
if (!validationCheck() && transactionTemplateToggle !== TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES) {
|
if (!validationCheck() && transactionTemplateToggle != TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES) {
|
||||||
setSubmitError((prev) => ({ ...prev, showError: true }))
|
setSubmitError((prev) => ({ ...prev, showError: true }))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -225,7 +231,7 @@ const ProcessStepOne = () => {
|
||||||
await api.patch(`/api/v1/accounts/${accountId}/${transactionTemplateToggle}/${transactionId}/documents`, { "documents": documentsData });
|
await api.patch(`/api/v1/accounts/${accountId}/${transactionTemplateToggle}/${transactionId}/documents`, { "documents": documentsData });
|
||||||
|
|
||||||
await api.get(`/api/v1/accounts/${accountId}/${transactionTemplateToggle}/${transactionId}/documents?include_pages=true`).then(res => {
|
await api.get(`/api/v1/accounts/${accountId}/${transactionTemplateToggle}/${transactionId}/documents?include_pages=true`).then(res => {
|
||||||
if (res.status === 200) {
|
if (res.status == 200) {
|
||||||
dispatch(setDocuments(res.data));
|
dispatch(setDocuments(res.data));
|
||||||
}
|
}
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
|
|
@ -246,7 +252,7 @@ const ProcessStepOne = () => {
|
||||||
const recipientsData = selectedRecipients.map((recipient, index) => ({
|
const recipientsData = selectedRecipients.map((recipient, index) => ({
|
||||||
id: "id" in recipient ? recipient.id : null,
|
id: "id" in recipient ? recipient.id : null,
|
||||||
routingOrder: "routingOrder" in recipient && recipient.routingOrder ? recipient.routingOrder : 1,
|
routingOrder: "routingOrder" in recipient && recipient.routingOrder ? recipient.routingOrder : 1,
|
||||||
// provideOwnTags: userData.email === recipient.email && (recipient.routingOrder ?? 1) === minRoutingOrder ? true : false,
|
// provideOwnTags: userData.email == recipient.email && (recipient.routingOrder ?? 1) == minRoutingOrder ? true : false,
|
||||||
provideOwnTags: false,
|
provideOwnTags: false,
|
||||||
type: recipient.type,
|
type: recipient.type,
|
||||||
firstName: recipient.firstName,
|
firstName: recipient.firstName,
|
||||||
|
|
@ -272,7 +278,7 @@ const ProcessStepOne = () => {
|
||||||
let recipientsDataTemp = recipientsData;
|
let recipientsDataTemp = recipientsData;
|
||||||
let recipientId = null;
|
let recipientId = null;
|
||||||
|
|
||||||
if (signType === SignTypeEnum.selfSign) {
|
if (signType == SignTypeEnum.selfSign) {
|
||||||
dispatch(removeAllRecipients());
|
dispatch(removeAllRecipients());
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
selectedRecipients.map((recipient) => dispatch(removeRecipientAsync({
|
selectedRecipients.map((recipient) => dispatch(removeRecipientAsync({
|
||||||
|
|
@ -321,15 +327,15 @@ const ProcessStepOne = () => {
|
||||||
dispatch(addRecipientAsync({ recipientsData: recipientsDataTemp, accountId, transactionId }));
|
dispatch(addRecipientAsync({ recipientsData: recipientsDataTemp, accountId, transactionId }));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (transactionTemplateToggle === TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES) {
|
if (transactionTemplateToggle == TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES) {
|
||||||
dispatch(hideLoader());
|
dispatch(hideLoader());
|
||||||
if (!saveAndClose) {
|
if (!saveAndClose) {
|
||||||
navigate(`/process-step-two/${accountId}/template/${transactionId}`)
|
navigate(`/review-and-tag/${accountId}/template/${transactionId}`)
|
||||||
} else {
|
} else {
|
||||||
navigate(`/templates`)
|
navigate(`/templates`)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (signType === SignTypeEnum.selfSign) {
|
if (signType == SignTypeEnum.selfSign) {
|
||||||
dispatch(showLoader("Processing eSignature..."));
|
dispatch(showLoader("Processing eSignature..."));
|
||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
|
|
@ -342,7 +348,7 @@ const ProcessStepOne = () => {
|
||||||
}
|
}
|
||||||
})()
|
})()
|
||||||
} else {
|
} else {
|
||||||
navigate(`/process-step-two/${accountId}/${transactionId}`);
|
navigate(`/review-and-tag/${accountId}/${transactionId}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -371,7 +377,7 @@ const ProcessStepOne = () => {
|
||||||
} else {
|
} else {
|
||||||
navigate('/')
|
navigate('/')
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -419,7 +425,7 @@ const ProcessStepOne = () => {
|
||||||
<div className="hidden md:block absolute left-[55px] w-[1px] h-[62px] bg-gray-300"></div>
|
<div className="hidden md:block absolute left-[55px] w-[1px] h-[62px] bg-gray-300"></div>
|
||||||
|
|
||||||
<p className="text-base font-normal text-gray-700 relative w-full sm:w-auto">
|
<p className="text-base font-normal text-gray-700 relative w-full sm:w-auto">
|
||||||
{transactionTemplateToggle === TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES ? (
|
{transactionTemplateToggle == TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES ? (
|
||||||
<>
|
<>
|
||||||
<input
|
<input
|
||||||
value={templateName}
|
value={templateName}
|
||||||
|
|
@ -448,7 +454,7 @@ const ProcessStepOne = () => {
|
||||||
Advanced Options
|
Advanced Options
|
||||||
</button> */}
|
</button> */}
|
||||||
|
|
||||||
{transactionTemplateToggle === TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES && (
|
{transactionTemplateToggle == TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES && (
|
||||||
<button
|
<button
|
||||||
onClick={() => handleNextClick(true)}
|
onClick={() => handleNextClick(true)}
|
||||||
className="text-sm w-full sm:w-auto px-4 py-2 rounded bg-[var(--primary)] text-white shadow transition duration-300 cursor-pointer"
|
className="text-sm w-full sm:w-auto px-4 py-2 rounded bg-[var(--primary)] text-white shadow transition duration-300 cursor-pointer"
|
||||||
|
|
@ -459,9 +465,9 @@ const ProcessStepOne = () => {
|
||||||
|
|
||||||
<button
|
<button
|
||||||
onClick={() => handleNextClick(false)}
|
onClick={() => handleNextClick(false)}
|
||||||
className={`text-sm w-full sm:w-auto px-4 py-2 rounded bg-[var(--primary)] text-white shadow transition duration-300 cursor-pointer ${transactionTemplateToggle === TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES || submitError.allValid || (signType === SignTypeEnum.selfSign && selectedDocuments.length) ? "opacity-100" : "opacity-60"}`}
|
className={`text-sm w-full sm:w-auto px-4 py-2 rounded bg-[var(--primary)] text-white shadow transition duration-300 cursor-pointer ${transactionTemplateToggle == TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES || submitError.allValid || (signType == SignTypeEnum.selfSign && selectedDocuments.length) ? "opacity-100" : "opacity-60"}`}
|
||||||
>
|
>
|
||||||
{signType === SignTypeEnum.selfSign ? "Sign" : "Next"}
|
{signType == SignTypeEnum.selfSign ? "Sign" : "Next"}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -485,12 +491,12 @@ const ProcessStepOne = () => {
|
||||||
<section className="mt-8">
|
<section className="mt-8">
|
||||||
<p className="border-t border-gray-200"></p>
|
<p className="border-t border-gray-200"></p>
|
||||||
{!isTemplate &&
|
{!isTemplate &&
|
||||||
transactionTemplateToggle !== TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES &&
|
transactionTemplateToggle != TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES &&
|
||||||
<div className="flex justify-between items-center">
|
<div className="flex justify-between items-center">
|
||||||
<h2 className=" text-lg font-medium mb-4 pt-6 text-[var(--processStepOneTextHead)]">Signers</h2>
|
<h2 className=" text-lg font-medium mb-4 pt-6 text-[var(--processStepOneTextHead)]">Signers</h2>
|
||||||
{/* <div className="flex items-center mr-3">
|
{/* <div className="flex items-center mr-3">
|
||||||
<input
|
<input
|
||||||
checked={signType === SignTypeEnum.selfSign}
|
checked={signType == SignTypeEnum.selfSign}
|
||||||
onChange={(e) => handleSelfSignCb(e)}
|
onChange={(e) => handleSelfSignCb(e)}
|
||||||
id="default-checkbox" type="checkbox" value="" className="w-4 h-4 checked:bg-[var(--mainPrimaryBtn)] bg-gray-100 border-gray-300 rounded-sm outline-none"
|
id="default-checkbox" type="checkbox" value="" className="w-4 h-4 checked:bg-[var(--mainPrimaryBtn)] bg-gray-100 border-gray-300 rounded-sm outline-none"
|
||||||
/>
|
/>
|
||||||
|
|
@ -501,7 +507,7 @@ const ProcessStepOne = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
(signType !== SignTypeEnum.selfSign || showSelfSignWarnModal) &&
|
(signType != SignTypeEnum.selfSign || showSelfSignWarnModal) &&
|
||||||
<>
|
<>
|
||||||
<RecipientsCon
|
<RecipientsCon
|
||||||
transactionTemplateToggle={transactionTemplateToggle}
|
transactionTemplateToggle={transactionTemplateToggle}
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ const RecipientAddCard = ({ transactionTemplateToggle, editRecipient, editCase,
|
||||||
const dispatch = useDispatch<AppDispatch>();
|
const dispatch = useDispatch<AppDispatch>();
|
||||||
const formRef = useRef<HTMLFormElement | null>(null);
|
const formRef = useRef<HTMLFormElement | null>(null);
|
||||||
|
|
||||||
const [recipient, setRecipients] = useState<Recipient>(recipientData !== null ? { ...recipientData } : { uuid: null, newOne: false, firstName: "", lastName: "", email: "", hostName: "", hostEmail: "", roleName: "", type: recipientType.SIGNER, allowSenderToEdit: true, allowSenderToDelete: true });
|
const [recipient, setRecipients] = useState<Recipient>(recipientData != null ? { ...recipientData } : { uuid: null, newOne: false, firstName: "", lastName: "", email: "", hostName: "", hostEmail: "", roleName: "", type: recipientType.SIGNER, allowSenderToEdit: true, allowSenderToDelete: true });
|
||||||
|
|
||||||
const [showAdvanceSettings, setShowAdvanceSettings] = useState(false)
|
const [showAdvanceSettings, setShowAdvanceSettings] = useState(false)
|
||||||
|
|
||||||
|
|
@ -71,13 +71,13 @@ const RecipientAddCard = ({ transactionTemplateToggle, editRecipient, editCase,
|
||||||
// Check if the recipient exists in the list (using uuid or id or email)
|
// Check if the recipient exists in the list (using uuid or id or email)
|
||||||
const exists = recipients.some((r) => {
|
const exists = recipients.some((r) => {
|
||||||
return (
|
return (
|
||||||
(r.uuid && r.uuid === editRecipient?.uuid) ||
|
(r.uuid && r.uuid == editRecipient?.uuid) ||
|
||||||
(r.id && r.id === editRecipient?.id) ||
|
(r.id && r.id == editRecipient?.id) ||
|
||||||
(r.email && r.email === editRecipient?.email)
|
(r.email && r.email == editRecipient?.email)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (editCase === "Edit" && editRecipient) {
|
if (editCase == "Edit" && editRecipient) {
|
||||||
|
|
||||||
if (!exists) {
|
if (!exists) {
|
||||||
// Recipient was deleted -> reset
|
// Recipient was deleted -> reset
|
||||||
|
|
@ -136,7 +136,7 @@ const RecipientAddCard = ({ transactionTemplateToggle, editRecipient, editCase,
|
||||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||||
|
|
||||||
// 🔹 Check if we're in TRANSACTIONS mode
|
// 🔹 Check if we're in TRANSACTIONS mode
|
||||||
if (transactionTemplateToggle === TRANSACTION_TEMPLATE_TOGGLE.TRANSACTIONS) {
|
if (transactionTemplateToggle == TRANSACTION_TEMPLATE_TOGGLE.TRANSACTIONS) {
|
||||||
if (lastNameFilled || emailFilled) {
|
if (lastNameFilled || emailFilled) {
|
||||||
if (lastNameFilled && !emailFilled) {
|
if (lastNameFilled && !emailFilled) {
|
||||||
setErrors({ ...newErrors, email: true });
|
setErrors({ ...newErrors, email: true });
|
||||||
|
|
@ -208,15 +208,15 @@ const RecipientAddCard = ({ transactionTemplateToggle, editRecipient, editCase,
|
||||||
|
|
||||||
// Clear hostName and hostEmail if type is SIGNER or CC
|
// Clear hostName and hostEmail if type is SIGNER or CC
|
||||||
if (
|
if (
|
||||||
updatedRecipient.type === recipientType.SIGNER ||
|
updatedRecipient.type == recipientType.SIGNER ||
|
||||||
updatedRecipient.type === recipientType.CC
|
updatedRecipient.type == recipientType.CC
|
||||||
) {
|
) {
|
||||||
updatedRecipient.hostName = "";
|
updatedRecipient.hostName = "";
|
||||||
updatedRecipient.hostEmail = "";
|
updatedRecipient.hostEmail = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (editCase === "Edit") {
|
if (editCase == "Edit") {
|
||||||
dispatch(updateRecipient(updatedRecipient));
|
dispatch(updateRecipient(updatedRecipient));
|
||||||
} else {
|
} else {
|
||||||
updatedRecipient.routingOrder = 1;
|
updatedRecipient.routingOrder = 1;
|
||||||
|
|
@ -298,7 +298,7 @@ const RecipientAddCard = ({ transactionTemplateToggle, editRecipient, editCase,
|
||||||
|
|
||||||
const inputValue = recipient[activeField].trim().toLowerCase();
|
const inputValue = recipient[activeField].trim().toLowerCase();
|
||||||
console.log(inputValue, "Line 297", activeField)
|
console.log(inputValue, "Line 297", activeField)
|
||||||
if (inputValue.length === 0) {
|
if (inputValue.length == 0) {
|
||||||
setFilteredContacts(cachedContacts);
|
setFilteredContacts(cachedContacts);
|
||||||
setContactData({ type: activeField, contacts: cachedContacts });
|
setContactData({ type: activeField, contacts: cachedContacts });
|
||||||
setOpenContactModal(true); // Keep showing modal with all options
|
setOpenContactModal(true); // Keep showing modal with all options
|
||||||
|
|
@ -322,8 +322,8 @@ const RecipientAddCard = ({ transactionTemplateToggle, editRecipient, editCase,
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (lastQuery !== inputValue) {
|
if (lastQuery != inputValue) {
|
||||||
if (lastQuery !== null && inputValue.startsWith(lastQuery)) return
|
if (lastQuery != null && inputValue.startsWith(lastQuery)) return
|
||||||
|
|
||||||
setLastQuery(inputValue);
|
setLastQuery(inputValue);
|
||||||
api
|
api
|
||||||
|
|
@ -373,7 +373,7 @@ const RecipientAddCard = ({ transactionTemplateToggle, editRecipient, editCase,
|
||||||
id="add-recipient-step-one"
|
id="add-recipient-step-one"
|
||||||
className="w-full bg-white border border-gray-300 rounded-lg px-3 sm:px-4 lg:px-6 py-3 sm:py-4 space-y-3 sm:space-y-4 relative"
|
className="w-full bg-white border border-gray-300 rounded-lg px-3 sm:px-4 lg:px-6 py-3 sm:py-4 space-y-3 sm:space-y-4 relative"
|
||||||
>
|
>
|
||||||
{transactionTemplateToggle === TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES && (
|
{transactionTemplateToggle == TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES && (
|
||||||
<div className="space-y-2 sm:space-y-3">
|
<div className="space-y-2 sm:space-y-3">
|
||||||
{/* Role Name and Permissions Section - Responsive Layout */}
|
{/* Role Name and Permissions Section - Responsive Layout */}
|
||||||
<div className="flex flex-col lg:flex-row lg:justify-between lg:items-start gap-3 lg:gap-4">
|
<div className="flex flex-col lg:flex-row lg:justify-between lg:items-start gap-3 lg:gap-4">
|
||||||
|
|
@ -500,10 +500,10 @@ const RecipientAddCard = ({ transactionTemplateToggle, editRecipient, editCase,
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Host Fields for In-Person Signers */}
|
{/* Host Fields for In-Person Signers */}
|
||||||
{recipient.type === recipientType.INPERSONSIGNER && (
|
{recipient.type == recipientType.INPERSONSIGNER && (
|
||||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3 sm:gap-4">
|
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3 sm:gap-4">
|
||||||
<input
|
<input
|
||||||
required={transactionTemplateToggle !== TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES}
|
required={transactionTemplateToggle != TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES}
|
||||||
type="text"
|
type="text"
|
||||||
onFocus={() => setOpenContactModal(true)}
|
onFocus={() => setOpenContactModal(true)}
|
||||||
onBlur={handleContactModalBlur}
|
onBlur={handleContactModalBlur}
|
||||||
|
|
@ -513,7 +513,7 @@ const RecipientAddCard = ({ transactionTemplateToggle, editRecipient, editCase,
|
||||||
onChange={(e) => setRecipients({ ...recipient, hostName: e.target.value })}
|
onChange={(e) => setRecipients({ ...recipient, hostName: e.target.value })}
|
||||||
/>
|
/>
|
||||||
<input
|
<input
|
||||||
required={transactionTemplateToggle !== TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES}
|
required={transactionTemplateToggle != TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES}
|
||||||
type="email"
|
type="email"
|
||||||
onFocus={() => setOpenContactModal(true)}
|
onFocus={() => setOpenContactModal(true)}
|
||||||
onBlur={handleContactModalBlur}
|
onBlur={handleContactModalBlur}
|
||||||
|
|
@ -556,7 +556,7 @@ const RecipientAddCard = ({ transactionTemplateToggle, editRecipient, editCase,
|
||||||
type="radio"
|
type="radio"
|
||||||
name="recipient-type"
|
name="recipient-type"
|
||||||
value={option.value}
|
value={option.value}
|
||||||
checked={recipient.type === option.value}
|
checked={recipient.type == option.value}
|
||||||
onChange={(e) => setRecipients({ ...recipient, type: e.target.value })}
|
onChange={(e) => setRecipients({ ...recipient, type: e.target.value })}
|
||||||
className="accent-[var(--primary)] cursor-pointer w-3 h-3 sm:w-4 sm:h-4"
|
className="accent-[var(--primary)] cursor-pointer w-3 h-3 sm:w-4 sm:h-4"
|
||||||
/>
|
/>
|
||||||
|
|
@ -573,7 +573,7 @@ const RecipientAddCard = ({ transactionTemplateToggle, editRecipient, editCase,
|
||||||
>
|
>
|
||||||
{/* <FaPlus size={12} className="sm:w-3.5 sm:h-3.5" /> */}
|
{/* <FaPlus size={12} className="sm:w-3.5 sm:h-3.5" /> */}
|
||||||
<span className="whitespace-nowrap">
|
<span className="whitespace-nowrap">
|
||||||
{editCase === "Edit" ? "Edit" : "Add"}
|
{editCase == "Edit" ? "Edit" : "Add"}
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -83,13 +83,13 @@ const RecipientCards = ({
|
||||||
};
|
};
|
||||||
|
|
||||||
const isEditable = (recipient: any) => {
|
const isEditable = (recipient: any) => {
|
||||||
return transactionTemplateToggle === TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES
|
return transactionTemplateToggle == TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES
|
||||||
? true
|
? true
|
||||||
: recipient.newOne || recipient.allowSenderToEdit;
|
: recipient.newOne || recipient.allowSenderToEdit;
|
||||||
};
|
};
|
||||||
|
|
||||||
const validateInPersonSignerFields = (recipient: any, updatedFields: any) => {
|
const validateInPersonSignerFields = (recipient: any, updatedFields: any) => {
|
||||||
if (recipient.type !== recipientType.INPERSONSIGNER) return true;
|
if (recipient.type != recipientType.INPERSONSIGNER) return true;
|
||||||
const hostName = updatedFields.hostName ?? getCurrentValue(recipient, "hostName");
|
const hostName = updatedFields.hostName ?? getCurrentValue(recipient, "hostName");
|
||||||
const hostEmail = updatedFields.hostEmail ?? getCurrentValue(recipient, "hostEmail");
|
const hostEmail = updatedFields.hostEmail ?? getCurrentValue(recipient, "hostEmail");
|
||||||
const identifier = getRecipientIdentifier(recipient);
|
const identifier = getRecipientIdentifier(recipient);
|
||||||
|
|
@ -106,7 +106,7 @@ const RecipientCards = ({
|
||||||
const identifier = getRecipientIdentifier(recipient);
|
const identifier = getRecipientIdentifier(recipient);
|
||||||
const updatedRecipient = { ...recipient, [fieldName]: value, uuid: identifier };
|
const updatedRecipient = { ...recipient, [fieldName]: value, uuid: identifier };
|
||||||
|
|
||||||
if (recipient.type === recipientType.INPERSONSIGNER && (fieldName === "hostName" || fieldName === "hostEmail")) {
|
if (recipient.type == recipientType.INPERSONSIGNER && (fieldName == "hostName" || fieldName == "hostEmail")) {
|
||||||
if (!validateInPersonSignerFields(recipient, { [fieldName]: value })) {
|
if (!validateInPersonSignerFields(recipient, { [fieldName]: value })) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -132,12 +132,12 @@ const RecipientCards = ({
|
||||||
const getCurrentValue = (recipient: any, fieldName: string) => {
|
const getCurrentValue = (recipient: any, fieldName: string) => {
|
||||||
const identifier = getRecipientIdentifier(recipient);
|
const identifier = getRecipientIdentifier(recipient);
|
||||||
const localValue = localChanges[`${identifier}_${fieldName}`];
|
const localValue = localChanges[`${identifier}_${fieldName}`];
|
||||||
return localValue !== undefined ? localValue : recipient[fieldName];
|
return localValue != undefined ? localValue : recipient[fieldName];
|
||||||
};
|
};
|
||||||
|
|
||||||
const hasValue = (recipient: any, fieldName: string) => {
|
const hasValue = (recipient: any, fieldName: string) => {
|
||||||
const currentValue = getCurrentValue(recipient, fieldName);
|
const currentValue = getCurrentValue(recipient, fieldName);
|
||||||
return currentValue && currentValue.toString().trim() !== "";
|
return currentValue && currentValue.toString().trim() != "";
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderEditableField = (
|
const renderEditableField = (
|
||||||
|
|
@ -163,7 +163,7 @@ const RecipientCards = ({
|
||||||
// onChange={(e) => handleFieldChange(recipient, fieldName, e.target.value)}
|
// onChange={(e) => handleFieldChange(recipient, fieldName, e.target.value)}
|
||||||
onInput={(e) => handleFieldChange(recipient, fieldName, (e.target as HTMLInputElement).value)}
|
onInput={(e) => handleFieldChange(recipient, fieldName, (e.target as HTMLInputElement).value)}
|
||||||
onKeyPress={(e) => {
|
onKeyPress={(e) => {
|
||||||
if (e.key === "Enter") {
|
if (e.key == "Enter") {
|
||||||
e.currentTarget.blur();
|
e.currentTarget.blur();
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
|
@ -201,13 +201,13 @@ const RecipientCards = ({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (recipients.length === 2) {
|
if (recipients.length == 2) {
|
||||||
const leftRecipient = recipients.filter((obj) => {
|
const leftRecipient = recipients.filter((obj) => {
|
||||||
if ("id" in obj && "id" in recipient) {
|
if ("id" in obj && "id" in recipient) {
|
||||||
return obj.id !== recipient.id;
|
return obj.id != recipient.id;
|
||||||
}
|
}
|
||||||
if ("email" in obj && "email" in recipient) {
|
if ("email" in obj && "email" in recipient) {
|
||||||
return obj.email !== recipient.email;
|
return obj.email != recipient.email;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
@ -221,11 +221,11 @@ const RecipientCards = ({
|
||||||
const identifier = getRecipientIdentifier(recipient);
|
const identifier = getRecipientIdentifier(recipient);
|
||||||
const updatedRecipient = { ...recipient, type, uuid: identifier };
|
const updatedRecipient = { ...recipient, type, uuid: identifier };
|
||||||
|
|
||||||
if (type === recipientType.SIGNER || type === recipientType.CC) {
|
if (type == recipientType.SIGNER || type == recipientType.CC) {
|
||||||
updatedRecipient.hostName = "";
|
updatedRecipient.hostName = "";
|
||||||
updatedRecipient.hostEmail = "";
|
updatedRecipient.hostEmail = "";
|
||||||
setErrors((prev) => ({ ...prev, [identifier]: { hostName: false, hostEmail: false } }));
|
setErrors((prev) => ({ ...prev, [identifier]: { hostName: false, hostEmail: false } }));
|
||||||
} else if (type === recipientType.INPERSONSIGNER) {
|
} else if (type == recipientType.INPERSONSIGNER) {
|
||||||
if (!validateInPersonSignerFields(recipient, updatedRecipient)) {
|
if (!validateInPersonSignerFields(recipient, updatedRecipient)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -237,19 +237,19 @@ const RecipientCards = ({
|
||||||
|
|
||||||
const handleDragEnd = (event: DragEndEvent) => {
|
const handleDragEnd = (event: DragEndEvent) => {
|
||||||
const { active, over } = event;
|
const { active, over } = event;
|
||||||
if (!over || active.id === over.id) return;
|
if (!over || active.id == over.id) return;
|
||||||
|
|
||||||
console.log(over, "Over")
|
console.log(over, "Over")
|
||||||
console.log(active, "Active")
|
console.log(active, "Active")
|
||||||
|
|
||||||
const activeIndex = recipients.findIndex((r) => (r.id || r.uuid) === active.id);
|
const activeIndex = recipients.findIndex((r) => (r.id || r.uuid) == active.id);
|
||||||
const overIndex = recipients.findIndex((r) => (r.id || r.uuid) === over.id);
|
const overIndex = recipients.findIndex((r) => (r.id || r.uuid) == over.id);
|
||||||
|
|
||||||
const activeRec = recipients[activeIndex]
|
const activeRec = recipients[activeIndex]
|
||||||
const overRec = recipients[overIndex]
|
const overRec = recipients[overIndex]
|
||||||
|
|
||||||
const activeRecRo = Number(activeRec.routingOrder) === 0 || !activeRec.routingOrder ? 1 : activeRec.routingOrder
|
const activeRecRo = Number(activeRec.routingOrder) == 0 || !activeRec.routingOrder ? 1 : activeRec.routingOrder
|
||||||
const overRecRo = Number(overRec.routingOrder) === 0 || !overRec.routingOrder ? 1 : overRec.routingOrder
|
const overRecRo = Number(overRec.routingOrder) == 0 || !overRec.routingOrder ? 1 : overRec.routingOrder
|
||||||
|
|
||||||
let newActiveRecRo = 1
|
let newActiveRecRo = 1
|
||||||
let newOverRecRo = 1
|
let newOverRecRo = 1
|
||||||
|
|
@ -318,24 +318,24 @@ const RecipientCards = ({
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (activeRecRo === activeRecRo && activeIndex < overIndex) {
|
if (activeRecRo == activeRecRo && activeIndex < overIndex) {
|
||||||
newActiveRecRo = activeRecRo > 1 ? activeRecRo + 1 : 2
|
newActiveRecRo = activeRecRo > 1 ? activeRecRo + 1 : 2
|
||||||
newOverRecRo = overRecRo > 1 ? overRecRo : 1
|
newOverRecRo = overRecRo > 1 ? overRecRo : 1
|
||||||
}
|
}
|
||||||
if (activeRecRo === overRecRo && activeIndex > overIndex) {
|
if (activeRecRo == overRecRo && activeIndex > overIndex) {
|
||||||
newActiveRecRo = activeRecRo > 1 ? activeRecRo : 1
|
newActiveRecRo = activeRecRo > 1 ? activeRecRo : 1
|
||||||
newOverRecRo = overRecRo > 1 ? overRecRo + 1 : 2
|
newOverRecRo = overRecRo > 1 ? overRecRo + 1 : 2
|
||||||
}
|
}
|
||||||
|
|
||||||
// let reordered = recipients.map((r, idx) => {
|
// let reordered = recipients.map((r, idx) => {
|
||||||
// if (idx === activeIndex) {
|
// if (idx == activeIndex) {
|
||||||
// return (
|
// return (
|
||||||
// {
|
// {
|
||||||
// ...r, routingOrder: newActiveRecRo
|
// ...r, routingOrder: newActiveRecRo
|
||||||
// }
|
// }
|
||||||
// )
|
// )
|
||||||
// }
|
// }
|
||||||
// if (idx === overRecRo) {
|
// if (idx == overRecRo) {
|
||||||
// return (
|
// return (
|
||||||
// {
|
// {
|
||||||
// ...r, routingOrder: newOverRecRo
|
// ...r, routingOrder: newOverRecRo
|
||||||
|
|
@ -389,7 +389,7 @@ const RecipientCards = ({
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
key={recipient.email + idx}
|
key={recipient.email + idx}
|
||||||
className={`relative flex flex-col lg:flex-row lg:items-center justify-between px-2 sm:px-3 lg:px-2 py-3 transition-colors gap-3 lg:gap-0 ${(recipient.uuid || recipient.id) === editRecipientCurrentEmail
|
className={`relative flex flex-col lg:flex-row lg:items-center justify-between px-2 sm:px-3 lg:px-2 py-3 transition-colors gap-3 lg:gap-0 ${(recipient.uuid || recipient.id) == editRecipientCurrentEmail
|
||||||
? "bg-neutral-100 opacity-40"
|
? "bg-neutral-100 opacity-40"
|
||||||
: ""
|
: ""
|
||||||
}`}
|
}`}
|
||||||
|
|
@ -401,7 +401,7 @@ const RecipientCards = ({
|
||||||
<div className="relative flex-shrink-0">
|
<div className="relative flex-shrink-0">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
value={recipient.routingOrder === 0 ? "" : recipient.routingOrder}
|
value={recipient.routingOrder == 0 ? "" : recipient.routingOrder}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
const value = e.target.value;
|
const value = e.target.value;
|
||||||
if (/^\d*$/.test(value)) {
|
if (/^\d*$/.test(value)) {
|
||||||
|
|
@ -410,13 +410,13 @@ const RecipientCards = ({
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onKeyDown={(e) => {
|
onKeyDown={(e) => {
|
||||||
if (!/[0-9]/.test(e.key) && e.key !== "Backspace" && e.key !== "Tab") {
|
if (!/[0-9]/.test(e.key) && e.key != "Backspace" && e.key != "Tab") {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
className="w-8 sm: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"
|
className="w-8 sm: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"
|
||||||
/>
|
/>
|
||||||
{idx === 0 && recipients.length > 1 && <p className="group">
|
{idx == 0 && recipients.length > 1 && <p className="group">
|
||||||
<BiSolidHelpCircle className="absolute top-[-12px] right-[-10px] text-gray-400 cursor-pointer" />
|
<BiSolidHelpCircle className="absolute top-[-12px] right-[-10px] text-gray-400 cursor-pointer" />
|
||||||
|
|
||||||
{/* Tooltip */}
|
{/* Tooltip */}
|
||||||
|
|
@ -452,7 +452,7 @@ const RecipientCards = ({
|
||||||
{/* Role Name and Permissions Row */}
|
{/* Role Name and Permissions Row */}
|
||||||
<div className="flex flex-col lg:flex-row lg:items-center gap-2 mb-2">
|
<div className="flex flex-col lg:flex-row lg:items-center gap-2 mb-2">
|
||||||
{<div className="flex lg:w-1/2">
|
{<div className="flex lg:w-1/2">
|
||||||
{transactionTemplateToggle === TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES ?
|
{transactionTemplateToggle == TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES ?
|
||||||
<div className="font-semibold text-gray-800 text-xs">
|
<div className="font-semibold text-gray-800 text-xs">
|
||||||
{renderEditableField(recipient, "roleName", "Role name")}
|
{renderEditableField(recipient, "roleName", "Role name")}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -465,7 +465,7 @@ const RecipientCards = ({
|
||||||
|
|
||||||
{/* Permissions - Mobile: Below role, Desktop: Right side */}
|
{/* Permissions - Mobile: Below role, Desktop: Right side */}
|
||||||
<div className="lg:w-1/2 lg:flex lg:items-center lg:justify-end">
|
<div className="lg:w-1/2 lg:flex lg:items-center lg:justify-end">
|
||||||
{transactionTemplateToggle === TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES && (
|
{transactionTemplateToggle == TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES && (
|
||||||
<div className="flex ps-2.5 sm:flex-row items-start sm:items-center gap-2 sm:gap-4">
|
<div className="flex ps-2.5 sm:flex-row items-start sm:items-center gap-2 sm:gap-4">
|
||||||
<label className="flex items-center gap-1 text-xs sm:text-sm text-gray-700">
|
<label className="flex items-center gap-1 text-xs sm:text-sm text-gray-700">
|
||||||
<input
|
<input
|
||||||
|
|
@ -532,7 +532,7 @@ const RecipientCards = ({
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Host Fields (for In-Person Signers) */}
|
{/* Host Fields (for In-Person Signers) */}
|
||||||
{recipient.type === recipientType.INPERSONSIGNER && (
|
{recipient.type == recipientType.INPERSONSIGNER && (
|
||||||
<div className="mb-2">
|
<div className="mb-2">
|
||||||
<div className="flex flex-col sm:flex-row gap-1 sm:gap-2">
|
<div className="flex flex-col sm:flex-row gap-1 sm:gap-2">
|
||||||
<div className="w-full sm:w-1/2">
|
<div className="w-full sm:w-1/2">
|
||||||
|
|
@ -556,7 +556,7 @@ const RecipientCards = ({
|
||||||
type="radio"
|
type="radio"
|
||||||
name={`recipient-type-${getRecipientIdentifier(recipient)}`}
|
name={`recipient-type-${getRecipientIdentifier(recipient)}`}
|
||||||
value={recipientType.SIGNER}
|
value={recipientType.SIGNER}
|
||||||
checked={recipient.type === recipientType.SIGNER}
|
checked={recipient.type == recipientType.SIGNER}
|
||||||
onChange={() => handleTypeChange(recipient, recipientType.SIGNER)}
|
onChange={() => handleTypeChange(recipient, recipientType.SIGNER)}
|
||||||
onBlur={() => setEditingField(null)}
|
onBlur={() => setEditingField(null)}
|
||||||
className="accent-[var(--primary)] w-3 h-3"
|
className="accent-[var(--primary)] w-3 h-3"
|
||||||
|
|
@ -569,7 +569,7 @@ const RecipientCards = ({
|
||||||
type="radio"
|
type="radio"
|
||||||
name={`recipient-type-${getRecipientIdentifier(recipient)}`}
|
name={`recipient-type-${getRecipientIdentifier(recipient)}`}
|
||||||
value={recipientType.INPERSONSIGNER}
|
value={recipientType.INPERSONSIGNER}
|
||||||
checked={recipient.type === recipientType.INPERSONSIGNER}
|
checked={recipient.type == recipientType.INPERSONSIGNER}
|
||||||
onChange={() => handleTypeChange(recipient, recipientType.INPERSONSIGNER)}
|
onChange={() => handleTypeChange(recipient, recipientType.INPERSONSIGNER)}
|
||||||
onBlur={() => setEditingField(null)}
|
onBlur={() => setEditingField(null)}
|
||||||
className="accent-[var(--primary)] w-3 h-3"
|
className="accent-[var(--primary)] w-3 h-3"
|
||||||
|
|
@ -582,7 +582,7 @@ const RecipientCards = ({
|
||||||
type="radio"
|
type="radio"
|
||||||
name={`recipient-type-${getRecipientIdentifier(recipient)}`}
|
name={`recipient-type-${getRecipientIdentifier(recipient)}`}
|
||||||
value={recipientType.CC}
|
value={recipientType.CC}
|
||||||
checked={recipient.type === recipientType.CC}
|
checked={recipient.type == recipientType.CC}
|
||||||
onChange={() => handleTypeChange(recipient, recipientType.CC)}
|
onChange={() => handleTypeChange(recipient, recipientType.CC)}
|
||||||
onBlur={() => setEditingField(null)}
|
onBlur={() => setEditingField(null)}
|
||||||
className="accent-[var(--primary)] w-3 h-3"
|
className="accent-[var(--primary)] w-3 h-3"
|
||||||
|
|
@ -595,7 +595,7 @@ const RecipientCards = ({
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Action Buttons */}
|
{/* Action Buttons */}
|
||||||
{signType !== "self-sign" && (
|
{signType != "self-sign" && (
|
||||||
<div className="lg:ml-2 absolute top-[-8px] right-[-5px] px-1.5 py-1.5">
|
<div className="lg:ml-2 absolute top-[-8px] right-[-5px] px-1.5 py-1.5">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
|
@ -603,7 +603,7 @@ const RecipientCards = ({
|
||||||
aria-label={`Remove recipient ${recipient.firstName}`}
|
aria-label={`Remove recipient ${recipient.firstName}`}
|
||||||
onClick={() => handleRemoveRecipient(recipient)}
|
onClick={() => handleRemoveRecipient(recipient)}
|
||||||
disabled={
|
disabled={
|
||||||
transactionTemplateToggle === TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES
|
transactionTemplateToggle == TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES
|
||||||
? false
|
? false
|
||||||
: !recipient.newOne && !recipient.allowSenderToDelete
|
: !recipient.newOne && !recipient.allowSenderToDelete
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ const RecipientsCon: React.FC<RecipientsConIntProps> = ({ transactionTemplateTog
|
||||||
const recipientsData = selectedRecipients.map((recipient, index) => ({
|
const recipientsData = selectedRecipients.map((recipient, index) => ({
|
||||||
id: "id" in recipient ? recipient.id : null,
|
id: "id" in recipient ? recipient.id : null,
|
||||||
routingOrder: "routingOrder" in recipient && recipient.routingOrder ? recipient.routingOrder : 1,
|
routingOrder: "routingOrder" in recipient && recipient.routingOrder ? recipient.routingOrder : 1,
|
||||||
provideOwnTags: userData.email === recipient.email && (recipient.routingOrder ?? 1) === minRoutingOrder ? true : false,
|
provideOwnTags: userData.email == recipient.email && (recipient.routingOrder ?? 1) == minRoutingOrder ? true : false,
|
||||||
type: recipient.type,
|
type: recipient.type,
|
||||||
firstName: recipient.firstName,
|
firstName: recipient.firstName,
|
||||||
lastName: recipient.lastName,
|
lastName: recipient.lastName,
|
||||||
|
|
@ -69,7 +69,7 @@ const RecipientsCon: React.FC<RecipientsConIntProps> = ({ transactionTemplateTog
|
||||||
let recipientsDataTemp = recipientsData;
|
let recipientsDataTemp = recipientsData;
|
||||||
let recipientId = null;
|
let recipientId = null;
|
||||||
|
|
||||||
if (signType === SignTypeEnum.selfSign) {
|
if (signType == SignTypeEnum.selfSign) {
|
||||||
dispatch(removeAllRecipients());
|
dispatch(removeAllRecipients());
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
selectedRecipients.map((recipient) => dispatch(removeRecipientAsync({
|
selectedRecipients.map((recipient) => dispatch(removeRecipientAsync({
|
||||||
|
|
@ -123,7 +123,7 @@ const RecipientsCon: React.FC<RecipientsConIntProps> = ({ transactionTemplateTog
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{(signType !== SignTypeEnum.selfSign || showSelfSignWarnModal) && <>
|
{(signType != SignTypeEnum.selfSign || showSelfSignWarnModal) && <>
|
||||||
<div className="flex flex-col gap-4 align-start">
|
<div className="flex flex-col gap-4 align-start">
|
||||||
{isModal && <div className="flex justify-between items-center">
|
{isModal && <div className="flex justify-between items-center">
|
||||||
<p className="font-medium">Recipients</p>
|
<p className="font-medium">Recipients</p>
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ const SelectedDocuments: React.FC<SelectedDocumentsIntProps> = ({ transactionTem
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isModalOpen) {
|
if (isModalOpen) {
|
||||||
if (errorDocuments[DocumentErrorEnum.FILE_SIZE_EXCEEDED].length === 0 && errorDocuments[DocumentErrorEnum.UNSUPPORTED_DOC_TYPE].length === 0) setModalOpen(false);
|
if (errorDocuments[DocumentErrorEnum.FILE_SIZE_EXCEEDED].length == 0 && errorDocuments[DocumentErrorEnum.UNSUPPORTED_DOC_TYPE].length == 0) setModalOpen(false);
|
||||||
}
|
}
|
||||||
}, [documents])
|
}, [documents])
|
||||||
|
|
||||||
|
|
@ -84,7 +84,7 @@ const SelectedDocuments: React.FC<SelectedDocumentsIntProps> = ({ transactionTem
|
||||||
|
|
||||||
// Get proper Tailwind class names for upload card span
|
// Get proper Tailwind class names for upload card span
|
||||||
const getUploadCardSpanClass = () => {
|
const getUploadCardSpanClass = () => {
|
||||||
if (docCount === 0) {
|
if (docCount == 0) {
|
||||||
// Upload card takes all columns only when no docs
|
// Upload card takes all columns only when no docs
|
||||||
return "col-span-1 sm:col-span-2 md:col-span-3 lg:col-span-4 xl:col-span-5";
|
return "col-span-1 sm:col-span-2 md:col-span-3 lg:col-span-4 xl:col-span-5";
|
||||||
}
|
}
|
||||||
|
|
@ -107,7 +107,7 @@ const SelectedDocuments: React.FC<SelectedDocumentsIntProps> = ({ transactionTem
|
||||||
|
|
||||||
// Calculate how many documents should be in the first row
|
// Calculate how many documents should be in the first row
|
||||||
// const getFirstRowDocCount = () => {
|
// const getFirstRowDocCount = () => {
|
||||||
// if (docCount === 0) return 0;
|
// if (docCount == 0) return 0;
|
||||||
// if (docCount <= 4) return docCount; // All docs fit in first row
|
// if (docCount <= 4) return docCount; // All docs fit in first row
|
||||||
// return 4; // Max 4 docs in first row when upload card takes 1 column
|
// return 4; // Max 4 docs in first row when upload card takes 1 column
|
||||||
// };
|
// };
|
||||||
|
|
@ -170,7 +170,7 @@ const SelectedDocuments: React.FC<SelectedDocumentsIntProps> = ({ transactionTem
|
||||||
name={doc.name}
|
name={doc.name}
|
||||||
isCompleted={
|
isCompleted={
|
||||||
"isCompleted" in doc ||
|
"isCompleted" in doc ||
|
||||||
("status" in doc && doc.status === "UPLOADED")
|
("status" in doc && doc.status == "UPLOADED")
|
||||||
? true
|
? true
|
||||||
: false
|
: false
|
||||||
}
|
}
|
||||||
|
|
@ -204,7 +204,7 @@ const SelectedDocuments: React.FC<SelectedDocumentsIntProps> = ({ transactionTem
|
||||||
{tabs.map((tab) => (
|
{tabs.map((tab) => (
|
||||||
<button
|
<button
|
||||||
key={tab.name}
|
key={tab.name}
|
||||||
className={`flex items-center gap-2 p-3 rounded-md text-sm font-medium transition whitespace-nowrap ${activeTab === tab.name
|
className={`flex items-center gap-2 p-3 rounded-md text-sm font-medium transition whitespace-nowrap ${activeTab == tab.name
|
||||||
? "bg-white shadow text-[var(--primary)]"
|
? "bg-white shadow text-[var(--primary)]"
|
||||||
: "hover:bg-gray-200 text-gray-600"
|
: "hover:bg-gray-200 text-gray-600"
|
||||||
}`}
|
}`}
|
||||||
|
|
@ -217,7 +217,7 @@ const SelectedDocuments: React.FC<SelectedDocumentsIntProps> = ({ transactionTem
|
||||||
|
|
||||||
{/* Modal Content */}
|
{/* Modal Content */}
|
||||||
<div className="w-full sm:w-3/4 p-4 sm:p-6 overflow-y-auto">
|
<div className="w-full sm:w-3/4 p-4 sm:p-6 overflow-y-auto">
|
||||||
{activeTab === "Upload" && (
|
{activeTab == "Upload" && (
|
||||||
<div
|
<div
|
||||||
onClick={() => fileInputRef.current?.click()}
|
onClick={() => fileInputRef.current?.click()}
|
||||||
onDragOver={(e) => e.preventDefault()}
|
onDragOver={(e) => e.preventDefault()}
|
||||||
|
|
@ -258,7 +258,7 @@ const SelectedDocuments: React.FC<SelectedDocumentsIntProps> = ({ transactionTem
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
)}
|
)}
|
||||||
{activeTab !== "Upload" && (
|
{activeTab != "Upload" && (
|
||||||
<div className="flex items-center justify-center h-full text-gray-400 text-sm">
|
<div className="flex items-center justify-center h-full text-gray-400 text-sm">
|
||||||
<p>{activeTab} integration coming soon...</p>
|
<p>{activeTab} integration coming soon...</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ const SortableRecipient = ({ recipient, idx, editRecipientCurrentEmail, children
|
||||||
<div
|
<div
|
||||||
ref={setNodeRef}
|
ref={setNodeRef}
|
||||||
style={style}
|
style={style}
|
||||||
className={`relative flex flex-col lg:flex-row lg:items-center justify-between px-2 sm:px-3 lg:px-2 py-3 transition-colors gap-3 lg:gap-0 ${(recipient.uuid || recipient.id) === editRecipientCurrentEmail ? "bg-neutral-100 opacity-40" : ""}
|
className={`relative flex flex-col lg:flex-row lg:items-center justify-between px-2 sm:px-3 lg:px-2 py-3 transition-colors gap-3 lg:gap-0 ${(recipient.uuid || recipient.id) == editRecipientCurrentEmail ? "bg-neutral-100 opacity-40" : ""}
|
||||||
${isDragging ? "bg-blue-50 shadow-lg" : ""}
|
${isDragging ? "bg-blue-50 shadow-lg" : ""}
|
||||||
`}
|
`}
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ const DocumentContainer = forwardRef<DocumentContainerRef, DocumentContainerProp
|
||||||
}
|
}
|
||||||
|
|
||||||
// If is preview is enable
|
// If is preview is enable
|
||||||
if (isPreview && aId !== null && tId !== null) {
|
if (isPreview && aId != null && tId != null) {
|
||||||
accountId = aId;
|
accountId = aId;
|
||||||
transactionId = tId;
|
transactionId = tId;
|
||||||
}
|
}
|
||||||
|
|
@ -107,8 +107,8 @@ const DocumentContainer = forwardRef<DocumentContainerRef, DocumentContainerProp
|
||||||
const [hotKeysObj, setHotKeysObj] = useState<HotKeysObj>(hotKeysObjInitial);
|
const [hotKeysObj, setHotKeysObj] = useState<HotKeysObj>(hotKeysObjInitial);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
selectedRecipients.length === 0 && dispatch(fetchRecipients({ accountId, transactionId }));
|
selectedRecipients.length == 0 && dispatch(fetchRecipients({ accountId, transactionId }));
|
||||||
selectedDocuments.length === 0 && dispatch(fetchDocuments({ accountId, transactionId }));
|
selectedDocuments.length == 0 && dispatch(fetchDocuments({ accountId, transactionId }));
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -148,7 +148,7 @@ const DocumentContainer = forwardRef<DocumentContainerRef, DocumentContainerProp
|
||||||
|
|
||||||
// FETCHING TAG - START
|
// FETCHING TAG - START
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedRecipients.length === 0) return;
|
if (selectedRecipients.length == 0) return;
|
||||||
fetchTags();
|
fetchTags();
|
||||||
}, [selectedRecipients, isPreview]);
|
}, [selectedRecipients, isPreview]);
|
||||||
// FETCHING TAG - END
|
// FETCHING TAG - END
|
||||||
|
|
@ -235,7 +235,7 @@ const DocumentContainer = forwardRef<DocumentContainerRef, DocumentContainerProp
|
||||||
|
|
||||||
const handleTransactionProcess = async (save: boolean = false) => {
|
const handleTransactionProcess = async (save: boolean = false) => {
|
||||||
dispatch(showLoader("Saving Tags ..."))
|
dispatch(showLoader("Saving Tags ..."))
|
||||||
if (Object.keys(droppedItems).length === 0) return;
|
if (Object.keys(droppedItems).length == 0) return;
|
||||||
// if (!save) return;
|
// if (!save) return;
|
||||||
|
|
||||||
let updatedTags: any = [];
|
let updatedTags: any = [];
|
||||||
|
|
@ -253,8 +253,8 @@ const DocumentContainer = forwardRef<DocumentContainerRef, DocumentContainerProp
|
||||||
dispatch(showLoader("Sending ..."))
|
dispatch(showLoader("Sending ..."))
|
||||||
const res = await api.put(`/api/v1/accounts/${accountId}/${transactionTemplateToggle}/${transactionId}`, { status: "SENT" })
|
const res = await api.put(`/api/v1/accounts/${accountId}/${transactionTemplateToggle}/${transactionId}`, { status: "SENT" })
|
||||||
if (res.status >= 200 && res.status < 300) {
|
if (res.status >= 200 && res.status < 300) {
|
||||||
// navigate(`/transaction-sent/${accountId}/${transactionId}`, { replace: true })
|
navigate(`/transaction-sent/${accountId}/${transactionId}`, { replace: true })
|
||||||
window.location.href = `${import.meta.env.VITE_BASE_URI}/transaction-sent/${accountId}/${transactionId}`
|
// window.location.href = `${import.meta.env.VITE_BASE_URI}/transaction-sent/${accountId}/${transactionId}`
|
||||||
}
|
}
|
||||||
dispatch(hideLoader())
|
dispatch(hideLoader())
|
||||||
}
|
}
|
||||||
|
|
@ -295,7 +295,7 @@ const DocumentContainer = forwardRef<DocumentContainerRef, DocumentContainerProp
|
||||||
const field = { ...dragElemData }
|
const field = { ...dragElemData }
|
||||||
if (!field.label) return;
|
if (!field.label) return;
|
||||||
|
|
||||||
// const field = fields.find((item) => item.label === dragElemData.label); // Find corresponding field
|
// const field = fields.find((item) => item.label == dragElemData.label); // Find corresponding field
|
||||||
// if (!field) return; // If not found, exit
|
// if (!field) return; // If not found, exit
|
||||||
|
|
||||||
const dropZone = event.currentTarget.getBoundingClientRect();
|
const dropZone = event.currentTarget.getBoundingClientRect();
|
||||||
|
|
@ -334,7 +334,7 @@ const DocumentContainer = forwardRef<DocumentContainerRef, DocumentContainerProp
|
||||||
width: dragElemData.width,
|
width: dragElemData.width,
|
||||||
height: dragElemData.height,
|
height: dragElemData.height,
|
||||||
},
|
},
|
||||||
styles: dragElemData.label === "text" ? {
|
styles: dragElemData.label == "text" ? {
|
||||||
"font": "Great Vibes",
|
"font": "Great Vibes",
|
||||||
"italic": false,
|
"italic": false,
|
||||||
"bold": false,
|
"bold": false,
|
||||||
|
|
@ -346,7 +346,7 @@ const DocumentContainer = forwardRef<DocumentContainerRef, DocumentContainerProp
|
||||||
pageIndex: pageIndex,
|
pageIndex: pageIndex,
|
||||||
recipientId: dragElemData.recipientId,
|
recipientId: dragElemData.recipientId,
|
||||||
recipientIndx: dragElemData.recipientIndx,
|
recipientIndx: dragElemData.recipientIndx,
|
||||||
required: (dragElemData.label !== TagsTypes.SIGNATURE && dragElemData.label !== TagsTypes.INITIALS) ? false : true,
|
required: (dragElemData.label != TagsTypes.SIGNATURE && dragElemData.label != TagsTypes.INITIALS) ? false : true,
|
||||||
update: true,
|
update: true,
|
||||||
isDeleted: false
|
isDeleted: false
|
||||||
}
|
}
|
||||||
|
|
@ -357,13 +357,13 @@ const DocumentContainer = forwardRef<DocumentContainerRef, DocumentContainerProp
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prepData.type === "temporal") {
|
if (prepData.type == "temporal") {
|
||||||
prepData.currentTimeStamp = true;
|
prepData.currentTimeStamp = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (prepData.type.toLowerCase() === "number") {
|
if (prepData.type.toLowerCase() == "number") {
|
||||||
prepData.decimalPlace = 0;
|
prepData.decimalPlace = 0;
|
||||||
prepData.isCurrency = false;
|
prepData.isCurrency = false;
|
||||||
}
|
}
|
||||||
|
|
@ -442,10 +442,10 @@ const DocumentContainer = forwardRef<DocumentContainerRef, DocumentContainerProp
|
||||||
const tagIndex = tag.getAttribute("data-tag-id") ?? "";
|
const tagIndex = tag.getAttribute("data-tag-id") ?? "";
|
||||||
const key = tag.getAttribute("data-drop-key") ?? "";
|
const key = tag.getAttribute("data-drop-key") ?? "";
|
||||||
|
|
||||||
childRef.current.handleRemoveTag(key, Number(tagIndex))
|
childRef.current.handleRemoveTag(key, tagIndex)
|
||||||
})
|
})
|
||||||
|
|
||||||
if (allselectedTags.length === 0) childRef.current.handleRemoveTag(selectedTag?.key, selectedTag?.index)
|
if (allselectedTags.length == 0) childRef.current.handleRemoveTag(selectedTag?.key, selectedTag?.index)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -522,7 +522,21 @@ const DocumentContainer = forwardRef<DocumentContainerRef, DocumentContainerProp
|
||||||
className='drop-page-in shadow-md relative'
|
className='drop-page-in shadow-md relative'
|
||||||
>
|
>
|
||||||
|
|
||||||
|
<img
|
||||||
|
// style={{ "minWidth": page.width, "minHeight": page.height, "maxWidth": page.width, "maxHeight": page.height }}
|
||||||
|
style={{ "width": page.width, "height": page.height, "maxWidth": "100%", "maxHeight": "100%" }}
|
||||||
|
// style={{ "width": "100%", "height": "100%", "maxWidth": "100%", "maxHeight": "100%" }}
|
||||||
|
// className={`w-[${(page.width / 2)}px] h-[${(page.height / 2)}px] sm:w-[${page.width}px] sm:h-[${page.height}px]`}
|
||||||
|
draggable="false"
|
||||||
|
width={page.width}
|
||||||
|
height={page.height}
|
||||||
|
// src={`http://10.10.1.99:8083/api/v1/accounts/${accountId}/transactions/${transactionId}/documents/${doc.id}/pages/${page.id}`}
|
||||||
|
src={page.src}
|
||||||
|
loading='lazy'
|
||||||
|
/>
|
||||||
|
|
||||||
<DroppedItemsTagsCon
|
<DroppedItemsTagsCon
|
||||||
|
pageWidth={page.width}
|
||||||
ref={childRef}
|
ref={childRef}
|
||||||
droppedItems={droppedItems}
|
droppedItems={droppedItems}
|
||||||
pageIdkey={key}
|
pageIdkey={key}
|
||||||
|
|
@ -536,17 +550,6 @@ const DocumentContainer = forwardRef<DocumentContainerRef, DocumentContainerProp
|
||||||
tagUndoRef={tagUndoRef}
|
tagUndoRef={tagUndoRef}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<img
|
|
||||||
style={{ "minWidth": page.width, "minHeight": page.height, "maxWidth": page.width, "maxHeight": page.height }}
|
|
||||||
draggable="false"
|
|
||||||
width={page.width}
|
|
||||||
height={page.height}
|
|
||||||
// src={`http://10.10.1.99:8083/api/v1/accounts/${accountId}/transactions/${transactionId}/documents/${doc.id}/pages/${page.id}`}
|
|
||||||
src={page.src}
|
|
||||||
loading='lazy'
|
|
||||||
/>
|
|
||||||
|
|
||||||
|
|
||||||
{/* Side details of documents Pages and document Name - START */}
|
{/* Side details of documents Pages and document Name - START */}
|
||||||
<p className='absolute top-[50%] translate-y-[-50%] rotate-[-90deg] text-xs left-[-60px] text-slate-600'>
|
<p className='absolute top-[50%] translate-y-[-50%] rotate-[-90deg] text-xs left-[-60px] text-slate-600'>
|
||||||
page {indx + 1} of {doc.pages && doc.pages.length}
|
page {indx + 1} of {doc.pages && doc.pages.length}
|
||||||
|
|
@ -572,7 +575,7 @@ const DocumentContainer = forwardRef<DocumentContainerRef, DocumentContainerProp
|
||||||
|
|
||||||
</div >
|
</div >
|
||||||
|
|
||||||
{selectedTag && selectedTag !== null && "key" in selectedTag && "index" in selectedTag && <RightSideBar
|
{selectedTag && selectedTag != null && "key" in selectedTag && "index" in selectedTag && <RightSideBar
|
||||||
droppedItems={droppedItems}
|
droppedItems={droppedItems}
|
||||||
selectedTag={droppedItems[selectedTag.key][selectedTag.index]}
|
selectedTag={droppedItems[selectedTag.key][selectedTag.index]}
|
||||||
setDroppedItems={setDroppedItems}
|
setDroppedItems={setDroppedItems}
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ import { Recipient } from '../../../store/slices/selectedRecipientsSlice';
|
||||||
import { DroppedItem } from '../../../utlity/types';
|
import { DroppedItem } from '../../../utlity/types';
|
||||||
|
|
||||||
interface DroppedItemsTagsConProps {
|
interface DroppedItemsTagsConProps {
|
||||||
|
pageWidth: number;
|
||||||
droppedItems: DroppedItemsObj;
|
droppedItems: DroppedItemsObj;
|
||||||
pageIdkey: string;
|
pageIdkey: string;
|
||||||
selectedTag: { key: string; index: number } | null;
|
selectedTag: { key: string; index: number } | null;
|
||||||
|
|
@ -33,6 +34,7 @@ interface DroppedItemsTagsConProps {
|
||||||
|
|
||||||
// 👶 Child component with forwardRef
|
// 👶 Child component with forwardRef
|
||||||
const DroppedItemsTagsCon = forwardRef(({
|
const DroppedItemsTagsCon = forwardRef(({
|
||||||
|
pageWidth,
|
||||||
droppedItems,
|
droppedItems,
|
||||||
pageIdkey,
|
pageIdkey,
|
||||||
selectedTag,
|
selectedTag,
|
||||||
|
|
@ -52,7 +54,7 @@ const DroppedItemsTagsCon = forwardRef(({
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleRemoveTag = (key: string, targetIndex: number) => {
|
const handleRemoveTag = (key: string, targetIndex: number) => {
|
||||||
if (key === undefined || targetIndex === undefined) return
|
if (key == undefined || targetIndex == undefined) return
|
||||||
|
|
||||||
const tag = droppedItems[key][targetIndex];
|
const tag = droppedItems[key][targetIndex];
|
||||||
const recipientId = tag.recipientId;
|
const recipientId = tag.recipientId;
|
||||||
|
|
@ -61,7 +63,7 @@ const DroppedItemsTagsCon = forwardRef(({
|
||||||
if ("id" in tag) {
|
if ("id" in tag) {
|
||||||
try {
|
try {
|
||||||
const response = await api.delete(`/api/v1/accounts/${accountId}/${transactionTemplateToggle}/${transactionId}/recipients/${recipientId}/tags/${tag.id}`)
|
const response = await api.delete(`/api/v1/accounts/${accountId}/${transactionTemplateToggle}/${transactionId}/recipients/${recipientId}/tags/${tag.id}`)
|
||||||
if (response.status !== 200) throw "Tag Deletion error"
|
if (response.status != 200) throw "Tag Deletion error"
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("Tag Deletion error")
|
console.error("Tag Deletion error")
|
||||||
return;
|
return;
|
||||||
|
|
@ -79,13 +81,13 @@ const DroppedItemsTagsCon = forwardRef(({
|
||||||
// Find all items in the same group
|
// Find all items in the same group
|
||||||
const groupItems = droppedItems[key]
|
const groupItems = droppedItems[key]
|
||||||
.map((item, idx) => ({ item, index: idx }))
|
.map((item, idx) => ({ item, index: idx }))
|
||||||
.filter(({ item }) => 'group' in item && item.group === groupId && !item.isDeleted);
|
.filter(({ item }) => 'group' in item && item.group == groupId && !item.isDeleted);
|
||||||
|
|
||||||
// Sort group items by their top position to identify the parent (top-most)
|
// Sort group items by their top position to identify the parent (top-most)
|
||||||
groupItems.sort((a, b) => a.item.dimensions.top - b.item.dimensions.top);
|
groupItems.sort((a, b) => a.item.dimensions.top - b.item.dimensions.top);
|
||||||
|
|
||||||
// Check if the item being removed is the parent (top-most item)
|
// Check if the item being removed is the parent (top-most item)
|
||||||
const isParentItem = groupItems.length > 0 && groupItems[0].index === targetIndex;
|
const isParentItem = groupItems.length > 0 && groupItems[0].index == targetIndex;
|
||||||
|
|
||||||
if (isParentItem && groupItems.length > 1) {
|
if (isParentItem && groupItems.length > 1) {
|
||||||
// If removing the parent and there are child items, mark all items in the group as deleted
|
// If removing the parent and there are child items, mark all items in the group as deleted
|
||||||
|
|
@ -113,17 +115,17 @@ const DroppedItemsTagsCon = forwardRef(({
|
||||||
setDroppedItems(prevState => ({
|
setDroppedItems(prevState => ({
|
||||||
...prevState,
|
...prevState,
|
||||||
[key]: prevState[key].map((item, index) =>
|
[key]: prevState[key].map((item, index) =>
|
||||||
index === targetIndex ? { ...item, isDeleted: true } : item
|
index == targetIndex ? { ...item, isDeleted: true } : item
|
||||||
)
|
)
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Check if this was the last item in the group after state update
|
// Check if this was the last item in the group after state update
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const remainingGroupItems = droppedItems[key].filter(item =>
|
const remainingGroupItems = droppedItems[key].filter(item =>
|
||||||
'group' in item && item.group === groupId && !item.isDeleted
|
'group' in item && item.group == groupId && !item.isDeleted
|
||||||
);
|
);
|
||||||
|
|
||||||
if (remainingGroupItems.length === 0) {
|
if (remainingGroupItems.length == 0) {
|
||||||
// Remove group borders if no items left
|
// Remove group borders if no items left
|
||||||
removeGroupBorders(groupId);
|
removeGroupBorders(groupId);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -137,7 +139,7 @@ const DroppedItemsTagsCon = forwardRef(({
|
||||||
setDroppedItems(prevState => ({
|
setDroppedItems(prevState => ({
|
||||||
...prevState,
|
...prevState,
|
||||||
[key]: prevState[key].map((item, index) =>
|
[key]: prevState[key].map((item, index) =>
|
||||||
index === targetIndex ? { ...item, isDeleted: true } : item
|
index == targetIndex ? { ...item, isDeleted: true } : item
|
||||||
)
|
)
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
@ -206,7 +208,7 @@ const DroppedItemsTagsCon = forwardRef(({
|
||||||
// ...prevState,
|
// ...prevState,
|
||||||
// [key]: Array.isArray(prevState[key])
|
// [key]: Array.isArray(prevState[key])
|
||||||
// ? prevState[key].map((item, i) =>
|
// ? prevState[key].map((item, i) =>
|
||||||
// i === index ? { ...item, dimensions: { ...item.dimensions, left, top }, update: true } : item
|
// i == index ? { ...item, dimensions: { ...item.dimensions, left, top }, update: true } : item
|
||||||
// )
|
// )
|
||||||
// : [],
|
// : [],
|
||||||
// }));
|
// }));
|
||||||
|
|
@ -248,7 +250,7 @@ const DroppedItemsTagsCon = forwardRef(({
|
||||||
...prevState,
|
...prevState,
|
||||||
[key]: Array.isArray(prevState[key])
|
[key]: Array.isArray(prevState[key])
|
||||||
? prevState[key].map((item, i) =>
|
? prevState[key].map((item, i) =>
|
||||||
i === index ? { ...item, dimensions: { ...item.dimensions, left, top }, update: true } : item
|
i == index ? { ...item, dimensions: { ...item.dimensions, left, top }, update: true } : item
|
||||||
)
|
)
|
||||||
: [],
|
: [],
|
||||||
}));
|
}));
|
||||||
|
|
@ -286,19 +288,19 @@ const DroppedItemsTagsCon = forwardRef(({
|
||||||
|
|
||||||
|
|
||||||
const dropZone: DOMRect = targetContainer?.getBoundingClientRect() as DOMRect;
|
const dropZone: DOMRect = targetContainer?.getBoundingClientRect() as DOMRect;
|
||||||
const droppedElemRect: DOMRect = targetElement?.getBoundingClientRect() as DOMRect;
|
const droppedElemRect: DOMRect = targetElement?.getBoundingClientRect() as DOMRect;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
console.log(dropZone, "dropZone Line 309")
|
console.log(dropZone, "dropZone Line 309")
|
||||||
console.log(droppedElemRect, "rect Line 309")
|
console.log(droppedElemRect, "rect Line 309")
|
||||||
|
|
||||||
let newWidth = startWidth + (event.clientX - startX);
|
let newWidth = startWidth + (event.clientX - startX);
|
||||||
let newHeight = startHeight + (event.clientY - startY);
|
let newHeight = startHeight + (event.clientY - startY);
|
||||||
|
|
||||||
|
|
||||||
if (newHeight > 200 || newWidth > 400) {
|
if (newHeight > 200 || newWidth > 400) {
|
||||||
if (newHeight > 200) {
|
if (newHeight > 200) {
|
||||||
newHeight = 200
|
newHeight = 200
|
||||||
|
|
@ -308,7 +310,7 @@ const DroppedItemsTagsCon = forwardRef(({
|
||||||
newWidth = 400
|
newWidth = 400
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((dropZone.right - (droppedElemRect.left + newWidth)) < 0) {
|
if ((dropZone.right - (droppedElemRect.left + newWidth)) < 0) {
|
||||||
newWidth = startWidth
|
newWidth = startWidth
|
||||||
}
|
}
|
||||||
|
|
@ -321,7 +323,7 @@ const DroppedItemsTagsCon = forwardRef(({
|
||||||
...droppedItems,
|
...droppedItems,
|
||||||
[key]: Array.isArray(droppedItems[key]) // Ensure it's an array
|
[key]: Array.isArray(droppedItems[key]) // Ensure it's an array
|
||||||
? droppedItems[key].map((item, i) =>
|
? droppedItems[key].map((item, i) =>
|
||||||
i === index ? { ...item, dimensions: { ...item.dimensions, width: newWidth, height: newHeight }, update: true } : item
|
i == index ? { ...item, dimensions: { ...item.dimensions, width: newWidth, height: newHeight }, update: true } : item
|
||||||
)
|
)
|
||||||
: [], // Provide a fallback in case it's undefined or not an array
|
: [], // Provide a fallback in case it's undefined or not an array
|
||||||
});
|
});
|
||||||
|
|
@ -354,7 +356,7 @@ const DroppedItemsTagsCon = forwardRef(({
|
||||||
const handleIGroupBorderPosition = (groupId: string) => {
|
const handleIGroupBorderPosition = (groupId: string) => {
|
||||||
const groupElements: NodeListOf<HTMLElement> = document.querySelectorAll(`div[group="${groupId}"]`);
|
const groupElements: NodeListOf<HTMLElement> = document.querySelectorAll(`div[group="${groupId}"]`);
|
||||||
|
|
||||||
if (groupElements.length === 0) {
|
if (groupElements.length == 0) {
|
||||||
console.log("No group elements found for:", groupId);
|
console.log("No group elements found for:", groupId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -381,7 +383,7 @@ const DroppedItemsTagsCon = forwardRef(({
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleGroupBorderPosition = (groupElements: NodeListOf<HTMLElement>, containerRect: DOMRect, offsetX: number, offsetY: number) => {
|
const handleGroupBorderPosition = (groupElements: NodeListOf<HTMLElement>, containerRect: DOMRect, offsetX: number, offsetY: number) => {
|
||||||
if (!groupElements || groupElements.length === 0) return;
|
if (!groupElements || groupElements.length == 0) return;
|
||||||
|
|
||||||
const groupId = groupElements[0].getAttribute('group');
|
const groupId = groupElements[0].getAttribute('group');
|
||||||
if (!groupId) return;
|
if (!groupId) return;
|
||||||
|
|
@ -424,17 +426,17 @@ const DroppedItemsTagsCon = forwardRef(({
|
||||||
if (!borderElement) {
|
if (!borderElement) {
|
||||||
// Create border element if it doesn't exist
|
// Create border element if it doesn't exist
|
||||||
borderElement = document.createElement('div');
|
borderElement = document.createElement('div');
|
||||||
borderElement.className = `group-border ${position === 'bottom' ? 'bottom-border' : ''}`;
|
borderElement.className = `group-border ${position == 'bottom' ? 'bottom-border' : ''}`;
|
||||||
borderElement.setAttribute('border-group', groupId);
|
borderElement.setAttribute('border-group', groupId);
|
||||||
borderElement.setAttribute('border-pos', position);
|
borderElement.setAttribute('border-pos', position);
|
||||||
|
|
||||||
// Add the + icon for bottom border
|
// Add the + icon for bottom border
|
||||||
if (position === 'bottom') {
|
if (position == 'bottom') {
|
||||||
const addIcon = document.createElement('div');
|
const addIcon = document.createElement('div');
|
||||||
addIcon.innerHTML = '<IoAdd />'; // You might need to adjust this based on your icon system
|
addIcon.innerHTML = '<IoAdd />'; // You might need to adjust this based on your icon system
|
||||||
addIcon.onclick = () => {
|
addIcon.onclick = () => {
|
||||||
// Find the original item to pass to handleAddGroupItemClicked
|
// Find the original item to pass to handleAddGroupItemClicked
|
||||||
const originalItem = droppedItems[key]?.find(item => 'group' in item && item.group === groupId);
|
const originalItem = droppedItems[key]?.find(item => 'group' in item && item.group == groupId);
|
||||||
if (originalItem) {
|
if (originalItem) {
|
||||||
handleAddGroupItemClicked(key, originalItem);
|
handleAddGroupItemClicked(key, originalItem);
|
||||||
}
|
}
|
||||||
|
|
@ -448,7 +450,7 @@ const DroppedItemsTagsCon = forwardRef(({
|
||||||
|
|
||||||
// Position the border element
|
// Position the border element
|
||||||
borderElement.style.position = 'absolute';
|
borderElement.style.position = 'absolute';
|
||||||
borderElement.style.pointerEvents = position === 'bottom' ? 'auto' : 'none';
|
borderElement.style.pointerEvents = position == 'bottom' ? 'auto' : 'none';
|
||||||
|
|
||||||
switch (position) {
|
switch (position) {
|
||||||
case 'top':
|
case 'top':
|
||||||
|
|
@ -484,11 +486,11 @@ const DroppedItemsTagsCon = forwardRef(({
|
||||||
|
|
||||||
// Find all existing items in this group to determine the bottom-most position
|
// Find all existing items in this group to determine the bottom-most position
|
||||||
const existingGroupItems = droppedItems[key]?.filter(existingItem =>
|
const existingGroupItems = droppedItems[key]?.filter(existingItem =>
|
||||||
'group' in existingItem && existingItem.group === groupId
|
'group' in existingItem && existingItem.group == groupId
|
||||||
) || [];
|
) || [];
|
||||||
|
|
||||||
const existingGroupItem = droppedItems[key]?.filter(existingItem =>
|
const existingGroupItem = droppedItems[key]?.filter(existingItem =>
|
||||||
'group' in existingItem && existingItem.group === groupId
|
'group' in existingItem && existingItem.group == groupId
|
||||||
) || [];
|
) || [];
|
||||||
|
|
||||||
existingGroupItem[0].options
|
existingGroupItem[0].options
|
||||||
|
|
@ -560,7 +562,7 @@ const DroppedItemsTagsCon = forwardRef(({
|
||||||
|
|
||||||
const type = item.type.toUpperCase();
|
const type = item.type.toUpperCase();
|
||||||
const IconComponent = typeToIconMap[type] || <FaQuestionCircle />;
|
const IconComponent = typeToIconMap[type] || <FaQuestionCircle />;
|
||||||
const selectedRecipient = selectedRecipients.filter((obj, indx) => obj.id === item.recipientId);
|
const selectedRecipient = selectedRecipients.filter((obj, indx) => obj.id == item.recipientId);
|
||||||
return (
|
return (
|
||||||
<React.Fragment key={index}>
|
<React.Fragment key={index}>
|
||||||
<div
|
<div
|
||||||
|
|
@ -568,20 +570,27 @@ const DroppedItemsTagsCon = forwardRef(({
|
||||||
draggable="false"
|
draggable="false"
|
||||||
data-tag-id={index}
|
data-tag-id={index}
|
||||||
data-drop-key={pageIdkey}
|
data-drop-key={pageIdkey}
|
||||||
data-tag-selected={index === selectedTag?.index}
|
data-tag-selected={index == selectedTag?.index}
|
||||||
className="absolute rounded dropped-item"
|
className="absolute rounded dropped-item"
|
||||||
onClick={() => handleTagClick(pageIdkey, index)}
|
onClick={() => handleTagClick(pageIdkey, index)}
|
||||||
|
// style={{
|
||||||
|
// left: `${item.dimensions.left}px`,
|
||||||
|
// top: `${item.dimensions.top}px`,
|
||||||
|
// width: item.type == "radio" ? `${item.dimensions.width + 20}px` : `${item.dimensions.width}px`,
|
||||||
|
// height: item.type == "radio" ? `max-content` : `${item.dimensions.height}px`
|
||||||
|
// }}
|
||||||
|
|
||||||
style={{
|
style={{
|
||||||
left: `${item.dimensions.left}px`,
|
left: `${((item.dimensions.left / pageWidth) * 100)}%`,
|
||||||
top: `${item.dimensions.top}px`,
|
top: item.dimensions.top,
|
||||||
width: item.type === "radio" ? `${item.dimensions.width + 20}px` : `${item.dimensions.width}px`,
|
width: `${((item.dimensions.width / pageWidth) * 100)}%`,
|
||||||
height: item.type === "radio" ? `max-content` : `${item.dimensions.height}px`
|
height: item.dimensions.height,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|
||||||
|
|
||||||
{/* If Selected Tag Recipient Info- START */}
|
{/* If Selected Tag Recipient Info- START */}
|
||||||
{selectedTag?.key && selectedTag.key === pageIdkey && selectedTag.index === index &&
|
{selectedTag?.key && selectedTag.key == pageIdkey && selectedTag.index == index &&
|
||||||
<div className='absolute flex justify-between items-center w-full max-w-max bg-white top-[-22px] shadow z-20 text-sm rounded-t-sm' >
|
<div className='absolute flex justify-between items-center w-full max-w-max bg-white top-[-22px] shadow z-20 text-sm rounded-t-sm' >
|
||||||
<div className='flex justify-center items-center gap-1 bg-white px-2 shadow'>
|
<div className='flex justify-center items-center gap-1 bg-white px-2 shadow'>
|
||||||
<p className='w-2.5 h-2.5 rounded'
|
<p className='w-2.5 h-2.5 rounded'
|
||||||
|
|
@ -601,7 +610,7 @@ const DroppedItemsTagsCon = forwardRef(({
|
||||||
|
|
||||||
|
|
||||||
{/* Expand Circle - STARTS */}
|
{/* Expand Circle - STARTS */}
|
||||||
{item.type !== "radio" && item.type !== "checkbox" && <div
|
{item.type != "radio" && item.type != "checkbox" && <div
|
||||||
onPointerDown={(e) => handleExpandTag(e, pageIdkey, index)}
|
onPointerDown={(e) => handleExpandTag(e, pageIdkey, index)}
|
||||||
className='w-2.5 h-2.5 absolute bg-red-400 rounded-full bottom-[-8px] right-[-8px] cursor-nw-resize hover:bg-blue-400'>
|
className='w-2.5 h-2.5 absolute bg-red-400 rounded-full bottom-[-8px] right-[-8px] cursor-nw-resize hover:bg-blue-400'>
|
||||||
</div>}
|
</div>}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ const handlePointerDown = (event: React.DragEvent<HTMLDivElement>, label: string
|
||||||
let width = dragElemRect.width
|
let width = dragElemRect.width
|
||||||
let height = dragElemRect.height
|
let height = dragElemRect.height
|
||||||
|
|
||||||
if (label === TagsTypes.RADIO || label === TagsTypes.CHECKBOX) {
|
if (label == TagsTypes.RADIO || label == TagsTypes.CHECKBOX) {
|
||||||
const innerIconConRect = event.currentTarget.children[0].getBoundingClientRect();
|
const innerIconConRect = event.currentTarget.children[0].getBoundingClientRect();
|
||||||
width = innerIconConRect.width + 10
|
width = innerIconConRect.width + 10
|
||||||
height = innerIconConRect.height + 10
|
height = innerIconConRect.height + 10
|
||||||
|
|
@ -92,7 +92,7 @@ const handlePointerDown = (event: React.DragEvent<HTMLDivElement>, label: string
|
||||||
properties: tagsProperties
|
properties: tagsProperties
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj.label.toLowerCase() === "radio" || obj.label.toLowerCase() === "checkbox") obj.group = uuidv4();
|
if (obj.label.toLowerCase() == "radio" || obj.label.toLowerCase() == "checkbox") obj.group = uuidv4();
|
||||||
|
|
||||||
window.dragElemData = JSON.stringify(obj);
|
window.dragElemData = JSON.stringify(obj);
|
||||||
}
|
}
|
||||||
|
|
@ -130,7 +130,7 @@ const FieldList: React.FC<FieldListProps> = ({ color, recipientId, recipientIndx
|
||||||
const priorityOrder = ['SIGNATURE', 'INITIALS', 'STAMP'];
|
const priorityOrder = ['SIGNATURE', 'INITIALS', 'STAMP'];
|
||||||
|
|
||||||
const data = res.data.filter((obj, indx) => {
|
const data = res.data.filter((obj, indx) => {
|
||||||
if (obj.type === "STAMP" || obj.type === "RADIO" || obj.type === "CHECKBOX" || obj.type === "ATTACHMENT") return false
|
if (obj.type == "STAMP" || obj.type == "RADIO" || obj.type == "CHECKBOX" || obj.type == "ATTACHMENT") return false
|
||||||
return true
|
return true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -145,7 +145,7 @@ const FieldList: React.FC<FieldListProps> = ({ color, recipientId, recipientIndx
|
||||||
|
|
||||||
// Maintain the custom order of priority
|
// Maintain the custom order of priority
|
||||||
const prioritizedSorted = priorityOrder
|
const prioritizedSorted = priorityOrder
|
||||||
.map((type) => prioritized.find((tag: any) => tag.type === type))
|
.map((type) => prioritized.find((tag: any) => tag.type == type))
|
||||||
.filter(Boolean); // remove undefined in case not found
|
.filter(Boolean); // remove undefined in case not found
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -249,7 +249,7 @@ const FieldList: React.FC<FieldListProps> = ({ color, recipientId, recipientIndx
|
||||||
const priorityOrder = ['SIGNATURE', 'INITIALS', 'STAMP'];
|
const priorityOrder = ['SIGNATURE', 'INITIALS', 'STAMP'];
|
||||||
|
|
||||||
data = data.filter((obj, indx) => {
|
data = data.filter((obj, indx) => {
|
||||||
if (obj.type === "STAMP" || obj.type === "RADIO" || obj.type === "CHECKBOX" || obj.type === "ATTACHMENT") return false
|
if (obj.type == "STAMP" || obj.type == "RADIO" || obj.type == "CHECKBOX" || obj.type == "ATTACHMENT") return false
|
||||||
return true
|
return true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -264,7 +264,7 @@ const FieldList: React.FC<FieldListProps> = ({ color, recipientId, recipientIndx
|
||||||
|
|
||||||
// Maintain the custom order of priority
|
// Maintain the custom order of priority
|
||||||
const prioritizedSorted = priorityOrder
|
const prioritizedSorted = priorityOrder
|
||||||
.map((type) => prioritized.find((tag: any) => tag.type === type))
|
.map((type) => prioritized.find((tag: any) => tag.type == type))
|
||||||
.filter(Boolean); // remove undefined in case not found
|
.filter(Boolean); // remove undefined in case not found
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,8 @@ import { useParams } from 'react-router-dom';
|
||||||
import { fetchDocuments } from '../../../store/slices/documentSlice';
|
import { fetchDocuments } from '../../../store/slices/documentSlice';
|
||||||
import { GrFormPrevious } from 'react-icons/gr';
|
import { GrFormPrevious } from 'react-icons/gr';
|
||||||
import { LuTableOfContents } from 'react-icons/lu';
|
import { LuTableOfContents } from 'react-icons/lu';
|
||||||
import { IoIosDocument } from 'react-icons/io';
|
import { IoIosDocument, IoMdClose } from 'react-icons/io';
|
||||||
|
import { FaAngleUp, FaChevronRight } from 'react-icons/fa';
|
||||||
|
|
||||||
interface LeftSideBarProps {
|
interface LeftSideBarProps {
|
||||||
isFields: boolean;
|
isFields: boolean;
|
||||||
|
|
@ -19,7 +20,7 @@ interface LeftSideBarProps {
|
||||||
selectedRecipientIndx: number;
|
selectedRecipientIndx: number;
|
||||||
setSelectedRecipient: React.Dispatch<React.SetStateAction<number>>
|
setSelectedRecipient: React.Dispatch<React.SetStateAction<number>>
|
||||||
handleSetIsFields: (setTo: boolean) => void;
|
handleSetIsFields: (setTo: boolean) => void;
|
||||||
handleSetIsPages:(setTo: boolean) => void;
|
handleSetIsPages: (setTo: boolean) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const LeftSideBar: React.FC<LeftSideBarProps> = ({ isFields, isPages, selectedRecipientIndx, setSelectedRecipient, handleSetIsFields, handleSetIsPages }) => {
|
const LeftSideBar: React.FC<LeftSideBarProps> = ({ isFields, isPages, selectedRecipientIndx, setSelectedRecipient, handleSetIsFields, handleSetIsPages }) => {
|
||||||
|
|
@ -46,13 +47,13 @@ const LeftSideBar: React.FC<LeftSideBarProps> = ({ isFields, isPages, selectedRe
|
||||||
const [currentPage, setCurrentPage] = useState(0);
|
const [currentPage, setCurrentPage] = useState(0);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedRecipients.length === 0) {
|
if (selectedRecipients.length == 0) {
|
||||||
dispatch(fetchRecipients({ accountId, transactionId }));
|
dispatch(fetchRecipients({ accountId, transactionId }));
|
||||||
}
|
}
|
||||||
}, [dispatch, accountId, transactionId, selectedRecipients.length]);
|
}, [dispatch, accountId, transactionId, selectedRecipients.length]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedDocuments.length === 0) {
|
if (selectedDocuments.length == 0) {
|
||||||
dispatch(fetchDocuments({ accountId, transactionId }));
|
dispatch(fetchDocuments({ accountId, transactionId }));
|
||||||
}
|
}
|
||||||
}, [dispatch, accountId, transactionId, selectedDocuments.length]);
|
}, [dispatch, accountId, transactionId, selectedDocuments.length]);
|
||||||
|
|
@ -72,9 +73,9 @@ const LeftSideBar: React.FC<LeftSideBarProps> = ({ isFields, isPages, selectedRe
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedRecipient && selectedRecipient.type === recipientType.CC) {
|
if (selectedRecipient && selectedRecipient.type == recipientType.CC) {
|
||||||
for (const [indx, recip] of selectedRecipients.entries()) {
|
for (const [indx, recip] of selectedRecipients.entries()) {
|
||||||
if (recip.type !== recipientType.CC) {
|
if (recip.type != recipientType.CC) {
|
||||||
setSelectedRecipient(indx);
|
setSelectedRecipient(indx);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -82,7 +83,7 @@ const LeftSideBar: React.FC<LeftSideBarProps> = ({ isFields, isPages, selectedRe
|
||||||
};
|
};
|
||||||
}, [selectedRecipient])
|
}, [selectedRecipient])
|
||||||
|
|
||||||
if (selectedRecipient && selectedRecipient.type === recipientType.CC) {
|
if (selectedRecipient && selectedRecipient.type == recipientType.CC) {
|
||||||
return <div className='col-span-2 bg-white h-full p-4 overflow-y-auto'></div>;
|
return <div className='col-span-2 bg-white h-full p-4 overflow-y-auto'></div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -90,9 +91,17 @@ const LeftSideBar: React.FC<LeftSideBarProps> = ({ isFields, isPages, selectedRe
|
||||||
<>
|
<>
|
||||||
{/* Left Side Bar - START */}
|
{/* Left Side Bar - START */}
|
||||||
{
|
{
|
||||||
<div className={`${!isFields && !isPages ? "hidden" : ""} p-4 absolute top-[48px] sm:top-[0] rounded-tr-md z-50 sm:relative sm:col-span-2 bg-white border-t-1 border-r-1 border-slate-300 h-[calc(100vh-40px)] overflow-y-auto`}>
|
(isPages || isFields) && <div className={`sm:block p-4 absolute top-[48px] sm:top-[0] rounded-tr-md z-50 sm:relative sm:col-span-2 bg-white border-t-1 border-r-1 border-slate-300 h-[calc(100vh-40px)] overflow-y-auto`}>
|
||||||
|
<div
|
||||||
|
onClick={() => {
|
||||||
|
handleSetIsPages(false)
|
||||||
|
handleSetIsFields(false)
|
||||||
|
}}
|
||||||
|
className='absolute top-[5px] right-[5px] bg-white rounded-full'>
|
||||||
|
<IoMdClose />
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className='flex flex-col md:flex-row justify-between items-center bg-slate-100 p-1.5 rounded-2xl border-1 border-gray-200 mb-3'>
|
<div className='hidden sm:flex flex-col md:flex-row justify-between items-center bg-slate-100 p-1.5 rounded-2xl border-1 border-gray-200 mb-3'>
|
||||||
<div
|
<div
|
||||||
onClick={() => handleSetIsFields(!isFields)}
|
onClick={() => handleSetIsFields(!isFields)}
|
||||||
className={`flex items-center gap-1 cursor-pointer text-xs w-full justify-center py-1.5 rounded-2xl ${isFields ? 'bg-[var(--primary)] text-white' : ''} transition-all duration-300`}>
|
className={`flex items-center gap-1 cursor-pointer text-xs w-full justify-center py-1.5 rounded-2xl ${isFields ? 'bg-[var(--primary)] text-white' : ''} transition-all duration-300`}>
|
||||||
|
|
@ -125,8 +134,8 @@ const LeftSideBar: React.FC<LeftSideBarProps> = ({ isFields, isPages, selectedRe
|
||||||
{/* <FaUserTie className='w-3 h-3 text-2xl mt-[1px]' style={{ color: selectedRecipient.color }} /> */}
|
{/* <FaUserTie className='w-3 h-3 text-2xl mt-[1px]' style={{ color: selectedRecipient.color }} /> */}
|
||||||
<p>
|
<p>
|
||||||
{
|
{
|
||||||
selectedRecipient.firstName.length === 0 && selectedRecipient.lastName.length === 0 ?
|
selectedRecipient.firstName.length == 0 && selectedRecipient.lastName.length == 0 ?
|
||||||
(selectedRecipient.email.length === 0 ? selectedRecipient.roleName : selectedRecipient.email) :
|
(selectedRecipient.email.length == 0 ? selectedRecipient.roleName : selectedRecipient.email) :
|
||||||
`${selectedRecipient.firstName + " " + selectedRecipient.lastName}`
|
`${selectedRecipient.firstName + " " + selectedRecipient.lastName}`
|
||||||
}
|
}
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -137,7 +146,7 @@ const LeftSideBar: React.FC<LeftSideBarProps> = ({ isFields, isPages, selectedRe
|
||||||
<div
|
<div
|
||||||
className={`absolute w-full shadow-md rounded-md mt-1 px-2 py-1 z-20 bg-white ${dropDownToggle ? '' : 'hidden'}`}>
|
className={`absolute w-full shadow-md rounded-md mt-1 px-2 py-1 z-20 bg-white ${dropDownToggle ? '' : 'hidden'}`}>
|
||||||
{selectedRecipients.length && selectedRecipients.map((recipient, indx) => {
|
{selectedRecipients.length && selectedRecipients.map((recipient, indx) => {
|
||||||
if (recipient.type === recipientType.CC) return null; // Skip CC recipients
|
if (recipient.type == recipientType.CC) return null; // Skip CC recipients
|
||||||
return (<div
|
return (<div
|
||||||
key={indx}
|
key={indx}
|
||||||
className='flex items-center justify-between gap-2 w-full p-2 text-xs rounded-sm cursor-pointer hover:bg-slate-100'
|
className='flex items-center justify-between gap-2 w-full p-2 text-xs rounded-sm cursor-pointer hover:bg-slate-100'
|
||||||
|
|
@ -153,13 +162,13 @@ const LeftSideBar: React.FC<LeftSideBarProps> = ({ isFields, isPages, selectedRe
|
||||||
{/* <FaUser className='w-3 h-3 text-2xl mt-[1px]' style={{ color: recipient.color }} /> */}
|
{/* <FaUser className='w-3 h-3 text-2xl mt-[1px]' style={{ color: recipient.color }} /> */}
|
||||||
<p>
|
<p>
|
||||||
{
|
{
|
||||||
recipient.firstName.length === 0 && recipient.lastName.length === 0 ?
|
recipient.firstName.length == 0 && recipient.lastName.length == 0 ?
|
||||||
(recipient.email.length === 0 ? recipient.roleName : recipient.email) :
|
(recipient.email.length == 0 ? recipient.roleName : recipient.email) :
|
||||||
`${recipient.firstName + " " + recipient.lastName}`
|
`${recipient.firstName + " " + recipient.lastName}`
|
||||||
}
|
}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{selectedRecipientIndx === indx && <IoCheckmark className='text-[var(--primary)]' />}
|
{selectedRecipientIndx == indx && <IoCheckmark className='text-[var(--primary)]' />}
|
||||||
</div>)
|
</div>)
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -187,8 +196,8 @@ const LeftSideBar: React.FC<LeftSideBarProps> = ({ isFields, isPages, selectedRe
|
||||||
// onBlur={() => setDropDownTogglePage('')}
|
// onBlur={() => setDropDownTogglePage('')}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
onClick={() => setDropDownTogglePage(`${(dropDownTogglePage === 'pageDropDown' + indx) ? '' : 'pageDropDown' + indx}`)}
|
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`}>
|
className={`p-2 ${(dropDownTogglePage == 'pageDropDown' + indx) ? "bg-[var(--primary)]" : "bg-slate-200"} flex flex-col justify-center items-center gap-2 rounded`}>
|
||||||
{
|
{
|
||||||
document.pages != undefined && <img
|
document.pages != undefined && <img
|
||||||
key={indx}
|
key={indx}
|
||||||
|
|
@ -200,21 +209,21 @@ const LeftSideBar: React.FC<LeftSideBarProps> = ({ isFields, isPages, selectedRe
|
||||||
<div
|
<div
|
||||||
className='flex items-center justify-between w-full text-xs rounded-sm cursor-pointer text-slate-100'>
|
className='flex items-center justify-between w-full text-xs rounded-sm cursor-pointer text-slate-100'>
|
||||||
<p className='whitespace-nowrap overflow-hidden text-ellipsis max-w-[18ch]'>{document.name}</p>
|
<p className='whitespace-nowrap overflow-hidden text-ellipsis max-w-[18ch]'>{document.name}</p>
|
||||||
<MdKeyboardArrowDown className={`${(dropDownTogglePage === 'pageDropDown' + indx) ? 'rotate-180' : ''}`} />
|
<MdKeyboardArrowDown className={`${(dropDownTogglePage == 'pageDropDown' + indx) ? 'rotate-180' : ''}`} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
dropDownTogglePage === 'pageDropDown' + indx &&
|
dropDownTogglePage == 'pageDropDown' + indx &&
|
||||||
<div className="my-1 flex justify-center items-center gap-2 flex-wrap">
|
<div className="my-1 flex justify-center items-center gap-2 flex-wrap">
|
||||||
{/* Prev Button */}
|
{/* Prev Button */}
|
||||||
<a
|
<a
|
||||||
href={"#" + document.id + (currentPage - 1)}
|
href={"#" + document.id + (currentPage - 1)}
|
||||||
className={`cursor-pointer px-2 py-1 shadow rounded-sm text-sm bg-slate-200 hover:border-[var(--primary)] transition-all duration-300 ${currentPage === 0 ? "pointer-events-none opacity-50" : ""
|
className={`cursor-pointer px-2 py-1 shadow rounded-sm text-sm bg-slate-200 hover:border-[var(--primary)] transition-all duration-300 ${currentPage == 0 ? "pointer-events-none opacity-50" : ""
|
||||||
}`}
|
}`}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
if (currentPage === 0) e.preventDefault();
|
if (currentPage == 0) e.preventDefault();
|
||||||
else setCurrentPage(currentPage - 1);
|
else setCurrentPage(currentPage - 1);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|
@ -245,10 +254,10 @@ const LeftSideBar: React.FC<LeftSideBarProps> = ({ isFields, isPages, selectedRe
|
||||||
{/* Next Button */}
|
{/* Next Button */}
|
||||||
<a
|
<a
|
||||||
href={"#" + document.id + (currentPage + 1)}
|
href={"#" + document.id + (currentPage + 1)}
|
||||||
className={`cursor-pointer px-2 py-1 shadow rounded-sm text-sm bg-slate-200 hover:border-[var(--primary)] transition-all duration-300 ${currentPage === document.pages?.length - 1 ? "pointer-events-none opacity-50" : ""
|
className={`cursor-pointer px-2 py-1 shadow rounded-sm text-sm bg-slate-200 hover:border-[var(--primary)] transition-all duration-300 ${currentPage == document.pages?.length - 1 ? "pointer-events-none opacity-50" : ""
|
||||||
}`}
|
}`}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
if (currentPage === document.pages?.length - 1) e.preventDefault();
|
if (currentPage == document.pages?.length - 1) e.preventDefault();
|
||||||
else setCurrentPage(currentPage + 1);
|
else setCurrentPage(currentPage + 1);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|
@ -266,8 +275,59 @@ const LeftSideBar: React.FC<LeftSideBarProps> = ({ isFields, isPages, selectedRe
|
||||||
</>}
|
</>}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
{/* Left Side Bar - END */}
|
{/* Left Side Bar - END */}
|
||||||
|
|
||||||
|
{/* Small Devices - START */}
|
||||||
|
|
||||||
|
|
||||||
|
<div>
|
||||||
|
|
||||||
|
{/* Left Side Pages */}
|
||||||
|
{!isPages && <div
|
||||||
|
onClick={() => {
|
||||||
|
handleSetIsPages(true)
|
||||||
|
handleSetIsFields(false)
|
||||||
|
}}
|
||||||
|
className='sm:hidden fixed top-[8%] left-0 bg-[var(--primary)] z-50 flex items-center text-white rounded-tr-md rounded-br-md cursor-pointer opacity-30 hover:opacity-100 transition-all duration-300'>
|
||||||
|
<div className='py-2'>
|
||||||
|
<FaAngleUp className='rotate-90' />
|
||||||
|
<p className='flex flex-col justify-center items-center text-xs tracking-widest mt-1 pt-1 border-t-1 border-white'>
|
||||||
|
<span>P</span>
|
||||||
|
<span>A</span>
|
||||||
|
<span>G</span>
|
||||||
|
<span>E</span>
|
||||||
|
<span>S</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>}
|
||||||
|
|
||||||
|
|
||||||
|
<div
|
||||||
|
className='sm:hidden fixed bottom-0 left-0 rounded-tr-md rounded-tl-md bg-[var(--primary)] z-50 w-full flex justify-center text-white cursor-pointer opacity-30 hover:opacity-100 transition-all duration-300'
|
||||||
|
onClick={() => {
|
||||||
|
handleSetIsPages(false)
|
||||||
|
handleSetIsFields(true)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className='flex'>
|
||||||
|
<FaAngleUp />
|
||||||
|
<p className='flex justify-center items-center text-xs tracking-widest ml-1 pl-1 border-l-1 border-white'>
|
||||||
|
<span>T</span>
|
||||||
|
<span>A</span>
|
||||||
|
<span>G</span>
|
||||||
|
<span>S</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
{/* Small Devices - END */}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,7 @@ const NavTwo: React.FC<NavTwoProps> = ({
|
||||||
}
|
}
|
||||||
|
|
||||||
// If is preview is enable
|
// If is preview is enable
|
||||||
if (isPreview && aId !== null && tId !== null) {
|
if (isPreview && aId != null && tId != null) {
|
||||||
accountId = aId;
|
accountId = aId;
|
||||||
transactionId = tId;
|
transactionId = tId;
|
||||||
}
|
}
|
||||||
|
|
@ -113,8 +113,8 @@ const NavTwo: React.FC<NavTwoProps> = ({
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedRecipients.length || selectedDocuments.length) return;
|
if (selectedRecipients.length || selectedDocuments.length) return;
|
||||||
(async () => {
|
(async () => {
|
||||||
selectedRecipients.length === 0 && await dispatch(fetchRecipients({ accountId, transactionId }));
|
selectedRecipients.length == 0 && await dispatch(fetchRecipients({ accountId, transactionId }));
|
||||||
selectedDocuments.length === 0 && await dispatch(fetchDocuments({ accountId, transactionId }));
|
selectedDocuments.length == 0 && await dispatch(fetchDocuments({ accountId, transactionId }));
|
||||||
})()
|
})()
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
|
@ -134,7 +134,7 @@ const NavTwo: React.FC<NavTwoProps> = ({
|
||||||
minRoutingOrder = recipient.routingOrder;
|
minRoutingOrder = recipient.routingOrder;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (recipient.email === userDetails.email) {
|
if (recipient.email == userDetails.email) {
|
||||||
userEmailPresent.present = true;
|
userEmailPresent.present = true;
|
||||||
userEmailPresent.routingOrder = recipient.routingOrder;
|
userEmailPresent.routingOrder = recipient.routingOrder;
|
||||||
userEmailPresent.recipientId = recipient.id;
|
userEmailPresent.recipientId = recipient.id;
|
||||||
|
|
@ -142,7 +142,7 @@ const NavTwo: React.FC<NavTwoProps> = ({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (userEmailPresent.present && userEmailPresent.routingOrder === minRoutingOrder && userEmailPresent.type !== recipientType.CC && userEmailPresent.type !== recipientType.INPERSONSIGNER) {
|
if (userEmailPresent.present && userEmailPresent.routingOrder == minRoutingOrder && userEmailPresent.type != recipientType.CC && userEmailPresent.type != recipientType.INPERSONSIGNER) {
|
||||||
setSelfUserSign({ sign: true, recipientId: userEmailPresent.recipientId })
|
setSelfUserSign({ sign: true, recipientId: userEmailPresent.recipientId })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -177,13 +177,13 @@ const NavTwo: React.FC<NavTwoProps> = ({
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (isSend === null) {
|
// if (isSend == null) {
|
||||||
// setIsSend(false);
|
// setIsSend(false);
|
||||||
// }
|
// }
|
||||||
// setIsSend(!isSend);
|
// setIsSend(!isSend);
|
||||||
|
|
||||||
// setTimeout(() => {
|
// setTimeout(() => {
|
||||||
if (transactionTemplateToggle === TRANSACTION_TEMPLATE_TOGGLE.TRANSACTIONS) {
|
if (transactionTemplateToggle == TRANSACTION_TEMPLATE_TOGGLE.TRANSACTIONS) {
|
||||||
if (isSignSend) {
|
if (isSignSend) {
|
||||||
window.open(`./../../../sign/${selfUserSign.recipientId}`, "_self");
|
window.open(`./../../../sign/${selfUserSign.recipientId}`, "_self");
|
||||||
}
|
}
|
||||||
|
|
@ -205,7 +205,7 @@ const NavTwo: React.FC<NavTwoProps> = ({
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let indx = fitObj[selFitIndx].value
|
let indx = fitObj[selFitIndx].value
|
||||||
if (indx === "FIT") {
|
if (indx == "FIT") {
|
||||||
indx = "100";
|
indx = "100";
|
||||||
}
|
}
|
||||||
zoom(Number(indx), 'zoom-con')
|
zoom(Number(indx), 'zoom-con')
|
||||||
|
|
@ -263,7 +263,7 @@ const NavTwo: React.FC<NavTwoProps> = ({
|
||||||
|
|
||||||
className='flex items-center justify-between w-full'>
|
className='flex items-center justify-between w-full'>
|
||||||
<p className='whitespace-nowrap overflow-hidden text-ellipsis max-w-[12ch]'>{val.label}</p>
|
<p className='whitespace-nowrap overflow-hidden text-ellipsis max-w-[12ch]'>{val.label}</p>
|
||||||
{selFitIndx === indx && <FaCheck className='text-sm text-slate-400' />}
|
{selFitIndx == indx && <FaCheck className='text-sm text-slate-400' />}
|
||||||
</div>
|
</div>
|
||||||
</div>)
|
</div>)
|
||||||
})
|
})
|
||||||
|
|
@ -387,11 +387,11 @@ const NavTwo: React.FC<NavTwoProps> = ({
|
||||||
onClick={() => handleSend()}
|
onClick={() => handleSend()}
|
||||||
className='flex items-center gap-2 cursor-pointer text-xs px-4 py-2 ml-3 rounded-sm bg-[var(--primary)]'>
|
className='flex items-center gap-2 cursor-pointer text-xs px-4 py-2 ml-3 rounded-sm bg-[var(--primary)]'>
|
||||||
<p className='tracking-wide text-white'>
|
<p className='tracking-wide text-white'>
|
||||||
{transactionTemplateToggle === TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES ? "Save" : "Send"}
|
{transactionTemplateToggle == TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES ? "Save" : "Send"}
|
||||||
</p>
|
</p>
|
||||||
<FaSignature className='text-white text-md' />
|
<FaSignature className='text-white text-md' />
|
||||||
</div>
|
</div>
|
||||||
{/* {transactionTemplateToggle !== TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES && selfUserSign.sign && <div
|
{/* {transactionTemplateToggle != TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES && selfUserSign.sign && <div
|
||||||
id='send-and-sign-dash-btn'
|
id='send-and-sign-dash-btn'
|
||||||
onClick={() => handleSend(selfUserSign.sign)}
|
onClick={() => handleSend(selfUserSign.sign)}
|
||||||
className='flex items-center gap-2 cursor-pointer text-xs px-4 py-2 ml-3 rounded-sm bg-[var(--primary)]'>
|
className='flex items-center gap-2 cursor-pointer text-xs px-4 py-2 ml-3 rounded-sm bg-[var(--primary)]'>
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,12 @@ import LeftSideBar from './LeftSideBar';
|
||||||
import DocumentContainer, { DocumentContainerRef } from './DocumentContainer';
|
import DocumentContainer, { DocumentContainerRef } from './DocumentContainer';
|
||||||
|
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
import { RootState } from '../../../store/store';
|
import { AppDispatch, RootState } from '../../../store/store';
|
||||||
import Loader from '../../dashboard/Loader';
|
import Loader from '../../dashboard/Loader';
|
||||||
import { hideLoader } from '../../../store/slices/loaderSlice';
|
import { hideLoader } from '../../../store/slices/loaderSlice';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate, useParams } from 'react-router-dom';
|
||||||
import api from '../../../config/api';
|
import api from '../../../config/api';
|
||||||
|
import { toggleToTemplates, TRANSACTION_TEMPLATE_TOGGLE } from '../../../store/slices/selectedRecipientsSlice';
|
||||||
|
|
||||||
export interface IsSendInterface {
|
export interface IsSendInterface {
|
||||||
send: boolean | null;
|
send: boolean | null;
|
||||||
|
|
@ -17,6 +18,23 @@ export interface IsSendInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProcessStepTwo = () => {
|
const ProcessStepTwo = () => {
|
||||||
|
let transactionTemplateToggle = TRANSACTION_TEMPLATE_TOGGLE.TRANSACTIONS;
|
||||||
|
const dispatch = useDispatch();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
const params = useParams<{ accountId?: string; transactionId?: string; templateId?: string }>();
|
||||||
|
let accountId = params.accountId;
|
||||||
|
let transactionId = params.transactionId
|
||||||
|
if (!transactionId) {
|
||||||
|
transactionTemplateToggle = TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES;
|
||||||
|
transactionId = params.templateId;
|
||||||
|
dispatch(toggleToTemplates());
|
||||||
|
}
|
||||||
|
if (!accountId || !transactionId) {
|
||||||
|
window.location.href = "/";
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const windowWidth = window.innerWidth;
|
const windowWidth = window.innerWidth;
|
||||||
|
|
||||||
const [isFields, setIsFields] = useState(windowWidth > 638 ? true : false);
|
const [isFields, setIsFields] = useState(windowWidth > 638 ? true : false);
|
||||||
|
|
@ -28,8 +46,7 @@ const ProcessStepTwo = () => {
|
||||||
|
|
||||||
const [isSend, setIsSend] = useState<boolean | null>(null);
|
const [isSend, setIsSend] = useState<boolean | null>(null);
|
||||||
const globalLoader = useSelector((state: RootState) => state.loader)
|
const globalLoader = useSelector((state: RootState) => state.loader)
|
||||||
const dispatch = useDispatch();
|
|
||||||
const navigate = useNavigate();
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
|
@ -37,20 +54,34 @@ const ProcessStepTwo = () => {
|
||||||
}, 800)
|
}, 800)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
(async () => {
|
||||||
|
try {
|
||||||
|
const res = await api.get(`/api/v1/accounts/${accountId}/${transactionTemplateToggle}/${transactionId}`);
|
||||||
|
if (res.data.status === "COMPLETED" || res.data.status === "SENT") {
|
||||||
|
navigate("/")
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
})()
|
||||||
|
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
|
||||||
const handleSetIsFields = (setTo: boolean) => {
|
const handleSetIsFields = (setTo: boolean) => {
|
||||||
if (setTo !== undefined && setTo !== isFields) {
|
if (setTo != undefined && setTo != isFields) {
|
||||||
setIsFields(setTo)
|
setIsFields(setTo)
|
||||||
if (setTo === true) {
|
if (setTo == true) {
|
||||||
setIsPages(false)
|
setIsPages(false)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleSetIsPages = (setTo: boolean) => {
|
const handleSetIsPages = (setTo: boolean) => {
|
||||||
if (setTo !== undefined && setTo !== isPages) {
|
if (setTo != undefined && setTo != isPages) {
|
||||||
setIsPages(setTo)
|
setIsPages(setTo)
|
||||||
if (setTo === true) {
|
if (setTo == true) {
|
||||||
setIsFields(false)
|
setIsFields(false)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -110,14 +110,14 @@ const RightSideBar: React.FC<DroppedItemProps> = (
|
||||||
const [styleOpen, setStyleOpen] = useState(false);
|
const [styleOpen, setStyleOpen] = useState(false);
|
||||||
|
|
||||||
const handlePropertyChange = (changeTo: string, changeWith: string | boolean | number | StylesInterface, is24Hrs = null) => {
|
const handlePropertyChange = (changeTo: string, changeWith: string | boolean | number | StylesInterface, is24Hrs = null) => {
|
||||||
if (changeTo === '') return
|
if (changeTo == '') return
|
||||||
|
|
||||||
if (!signClient) {
|
if (!signClient) {
|
||||||
setDroppedItems((prev) => {
|
setDroppedItems((prev) => {
|
||||||
|
|
||||||
const updatedItems = Array.isArray(prev[selTagKey])
|
const updatedItems = Array.isArray(prev[selTagKey])
|
||||||
? prev[selTagKey].map((item, i) =>
|
? prev[selTagKey].map((item, i) =>
|
||||||
i === selTagIndx ? { ...item, [changeTo]: changeWith, update: true } : item
|
i == selTagIndx ? { ...item, [changeTo]: changeWith, update: true } : item
|
||||||
)
|
)
|
||||||
: [];
|
: [];
|
||||||
|
|
||||||
|
|
@ -129,7 +129,7 @@ const RightSideBar: React.FC<DroppedItemProps> = (
|
||||||
} else {
|
} else {
|
||||||
setDroppedItems((prev) => {
|
setDroppedItems((prev) => {
|
||||||
return (prev.map((item, idx) => {
|
return (prev.map((item, idx) => {
|
||||||
if (idx === selTagIndx) {
|
if (idx == selTagIndx) {
|
||||||
return { ...item, [changeTo]: changeWith, update: true }
|
return { ...item, [changeTo]: changeWith, update: true }
|
||||||
}
|
}
|
||||||
return item;
|
return item;
|
||||||
|
|
@ -141,12 +141,12 @@ const RightSideBar: React.FC<DroppedItemProps> = (
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedTag.label === "temporal" && !("dateFormat" in selectedTag)) {
|
if (selectedTag.label == "temporal" && !("dateFormat" in selectedTag)) {
|
||||||
handlePropertyChange("dateFormat", TEMPORAL.DATE);
|
handlePropertyChange("dateFormat", TEMPORAL.DATE);
|
||||||
handlePropertyChange("format", "DD/MM/YY");
|
handlePropertyChange("format", "DD/MM/YY");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selectedTag.label === TagsTypes.TEXT && !("multiLine" in selectedTag)) {
|
if (selectedTag.label == TagsTypes.TEXT && !("multiLine" in selectedTag)) {
|
||||||
handlePropertyChange("multiLine", true);
|
handlePropertyChange("multiLine", true);
|
||||||
}
|
}
|
||||||
}, [selectedTag])
|
}, [selectedTag])
|
||||||
|
|
@ -158,8 +158,8 @@ const RightSideBar: React.FC<DroppedItemProps> = (
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedTag.decimalPlace === undefined) return;
|
if (selectedTag.decimalPlace == undefined) return;
|
||||||
if (selectedTag.decimalPlace === decimalPlace) return;
|
if (selectedTag.decimalPlace == decimalPlace) return;
|
||||||
setDecimalPlace(selectedTag.decimalPlace ?? 0)
|
setDecimalPlace(selectedTag.decimalPlace ?? 0)
|
||||||
}, [selectedTag.decimalPlace ?? 0])
|
}, [selectedTag.decimalPlace ?? 0])
|
||||||
|
|
||||||
|
|
@ -214,7 +214,7 @@ const RightSideBar: React.FC<DroppedItemProps> = (
|
||||||
...droppedItems,
|
...droppedItems,
|
||||||
[selTagKey]: Array.isArray(droppedItems[selTagKey])
|
[selTagKey]: Array.isArray(droppedItems[selTagKey])
|
||||||
? droppedItems[selTagKey].map((item, i) =>
|
? droppedItems[selTagKey].map((item, i) =>
|
||||||
i === selTagIndx
|
i == selTagIndx
|
||||||
? { ...item, dimensions: { ...item.dimensions, left: newLeft, top: newTop }, update: true }
|
? { ...item, dimensions: { ...item.dimensions, left: newLeft, top: newTop }, update: true }
|
||||||
: item
|
: item
|
||||||
)
|
)
|
||||||
|
|
@ -249,7 +249,7 @@ const RightSideBar: React.FC<DroppedItemProps> = (
|
||||||
...droppedItems,
|
...droppedItems,
|
||||||
[selTagKey]: Array.isArray(droppedItems[selTagKey])
|
[selTagKey]: Array.isArray(droppedItems[selTagKey])
|
||||||
? droppedItems[selTagKey].map((item, i) =>
|
? droppedItems[selTagKey].map((item, i) =>
|
||||||
i === selTagIndx
|
i == selTagIndx
|
||||||
? {
|
? {
|
||||||
...item,
|
...item,
|
||||||
dimensions: {
|
dimensions: {
|
||||||
|
|
@ -306,12 +306,12 @@ const RightSideBar: React.FC<DroppedItemProps> = (
|
||||||
<DirectionalControls {...DirectionalControlsProps} selectedType={selectedTag.dimensions} />
|
<DirectionalControls {...DirectionalControlsProps} selectedType={selectedTag.dimensions} />
|
||||||
|
|
||||||
{
|
{
|
||||||
(selectedTag.type !== TagsTypes.SIGNATURE && selectedTag.type !== TagsTypes.INITIALS) &&
|
(selectedTag.type != TagsTypes.SIGNATURE && selectedTag.type != TagsTypes.INITIALS) &&
|
||||||
<RequiredAttr required={selectedTag.required ? selectedTag.required : false} handlePropertyChange={handlePropertyChange} />
|
<RequiredAttr required={selectedTag.required ? selectedTag.required : false} handlePropertyChange={handlePropertyChange} />
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
selectedTag.type.toLowerCase() === TagsTypes.TEMPORAL &&
|
selectedTag.type.toLowerCase() == TagsTypes.TEMPORAL &&
|
||||||
<CurrTimeStampAttr type={selectedTag.type} handlePropertyChange={handlePropertyChange} />
|
<CurrTimeStampAttr type={selectedTag.type} handlePropertyChange={handlePropertyChange} />
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -342,7 +342,7 @@ const RightSideBar: React.FC<DroppedItemProps> = (
|
||||||
|
|
||||||
{/* Mask Type */}
|
{/* Mask Type */}
|
||||||
{
|
{
|
||||||
selectedTag.type.toLowerCase() === TagsTypes.TEXT &&
|
selectedTag.type.toLowerCase() == TagsTypes.TEXT &&
|
||||||
<TextValueFIll
|
<TextValueFIll
|
||||||
value={selectedTag.value ?? ""}
|
value={selectedTag.value ?? ""}
|
||||||
multiLine={selectedTag.multiLine ?? false}
|
multiLine={selectedTag.multiLine ?? false}
|
||||||
|
|
@ -352,9 +352,9 @@ const RightSideBar: React.FC<DroppedItemProps> = (
|
||||||
|
|
||||||
{/* TEMPORAL DATE FORMAT - START */}
|
{/* TEMPORAL DATE FORMAT - START */}
|
||||||
{
|
{
|
||||||
selectedTag && (selectedTag?.dateFormat === TEMPORAL.DATE ||
|
selectedTag && (selectedTag?.dateFormat == TEMPORAL.DATE ||
|
||||||
selectedTag?.dateFormat === TEMPORAL.TIME ||
|
selectedTag?.dateFormat == TEMPORAL.TIME ||
|
||||||
selectedTag?.dateFormat === TEMPORAL.DATE_TIME) &&
|
selectedTag?.dateFormat == TEMPORAL.DATE_TIME) &&
|
||||||
<TemporalDateAttr
|
<TemporalDateAttr
|
||||||
dateFormat={selectedTag.dateFormat ?? TEMPORAL.DATE_TIME}
|
dateFormat={selectedTag.dateFormat ?? TEMPORAL.DATE_TIME}
|
||||||
format={selectedTag.format}
|
format={selectedTag.format}
|
||||||
|
|
@ -367,7 +367,7 @@ const RightSideBar: React.FC<DroppedItemProps> = (
|
||||||
|
|
||||||
{/* NUMBER - DECIMAL PLACES */}
|
{/* NUMBER - DECIMAL PLACES */}
|
||||||
{
|
{
|
||||||
selectedTag?.type.toLowerCase() === TagsTypes.NUMBER &&
|
selectedTag?.type.toLowerCase() == TagsTypes.NUMBER &&
|
||||||
<div>
|
<div>
|
||||||
<label htmlFor="" className="font-medium">Decimal Places</label>
|
<label htmlFor="" className="font-medium">Decimal Places</label>
|
||||||
<input
|
<input
|
||||||
|
|
@ -379,7 +379,7 @@ const RightSideBar: React.FC<DroppedItemProps> = (
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
(selectedTag.type.toLowerCase() === TagsTypes.SELECT) &&
|
(selectedTag.type.toLowerCase() == TagsTypes.SELECT) &&
|
||||||
<SelectTagAttr
|
<SelectTagAttr
|
||||||
options={selectedTag.options ?? []}
|
options={selectedTag.options ?? []}
|
||||||
selTagKey={selTagKey}
|
selTagKey={selTagKey}
|
||||||
|
|
@ -390,11 +390,11 @@ const RightSideBar: React.FC<DroppedItemProps> = (
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
(selectedTag.type.toLowerCase() === TagsTypes.TEXT || selectedTag.type.toLowerCase() === TagsTypes.COMPANY) &&
|
(selectedTag.type.toLowerCase() == TagsTypes.TEXT || selectedTag.type.toLowerCase() == TagsTypes.COMPANY) &&
|
||||||
<MaxMinLenAttr maxLength={selectedTag.maxLength} minLength={selectedTag.minLength} handlePropertyChange={handlePropertyChange} />
|
<MaxMinLenAttr maxLength={selectedTag.maxLength} minLength={selectedTag.minLength} handlePropertyChange={handlePropertyChange} />
|
||||||
}
|
}
|
||||||
|
|
||||||
{(selectedTag.type.toLowerCase() !== TagsTypes.SIGNATURE && selectedTag.type.toLowerCase() !== TagsTypes.INITIALS) &&
|
{(selectedTag.type.toLowerCase() != TagsTypes.SIGNATURE && selectedTag.type.toLowerCase() != TagsTypes.INITIALS) &&
|
||||||
<div className="">
|
<div className="">
|
||||||
<div className="flex items-center justify-between mr-2 cursor-pointer"
|
<div className="flex items-center justify-between mr-2 cursor-pointer"
|
||||||
onClick={() => setStyleOpen(!styleOpen)}
|
onClick={() => setStyleOpen(!styleOpen)}
|
||||||
|
|
|
||||||
|
|
@ -21,13 +21,13 @@ const CommonAttrDropDown: React.FC<CommonAttrDropDownInt> = ({ selectedType, sel
|
||||||
|
|
||||||
switch (selectedTag.type.toLowerCase()) {
|
switch (selectedTag.type.toLowerCase()) {
|
||||||
case "number":
|
case "number":
|
||||||
if (selectedTag.decimalPlace === undefined) {
|
if (selectedTag.decimalPlace == undefined) {
|
||||||
subType = NUMBER.INTEGER;
|
subType = NUMBER.INTEGER;
|
||||||
subTypeKey = "decimalPlace";
|
subTypeKey = "decimalPlace";
|
||||||
} else if (selectedTag.isCurrency !== undefined && selectedTag.isCurrency) {
|
} else if (selectedTag.isCurrency != undefined && selectedTag.isCurrency) {
|
||||||
subType = NUMBER.CURRENCY;
|
subType = NUMBER.CURRENCY;
|
||||||
subTypeKey = "isCurrency";
|
subTypeKey = "isCurrency";
|
||||||
} else if (selectedTag.decimalPlace === 0) {
|
} else if (selectedTag.decimalPlace == 0) {
|
||||||
subType = NUMBER.INTEGER;
|
subType = NUMBER.INTEGER;
|
||||||
subTypeKey = "decimalPlace";
|
subTypeKey = "decimalPlace";
|
||||||
} else if (selectedTag.decimalPlace > 0) {
|
} else if (selectedTag.decimalPlace > 0) {
|
||||||
|
|
@ -36,7 +36,7 @@ const CommonAttrDropDown: React.FC<CommonAttrDropDownInt> = ({ selectedType, sel
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "text":
|
case "text":
|
||||||
if (selectedTag.multiLine === undefined) {
|
if (selectedTag.multiLine == undefined) {
|
||||||
subType = TEXT.PARAGRAPH
|
subType = TEXT.PARAGRAPH
|
||||||
} else if (selectedTag.multiLine) {
|
} else if (selectedTag.multiLine) {
|
||||||
subType = TEXT.PARAGRAPH;
|
subType = TEXT.PARAGRAPH;
|
||||||
|
|
@ -44,12 +44,12 @@ const CommonAttrDropDown: React.FC<CommonAttrDropDownInt> = ({ selectedType, sel
|
||||||
subType = TEXT.SINGLE_LINE;
|
subType = TEXT.SINGLE_LINE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("maskType" in selectedTag && selectedTag.maskType !== null && selectedTag.maskType?.length) subType = TEXT.PASSWORD;
|
if ("maskType" in selectedTag && selectedTag.maskType != null && selectedTag.maskType?.length) subType = TEXT.PASSWORD;
|
||||||
|
|
||||||
subTypeKey = "multiLine";
|
subTypeKey = "multiLine";
|
||||||
break;
|
break;
|
||||||
case "temporal":
|
case "temporal":
|
||||||
if (selectedTag.dateFormat === undefined) {
|
if (selectedTag.dateFormat == undefined) {
|
||||||
subType = TEMPORAL.DATE;
|
subType = TEMPORAL.DATE;
|
||||||
} else {
|
} else {
|
||||||
subType = TEMPORAL[selectedTag.dateFormat.toUpperCase() as keyof typeof TEMPORAL];
|
subType = TEMPORAL[selectedTag.dateFormat.toUpperCase() as keyof typeof TEMPORAL];
|
||||||
|
|
@ -57,7 +57,7 @@ const CommonAttrDropDown: React.FC<CommonAttrDropDownInt> = ({ selectedType, sel
|
||||||
subTypeKey = "dateFormat";
|
subTypeKey = "dateFormat";
|
||||||
break;
|
break;
|
||||||
case "select":
|
case "select":
|
||||||
if (selectedTag.multiSelect !== undefined && selectedTag.multiSelect) {
|
if (selectedTag.multiSelect != undefined && selectedTag.multiSelect) {
|
||||||
subType = SELECT.MULTI_SELECT;
|
subType = SELECT.MULTI_SELECT;
|
||||||
} else {
|
} else {
|
||||||
subType = SELECT.SINGLE_SELECT;
|
subType = SELECT.SINGLE_SELECT;
|
||||||
|
|
@ -76,14 +76,14 @@ const CommonAttrDropDown: React.FC<CommonAttrDropDownInt> = ({ selectedType, sel
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<label htmlFor="" className="font-medium">Type</label>
|
<label htmlFor="" className="font-medium">Type</label>
|
||||||
<div
|
<div
|
||||||
onClick={() => setDropDownToggle(dropDownToggle === DROPDOWNTOGGLE.TYPE ? null : DROPDOWNTOGGLE.TYPE)}
|
onClick={() => setDropDownToggle(dropDownToggle == DROPDOWNTOGGLE.TYPE ? null : DROPDOWNTOGGLE.TYPE)}
|
||||||
className="flex justify-between items-center border-1 rounded px-2 py-1 border-slate-200">
|
className="flex justify-between items-center border-1 rounded px-2 py-1 border-slate-200">
|
||||||
<p className="capitalize cursor-pointer">{subType}</p>
|
<p className="capitalize cursor-pointer">{subType}</p>
|
||||||
{/* <p className="capitalize cursor-pointer">{subType ? (subType === "date_time" ? "Date Time" : subType) : selectedType[Object.keys(selectedType)[0] as keyof typeof selectedType]}</p> */}
|
{/* <p className="capitalize cursor-pointer">{subType ? (subType == "date_time" ? "Date Time" : subType) : selectedType[Object.keys(selectedType)[0] as keyof typeof selectedType]}</p> */}
|
||||||
<MdKeyboardArrowDown />
|
<MdKeyboardArrowDown />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{dropDownToggle === DROPDOWNTOGGLE.TYPE &&
|
{dropDownToggle == DROPDOWNTOGGLE.TYPE &&
|
||||||
<div className="shadow bg-slate-100 mt-1 border-[1px] border-slate-100 rounded">
|
<div className="shadow bg-slate-100 mt-1 border-[1px] border-slate-100 rounded">
|
||||||
{Object.keys(selectedType).map((val, indx) => {
|
{Object.keys(selectedType).map((val, indx) => {
|
||||||
|
|
||||||
|
|
@ -92,20 +92,20 @@ const CommonAttrDropDown: React.FC<CommonAttrDropDownInt> = ({ selectedType, sel
|
||||||
let isPassword = false;
|
let isPassword = false;
|
||||||
|
|
||||||
// Handling NUMBER - START
|
// Handling NUMBER - START
|
||||||
if (value === NUMBER.INTEGER || value === NUMBER.CURRENCY) {
|
if (value == NUMBER.INTEGER || value == NUMBER.CURRENCY) {
|
||||||
if (value === NUMBER.CURRENCY) {
|
if (value == NUMBER.CURRENCY) {
|
||||||
isCurrency = true;
|
isCurrency = true;
|
||||||
}
|
}
|
||||||
value = 0;
|
value = 0;
|
||||||
}
|
}
|
||||||
if (value === NUMBER.DECIMAL) {
|
if (value == NUMBER.DECIMAL) {
|
||||||
value = selectedTag.decimalPlace ?? 0 > 0 ? selectedTag.decimalPlace ?? 2 : 2;
|
value = selectedTag.decimalPlace ?? 0 > 0 ? selectedTag.decimalPlace ?? 2 : 2;
|
||||||
}
|
}
|
||||||
// Handling NUMBER - END
|
// Handling NUMBER - END
|
||||||
|
|
||||||
// Handling SELECT - START
|
// Handling SELECT - START
|
||||||
if (subTypeKey === "multiSelect") {
|
if (subTypeKey == "multiSelect") {
|
||||||
if (value === "multi_select") {
|
if (value == "multi_select") {
|
||||||
value = true;
|
value = true;
|
||||||
} else {
|
} else {
|
||||||
value = false
|
value = false
|
||||||
|
|
@ -114,14 +114,14 @@ const CommonAttrDropDown: React.FC<CommonAttrDropDownInt> = ({ selectedType, sel
|
||||||
// Handling SELECT - END
|
// Handling SELECT - END
|
||||||
|
|
||||||
// Handling TEXT - START
|
// Handling TEXT - START
|
||||||
if (subTypeKey === "multiLine") {
|
if (subTypeKey == "multiLine") {
|
||||||
if (value === "single_line") {
|
if (value == "single_line") {
|
||||||
value = false;
|
value = false;
|
||||||
} else {
|
} else {
|
||||||
value = true;
|
value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (val.toLowerCase() === TEXT.PASSWORD) {
|
if (val.toLowerCase() == TEXT.PASSWORD) {
|
||||||
isPassword = true;
|
isPassword = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -131,7 +131,7 @@ const CommonAttrDropDown: React.FC<CommonAttrDropDownInt> = ({ selectedType, sel
|
||||||
<div
|
<div
|
||||||
key={indx}
|
key={indx}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (selectedTag.type.toLowerCase() === TagsTypes.NUMBER) {
|
if (selectedTag.type.toLowerCase() == TagsTypes.NUMBER) {
|
||||||
if (isCurrency) {
|
if (isCurrency) {
|
||||||
handlePropertyChange("isCurrency", true);
|
handlePropertyChange("isCurrency", true);
|
||||||
return;
|
return;
|
||||||
|
|
@ -139,11 +139,11 @@ const CommonAttrDropDown: React.FC<CommonAttrDropDownInt> = ({ selectedType, sel
|
||||||
handlePropertyChange(subTypeKey, value as number);
|
handlePropertyChange(subTypeKey, value as number);
|
||||||
if (selectedTag.isCurrency) handlePropertyChange("isCurrency", false)
|
if (selectedTag.isCurrency) handlePropertyChange("isCurrency", false)
|
||||||
|
|
||||||
} else if (selectedTag.type.toLowerCase() === TagsTypes.SELECT) {
|
} else if (selectedTag.type.toLowerCase() == TagsTypes.SELECT) {
|
||||||
|
|
||||||
handlePropertyChange(subTypeKey, value as boolean);
|
handlePropertyChange(subTypeKey, value as boolean);
|
||||||
|
|
||||||
} else if (selectedTag.type.toLowerCase() === TagsTypes.TEXT) {
|
} else if (selectedTag.type.toLowerCase() == TagsTypes.TEXT) {
|
||||||
if (isPassword) {
|
if (isPassword) {
|
||||||
handlePropertyChange("maskType", MASKTYPE.ALL.toUpperCase());
|
handlePropertyChange("maskType", MASKTYPE.ALL.toUpperCase());
|
||||||
handlePropertyChange("maskCharacter", MASKCHARACTER.ASTERISK.toUpperCase());
|
handlePropertyChange("maskCharacter", MASKCHARACTER.ASTERISK.toUpperCase());
|
||||||
|
|
@ -154,9 +154,9 @@ const CommonAttrDropDown: React.FC<CommonAttrDropDownInt> = ({ selectedType, sel
|
||||||
|
|
||||||
}
|
}
|
||||||
handlePropertyChange(subTypeKey, value as boolean);
|
handlePropertyChange(subTypeKey, value as boolean);
|
||||||
} else if (selectedTag.type.toLowerCase() === TagsTypes.TEMPORAL) {
|
} else if (selectedTag.type.toLowerCase() == TagsTypes.TEMPORAL) {
|
||||||
handlePropertyChange(subTypeKey, selectedType[val as keyof typeof selectedType]);
|
handlePropertyChange(subTypeKey, selectedType[val as keyof typeof selectedType]);
|
||||||
if (subTypeKey === "dateFormat") {
|
if (subTypeKey == "dateFormat") {
|
||||||
let format = null;
|
let format = null;
|
||||||
switch (value) {
|
switch (value) {
|
||||||
case "date":
|
case "date":
|
||||||
|
|
@ -180,7 +180,7 @@ const CommonAttrDropDown: React.FC<CommonAttrDropDownInt> = ({ selectedType, sel
|
||||||
}}
|
}}
|
||||||
className={`capitalize px-2 py-1 hover:bg-slate-200 cursor-pointer`}
|
className={`capitalize px-2 py-1 hover:bg-slate-200 cursor-pointer`}
|
||||||
>
|
>
|
||||||
{selectedType[val as keyof typeof selectedType] === "date_time" ? "Date Time" : selectedType[val as keyof typeof selectedType]}
|
{selectedType[val as keyof typeof selectedType] == "date_time" ? "Date Time" : selectedType[val as keyof typeof selectedType]}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ const CurrTimeStampAttr: React.FC<CurrTimeStampAttrInt> = ({ type, handlePropert
|
||||||
const [isCurrentTimeStamp, setIsCurrentTimeStamp] = useState<boolean>(true);
|
const [isCurrentTimeStamp, setIsCurrentTimeStamp] = useState<boolean>(true);
|
||||||
|
|
||||||
const handleIsCurrentTimeStamp = (checked: boolean) => {
|
const handleIsCurrentTimeStamp = (checked: boolean) => {
|
||||||
if (type.toLowerCase() === "temporal") {
|
if (type.toLowerCase() == "temporal") {
|
||||||
setIsCurrentTimeStamp(checked)
|
setIsCurrentTimeStamp(checked)
|
||||||
handlePropertyChange("currentTimeStamp", checked);
|
handlePropertyChange("currentTimeStamp", checked);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,14 +45,14 @@ const DirectionalControls: React.FC<DirectionalControlsProps> = ({
|
||||||
};
|
};
|
||||||
|
|
||||||
const handlePositionInputChange = (type: 'left' | 'top', value: string) => {
|
const handlePositionInputChange = (type: 'left' | 'top', value: string) => {
|
||||||
if (type === 'left') setLeftValue(value);
|
if (type == 'left') setLeftValue(value);
|
||||||
else setTopValue(value);
|
else setTopValue(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handlePositionInputBlur = (type: 'left' | 'top') => {
|
const handlePositionInputBlur = (type: 'left' | 'top') => {
|
||||||
if (!onPositionChange) return;
|
if (!onPositionChange) return;
|
||||||
|
|
||||||
const numericValue = parseFloat(type === 'left' ? leftValue : topValue);
|
const numericValue = parseFloat(type == 'left' ? leftValue : topValue);
|
||||||
if (isNaN(numericValue)) {
|
if (isNaN(numericValue)) {
|
||||||
const { top = 0, left = 0 } = selectedType || {};
|
const { top = 0, left = 0 } = selectedType || {};
|
||||||
setLeftValue(Math.round(left).toString());
|
setLeftValue(Math.round(left).toString());
|
||||||
|
|
@ -61,14 +61,14 @@ const DirectionalControls: React.FC<DirectionalControlsProps> = ({
|
||||||
}
|
}
|
||||||
|
|
||||||
const { top = 0, left = 0 } = selectedType || {};
|
const { top = 0, left = 0 } = selectedType || {};
|
||||||
const newLeft = type === 'left' ? numericValue : left;
|
const newLeft = type == 'left' ? numericValue : left;
|
||||||
const newTop = type === 'top' ? numericValue : top;
|
const newTop = type == 'top' ? numericValue : top;
|
||||||
|
|
||||||
onPositionChange(newLeft, newTop);
|
onPositionChange(newLeft, newTop);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleKeyPress = (e: React.KeyboardEvent, type: 'left' | 'top') => {
|
const handleKeyPress = (e: React.KeyboardEvent, type: 'left' | 'top') => {
|
||||||
if (e.key === 'Enter') {
|
if (e.key == 'Enter') {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
handlePositionInputBlur(type)
|
handlePositionInputBlur(type)
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -19,14 +19,14 @@ const MaskTypePassAttr: React.FC<MaskTypePassAttrInt> = ({ maskType, maskCharact
|
||||||
<div>
|
<div>
|
||||||
<label htmlFor="" className="">Mask Type</label>
|
<label htmlFor="" className="">Mask Type</label>
|
||||||
<div
|
<div
|
||||||
onClick={() => setDropDownToggle(dropDownToggle === DROPDOWNTOGGLE.MASK_TYPE ? null : DROPDOWNTOGGLE.MASK_TYPE)}
|
onClick={() => setDropDownToggle(dropDownToggle == DROPDOWNTOGGLE.MASK_TYPE ? null : DROPDOWNTOGGLE.MASK_TYPE)}
|
||||||
className="flex justify-between items-center border-1 rounded px-2 py-1 border-slate-200">
|
className="flex justify-between items-center border-1 rounded px-2 py-1 border-slate-200">
|
||||||
<p className="capitalize cursor-pointer">{(maskType && maskType.replace("_", " ")) ? maskType : MASKTYPE.ALL}</p>
|
<p className="capitalize cursor-pointer">{(maskType && maskType.replace("_", " ")) ? maskType : MASKTYPE.ALL}</p>
|
||||||
<MdKeyboardArrowDown />
|
<MdKeyboardArrowDown />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{
|
{
|
||||||
dropDownToggle === DROPDOWNTOGGLE.MASK_TYPE &&
|
dropDownToggle == DROPDOWNTOGGLE.MASK_TYPE &&
|
||||||
<div className="shadow bg-slate-100 mt-1 border-[1px] border-slate-100 rounded">
|
<div className="shadow bg-slate-100 mt-1 border-[1px] border-slate-100 rounded">
|
||||||
{(Object.keys(MASKTYPE) as (keyof typeof MASKTYPE)[]).map((val, indx) =>
|
{(Object.keys(MASKTYPE) as (keyof typeof MASKTYPE)[]).map((val, indx) =>
|
||||||
(
|
(
|
||||||
|
|
@ -47,14 +47,14 @@ const MaskTypePassAttr: React.FC<MaskTypePassAttrInt> = ({ maskType, maskCharact
|
||||||
<div>
|
<div>
|
||||||
<label htmlFor="" className="">Mask Character</label>
|
<label htmlFor="" className="">Mask Character</label>
|
||||||
<div
|
<div
|
||||||
onClick={() => setDropDownToggle(dropDownToggle === DROPDOWNTOGGLE.MASK_CHARACTER ? null : DROPDOWNTOGGLE.MASK_CHARACTER)}
|
onClick={() => setDropDownToggle(dropDownToggle == DROPDOWNTOGGLE.MASK_CHARACTER ? null : DROPDOWNTOGGLE.MASK_CHARACTER)}
|
||||||
className="flex justify-between items-center border-1 rounded px-2 py-1 border-slate-200">
|
className="flex justify-between items-center border-1 rounded px-2 py-1 border-slate-200">
|
||||||
<p className="capitalize cursor-pointer py-1">
|
<p className="capitalize cursor-pointer py-1">
|
||||||
{maskCharacter
|
{maskCharacter
|
||||||
?
|
?
|
||||||
maskCharacter === MASKCHARACTER.ASTERISK && <LuAsterisk /> ||
|
maskCharacter == MASKCHARACTER.ASTERISK && <LuAsterisk /> ||
|
||||||
maskCharacter === MASKCHARACTER.DOT && <GoDotFill /> ||
|
maskCharacter == MASKCHARACTER.DOT && <GoDotFill /> ||
|
||||||
maskCharacter === MASKCHARACTER.X && <IoClose />
|
maskCharacter == MASKCHARACTER.X && <IoClose />
|
||||||
:
|
:
|
||||||
<LuAsterisk />
|
<LuAsterisk />
|
||||||
}
|
}
|
||||||
|
|
@ -65,7 +65,7 @@ const MaskTypePassAttr: React.FC<MaskTypePassAttrInt> = ({ maskType, maskCharact
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{
|
{
|
||||||
dropDownToggle === DROPDOWNTOGGLE.MASK_CHARACTER &&
|
dropDownToggle == DROPDOWNTOGGLE.MASK_CHARACTER &&
|
||||||
<div className="shadow bg-slate-100 mt-1 border-[1px] border-slate-100 rounded">
|
<div className="shadow bg-slate-100 mt-1 border-[1px] border-slate-100 rounded">
|
||||||
{(Object.keys(MASKCHARACTER) as (keyof typeof MASKCHARACTER)[]).map((val, indx) =>
|
{(Object.keys(MASKCHARACTER) as (keyof typeof MASKCHARACTER)[]).map((val, indx) =>
|
||||||
(
|
(
|
||||||
|
|
@ -75,15 +75,15 @@ const MaskTypePassAttr: React.FC<MaskTypePassAttrInt> = ({ maskType, maskCharact
|
||||||
className="capitalize p-2 hover:bg-slate-200 cursor-pointer"
|
className="capitalize p-2 hover:bg-slate-200 cursor-pointer"
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
MASKCHARACTER[val] === MASKCHARACTER.ASTERISK &&
|
MASKCHARACTER[val] == MASKCHARACTER.ASTERISK &&
|
||||||
<LuAsterisk />
|
<LuAsterisk />
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
MASKCHARACTER[val] === MASKCHARACTER.DOT &&
|
MASKCHARACTER[val] == MASKCHARACTER.DOT &&
|
||||||
<GoDotFill />
|
<GoDotFill />
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
MASKCHARACTER[val] === MASKCHARACTER.X &&
|
MASKCHARACTER[val] == MASKCHARACTER.X &&
|
||||||
<IoClose />
|
<IoClose />
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ const MaxMinLenAttr: React.FC<MaxMinLenAttrIntr> = ({ maxLength, minLength, hand
|
||||||
firstChangedField.current = 'maxLength';
|
firstChangedField.current = 'maxLength';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (firstChangedField.current === 'minLength' && newMax < minLength) {
|
if (firstChangedField.current == 'minLength' && newMax < minLength) {
|
||||||
alert(`Max Length must be greater than or equal to Min Length (${minLength})`);
|
alert(`Max Length must be greater than or equal to Min Length (${minLength})`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -29,7 +29,7 @@ const MaxMinLenAttr: React.FC<MaxMinLenAttrIntr> = ({ maxLength, minLength, hand
|
||||||
firstChangedField.current = 'minLength';
|
firstChangedField.current = 'minLength';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (firstChangedField.current === 'maxLength' && newMin > maxLength) {
|
if (firstChangedField.current == 'maxLength' && newMin > maxLength) {
|
||||||
alert(`Min Length must be less than or equal to Max Length (${maxLength})`);
|
alert(`Min Length must be less than or equal to Max Length (${maxLength})`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -56,8 +56,8 @@ const RecipientsAttrCon: React.FC<RecipientsAttrConIntr> = ({ selectedRecipientI
|
||||||
{/* <FaUserTie className='w-3 h-3 text-2xl mt-[1px]' style={{ color: selectedRecipient.color }} /> */}
|
{/* <FaUserTie className='w-3 h-3 text-2xl mt-[1px]' style={{ color: selectedRecipient.color }} /> */}
|
||||||
<p>
|
<p>
|
||||||
{
|
{
|
||||||
selectedRecipient.firstName.length === 0 && selectedRecipient.lastName.length === 0 ?
|
selectedRecipient.firstName.length == 0 && selectedRecipient.lastName.length == 0 ?
|
||||||
(selectedRecipient.email.length === 0 ? selectedRecipient.roleName : selectedRecipient.email) :
|
(selectedRecipient.email.length == 0 ? selectedRecipient.roleName : selectedRecipient.email) :
|
||||||
`${selectedRecipient.firstName + " " + selectedRecipient.lastName}`
|
`${selectedRecipient.firstName + " " + selectedRecipient.lastName}`
|
||||||
}
|
}
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -68,7 +68,7 @@ const RecipientsAttrCon: React.FC<RecipientsAttrConIntr> = ({ selectedRecipientI
|
||||||
<div
|
<div
|
||||||
className={`absolute w-full shadow-md rounded-md mt-1 px-2 py-1 z-20 bg-white ${dropDownToggle ? '' : 'hidden'}`}>
|
className={`absolute w-full shadow-md rounded-md mt-1 px-2 py-1 z-20 bg-white ${dropDownToggle ? '' : 'hidden'}`}>
|
||||||
{selectedRecipients.length && selectedRecipients.map((recipient, indx) => {
|
{selectedRecipients.length && selectedRecipients.map((recipient, indx) => {
|
||||||
if (recipient.type === recipientType.CC) return null; // Skip CC recipients
|
if (recipient.type == recipientType.CC) return null; // Skip CC recipients
|
||||||
return (<div
|
return (<div
|
||||||
key={indx}
|
key={indx}
|
||||||
className='flex items-center justify-between gap-2 w-full p-2 text-xs rounded-sm cursor-pointer hover:bg-slate-100'
|
className='flex items-center justify-between gap-2 w-full p-2 text-xs rounded-sm cursor-pointer hover:bg-slate-100'
|
||||||
|
|
@ -84,13 +84,13 @@ const RecipientsAttrCon: React.FC<RecipientsAttrConIntr> = ({ selectedRecipientI
|
||||||
{/* <FaUser className='w-3 h-3 text-2xl mt-[1px]' style={{ color: recipient.color }} /> */}
|
{/* <FaUser className='w-3 h-3 text-2xl mt-[1px]' style={{ color: recipient.color }} /> */}
|
||||||
<p>
|
<p>
|
||||||
{
|
{
|
||||||
recipient.firstName.length === 0 && recipient.lastName.length === 0 ?
|
recipient.firstName.length == 0 && recipient.lastName.length == 0 ?
|
||||||
(recipient.email.length === 0 ? recipient.roleName : recipient.email) :
|
(recipient.email.length == 0 ? recipient.roleName : recipient.email) :
|
||||||
`${recipient.firstName + " " + recipient.lastName}`
|
`${recipient.firstName + " " + recipient.lastName}`
|
||||||
}
|
}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{selectedRecipientId === recipient.id && <IoCheckmark className='text-[var(--primary)]' />}
|
{selectedRecipientId == recipient.id && <IoCheckmark className='text-[var(--primary)]' />}
|
||||||
</div>)
|
</div>)
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ const SelectTagAttr: React.FC<SelectTagAttrInt> = ({ options, selTagKey, selTagI
|
||||||
|
|
||||||
if (Array.isArray(prev)) {
|
if (Array.isArray(prev)) {
|
||||||
newState = prev.map((item, indx) => {
|
newState = prev.map((item, indx) => {
|
||||||
if (indx === selTagIndx) {
|
if (indx == selTagIndx) {
|
||||||
return {
|
return {
|
||||||
...item,
|
...item,
|
||||||
options: item.options ? [...item.options, { ...selectedOption }] : [{ ...selectedOption }],
|
options: item.options ? [...item.options, { ...selectedOption }] : [{ ...selectedOption }],
|
||||||
|
|
@ -39,7 +39,7 @@ const SelectTagAttr: React.FC<SelectTagAttrInt> = ({ options, selTagKey, selTagI
|
||||||
...prev,
|
...prev,
|
||||||
[selTagKey]: Array.isArray(prev[selTagKey])
|
[selTagKey]: Array.isArray(prev[selTagKey])
|
||||||
? prev[selTagKey].map((item, i) => {
|
? prev[selTagKey].map((item, i) => {
|
||||||
if (i === selTagIndx) {
|
if (i == selTagIndx) {
|
||||||
return {
|
return {
|
||||||
...item,
|
...item,
|
||||||
options: item.options ? [...item.options, { ...selectedOption }] : [{ ...selectedOption }],
|
options: item.options ? [...item.options, { ...selectedOption }] : [{ ...selectedOption }],
|
||||||
|
|
@ -65,9 +65,9 @@ const SelectTagAttr: React.FC<SelectTagAttrInt> = ({ options, selTagKey, selTagI
|
||||||
|
|
||||||
if (Array.isArray(prev)) {
|
if (Array.isArray(prev)) {
|
||||||
newState = prev.map((item, indx) => {
|
newState = prev.map((item, indx) => {
|
||||||
if (indx === selTagIndx) {
|
if (indx == selTagIndx) {
|
||||||
return {
|
return {
|
||||||
...item, options: item.options ? item.options.filter((_, i) => i !== indx) : []
|
...item, options: item.options ? item.options.filter((_, i) => i != indx) : []
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return item;
|
return item;
|
||||||
|
|
@ -77,8 +77,8 @@ const SelectTagAttr: React.FC<SelectTagAttrInt> = ({ options, selTagKey, selTagI
|
||||||
...prev,
|
...prev,
|
||||||
[selTagKey]: Array.isArray(prev[selTagKey])
|
[selTagKey]: Array.isArray(prev[selTagKey])
|
||||||
? prev[selTagKey].map((item, i) => {
|
? prev[selTagKey].map((item, i) => {
|
||||||
if (i === selTagIndx) {
|
if (i == selTagIndx) {
|
||||||
return { ...item, options: item.options ? item.options.filter((_, i) => i !== indx) : [] };
|
return { ...item, options: item.options ? item.options.filter((_, i) => i != indx) : [] };
|
||||||
}
|
}
|
||||||
return item;
|
return item;
|
||||||
})
|
})
|
||||||
|
|
@ -99,7 +99,7 @@ const SelectTagAttr: React.FC<SelectTagAttrInt> = ({ options, selTagKey, selTagI
|
||||||
onChange={(e) => setSelectedOption({ label: e.target.value, value: e.target.value })}
|
onChange={(e) => setSelectedOption({ label: e.target.value, value: e.target.value })}
|
||||||
// value={selectedOption}
|
// value={selectedOption}
|
||||||
onKeyUp={(e) => {
|
onKeyUp={(e) => {
|
||||||
if (e.code === "Enter") {
|
if (e.code == "Enter") {
|
||||||
e.currentTarget.value = "";
|
e.currentTarget.value = "";
|
||||||
handleAddSelectOption();
|
handleAddSelectOption();
|
||||||
}
|
}
|
||||||
|
|
@ -116,7 +116,7 @@ const SelectTagAttr: React.FC<SelectTagAttrInt> = ({ options, selTagKey, selTagI
|
||||||
<IoMdClose
|
<IoMdClose
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
// setSelectedOptions(prev =>
|
// setSelectedOptions(prev =>
|
||||||
// prev.filter((_, i) => i !== indx)
|
// prev.filter((_, i) => i != indx)
|
||||||
// )
|
// )
|
||||||
handleSelectOptionDel(indx)
|
handleSelectOptionDel(indx)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ const TemporalDateAttr: React.FC<TemporalDateAttrInt> = ({ dateFormat, format, s
|
||||||
let is24HourFormat = true
|
let is24HourFormat = true
|
||||||
|
|
||||||
if (selectedTag.format && selectedTag.format.split(/hh|mm/).length > 0) {
|
if (selectedTag.format && selectedTag.format.split(/hh|mm/).length > 0) {
|
||||||
if ((selectedTag.format.split(/:mm/)[0]).at(-1) === "h") {
|
if ((selectedTag.format.split(/:mm/)[0]).at(-1) == "h") {
|
||||||
is24HourFormat = false;
|
is24HourFormat = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -37,14 +37,14 @@ const TemporalDateAttr: React.FC<TemporalDateAttrInt> = ({ dateFormat, format, s
|
||||||
const [is24Hrs, setIs24Hrs] = useState<boolean>(is24HourFormat);
|
const [is24Hrs, setIs24Hrs] = useState<boolean>(is24HourFormat);
|
||||||
|
|
||||||
const handleIs24HrsClick = (checked: boolean) => {
|
const handleIs24HrsClick = (checked: boolean) => {
|
||||||
if (dateFormat === TEMPORAL.TIME) {
|
if (dateFormat == TEMPORAL.TIME) {
|
||||||
if (!checked) {
|
if (!checked) {
|
||||||
handlePropertyChange("format", timeFormats[1].format, !is24Hrs)
|
handlePropertyChange("format", timeFormats[1].format, !is24Hrs)
|
||||||
} else {
|
} else {
|
||||||
handlePropertyChange("format", timeFormats[0].format, is24Hrs)
|
handlePropertyChange("format", timeFormats[0].format, is24Hrs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (dateFormat === TEMPORAL.DATE_TIME) {
|
else if (dateFormat == TEMPORAL.DATE_TIME) {
|
||||||
const timeFormat = format = timeFormats[checked ? 0 : 1].format;
|
const timeFormat = format = timeFormats[checked ? 0 : 1].format;
|
||||||
const dateFormat = selectedTag.format && selectedTag.format.split(/hh|HH/)[0]
|
const dateFormat = selectedTag.format && selectedTag.format.split(/hh|HH/)[0]
|
||||||
handlePropertyChange("format", dateFormat+" "+timeFormat, checked ? is24Hrs : !is24Hrs)
|
handlePropertyChange("format", dateFormat+" "+timeFormat, checked ? is24Hrs : !is24Hrs)
|
||||||
|
|
@ -53,9 +53,9 @@ const TemporalDateAttr: React.FC<TemporalDateAttrInt> = ({ dateFormat, format, s
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (format === timeFormats[1].format && is24Hrs) {
|
if (format == timeFormats[1].format && is24Hrs) {
|
||||||
setIs24Hrs(false);
|
setIs24Hrs(false);
|
||||||
} else if (format === timeFormats[0].format && !is24Hrs) {
|
} else if (format == timeFormats[0].format && !is24Hrs) {
|
||||||
setIs24Hrs(true);
|
setIs24Hrs(true);
|
||||||
}
|
}
|
||||||
}, [format])
|
}, [format])
|
||||||
|
|
@ -64,7 +64,7 @@ const TemporalDateAttr: React.FC<TemporalDateAttrInt> = ({ dateFormat, format, s
|
||||||
<div>
|
<div>
|
||||||
<div className="flex justify-between">
|
<div className="flex justify-between">
|
||||||
<label htmlFor="" className="font-medium">Formats</label>
|
<label htmlFor="" className="font-medium">Formats</label>
|
||||||
{(dateFormat === TEMPORAL.DATE_TIME || dateFormat === TEMPORAL.TIME) &&
|
{(dateFormat == TEMPORAL.DATE_TIME || dateFormat == TEMPORAL.TIME) &&
|
||||||
<div className="flex justify-center items-center gap-1.5">
|
<div className="flex justify-center items-center gap-1.5">
|
||||||
<input
|
<input
|
||||||
checked={is24Hrs ? is24Hrs : false}
|
checked={is24Hrs ? is24Hrs : false}
|
||||||
|
|
@ -79,22 +79,22 @@ const TemporalDateAttr: React.FC<TemporalDateAttrInt> = ({ dateFormat, format, s
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
onClick={() => setDropDownToggle(dropDownToggle === DROPDOWNTOGGLE.DDMMYY_FORMAT ? null : DROPDOWNTOGGLE.DDMMYY_FORMAT)}
|
onClick={() => setDropDownToggle(dropDownToggle == DROPDOWNTOGGLE.DDMMYY_FORMAT ? null : DROPDOWNTOGGLE.DDMMYY_FORMAT)}
|
||||||
className="flex justify-between items-center border-1 rounded px-2 py-1 border-slate-200">
|
className="flex justify-between items-center border-1 rounded px-2 py-1 border-slate-200">
|
||||||
<p className="cursor-pointer py-1">
|
<p className="cursor-pointer py-1">
|
||||||
{format ? format : dateTimeFormatMap['date'][0].format}
|
{format ? format : dateTimeFormatMap['date'][0].format}
|
||||||
{/* {(dateFormat !== TEMPORAL.DATE && dateFormat !== TEMPORAL.TIME) ? (is24Hrs ? " " + timeFormats[0].format : " " + timeFormats[1].format) : ""} */}
|
{/* {(dateFormat != TEMPORAL.DATE && dateFormat != TEMPORAL.TIME) ? (is24Hrs ? " " + timeFormats[0].format : " " + timeFormats[1].format) : ""} */}
|
||||||
</p>
|
</p>
|
||||||
<MdKeyboardArrowDown />
|
<MdKeyboardArrowDown />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{
|
{
|
||||||
dropDownToggle === DROPDOWNTOGGLE.DDMMYY_FORMAT &&
|
dropDownToggle == DROPDOWNTOGGLE.DDMMYY_FORMAT &&
|
||||||
<div className="shadow bg-slate-100 mt-1 border-[1px] max-h-[200px] overflow-y-auto border-slate-100 rounded">
|
<div className="shadow bg-slate-100 mt-1 border-[1px] max-h-[200px] overflow-y-auto border-slate-100 rounded">
|
||||||
{dateTimeFormatMap[dateFormat].map((valObj, indx) => {
|
{dateTimeFormatMap[dateFormat].map((valObj, indx) => {
|
||||||
// let val = showFormatEg ? valObj["example"] : valObj["format"]
|
// let val = showFormatEg ? valObj["example"] : valObj["format"]
|
||||||
let val = valObj["format"]
|
let val = valObj["format"]
|
||||||
if (dateFormat === TEMPORAL.DATE_TIME) {
|
if (dateFormat == TEMPORAL.DATE_TIME) {
|
||||||
if (is24Hrs) {
|
if (is24Hrs) {
|
||||||
val = val+" "+timeFormats[0].format;
|
val = val+" "+timeFormats[0].format;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ const ProtectedRoute = ({ children }: { children: JSX.Element }) => {
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
// Fetch only if we don't have user data yet
|
// Fetch only if we don't have user data yet
|
||||||
if (user.id === null && user.loading === false) {
|
if (user.id == null && user.loading == false) {
|
||||||
dispatch(fetchUserDetails());
|
dispatch(fetchUserDetails());
|
||||||
}
|
}
|
||||||
}, [dispatch, user, status]);
|
}, [dispatch, user, status]);
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ const AsideSection = ({
|
||||||
mainTabTitle
|
mainTabTitle
|
||||||
}: AsideSectionProps) => {
|
}: AsideSectionProps) => {
|
||||||
// If no subsections, don't render the aside navigation
|
// If no subsections, don't render the aside navigation
|
||||||
if (subSections.length === 0) {
|
if (subSections.length == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -31,7 +31,7 @@ const AsideSection = ({
|
||||||
onSubSectionClick(subSection.id);
|
onSubSectionClick(subSection.id);
|
||||||
}}
|
}}
|
||||||
className={`flex items-center gap-2 w-full text-left px-3 py-2 rounded-md text-sm font-medium transition-all duration-200 hover:bg-gray-50 cursor-pointer no-underline ${
|
className={`flex items-center gap-2 w-full text-left px-3 py-2 rounded-md text-sm font-medium transition-all duration-200 hover:bg-gray-50 cursor-pointer no-underline ${
|
||||||
activeSubSection === subSection.id
|
activeSubSection == subSection.id
|
||||||
? "bg-[#F4F9FF] text-[var(--primary)]"
|
? "bg-[#F4F9FF] text-[var(--primary)]"
|
||||||
: "text-gray-600 hover:text-gray-800 hover:bg-gray-50"
|
: "text-gray-600 hover:text-gray-800 hover:bg-gray-50"
|
||||||
}`}
|
}`}
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ const ContactForm = ({ onSubmit, loading }: Props) => {
|
||||||
// };
|
// };
|
||||||
|
|
||||||
// const removePhoneField = (index: number) => {
|
// const removePhoneField = (index: number) => {
|
||||||
// const updatedPhone = formData.phone.filter((_, i) => i !== index);
|
// const updatedPhone = formData.phone.filter((_, i) => i != index);
|
||||||
// setFormData((prev) => ({ ...prev, phone: updatedPhone }));
|
// setFormData((prev) => ({ ...prev, phone: updatedPhone }));
|
||||||
// };
|
// };
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ const CreateAndInvite = ({
|
||||||
setAccountSearchTerm(value);
|
setAccountSearchTerm(value);
|
||||||
|
|
||||||
// Clear selected account if user is typing
|
// Clear selected account if user is typing
|
||||||
if (selectedAccount && value !== selectedAccount.accountName) {
|
if (selectedAccount && value != selectedAccount.accountName) {
|
||||||
setSelectedAccount(null);
|
setSelectedAccount(null);
|
||||||
setInviteFormData((prev) => ({ ...prev, i_accountName: 0 }));
|
setInviteFormData((prev) => ({ ...prev, i_accountName: 0 }));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -146,7 +146,7 @@ const Setting = () => {
|
||||||
if (hash) {
|
if (hash) {
|
||||||
// Check if the hash corresponds to a valid subsection
|
// Check if the hash corresponds to a valid subsection
|
||||||
const allSubSections = getSubSections(activeTab);
|
const allSubSections = getSubSections(activeTab);
|
||||||
const validSubSection = allSubSections.find(section => section.id === hash);
|
const validSubSection = allSubSections.find(section => section.id == hash);
|
||||||
|
|
||||||
if (validSubSection) {
|
if (validSubSection) {
|
||||||
setActiveSubSection(hash);
|
setActiveSubSection(hash);
|
||||||
|
|
@ -200,7 +200,7 @@ const Setting = () => {
|
||||||
const renderContent = () => {
|
const renderContent = () => {
|
||||||
const currentSubSections = getSubSections(activeTab);
|
const currentSubSections = getSubSections(activeTab);
|
||||||
|
|
||||||
if (currentSubSections.length === 0) {
|
if (currentSubSections.length == 0) {
|
||||||
// If no subsections, render the main content directly
|
// If no subsections, render the main content directly
|
||||||
switch (activeTab) {
|
switch (activeTab) {
|
||||||
case "userProfile":
|
case "userProfile":
|
||||||
|
|
@ -258,7 +258,7 @@ const Setting = () => {
|
||||||
// Listen for sessionStorage changes
|
// Listen for sessionStorage changes
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleStorageChange = (e: StorageEvent) => {
|
const handleStorageChange = (e: StorageEvent) => {
|
||||||
if (e.key === 'activeAccountId') {
|
if (e.key == 'activeAccountId') {
|
||||||
const newActiveAccountId = e.newValue ? JSON.parse(e.newValue) : null;
|
const newActiveAccountId = e.newValue ? JSON.parse(e.newValue) : null;
|
||||||
setActiveAccountId(newActiveAccountId);
|
setActiveAccountId(newActiveAccountId);
|
||||||
}
|
}
|
||||||
|
|
@ -269,7 +269,7 @@ const Setting = () => {
|
||||||
|
|
||||||
// Custom event listener for same-tab changes
|
// Custom event listener for same-tab changes
|
||||||
const handleCustomStorageChange = (e: CustomEvent) => {
|
const handleCustomStorageChange = (e: CustomEvent) => {
|
||||||
if (e.detail.key === 'activeAccountId') {
|
if (e.detail.key == 'activeAccountId') {
|
||||||
setActiveAccountId(e.detail.newValue);
|
setActiveAccountId(e.detail.newValue);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -317,11 +317,11 @@ const Setting = () => {
|
||||||
|
|
||||||
if (subSections.length > 0) {
|
if (subSections.length > 0) {
|
||||||
// If there's a hash and it's valid for current tab, use it
|
// If there's a hash and it's valid for current tab, use it
|
||||||
if (hash && subSections.find(s => s.id === hash)) {
|
if (hash && subSections.find(s => s.id == hash)) {
|
||||||
setActiveSubSection(hash);
|
setActiveSubSection(hash);
|
||||||
}
|
}
|
||||||
// If no valid hash or no current activeSubSection, use first subsection
|
// If no valid hash or no current activeSubSection, use first subsection
|
||||||
else if (!activeSubSection || !subSections.find(s => s.id === activeSubSection)) {
|
else if (!activeSubSection || !subSections.find(s => s.id == activeSubSection)) {
|
||||||
const firstSubSectionId = subSections[0].id;
|
const firstSubSectionId = subSections[0].id;
|
||||||
setActiveSubSection(firstSubSectionId);
|
setActiveSubSection(firstSubSectionId);
|
||||||
// Update URL hash if no hash exists
|
// Update URL hash if no hash exists
|
||||||
|
|
@ -346,15 +346,15 @@ const Setting = () => {
|
||||||
try {
|
try {
|
||||||
let res;
|
let res;
|
||||||
let toastMesaage;
|
let toastMesaage;
|
||||||
if (action === 'create') {
|
if (action == 'create') {
|
||||||
const payloadAccount = {
|
const payloadAccount = {
|
||||||
name: data.accountName
|
name: data.accountName
|
||||||
}
|
}
|
||||||
res = await api.post(`/api/v1/user/accounts`, payloadAccount)
|
res = await api.post(`/api/v1/user/accounts`, payloadAccount)
|
||||||
if (res.status === 201) {
|
if (res.status == 201) {
|
||||||
toastMesaage = `${action.toUpperCase()} Created Successfull...!`
|
toastMesaage = `${action.toUpperCase()} Created Successfull...!`
|
||||||
}
|
}
|
||||||
} else if (action === 'invite') {
|
} else if (action == 'invite') {
|
||||||
const payloadInvite = {
|
const payloadInvite = {
|
||||||
email: data.email,
|
email: data.email,
|
||||||
role: data.role
|
role: data.role
|
||||||
|
|
@ -391,7 +391,7 @@ const Setting = () => {
|
||||||
try {
|
try {
|
||||||
setCreateAndInviteLoader(true);
|
setCreateAndInviteLoader(true);
|
||||||
const res = await api.post(`/api/v1/accounts/${activeAccountId}/contacts`, [data]);
|
const res = await api.post(`/api/v1/accounts/${activeAccountId}/contacts`, [data]);
|
||||||
if (res.status === 200) {
|
if (res.status == 200) {
|
||||||
toast.success('Contact created successfully!', {
|
toast.success('Contact created successfully!', {
|
||||||
position: "top-center",
|
position: "top-center",
|
||||||
autoClose: 1500,
|
autoClose: 1500,
|
||||||
|
|
@ -417,12 +417,12 @@ const Setting = () => {
|
||||||
<div className="sticky top-0 z-10 bg-white border-b border-gray-200 px-4 md:px-6 lg:px-8 pt-4">
|
<div className="sticky top-0 z-10 bg-white border-b border-gray-200 px-4 md:px-6 lg:px-8 pt-4">
|
||||||
<div className="flex flex-wrap md:gap-4 ">
|
<div className="flex flex-wrap md:gap-4 ">
|
||||||
{tabs.map((tab) =>
|
{tabs.map((tab) =>
|
||||||
tab.type === page1 && (
|
tab.type == page1 && (
|
||||||
<button
|
<button
|
||||||
key={tab.id}
|
key={tab.id}
|
||||||
onClick={() => handleMainTabClick(tab.id)}
|
onClick={() => handleMainTabClick(tab.id)}
|
||||||
className={`cursor-pointer relative px-4 pb-3 text-sm font-medium transition-all duration-200
|
className={`cursor-pointer relative px-4 pb-3 text-sm font-medium transition-all duration-200
|
||||||
${activeTab === tab.id
|
${activeTab == tab.id
|
||||||
? "text-[#34BEFF] after:absolute after:bottom-0 after:left-0 after:right-0 after:h-0.5 after:bg-[#34BEFF] bg-gradient-to-t from-[#E5F6FF] to-transparent"
|
? "text-[#34BEFF] after:absolute after:bottom-0 after:left-0 after:right-0 after:h-0.5 after:bg-[#34BEFF] bg-gradient-to-t from-[#E5F6FF] to-transparent"
|
||||||
: "text-gray-600 hover:text-[#34BEFF]"
|
: "text-gray-600 hover:text-[#34BEFF]"
|
||||||
}`}
|
}`}
|
||||||
|
|
@ -438,7 +438,7 @@ const Setting = () => {
|
||||||
<div className="flex-1 min-h-0 flex flex-col lg:flex-row">
|
<div className="flex-1 min-h-0 flex flex-col lg:flex-row">
|
||||||
|
|
||||||
{/* Sidebar (hidden on small, shown on lg) */}
|
{/* Sidebar (hidden on small, shown on lg) */}
|
||||||
{activeTab === 'userProfile' && (
|
{activeTab == 'userProfile' && (
|
||||||
<section className="hidden lg:block flex-shrink-0 w-70 border-r-1 border-slate-200">
|
<section className="hidden lg:block flex-shrink-0 w-70 border-r-1 border-slate-200">
|
||||||
<div className="border-b-1 border-slate-200 py-4 px-6">
|
<div className="border-b-1 border-slate-200 py-4 px-6">
|
||||||
<div className="flex justify-start items-center gap-2">
|
<div className="flex justify-start items-center gap-2">
|
||||||
|
|
@ -459,14 +459,14 @@ const Setting = () => {
|
||||||
activeSubSection={activeSubSection}
|
activeSubSection={activeSubSection}
|
||||||
onSubSectionClick={handleSubSectionClick}
|
onSubSectionClick={handleSubSectionClick}
|
||||||
subSections={getSubSections(activeTab)}
|
subSections={getSubSections(activeTab)}
|
||||||
mainTabTitle={tabs.find(t => t.id === activeTab)?.label || ""}
|
mainTabTitle={tabs.find(t => t.id == activeTab)?.label || ""}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Sidebar as horizontal nav (only on mobile) */}
|
{/* Sidebar as horizontal nav (only on mobile) */}
|
||||||
{activeTab === 'userProfile' && (
|
{activeTab == 'userProfile' && (
|
||||||
<section className="lg:hidden mb-2">
|
<section className="lg:hidden mb-2">
|
||||||
<div className="flex overflow-x-auto no-scrollbar gap-4 border-b border-gray-200 pb-2">
|
<div className="flex overflow-x-auto no-scrollbar gap-4 border-b border-gray-200 pb-2">
|
||||||
{getSubSections(activeTab).map((sub) => (
|
{getSubSections(activeTab).map((sub) => (
|
||||||
|
|
@ -474,7 +474,7 @@ const Setting = () => {
|
||||||
key={sub.id}
|
key={sub.id}
|
||||||
onClick={() => handleSubSectionClick(sub.id)}
|
onClick={() => handleSubSectionClick(sub.id)}
|
||||||
className={`whitespace-nowrap text-sm font-medium px-2 py-1 rounded-md
|
className={`whitespace-nowrap text-sm font-medium px-2 py-1 rounded-md
|
||||||
${activeSubSection === sub.id ? "bg-blue-100 text-blue-600" : "text-gray-600"}
|
${activeSubSection == sub.id ? "bg-blue-100 text-blue-600" : "text-gray-600"}
|
||||||
`}
|
`}
|
||||||
>
|
>
|
||||||
{sub.label}
|
{sub.label}
|
||||||
|
|
|
||||||
|
|
@ -65,21 +65,29 @@ const AddSignatureModal: React.FC<AddSignatureModalProps> = ({
|
||||||
initials: string | null;
|
initials: string | null;
|
||||||
}>({ fullSignature: null, initials: null });
|
}>({ fullSignature: null, initials: null });
|
||||||
|
|
||||||
const signatureOptions = [
|
// const signatureOptions = [
|
||||||
{ id: 1, name: 'print', initials: 'LA', style: 'print' },
|
// { id: 1, name: 'print', initials: 'LA', style: 'print' },
|
||||||
{ id: 2, name: 'cursive', initials: 'LA', style: 'cursive' },
|
// { id: 2, name: 'cursive', initials: 'LA', style: 'cursive' },
|
||||||
{ id: 3, name: 'script', initials: 'LA', style: 'script' },
|
// { id: 3, name: 'script', initials: 'LA', style: 'script' },
|
||||||
{ id: 4, name: 'elegant', initials: 'LA', style: 'elegant' },
|
// { id: 4, name: 'elegant', initials: 'LA', style: 'elegant' },
|
||||||
{ id: 5, name: 'modern', initials: 'LA', style: 'modern' },
|
// { id: 5, name: 'modern', initials: 'LA', style: 'modern' },
|
||||||
{ id: 6, name: 'classic', initials: 'LA', style: 'classic' },
|
// { id: 6, name: 'classic', initials: 'LA', style: 'classic' },
|
||||||
];
|
// ];
|
||||||
|
|
||||||
const [checked, setChecked] = useState(false);
|
const [checked, setChecked] = useState(false);
|
||||||
|
|
||||||
const toggleCheckbox = () => setChecked(!checked);
|
const toggleCheckbox = () => setChecked(!checked);
|
||||||
|
|
||||||
|
|
||||||
|
const fontsMap = [
|
||||||
|
{ style: "'Great Vibes', cursive", label: "Elegant Script", acronym: "f1" },
|
||||||
|
{ style: "'Pacifico', cursive", label: "Casual Handwritten", acronym: "f2" },
|
||||||
|
{ style: "'Dancing Script', cursive", label: "Smooth Flow", acronym: "f3" },
|
||||||
|
{ style: "'Playfair Display', serif", label: "Classic Serif", acronym: "f4" },
|
||||||
|
]
|
||||||
|
|
||||||
const [selectedSignature, setSelectedSignature] = useState<SelectStyle>(
|
const [selectedSignature, setSelectedSignature] = useState<SelectStyle>(
|
||||||
signatureOptions.length > 0 ? { id: signatureOptions[0].id, style: signatureOptions[0].style } : { id: 0, style: "" }
|
fontsMap.length > 0 ? { id: fontsMap[0].acronym, style: fontsMap[0].style } : { id: "f1", style: "" }
|
||||||
);
|
);
|
||||||
|
|
||||||
// Store the actual file
|
// Store the actual file
|
||||||
|
|
@ -121,9 +129,9 @@ const AddSignatureModal: React.FC<AddSignatureModalProps> = ({
|
||||||
setActiveTab(editingSignature.signatureType as 'SELECT' | 'DRAW' | 'UPLOAD');
|
setActiveTab(editingSignature.signatureType as 'SELECT' | 'DRAW' | 'UPLOAD');
|
||||||
|
|
||||||
// Set font for SELECT tab
|
// Set font for SELECT tab
|
||||||
const fontOption = signatureOptions.find(option => option.style === editingSignature.font);
|
const fontOption = fontsMap.find(option => option.style == editingSignature.font);
|
||||||
if (fontOption) {
|
if (fontOption) {
|
||||||
setSelectedSignature({ id: fontOption.id, style: fontOption.style });
|
setSelectedSignature({ id: fontOption.acronym, style: fontOption.style });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set signature blobs for all tabs
|
// Set signature blobs for all tabs
|
||||||
|
|
@ -134,7 +142,7 @@ const AddSignatureModal: React.FC<AddSignatureModalProps> = ({
|
||||||
});
|
});
|
||||||
|
|
||||||
// Set preview URLs for UPLOAD tab
|
// Set preview URLs for UPLOAD tab
|
||||||
if (editingSignature.signatureType === 'UPLOAD') {
|
if (editingSignature.signatureType == 'UPLOAD') {
|
||||||
setPreview1(`data:image/png;base64,${editingSignature.signatureBlob}`);
|
setPreview1(`data:image/png;base64,${editingSignature.signatureBlob}`);
|
||||||
setPreview2(`data:image/png;base64,${editingSignature.initialsBlob}`);
|
setPreview2(`data:image/png;base64,${editingSignature.initialsBlob}`);
|
||||||
}
|
}
|
||||||
|
|
@ -194,7 +202,7 @@ const AddSignatureModal: React.FC<AddSignatureModalProps> = ({
|
||||||
setIsSubmitting(true);
|
setIsSubmitting(true);
|
||||||
|
|
||||||
// Only validate for DRAW and UPLOAD
|
// Only validate for DRAW and UPLOAD
|
||||||
if ((activeTab === 'DRAW' || activeTab === 'UPLOAD') &&
|
if ((activeTab == 'DRAW' || activeTab == 'UPLOAD') &&
|
||||||
(!signatures.fullSignature || !signatures.initials)) {
|
(!signatures.fullSignature || !signatures.initials)) {
|
||||||
// alert('Please provide both signature and initials');
|
// alert('Please provide both signature and initials');
|
||||||
// toast.error('Please provide both signature and initials in draw and upload case', {
|
// toast.error('Please provide both signature and initials in draw and upload case', {
|
||||||
|
|
@ -216,14 +224,15 @@ const AddSignatureModal: React.FC<AddSignatureModalProps> = ({
|
||||||
// Base payload
|
// Base payload
|
||||||
const payload = {
|
const payload = {
|
||||||
signatureType: activeTab,
|
signatureType: activeTab,
|
||||||
firstName: fullName.split(' ')[0] || user.firstName,
|
initials: activeTab == "SELECT" ? initials : "",
|
||||||
lastName: fullName.split(' ')[1] || user.lastName,
|
firstName: fullName.split(' ').length > 1 ? fullName.split(' ')[0] : "",
|
||||||
font: selectedSignature.style,
|
lastName: fullName.split(' ').length > 1 ? fullName.split(' ')[1] : fullName.split(' ')[0],
|
||||||
|
font: activeTab == "SELECT" ? selectedSignature.id : "",
|
||||||
default: checked
|
default: checked
|
||||||
};
|
};
|
||||||
|
|
||||||
// Only add signatures if not SELECT
|
// Only add signatures if not SELECT
|
||||||
if (activeTab !== 'SELECT') {
|
if (activeTab != 'SELECT') {
|
||||||
payload.signatureBase64 = signatures.fullSignature;
|
payload.signatureBase64 = signatures.fullSignature;
|
||||||
payload.initialsBase64 = signatures.initials;
|
payload.initialsBase64 = signatures.initials;
|
||||||
}
|
}
|
||||||
|
|
@ -292,41 +301,68 @@ const AddSignatureModal: React.FC<AddSignatureModalProps> = ({
|
||||||
switch (activeTab) {
|
switch (activeTab) {
|
||||||
case 'SELECT':
|
case 'SELECT':
|
||||||
return (
|
return (
|
||||||
<>
|
<div className="px-4 lg:px-6 py-4 flex-shrink-0">
|
||||||
{/* Form Inputs - Fixed */}
|
<h2 className='mt-4 mb-5 text-sm'>
|
||||||
<div className="px-4 lg:px-6 py-4 flex-shrink-0">
|
Confirm your name and choose signature style. *Are required fields.
|
||||||
<h2 className='mt-4 mb-5 text-sm'>Confirm your name and choose signature style. *Are required fields.</h2>
|
</h2>
|
||||||
<div className="grid grid-cols-2 gap-3">
|
|
||||||
<div className='w-full'>
|
|
||||||
<label className="block text-sm font-medium mb-2">
|
|
||||||
Full Name
|
|
||||||
<span className='text-red-600'> *</span>
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
value={fullName}
|
|
||||||
onChange={(e) => setFullName(e.target.value)}
|
|
||||||
placeholder="Enter full name"
|
|
||||||
className="w-full px-3 py-2 text-sm border border-gray-200 rounded-md outline-none"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className='w-full'>
|
|
||||||
<label className="block text-sm font-medium mb-2">
|
|
||||||
Initials
|
|
||||||
<span className='text-red-600'> *</span>
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
value={initials}
|
|
||||||
onChange={(e) => setInitials(e.target.value)}
|
|
||||||
placeholder="Enter initials"
|
|
||||||
className="w-full px-3 py-2 text-sm border border-gray-200 rounded-md outline-none"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
<div className="grid grid-cols-2 gap-3 mb-6">
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium mb-2">
|
||||||
|
Full Name
|
||||||
|
<span className='text-red-600'> *</span>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
value={fullName}
|
||||||
|
onChange={(e) => {
|
||||||
|
setFullName(e.target.value)
|
||||||
|
setInitials(e.target.value.trim().split(' ').length > 1 ? e.target.value.split(' ')[0][0] + "" + e.target.value.split(' ')[1][0] : e.target.value.split(' ')[0][0])
|
||||||
|
}}
|
||||||
|
placeholder="Enter full name"
|
||||||
|
className="w-full px-3 py-2 text-sm border border-gray-200 rounded-md outline-none"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label className="block text-sm font-medium mb-2">
|
||||||
|
Initials
|
||||||
|
<span className='text-red-600'> *</span>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
disabled
|
||||||
|
type="text"
|
||||||
|
value={initials}
|
||||||
|
// onChange={(e) => setInitials(e.target.value)}
|
||||||
|
placeholder="Enter initials"
|
||||||
|
className="w-full px-3 py-2 text-sm border border-gray-200 rounded-md outline-none"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
|
||||||
|
{/* Signature Style Options */}
|
||||||
|
<div className="grid grid-cols-2 gap-4">
|
||||||
|
{fontsMap.map((opt) => (
|
||||||
|
<div
|
||||||
|
key={opt.acronym}
|
||||||
|
onClick={() => setSelectedSignature({ id: opt.acronym, style: opt.style })}
|
||||||
|
className={`cursor-pointer border border-slate-200 rounded-xl p-4 text-center bg-white transition
|
||||||
|
${selectedSignature.id == opt.acronym
|
||||||
|
? "ring-2 ring-[var(--mainPrimaryBtn)]"
|
||||||
|
: "hover:shadow-md"}`}
|
||||||
|
>
|
||||||
|
<div style={{ fontFamily: opt.style, fontSize: "1.75rem" }}>
|
||||||
|
{fullName || "Full Name"}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
style={{ fontFamily: opt.style, fontSize: "1.25rem", opacity: 0.7 }}
|
||||||
|
>
|
||||||
|
{initials || "AB"}
|
||||||
|
</div>
|
||||||
|
<p className="text-xs mt-2 text-gray-500">{opt.label}</p>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
case 'DRAW':
|
case 'DRAW':
|
||||||
|
|
@ -483,17 +519,17 @@ const AddSignatureModal: React.FC<AddSignatureModalProps> = ({
|
||||||
<button
|
<button
|
||||||
key={item.id}
|
key={item.id}
|
||||||
onClick={() => setActiveTab(item.id as 'SELECT' | 'DRAW' | 'UPLOAD')}
|
onClick={() => setActiveTab(item.id as 'SELECT' | 'DRAW' | 'UPLOAD')}
|
||||||
className={`flex items-center justify-start space-x-1 px-2 sm:space-x-2 sm:px-3 py-4 text-sm font-medium transition-all duration-200 whitespace-nowrap ${activeTab === item.id
|
className={`flex items-center justify-start space-x-1 px-2 sm:space-x-2 sm:px-3 py-4 text-sm font-medium transition-all duration-200 whitespace-nowrap ${activeTab == item.id
|
||||||
? ' text-[var(--primary)]'
|
? ' text-[var(--primary)]'
|
||||||
: 'text-gray-400'
|
: 'text-gray-400'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<span className={activeTab === item.id ? 'text-[var(--mainPrimaryBtn)]' : 'text-gray-400'}>
|
<span className={activeTab == item.id ? 'text-[var(--mainPrimaryBtn)]' : 'text-gray-400'}>
|
||||||
{item.icon}
|
{item.icon}
|
||||||
</span>
|
</span>
|
||||||
<span>{item.label}</span>
|
<span>{item.label}</span>
|
||||||
</button>
|
</button>
|
||||||
{activeTab === item.id && <div className='absolute bottom-[-1px] w-full h-[3px] bg-[var(--mainPrimaryBtn)]'></div>}
|
{activeTab == item.id && <div className='absolute bottom-[-1px] w-full h-[3px] bg-[var(--mainPrimaryBtn)]'></div>}
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
))}
|
))}
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ const DrawSignatureCanvas: React.FC<Props> = ({ onSignatureChange, initialSignat
|
||||||
|
|
||||||
const checkComplete = () => {
|
const checkComplete = () => {
|
||||||
loadedCount++;
|
loadedCount++;
|
||||||
if (loadedCount === totalToLoad) {
|
if (loadedCount == totalToLoad) {
|
||||||
setInitialLoaded(true);
|
setInitialLoaded(true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -93,7 +93,7 @@ const DrawSignatureCanvas: React.FC<Props> = ({ onSignatureChange, initialSignat
|
||||||
img2.src = initialSignatures.initials;
|
img2.src = initialSignatures.initials;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (totalToLoad === 0) {
|
if (totalToLoad == 0) {
|
||||||
setInitialLoaded(true);
|
setInitialLoaded(true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -103,13 +103,13 @@ const DrawSignatureCanvas: React.FC<Props> = ({ onSignatureChange, initialSignat
|
||||||
const rect = e.currentTarget.getBoundingClientRect();
|
const rect = e.currentTarget.getBoundingClientRect();
|
||||||
const point = { x: e.clientX - rect.left, y: e.clientY - rect.top };
|
const point = { x: e.clientX - rect.left, y: e.clientY - rect.top };
|
||||||
setCurrentPath([point]);
|
setCurrentPath([point]);
|
||||||
setActiveCanvas(e.currentTarget === canvasRef1.current ? 'full' : 'initials');
|
setActiveCanvas(e.currentTarget == canvasRef1.current ? 'full' : 'initials');
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleMouseMove = (e: React.MouseEvent<HTMLCanvasElement>, type: "SIGNATURE" | "INITIAL") => {
|
const handleMouseMove = (e: React.MouseEvent<HTMLCanvasElement>, type: "SIGNATURE" | "INITIAL") => {
|
||||||
if (!isDrawing) return;
|
if (!isDrawing) return;
|
||||||
setIsDrawingType((prev) => {
|
setIsDrawingType((prev) => {
|
||||||
return { ...prev, signatureDrawn: type === "SIGNATURE" ? true : prev.signatureDrawn, initialDrawn: type === "INITIAL" ? true : prev.initialDrawn }
|
return { ...prev, signatureDrawn: type == "SIGNATURE" ? true : prev.signatureDrawn, initialDrawn: type == "INITIAL" ? true : prev.initialDrawn }
|
||||||
})
|
})
|
||||||
const rect = e.currentTarget.getBoundingClientRect();
|
const rect = e.currentTarget.getBoundingClientRect();
|
||||||
const point = { x: e.clientX - rect.left, y: e.clientY - rect.top };
|
const point = { x: e.clientX - rect.left, y: e.clientY - rect.top };
|
||||||
|
|
@ -148,9 +148,9 @@ const DrawSignatureCanvas: React.FC<Props> = ({ onSignatureChange, initialSignat
|
||||||
const handleMouseUp = () => {
|
const handleMouseUp = () => {
|
||||||
setIsDrawing(false);
|
setIsDrawing(false);
|
||||||
|
|
||||||
if (currentPath.length === 0 || !activeCanvas) return;
|
if (currentPath.length == 0 || !activeCanvas) return;
|
||||||
|
|
||||||
if (activeCanvas === 'full') {
|
if (activeCanvas == 'full') {
|
||||||
const newPaths = [...paths1, currentPath];
|
const newPaths = [...paths1, currentPath];
|
||||||
setPaths1(newPaths);
|
setPaths1(newPaths);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -217,11 +217,11 @@ const DrawSignatureCanvas: React.FC<Props> = ({ onSignatureChange, initialSignat
|
||||||
};
|
};
|
||||||
|
|
||||||
const undoLastPath = () => {
|
const undoLastPath = () => {
|
||||||
if (activeCanvas === 'full' && paths1.length > 0) {
|
if (activeCanvas == 'full' && paths1.length > 0) {
|
||||||
const newPaths = paths1.slice(0, -1);
|
const newPaths = paths1.slice(0, -1);
|
||||||
setPaths1(newPaths);
|
setPaths1(newPaths);
|
||||||
redrawCanvas(canvasRef1.current!, newPaths, initialImage1);
|
redrawCanvas(canvasRef1.current!, newPaths, initialImage1);
|
||||||
} else if (activeCanvas === 'initials' && paths2.length > 0) {
|
} else if (activeCanvas == 'initials' && paths2.length > 0) {
|
||||||
const newPaths = paths2.slice(0, -1);
|
const newPaths = paths2.slice(0, -1);
|
||||||
setPaths2(newPaths);
|
setPaths2(newPaths);
|
||||||
redrawCanvas(canvasRef2.current!, newPaths, initialImage2);
|
redrawCanvas(canvasRef2.current!, newPaths, initialImage2);
|
||||||
|
|
@ -256,7 +256,7 @@ const DrawSignatureCanvas: React.FC<Props> = ({ onSignatureChange, initialSignat
|
||||||
{/* <button
|
{/* <button
|
||||||
className="text-xs"
|
className="text-xs"
|
||||||
onClick={undoLastPath}
|
onClick={undoLastPath}
|
||||||
disabled={!activeCanvas || (activeCanvas === 'full' ? paths1.length === 0 : paths2.length === 0)}
|
disabled={!activeCanvas || (activeCanvas == 'full' ? paths1.length == 0 : paths2.length == 0)}
|
||||||
>
|
>
|
||||||
Undo Last
|
Undo Last
|
||||||
</button> */}
|
</button> */}
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ const SignatureManager: React.FC = () => {
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const handleEdit = (id: string) => {
|
const handleEdit = (id: string) => {
|
||||||
let editSignature = signatures.find((item) => item.id === id);
|
let editSignature = signatures.find((item) => item.id == id);
|
||||||
|
|
||||||
if (editSignature) {
|
if (editSignature) {
|
||||||
setEditingSignature(editSignature);
|
setEditingSignature(editSignature);
|
||||||
|
|
@ -92,7 +92,7 @@ const SignatureManager: React.FC = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const toggleDropdown = (id: string) => {
|
const toggleDropdown = (id: string) => {
|
||||||
setActiveDropdown(activeDropdown === id ? null : id);
|
setActiveDropdown(activeDropdown == id ? null : id);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleAddNew = () => {
|
const handleAddNew = () => {
|
||||||
|
|
@ -107,12 +107,12 @@ const SignatureManager: React.FC = () => {
|
||||||
|
|
||||||
|
|
||||||
const renderSignatureText = (type, font, firstName, lastName, mode = 'name') => {
|
const renderSignatureText = (type, font, firstName, lastName, mode = 'name') => {
|
||||||
if (type !== 'SELECT') return null;
|
if (type != 'SELECT') return null;
|
||||||
|
|
||||||
const selectedFont = signatureOptions.find(opt => opt.style === font);
|
const selectedFont = signatureOptions.find(opt => opt.style == font);
|
||||||
const fontClass = `${selectedFont?.style || 'print'}`;
|
const fontClass = `${selectedFont?.style || 'print'}`;
|
||||||
|
|
||||||
if (mode === 'initials') {
|
if (mode == 'initials') {
|
||||||
const initials = `${(firstName?.[0] ?? '')}${(lastName?.[0] ?? '')}`.toUpperCase();
|
const initials = `${(firstName?.[0] ?? '')}${(lastName?.[0] ?? '')}`.toUpperCase();
|
||||||
return (
|
return (
|
||||||
<div className={`text-center text-[24px]`} style={{ fontFamily: selectedFont?.style }}>
|
<div className={`text-center text-[24px]`} style={{ fontFamily: selectedFont?.style }}>
|
||||||
|
|
@ -190,7 +190,7 @@ const SignatureManager: React.FC = () => {
|
||||||
|
|
||||||
{/* Signature Image or Name/Initials */}
|
{/* Signature Image or Name/Initials */}
|
||||||
<div className="rounded-lg p-1 my-4 flex items-center justify-center">
|
<div className="rounded-lg p-1 my-4 flex items-center justify-center">
|
||||||
{signature?.signatureType !== 'SELECT' ? (
|
{signature?.signatureType != 'SELECT' ? (
|
||||||
<img
|
<img
|
||||||
src={`data:${signature?.signatureMimeType};base64,${signature?.signatureBlob}`}
|
src={`data:${signature?.signatureMimeType};base64,${signature?.signatureBlob}`}
|
||||||
className="h-[50px] w-[250px] object-contain"
|
className="h-[50px] w-[250px] object-contain"
|
||||||
|
|
@ -219,7 +219,7 @@ const SignatureManager: React.FC = () => {
|
||||||
|
|
||||||
{/* Signature Initials: Image or Generated Text */}
|
{/* Signature Initials: Image or Generated Text */}
|
||||||
<div className="rounded-lg p-1 my-4 flex items-center justify-center">
|
<div className="rounded-lg p-1 my-4 flex items-center justify-center">
|
||||||
{signature?.signatureType !== 'SELECT' ? (
|
{signature?.signatureType != 'SELECT' ? (
|
||||||
<img
|
<img
|
||||||
src={`data:${signature.initialsMimeType};base64,${signature.initialsBlob}`}
|
src={`data:${signature.initialsMimeType};base64,${signature.initialsBlob}`}
|
||||||
className="h-[50px] object-contain"
|
className="h-[50px] object-contain"
|
||||||
|
|
@ -262,7 +262,7 @@ const SignatureManager: React.FC = () => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Empty State (if no signatures) */}
|
{/* Empty State (if no signatures) */}
|
||||||
{signatures.length === 0 && (
|
{signatures.length == 0 && (
|
||||||
<div className=" rounded-xl p-12 text-center mt-8">
|
<div className=" rounded-xl p-12 text-center mt-8">
|
||||||
<div className="text-gray-400 mb-4">
|
<div className="text-gray-400 mb-4">
|
||||||
<FiEdit3 className="w-16 h-16 mx-auto" />
|
<FiEdit3 className="w-16 h-16 mx-auto" />
|
||||||
|
|
|
||||||
|
|
@ -75,10 +75,18 @@ interface UserData {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface SelectStyle {
|
interface SelectStyle {
|
||||||
id: number,
|
id: number | string,
|
||||||
style: string
|
style: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fontsMap = [
|
||||||
|
{ style: "'Great Vibes', cursive", label: "Elegant Script", acronym: "f1" },
|
||||||
|
{ style: "'Pacifico', cursive", label: "Casual Handwritten", acronym: "f2" },
|
||||||
|
{ style: "'Dancing Script', cursive", label: "Smooth Flow", acronym: "f3" },
|
||||||
|
{ style: "'Playfair Display', serif", label: "Classic Serif", acronym: "f4" },
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
const ClientSignCon: React.FC<ClientSignConProps> = ({
|
const ClientSignCon: React.FC<ClientSignConProps> = ({
|
||||||
recipient,
|
recipient,
|
||||||
setOpenSign,
|
setOpenSign,
|
||||||
|
|
@ -228,26 +236,9 @@ const ClientSignCon: React.FC<ClientSignConProps> = ({
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
const handleSubmit = async () => {
|
||||||
setIsSubmitting(true);
|
setIsSubmitting(true);
|
||||||
// if (!signatures.fullSignature || !signatures.initials) {
|
|
||||||
// alert('Please provide both signature and initials');
|
|
||||||
// setIsSubmitting(false);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
if ((activeTab === 'DRAW' || activeTab === 'UPLOAD') &&
|
if ((activeTab == 'DRAW' || activeTab == 'UPLOAD') &&
|
||||||
(!signatures.fullSignature || !signatures.initials)) {
|
(!signatures.fullSignature || !signatures.initials)) {
|
||||||
// alert('Please provide both signature and initials');
|
|
||||||
// toast.error('Please provide both signature and initials in draw and upload case', {
|
|
||||||
// position: "top-center",
|
|
||||||
// autoClose: 2000,
|
|
||||||
// hideProgressBar: false,
|
|
||||||
// closeOnClick: false,
|
|
||||||
// pauseOnHover: true,
|
|
||||||
// draggable: true,
|
|
||||||
// progress: undefined,
|
|
||||||
// theme: "light",
|
|
||||||
// transition: Bounce,
|
|
||||||
// });
|
|
||||||
setIsSubmitting(false);
|
setIsSubmitting(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -257,61 +248,43 @@ const ClientSignCon: React.FC<ClientSignConProps> = ({
|
||||||
tagId: signTagId,
|
tagId: signTagId,
|
||||||
// signatureId: signatureId,
|
// signatureId: signatureId,
|
||||||
type: activeTab,
|
type: activeTab,
|
||||||
firstName: fullName.split(' ')[0] || user.firstName,
|
firstName: fullName.split(' ').length > 1 ? fullName.split(' ')[0] : "",
|
||||||
lastName: fullName.split(' ')[1] || user.lastName,
|
lastName: fullName.split(' ').length > 1 ? fullName.split(' ')[1] : fullName.split(' ')[0],
|
||||||
initials: "",
|
initials: initials,
|
||||||
initialsBase64: signatures.initials,
|
initialsBase64: signatures.initials,
|
||||||
signatureBase64: signatures.fullSignature,
|
signatureBase64: signatures.fullSignature,
|
||||||
font: selectedSignature.style
|
font: activeTab == "SELECT" ? selectedSignature.id : ""
|
||||||
};
|
};
|
||||||
|
|
||||||
if (activeTab !== 'SELECT') {
|
if (activeTab != 'SELECT') {
|
||||||
payload.signatureBase64 = signatures.fullSignature;
|
payload.signatureBase64 = signatures.fullSignature;
|
||||||
payload.initialsBase64 = signatures.initials;
|
payload.initialsBase64 = signatures.initials;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (isEditMode && editingSignature) {
|
let res = null
|
||||||
// // Update existing signature
|
if (activeTab == 'SAVED') {
|
||||||
// const updatePayload = {
|
res = await axios.get(`${import.meta.env.VITE_BASE_URI}/api/v1/sign/${recipientId}/signatures/${selectedSignature.id}`)
|
||||||
// ...payload,
|
} else if (activeTab == 'SELECT') {
|
||||||
// signatureId: editingSignature.id
|
|
||||||
// };
|
|
||||||
// res = await axios.put(`${import.meta.env.VITE_BASE_URI}/api/v1/user/signatures`, updatePayload);
|
|
||||||
// console.log("handleUpdate", res);
|
|
||||||
|
|
||||||
// toast.success("Signature Updated Successfully", {
|
payload.signatureBase64 = ""
|
||||||
// position: "top-center",
|
payload.initialsBase64 = ""
|
||||||
// autoClose: 500,
|
|
||||||
// hideProgressBar: false,
|
|
||||||
// closeOnClick: false,
|
|
||||||
// pauseOnHover: true,
|
|
||||||
// draggable: true,
|
|
||||||
// progress: undefined,
|
|
||||||
// theme: "light",
|
|
||||||
// transition: Bounce,
|
|
||||||
// });
|
|
||||||
// } else {
|
|
||||||
// Create new signature
|
|
||||||
let res = await axios.post(`${import.meta.env.VITE_BASE_URI}/api/v1/sign/${recipientId}/signatures`,
|
|
||||||
payload,
|
|
||||||
{
|
|
||||||
headers: {
|
|
||||||
"ngrok-skip-browser-warning": "69420"
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// toast.success("Signature Created Successfully", {
|
res = await axios.post(`${import.meta.env.VITE_BASE_URI}/api/v1/sign/${recipientId}/signatures`,
|
||||||
// position: "top-center",
|
payload,
|
||||||
// autoClose: 500,
|
{
|
||||||
// hideProgressBar: false,
|
headers: {
|
||||||
// closeOnClick: false,
|
"ngrok-skip-browser-warning": "69420"
|
||||||
// pauseOnHover: true,
|
}
|
||||||
// draggable: true,
|
});
|
||||||
// progress: undefined,
|
} else {
|
||||||
// theme: "light",
|
res = await axios.post(`${import.meta.env.VITE_BASE_URI}/api/v1/sign/${recipientId}/signatures`,
|
||||||
// transition: Bounce,
|
payload,
|
||||||
// });
|
{
|
||||||
// }
|
headers: {
|
||||||
|
"ngrok-skip-browser-warning": "69420"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (res?.data) {
|
if (res?.data) {
|
||||||
setSignatures({
|
setSignatures({
|
||||||
|
|
@ -322,240 +295,29 @@ const ClientSignCon: React.FC<ClientSignConProps> = ({
|
||||||
signatureId: res.data.id ?? null,
|
signatureId: res.data.id ?? null,
|
||||||
saveType: res.data.signatureType ?? null,
|
saveType: res.data.signatureType ?? null,
|
||||||
save: true,
|
save: true,
|
||||||
signature: res.data.signatureBlob ?? null,
|
signature: res.data.signatureType == "SELECT" ? payload.firstName : (res.data.signatureBlob ?? null),
|
||||||
initial: res.data.initialsBlob ?? null,
|
initial: res.data.signatureType == "SELECT" ? payload.initials : (res.data.initialsBlob ?? null),
|
||||||
|
font: res.data.signatureType == "SELECT" ? selectedSignature.style : ""
|
||||||
});
|
});
|
||||||
setOpenSign(false);
|
setOpenSign(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error submitting signature:", error);
|
console.error("Error submitting signature:", error);
|
||||||
// toast.error(isEditMode ? "Failed to update signature" : "Failed to create signature", {
|
|
||||||
// position: "top-center",
|
|
||||||
// autoClose: 2000,
|
|
||||||
// hideProgressBar: false,
|
|
||||||
// closeOnClick: false,
|
|
||||||
// pauseOnHover: true,
|
|
||||||
// draggable: true,
|
|
||||||
// progress: undefined,
|
|
||||||
// theme: "light",
|
|
||||||
// transition: Bounce,
|
|
||||||
// });
|
|
||||||
} finally {
|
} finally {
|
||||||
setIsSubmitting(false);
|
setIsSubmitting(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// const renderContent = () => {
|
|
||||||
// switch (activeTab) {
|
|
||||||
// case 'SELECT':
|
|
||||||
// return (
|
|
||||||
// <div className="h-full flex flex-col ">
|
|
||||||
// <div className="mb-6">
|
|
||||||
// <h2 className="text-xl font-semibold text-gray-900 mb-2">Choose Signature Style</h2>
|
|
||||||
// <p className="text-sm text-gray-600">Select from pre-designed signature styles</p>
|
|
||||||
// </div>
|
|
||||||
|
|
||||||
// <div className="flex-1 overflow-y-auto">
|
|
||||||
// <div className="space-y-4">
|
|
||||||
// {signatureOptions.map((option) => (
|
|
||||||
// <div key={option.id} className="flex items-center space-x-4 px-2 py-1 border border-gray-200 rounded-lg hover:bg-gray-50 transition-colors">
|
|
||||||
// <input
|
|
||||||
// type="radio"
|
|
||||||
// id={`signature-${option.id}`}
|
|
||||||
// name="signature"
|
|
||||||
// checked={selectedSignature.id === option.id}
|
|
||||||
// onChange={() => setSelectedSignature({ id: option.id, style: option.style })}
|
|
||||||
// className="w-4 h-4 text-blue-600 focus:ring-blue-500"
|
|
||||||
// />
|
|
||||||
// <div className="flex-1 grid grid-cols-2 gap-2">
|
|
||||||
// <div className=" border-gray-300 rounded-lg px-2 py-1 bg-white ">
|
|
||||||
// <div className="text-xs text-gray-500 mb-2">Signed by:</div>
|
|
||||||
// <div className={`text-lg ${option.style === 'cursive' ? 'font-serif italic' :
|
|
||||||
// option.style === 'script' ? 'font-mono' :
|
|
||||||
// option.style === 'elegant' ? 'font-serif' :
|
|
||||||
// option.style === 'modern' ? 'font-sans tracking-wide' :
|
|
||||||
// 'font-sans'
|
|
||||||
// }`}>
|
|
||||||
// {fullName || option.name}
|
|
||||||
// </div>
|
|
||||||
// <div className="text-xs text-gray-400 mt-2">
|
|
||||||
// dca3e646-62cd-4cc...
|
|
||||||
// </div>
|
|
||||||
// </div>
|
|
||||||
// <div className=" rounded-lg px-2 py-2 bg-white ">
|
|
||||||
// <div className="text-xs text-gray-500 mb-2">DS</div>
|
|
||||||
// <div className={`text-2xl ${option.style === 'cursive' ? 'font-serif italic' :
|
|
||||||
// option.style === 'script' ? 'font-mono' :
|
|
||||||
// option.style === 'elegant' ? 'font-serif' :
|
|
||||||
// option.style === 'modern' ? 'font-sans tracking-wide' :
|
|
||||||
// 'font-sans'
|
|
||||||
// }`}>
|
|
||||||
// {initials || option.initials}
|
|
||||||
// </div>
|
|
||||||
// </div>
|
|
||||||
// </div>
|
|
||||||
// </div>
|
|
||||||
// ))}
|
|
||||||
// </div>
|
|
||||||
// </div>
|
|
||||||
// </div>
|
|
||||||
// );
|
|
||||||
|
|
||||||
// case 'DRAW':
|
|
||||||
// return (
|
|
||||||
// <DrawSignatureCanvas
|
|
||||||
// onSignatureChange={handleSignatureChange}
|
|
||||||
// // initialSignatures={isEditMode ? signatures : undefined}
|
|
||||||
// />
|
|
||||||
// );
|
|
||||||
|
|
||||||
// case 'UPLOAD':
|
|
||||||
// return (
|
|
||||||
// <div className="h-full flex flex-col">
|
|
||||||
// <div className="mb-6">
|
|
||||||
// <h2 className="text-xl font-semibold text-gray-900 mb-2">Upload Signature</h2>
|
|
||||||
// </div>
|
|
||||||
// <div className="flex-1 overflow-y-auto">
|
|
||||||
// <div>
|
|
||||||
// <div className="grid grid-cols-12 gap-6">
|
|
||||||
// {/* Upload 1 */}
|
|
||||||
// <div className="col-span-8">
|
|
||||||
// <label className="block text-sm font-medium text-gray-700 mb-2">Full Signature</label>
|
|
||||||
// <label htmlFor="upload1" className=" border-2 border-dashed border-gray-300 rounded-lg h-62 flex items-center justify-center bg-gray-50 hover:bg-gray-100 cursor-pointer transition-colors">
|
|
||||||
// {preview1 ? (
|
|
||||||
// <img src={preview1} alt="Signature Preview" className="max-h-44 object-contain" />
|
|
||||||
// ) : (
|
|
||||||
// <div className="text-center">
|
|
||||||
// <MdCloudUpload className="mx-auto h-12 w-12 text-gray-400 mb-3" />
|
|
||||||
// <p className="text-sm text-gray-500 mb-1">Click to upload or drag and drop</p>
|
|
||||||
// <p className="text-xs text-gray-400">PNG, JPG, GIF up to 10MB</p>
|
|
||||||
// </div>
|
|
||||||
// )}
|
|
||||||
// </label>
|
|
||||||
// <input
|
|
||||||
// id="upload1"
|
|
||||||
// type="file"
|
|
||||||
// accept="image/*"
|
|
||||||
// className="hidden"
|
|
||||||
// onChange={(e) => handleImageChange(e, setFile1, setPreview1, "fullSignature")}
|
|
||||||
// />
|
|
||||||
// </div>
|
|
||||||
|
|
||||||
// {/* Upload 2 */}
|
|
||||||
// <div className="col-span-4">
|
|
||||||
// <label className="block text-sm font-medium text-gray-700 mb-2">Initials</label>
|
|
||||||
// <label htmlFor="upload2" className=" border-2 border-dashed border-gray-300 rounded-lg h-62 flex items-center justify-center bg-gray-50 hover:bg-gray-100 cursor-pointer transition-colors">
|
|
||||||
// {preview2 ? (
|
|
||||||
// <img src={preview2} alt="Initials Preview" className="max-h-44 object-contain" />
|
|
||||||
// ) : (
|
|
||||||
// <div className="text-center">
|
|
||||||
// <MdCloudUpload className="mx-auto h-8 w-8 text-gray-400 mb-2" />
|
|
||||||
// <p className="text-xs text-gray-500">Upload initials</p>
|
|
||||||
// </div>
|
|
||||||
// )}
|
|
||||||
// </label>
|
|
||||||
// <input
|
|
||||||
// id="upload2"
|
|
||||||
// type="file"
|
|
||||||
// accept="image/*"
|
|
||||||
// className="hidden"
|
|
||||||
// onChange={(e) => handleImageChange(e, setFile2, setPreview2, "initials")}
|
|
||||||
// />
|
|
||||||
// </div>
|
|
||||||
// </div>
|
|
||||||
// </div>
|
|
||||||
// </div>
|
|
||||||
// </div>
|
|
||||||
// );
|
|
||||||
// case 'SAVED':
|
|
||||||
// return (
|
|
||||||
// <div className="h-full flex flex-col ">
|
|
||||||
// <div className="mb-6">
|
|
||||||
// <h2 className="text-xl font-semibold text-gray-900 mb-2">Saved Signature's</h2>
|
|
||||||
// {/* <p className="text-sm text-gray-600">Select from pre-designed signature styles</p> */}
|
|
||||||
// </div>
|
|
||||||
|
|
||||||
// <div className="flex-1 overflow-y-auto">
|
|
||||||
// <div className="space-y-4">
|
|
||||||
// {preSaveSignatures.map((signature) => (
|
|
||||||
// <div key={signature?.id} className="grid grid-cols-12 gap-4 px-6 py-9 hover:bg-gray-50 transition-colors duration-150">
|
|
||||||
// {/* Signature Column */}
|
|
||||||
// <div className="col-span-5">
|
|
||||||
// <div className="flex flex-col space-y-2 relative ps-6 border-l-3 border-blue-600 rounded-bl-2xl rounded-tl-2xl">
|
|
||||||
// <div className="text-sm text-gray-600 font-medium mb-1">
|
|
||||||
// Signed by:
|
|
||||||
// </div>
|
|
||||||
|
|
||||||
// {/* Signature Image or Fallback Text */}
|
|
||||||
// <div className="bg-white rounded-lg p-1 flex items-center justify-center">
|
|
||||||
// {signature?.signatureBlob ? (
|
|
||||||
// <img
|
|
||||||
// src={`data:${signature?.signatureMimeType || "image/png"};base64,${signature?.signatureBlob}`}
|
|
||||||
// className="h-[50px] w-[250px] object-contain"
|
|
||||||
// alt="Signature"
|
|
||||||
// />
|
|
||||||
// ) : (
|
|
||||||
// <div className="text-gray-400 italic text-sm">No Signature</div>
|
|
||||||
// )}
|
|
||||||
// </div>
|
|
||||||
|
|
||||||
// {/* Name */}
|
|
||||||
// <div className="text-xs text-gray-500 truncate">
|
|
||||||
// {signature?.signatureHash ?? ' '}
|
|
||||||
// </div>
|
|
||||||
// </div>
|
|
||||||
// </div>
|
|
||||||
|
|
||||||
// {/* Initial Column */}
|
|
||||||
// <div className="col-span-5">
|
|
||||||
// <div className="flex flex-col space-y-2 relative ps-6 border-l-3 border-green-600 rounded-bl-2xl rounded-tl-2xl">
|
|
||||||
// <div className="text-sm text-gray-600 font-medium mb-1">
|
|
||||||
// Initials
|
|
||||||
// </div>
|
|
||||||
|
|
||||||
// {/* Initials Image */}
|
|
||||||
// <div className="bg-white rounded-lg p-1 flex items-center justify-center">
|
|
||||||
// {signature?.initialsBlob ? (
|
|
||||||
// <img
|
|
||||||
// src={`data:image/png;base64,${signature?.initialsBlob}`}
|
|
||||||
// className="h-[50px] object-contain"
|
|
||||||
// alt="Initials"
|
|
||||||
// />
|
|
||||||
// ) : (
|
|
||||||
// <div className="text-gray-400 italic text-sm">No Initials</div>
|
|
||||||
// )}
|
|
||||||
// </div>
|
|
||||||
|
|
||||||
// {/* Optional initials hash or font */}
|
|
||||||
// <div className="text-xs text-gray-500 truncate">
|
|
||||||
// {signature?.initialsHash || " "}
|
|
||||||
// </div>
|
|
||||||
// </div>
|
|
||||||
// </div>
|
|
||||||
// </div>
|
|
||||||
// ))}
|
|
||||||
|
|
||||||
// </div>
|
|
||||||
// </div>
|
|
||||||
// </div>
|
|
||||||
// );
|
|
||||||
|
|
||||||
// default:
|
|
||||||
// return null;
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
|
|
||||||
|
|
||||||
const renderSignatureText = (type, font, firstName, lastName, mode = 'name') => {
|
const renderSignatureText = (type, font, firstName, lastName, mode = 'name') => {
|
||||||
if (type !== 'SELECT') return null;
|
if (type != 'SELECT') return null;
|
||||||
|
|
||||||
const selectedFont = signatureOptions.find(opt => opt.style === font);
|
const selectedFont = signatureOptions.find(opt => opt.style == font);
|
||||||
const fontClass = `${selectedFont?.style || 'print'}`;
|
const fontClass = `${selectedFont?.style || 'print'}`;
|
||||||
console.log("fontClass", fontClass)
|
console.log("fontClass", fontClass)
|
||||||
|
|
||||||
|
|
||||||
if (mode === 'initials') {
|
if (mode == 'initials') {
|
||||||
const initials = `${(firstName?.[0] ?? '')}${(lastName?.[0] ?? '')}`.toUpperCase();
|
const initials = `${(firstName?.[0] ?? '')}${(lastName?.[0] ?? '')}`.toUpperCase();
|
||||||
return (
|
return (
|
||||||
<div className={`text-center text-[24px]`} style={{ fontFamily: selectedFont?.style }}>
|
<div className={`text-center text-[24px]`} style={{ fontFamily: selectedFont?.style }}>
|
||||||
|
|
@ -579,10 +341,12 @@ const ClientSignCon: React.FC<ClientSignConProps> = ({
|
||||||
case 'SELECT':
|
case 'SELECT':
|
||||||
return (
|
return (
|
||||||
<div className="px-4 lg:px-6 py-4 flex-shrink-0">
|
<div className="px-4 lg:px-6 py-4 flex-shrink-0">
|
||||||
<h2 className='mt-4 mb-5 text-sm'>Confirm your name and choose signature style. *Are required fields.</h2>
|
<h2 className='mt-4 mb-5 text-sm'>
|
||||||
|
Confirm your name and choose signature style. *Are required fields.
|
||||||
|
</h2>
|
||||||
|
|
||||||
<div className="grid grid-cols-2 gap-3">
|
<div className="grid grid-cols-2 gap-3 mb-6">
|
||||||
<div className=''>
|
<div>
|
||||||
<label className="block text-sm font-medium mb-2">
|
<label className="block text-sm font-medium mb-2">
|
||||||
Full Name
|
Full Name
|
||||||
<span className='text-red-600'> *</span>
|
<span className='text-red-600'> *</span>
|
||||||
|
|
@ -590,29 +354,57 @@ const ClientSignCon: React.FC<ClientSignConProps> = ({
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
value={fullName}
|
value={fullName}
|
||||||
onChange={(e) => setFullName(e.target.value)}
|
onChange={(e) => {
|
||||||
|
setFullName(e.target.value)
|
||||||
|
setInitials(e.target.value.trim().split(' ').length > 1 ? e.target.value.split(' ')[0][0]+""+e.target.value.split(' ')[1][0] : e.target.value.split(' ')[0][0])
|
||||||
|
}}
|
||||||
placeholder="Enter full name"
|
placeholder="Enter full name"
|
||||||
className="w-full px-3 py-2 text-sm border border-gray-200 rounded-md outline-none"
|
className="w-full px-3 py-2 text-sm border border-gray-200 rounded-md outline-none"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className=''>
|
<div>
|
||||||
<label className="block text-sm font-medium mb-2">
|
<label className="block text-sm font-medium mb-2">
|
||||||
Initials
|
Initials
|
||||||
<span className='text-red-600'> *</span>
|
<span className='text-red-600'> *</span>
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
|
disabled
|
||||||
value={initials}
|
value={initials}
|
||||||
onChange={(e) => setInitials(e.target.value)}
|
// onChange={(e) => setInitials(e.target.value)}
|
||||||
placeholder="Enter initials"
|
placeholder="Enter initials"
|
||||||
className="w-full px-3 py-2 text-sm border border-gray-200 rounded-md outline-none"
|
className="w-full px-3 py-2 text-sm border border-gray-200 rounded-md outline-none"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Signature Style Options */}
|
||||||
|
<div className="grid grid-cols-2 gap-4">
|
||||||
|
{fontsMap.map((opt) => (
|
||||||
|
<div
|
||||||
|
key={opt.acronym}
|
||||||
|
onClick={() => setSelectedSignature({ id: opt.acronym, style: opt.style })}
|
||||||
|
className={`cursor-pointer border border-slate-200 rounded-xl p-4 text-center bg-white transition
|
||||||
|
${selectedSignature.id == opt.acronym
|
||||||
|
? "ring-2 ring-[var(--mainPrimaryBtn)]"
|
||||||
|
: "hover:shadow-md"}`}
|
||||||
|
>
|
||||||
|
<div style={{ fontFamily: opt.style, fontSize: "1.75rem" }}>
|
||||||
|
{fullName || "Full Name"}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
style={{ fontFamily: opt.style, fontSize: "1.25rem", opacity: 0.7 }}
|
||||||
|
>
|
||||||
|
{initials || "AB"}
|
||||||
|
</div>
|
||||||
|
<p className="text-xs mt-2 text-gray-500">{opt.label}</p>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
case 'DRAW':
|
case 'DRAW':
|
||||||
return (
|
return (
|
||||||
<div className="h-full">
|
<div className="h-full">
|
||||||
|
|
@ -716,12 +508,12 @@ const ClientSignCon: React.FC<ClientSignConProps> = ({
|
||||||
{/* Horizontal Scrollable List */}
|
{/* Horizontal Scrollable List */}
|
||||||
<div className="flex-1 overflow-x-auto px-2 sm:px-6">
|
<div className="flex-1 overflow-x-auto px-2 sm:px-6">
|
||||||
<div className="flex flex-col space-x-4 max-h-[40vh] gap-2">
|
<div className="flex flex-col space-x-4 max-h-[40vh] gap-2">
|
||||||
{preSaveSignatures.map((signature) => (
|
{preSaveSignatures.map((signature: Signature) => (
|
||||||
<div
|
<div
|
||||||
key={signature?.id}
|
key={signature?.id}
|
||||||
onClick={() => setSelectedSignature(signature?.id)}
|
onClick={() => setSelectedSignature({ id: signature?.id, style: "" })}
|
||||||
className={`cursor-pointer bg-white rounded-xl border p-4 w-full flex justify-between items-start transition-shadow duration-200 gap-3
|
className={`cursor-pointer bg-white rounded-xl border p-4 w-full flex justify-between items-start transition-shadow duration-200 gap-3
|
||||||
${selectedSignature === signature?.id ? 'border-blue-500 shadow-lg' : 'border-gray-200'}
|
${selectedSignature.id == signature?.id ? 'border-blue-500 shadow-lg' : 'border-gray-200'}
|
||||||
`}
|
`}
|
||||||
style={{ minWidth: '220px' }} // each card width
|
style={{ minWidth: '220px' }} // each card width
|
||||||
>
|
>
|
||||||
|
|
@ -729,7 +521,7 @@ const ClientSignCon: React.FC<ClientSignConProps> = ({
|
||||||
<div className="w-[60%] flex flex-col">
|
<div className="w-[60%] flex flex-col">
|
||||||
<span className="text-sm font-medium text-gray-600 mb-1">Signed by:</span>
|
<span className="text-sm font-medium text-gray-600 mb-1">Signed by:</span>
|
||||||
<div className="w-full bg-gray-50 rounded-lg p-2 flex items-center justify-center min-h-[60px]">
|
<div className="w-full bg-gray-50 rounded-lg p-2 flex items-center justify-center min-h-[60px]">
|
||||||
{signature?.signatureType !== 'SELECT' && signature?.signatureBlob ? (
|
{signature?.signatureType != 'SELECT' && signature?.signatureBlob ? (
|
||||||
<img
|
<img
|
||||||
src={`data:${signature?.signatureMimeType};base64,${signature?.signatureBlob}`}
|
src={`data:${signature?.signatureMimeType};base64,${signature?.signatureBlob}`}
|
||||||
className="w-full h-12 object-contain"
|
className="w-full h-12 object-contain"
|
||||||
|
|
@ -752,7 +544,7 @@ const ClientSignCon: React.FC<ClientSignConProps> = ({
|
||||||
<div className="w-[40%] flex flex-col">
|
<div className="w-[40%] flex flex-col">
|
||||||
<span className="text-sm font-medium text-gray-600 mb-1">Initials</span>
|
<span className="text-sm font-medium text-gray-600 mb-1">Initials</span>
|
||||||
<div className="bg-gray-50 rounded-lg p-1 flex items-center justify-center min-h-[40px]">
|
<div className="bg-gray-50 rounded-lg p-1 flex items-center justify-center min-h-[40px]">
|
||||||
{signature?.signatureType !== 'SELECT' && signature?.initialsBlob ? (
|
{signature?.signatureType != 'SELECT' && signature?.initialsBlob ? (
|
||||||
<img
|
<img
|
||||||
src={`data:${signature?.initialsMimeType};base64,${signature?.initialsBlob}`}
|
src={`data:${signature?.initialsMimeType};base64,${signature?.initialsBlob}`}
|
||||||
className="w-full h-10 object-contain"
|
className="w-full h-10 object-contain"
|
||||||
|
|
@ -835,17 +627,17 @@ const ClientSignCon: React.FC<ClientSignConProps> = ({
|
||||||
<button
|
<button
|
||||||
key={item.id}
|
key={item.id}
|
||||||
onClick={() => setActiveTab(item.id as 'SELECT' | 'DRAW' | 'UPLOAD')}
|
onClick={() => setActiveTab(item.id as 'SELECT' | 'DRAW' | 'UPLOAD')}
|
||||||
className={`flex items-center justify-start space-x-2 px-3 py-4 text-sm font-medium transition-all duration-200 whitespace-nowrap ${activeTab === item.id
|
className={`flex items-center justify-start space-x-2 px-3 py-4 text-sm font-medium transition-all duration-200 whitespace-nowrap ${activeTab == item.id
|
||||||
? ' text-[var(--primary)]'
|
? ' text-[var(--primary)]'
|
||||||
: 'text-gray-400'
|
: 'text-gray-400'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<span className={activeTab === item.id ? 'text-[var(--mainPrimaryBtn)]' : 'text-gray-400'}>
|
<span className={activeTab == item.id ? 'text-[var(--mainPrimaryBtn)]' : 'text-gray-400'}>
|
||||||
{item.icon}
|
{item.icon}
|
||||||
</span>
|
</span>
|
||||||
<span>{item.label}</span>
|
<span>{item.label}</span>
|
||||||
</button>
|
</button>
|
||||||
{activeTab === item.id && <div className='absolute bottom-[-1px] w-full h-[3px] bg-[var(--mainPrimaryBtn)]'></div>}
|
{activeTab == item.id && <div className='absolute bottom-[-1px] w-full h-[3px] bg-[var(--mainPrimaryBtn)]'></div>}
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
))}
|
))}
|
||||||
|
|
|
||||||
|
|
@ -144,19 +144,19 @@ const Draw: React.FC<DrawProps> = ({ saved, setSaved }) => {
|
||||||
|
|
||||||
<div className="flex flex-col md:flex-row not-first:flex justify-center gap-4 w-full">
|
<div className="flex flex-col md:flex-row not-first:flex justify-center gap-4 w-full">
|
||||||
{[canvasRef1, canvasRef2].map((ref, index) => {
|
{[canvasRef1, canvasRef2].map((ref, index) => {
|
||||||
const setIsDrawing = index === 0 ? setIsDrawing1 : setIsDrawing2;
|
const setIsDrawing = index == 0 ? setIsDrawing1 : setIsDrawing2;
|
||||||
const isDrawing = index === 0 ? isDrawing1 : isDrawing2;
|
const isDrawing = index == 0 ? isDrawing1 : isDrawing2;
|
||||||
const setHasDrawn = index === 0 ? setHasDrawn1 : setHasDrawn2;
|
const setHasDrawn = index == 0 ? setHasDrawn1 : setHasDrawn2;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div key={index}>
|
<div key={index}>
|
||||||
<div className='flex justify-between items-center w-full'>
|
<div className='flex justify-between items-center w-full'>
|
||||||
<p className='text-slate-400 font-semibold pointer-events-none'>{index === 0 ? "Signature" : "Initial"}</p>
|
<p className='text-slate-400 font-semibold pointer-events-none'>{index == 0 ? "Signature" : "Initial"}</p>
|
||||||
<div className='flex justify-center items-center gap-1'>
|
<div className='flex justify-center items-center gap-1'>
|
||||||
<div className="flex cursor-pointer">
|
<div className="flex cursor-pointer">
|
||||||
{['black', 'blue', 'red', 'green'].map((color) => (
|
{['black', 'blue', 'red', 'green'].map((color) => (
|
||||||
<div
|
<div
|
||||||
className={`w-4 h-4 rounded-sm shadow mr-1 flex justify-center items-center ${selectedColor === color ? 'scale-110' : 'scale-100'} transition-all`}
|
className={`w-4 h-4 rounded-sm shadow mr-1 flex justify-center items-center ${selectedColor == color ? 'scale-110' : 'scale-100'} transition-all`}
|
||||||
key={color}
|
key={color}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setSelectedColor(color as any);
|
setSelectedColor(color as any);
|
||||||
|
|
@ -166,7 +166,7 @@ const Draw: React.FC<DrawProps> = ({ saved, setSaved }) => {
|
||||||
style={{ backgroundColor: color }}
|
style={{ backgroundColor: color }}
|
||||||
>
|
>
|
||||||
{/* */}
|
{/* */}
|
||||||
{selectedColor === color && <FaCheck className='fill-white text-xs p-[1.5px]' />}
|
{selectedColor == color && <FaCheck className='fill-white text-xs p-[1.5px]' />}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -20,12 +20,12 @@ const SignUpload: React.FC<SignUploadProps> = ({ saved, setSaved }) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const file = e.dataTransfer.files[0];
|
const file = e.dataTransfer.files[0];
|
||||||
if (file && file.type.startsWith('image/')) {
|
if (file && file.type.startsWith('image/')) {
|
||||||
type === 'signature' ? setSignatureFile(file) : setInitialFile(file);
|
type == 'signature' ? setSignatureFile(file) : setInitialFile(file);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleClick = (type: 'signature' | 'initial') => {
|
const handleClick = (type: 'signature' | 'initial') => {
|
||||||
if (type === 'signature') signatureInputRef.current?.click();
|
if (type == 'signature') signatureInputRef.current?.click();
|
||||||
else initialInputRef.current?.click();
|
else initialInputRef.current?.click();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -35,7 +35,7 @@ const SignUpload: React.FC<SignUploadProps> = ({ saved, setSaved }) => {
|
||||||
// ) => {
|
// ) => {
|
||||||
// const file = e.target.files?.[0];
|
// const file = e.target.files?.[0];
|
||||||
// if (file && file.type.startsWith('image/')) {
|
// if (file && file.type.startsWith('image/')) {
|
||||||
// type === 'signature' ? setSignatureFile(file) : setInitialFile(file);
|
// type == 'signature' ? setSignatureFile(file) : setInitialFile(file);
|
||||||
// }
|
// }
|
||||||
// };
|
// };
|
||||||
|
|
||||||
|
|
@ -44,7 +44,7 @@ const SignUpload: React.FC<SignUploadProps> = ({ saved, setSaved }) => {
|
||||||
const reader = new FileReader();
|
const reader = new FileReader();
|
||||||
reader.readAsDataURL(file);
|
reader.readAsDataURL(file);
|
||||||
reader.onload = () => {
|
reader.onload = () => {
|
||||||
if (typeof reader.result === 'string') {
|
if (typeof reader.result == 'string') {
|
||||||
resolve(reader.result);
|
resolve(reader.result);
|
||||||
} else {
|
} else {
|
||||||
reject(new Error('FileReader result is not a string'));
|
reject(new Error('FileReader result is not a string'));
|
||||||
|
|
@ -61,7 +61,7 @@ const SignUpload: React.FC<SignUploadProps> = ({ saved, setSaved }) => {
|
||||||
if (file && file.type.startsWith('image/')) {
|
if (file && file.type.startsWith('image/')) {
|
||||||
try {
|
try {
|
||||||
const base64 = await toBase64(file);
|
const base64 = await toBase64(file);
|
||||||
type === 'signature' ? setSignatureFile(base64) : setInitialFile(base64);
|
type == 'signature' ? setSignatureFile(base64) : setInitialFile(base64);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error converting file to base64:', error);
|
console.error('Error converting file to base64:', error);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ const SignatureCon: React.FC<SignatureConProps> = ({ recipientId, openSign, setO
|
||||||
},
|
},
|
||||||
{ headers: { "ngrok-skip-browser-warning": "69420", } })
|
{ headers: { "ngrok-skip-browser-warning": "69420", } })
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.status === 200 || res.status === 201) {
|
if (res.status == 200 || res.status == 201) {
|
||||||
setSavedSignature(signatureDataUrl);
|
setSavedSignature(signatureDataUrl);
|
||||||
setOpenSign(false)
|
setOpenSign(false)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ const StampUpload: React.FC<StampUploadType> = ({ stamp, setStamp }) => {
|
||||||
|
|
||||||
|
|
||||||
reader.onload = () => {
|
reader.onload = () => {
|
||||||
if (typeof reader.result === 'string') {
|
if (typeof reader.result == 'string') {
|
||||||
setStamp((prev) => {
|
setStamp((prev) => {
|
||||||
return (
|
return (
|
||||||
{
|
{
|
||||||
|
|
@ -40,7 +40,7 @@ const StampUpload: React.FC<StampUploadType> = ({ stamp, setStamp }) => {
|
||||||
if (file && file.type.startsWith('image/')) {
|
if (file && file.type.startsWith('image/')) {
|
||||||
const reader = new FileReader();
|
const reader = new FileReader();
|
||||||
reader.onload = () => {
|
reader.onload = () => {
|
||||||
if (typeof reader.result === 'string') {
|
if (typeof reader.result == 'string') {
|
||||||
setStamp((prev) => {
|
setStamp((prev) => {
|
||||||
return (
|
return (
|
||||||
{
|
{
|
||||||
|
|
@ -149,7 +149,7 @@ const StampUpload: React.FC<StampUploadType> = ({ stamp, setStamp }) => {
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{stamp.length === 0 && <input
|
{stamp.length == 0 && <input
|
||||||
ref={fileInputRef}
|
ref={fileInputRef}
|
||||||
type="file"
|
type="file"
|
||||||
accept="image/*"
|
accept="image/*"
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ const TemplateTable = () => {
|
||||||
templateId: item.id,
|
templateId: item.id,
|
||||||
};
|
};
|
||||||
const res = await api.post(`/api/v1/accounts/${activeAccountId}/transactions`, payload);
|
const res = await api.post(`/api/v1/accounts/${activeAccountId}/transactions`, payload);
|
||||||
navigate(`/process-step-one/${activeAccountId}/${res?.data?.id}?useTemplate=true`);
|
navigate(`/setup-transaction/${activeAccountId}/${res?.data?.id}?useTemplate=true`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
|
|
@ -91,14 +91,14 @@ const TemplateTable = () => {
|
||||||
|
|
||||||
const handleEditClick = (templateId: string) => {
|
const handleEditClick = (templateId: string) => {
|
||||||
setShowMenu({ open: false, templateId: null });
|
setShowMenu({ open: false, templateId: null });
|
||||||
navigate(`/process-step-one/${activeAccountId}/template/${templateId}`);
|
navigate(`/setup-transaction/${activeAccountId}/template/${templateId}`);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDeleteClick = async (templateId: string) => {
|
const handleDeleteClick = async (templateId: string) => {
|
||||||
setShowMenu({ open: false, templateId: null });
|
setShowMenu({ open: false, templateId: null });
|
||||||
try {
|
try {
|
||||||
await api.delete(`/api/v1/accounts/${activeAccountId}/templates/${templateId}`);
|
await api.delete(`/api/v1/accounts/${activeAccountId}/templates/${templateId}`);
|
||||||
setTemplates((prev) => prev.filter((temp) => temp.id !== Number(templateId)));
|
setTemplates((prev) => prev.filter((temp) => temp.id != templateId));
|
||||||
setShowTemplateDeleteWarnModal({ show: false, templateId: "" });
|
setShowTemplateDeleteWarnModal({ show: false, templateId: "" });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
|
|
@ -108,7 +108,7 @@ const TemplateTable = () => {
|
||||||
return (
|
return (
|
||||||
<div className="bg-white rounded-xl shadow-sm border border-gray-200 overflow-hidden p-5">
|
<div className="bg-white rounded-xl shadow-sm border border-gray-200 overflow-hidden p-5">
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
{location.pathname !== "/templates" && (
|
{location.pathname != "/templates" && (
|
||||||
<div className="flex justify-between items-center pb-3">
|
<div className="flex justify-between items-center pb-3">
|
||||||
<h2 className="text-lg font-semibold text-gray-800">Recent Templates</h2>
|
<h2 className="text-lg font-semibold text-gray-800">Recent Templates</h2>
|
||||||
<span
|
<span
|
||||||
|
|
@ -122,7 +122,7 @@ const TemplateTable = () => {
|
||||||
|
|
||||||
{/* Table */}
|
{/* Table */}
|
||||||
<div
|
<div
|
||||||
className={`overflow-auto rounded-lg ${location.pathname === "/templates"
|
className={`overflow-auto rounded-lg ${location.pathname == "/templates"
|
||||||
? "min-h-[70vh] max-h-[70vh]"
|
? "min-h-[70vh] max-h-[70vh]"
|
||||||
: "min-h-[30vh] max-h-[50vh]"
|
: "min-h-[30vh] max-h-[50vh]"
|
||||||
}`}
|
}`}
|
||||||
|
|
@ -151,7 +151,7 @@ const TemplateTable = () => {
|
||||||
{templates.map((template, idx) => (
|
{templates.map((template, idx) => (
|
||||||
<tr
|
<tr
|
||||||
key={template.id}
|
key={template.id}
|
||||||
className={`${idx % 2 !== 0 ? "bg-gray-50" : "bg-white"
|
className={`${idx % 2 != 0 ? "bg-gray-50" : "bg-white"
|
||||||
} border-b border-gray-300 hover:bg-gray-100 transition`}
|
} border-b border-gray-300 hover:bg-gray-100 transition`}
|
||||||
>
|
>
|
||||||
<td className="px-6 py-3 text-gray-800 font-medium truncate max-w-xs">
|
<td className="px-6 py-3 text-gray-800 font-medium truncate max-w-xs">
|
||||||
|
|
@ -170,7 +170,7 @@ const TemplateTable = () => {
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
setShowMenu({
|
setShowMenu({
|
||||||
open:
|
open:
|
||||||
showMenu.open && showMenu.templateId === template.id ? false : true,
|
showMenu.open && showMenu.templateId == template.id ? false : true,
|
||||||
templateId: template.id,
|
templateId: template.id,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -179,7 +179,7 @@ const TemplateTable = () => {
|
||||||
<PiDotsThreeOutlineVerticalFill className="text-lg" />
|
<PiDotsThreeOutlineVerticalFill className="text-lg" />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
{showMenu.open && showMenu.templateId === template.id && (
|
{showMenu.open && showMenu.templateId == template.id && (
|
||||||
<div className="absolute right-0 mt-2 w-40 bg-white border border-gray-200 rounded-lg shadow-lg z-20 animate-fade-in">
|
<div className="absolute right-0 mt-2 w-40 bg-white border border-gray-200 rounded-lg shadow-lg z-20 animate-fade-in">
|
||||||
<button
|
<button
|
||||||
onClick={() => handleUseClick(template)}
|
onClick={() => handleUseClick(template)}
|
||||||
|
|
@ -254,8 +254,8 @@ const TemplateTable = () => {
|
||||||
|
|
||||||
<button
|
<button
|
||||||
onClick={() => setPage((prev) => Math.max(prev - 1, 0))}
|
onClick={() => setPage((prev) => Math.max(prev - 1, 0))}
|
||||||
disabled={page === 0}
|
disabled={page == 0}
|
||||||
className={`px-3 py-1 rounded border ${page === 0
|
className={`px-3 py-1 rounded border ${page == 0
|
||||||
? "bg-gray-100 text-gray-400 cursor-not-allowed"
|
? "bg-gray-100 text-gray-400 cursor-not-allowed"
|
||||||
: "bg-white hover:bg-gray-50"
|
: "bg-white hover:bg-gray-50"
|
||||||
}`}
|
}`}
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ const Templates = () => {
|
||||||
await dispatch(resetRecipients())
|
await dispatch(resetRecipients())
|
||||||
await dispatch(resetDocuments())
|
await dispatch(resetDocuments())
|
||||||
const res = await api.post(`/api/v1/accounts/${activeAccountId}/templates`);
|
const res = await api.post(`/api/v1/accounts/${activeAccountId}/templates`);
|
||||||
navigate(`/process-step-one/${activeAccountId}/template/${res.data.id}`)
|
navigate(`/setup-transaction/${activeAccountId}/template/${res.data.id}`)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error)
|
console.log(error)
|
||||||
}
|
}
|
||||||
|
|
@ -59,7 +59,7 @@ const Templates = () => {
|
||||||
key={filter}
|
key={filter}
|
||||||
onClick={() => setActiveFilter(filter)}
|
onClick={() => setActiveFilter(filter)}
|
||||||
className={`px-3 py-1 rounded-full text-xs border transition
|
className={`px-3 py-1 rounded-full text-xs border transition
|
||||||
${activeFilter === filter
|
${activeFilter == filter
|
||||||
? "bg-[var(--primary)] text-white"
|
? "bg-[var(--primary)] text-white"
|
||||||
: "border-gray-300 text-gray-600 hover:bg-gray-100"
|
: "border-gray-300 text-gray-600 hover:bg-gray-100"
|
||||||
}`}
|
}`}
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ const AuditModal: React.FC<AuditModalProps> = ({ closeModal }) => {
|
||||||
try {
|
try {
|
||||||
let res = await api.get(`/api/v1/accounts/${accountId}/transactions/${transactionId}/audit/events?lang=${userDetails.language || ''}`)
|
let res = await api.get(`/api/v1/accounts/${accountId}/transactions/${transactionId}/audit/events?lang=${userDetails.language || ''}`)
|
||||||
// let res = await api.get(`/api/v1/accounts/${accountId}/transactions/${transactionId}/audit?lang=hi`)
|
// let res = await api.get(`/api/v1/accounts/${accountId}/transactions/${transactionId}/audit?lang=hi`)
|
||||||
if (res?.status === 200) {
|
if (res?.status == 200) {
|
||||||
// console.log(res?.data?.events)
|
// console.log(res?.data?.events)
|
||||||
let auditResponse = res?.data?.events
|
let auditResponse = res?.data?.events
|
||||||
setAuditStatus(auditResponse)
|
setAuditStatus(auditResponse)
|
||||||
|
|
@ -154,9 +154,9 @@ const AuditModal: React.FC<AuditModalProps> = ({ closeModal }) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const getActionColor = (action: string, status: string) => {
|
const getActionColor = (action: string, status: string) => {
|
||||||
if (status === 'COMPLETED') return 'text-green-600';
|
if (status == 'COMPLETED') return 'text-green-600';
|
||||||
if (status === 'FAILED' || status === 'REJECTED') return 'text-red-600';
|
if (status == 'FAILED' || status == 'REJECTED') return 'text-red-600';
|
||||||
if (status === 'PENDING') return 'text-yellow-600';
|
if (status == 'PENDING') return 'text-yellow-600';
|
||||||
|
|
||||||
const colors = {
|
const colors = {
|
||||||
'SENT': 'text-blue-600',
|
'SENT': 'text-blue-600',
|
||||||
|
|
@ -296,7 +296,7 @@ const AuditModal: React.FC<AuditModalProps> = ({ closeModal }) => {
|
||||||
{/* Footer */}
|
{/* Footer */}
|
||||||
<div className="flex justify-between items-center p-3 border-t border-gray-200 bg-gray-50 text-sm">
|
<div className="flex justify-between items-center p-3 border-t border-gray-200 bg-gray-50 text-sm">
|
||||||
<div className="text-gray-600">
|
<div className="text-gray-600">
|
||||||
Showing {auditStatus.length} event{auditStatus.length !== 1 ? 's' : ''}
|
Showing {auditStatus.length} event{auditStatus.length != 1 ? 's' : ''}
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
onClick={closeModal}
|
onClick={closeModal}
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,7 @@ const TransactionView = () => {
|
||||||
const fetchDocuments = async () => {
|
const fetchDocuments = async () => {
|
||||||
try {
|
try {
|
||||||
const res = await api.get(`/api/v1/accounts/${accountId}/transactions/${transactionId}/documents`)
|
const res = await api.get(`/api/v1/accounts/${accountId}/transactions/${transactionId}/documents`)
|
||||||
if (res?.status === 200) {
|
if (res?.status == 200) {
|
||||||
let resDoc = res?.data
|
let resDoc = res?.data
|
||||||
setDocumentsData(resDoc)
|
setDocumentsData(resDoc)
|
||||||
}
|
}
|
||||||
|
|
@ -162,7 +162,7 @@ const TransactionView = () => {
|
||||||
More
|
More
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
{transactionDetails.transaction.status === "CREATED" && <Link className='cursor-pointer border text-green-700 border-gray-300 rounded-sm px-4 py-1 hover:bg-gray-100 font-bold' to={`/process-step-one/${accountId}/${transactionId}`}>
|
{transactionDetails.transaction.status == "CREATED" && <Link className='cursor-pointer border text-green-700 border-gray-300 rounded-sm px-4 py-1 hover:bg-gray-100 font-bold' to={`/setup-transaction/${accountId}/${transactionId}`}>
|
||||||
Edit
|
Edit
|
||||||
</Link>}
|
</Link>}
|
||||||
|
|
||||||
|
|
@ -212,14 +212,14 @@ const TransactionView = () => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Right section: status and actions */}
|
{/* Right section: status and actions */}
|
||||||
{recipient.type.toLowerCase() !== "cc" && <div className="flex flex-col items-start sm:items-end gap-1 text-sm text-slate-600">
|
{recipient.type.toLowerCase() != "cc" && <div className="flex flex-col items-start sm:items-end gap-1 text-sm text-slate-600">
|
||||||
<div className="flex flex-wrap gap-3 items-center relative">
|
<div className="flex flex-wrap gap-3 items-center relative">
|
||||||
<div className="pl-6 relative">
|
<div className="pl-6 relative">
|
||||||
<AiFillSignature className="absolute left-0 top-0 text-[1rem]" />
|
<AiFillSignature className="absolute left-0 top-0 text-[1rem]" />
|
||||||
<p className={`text-black text-xs font-semibold rounded-lg px-2 py-0.5 ${getStatusBadge(recipient.status)}`}>{recipient.status}</p>
|
<p className={`text-black text-xs font-semibold rounded-lg px-2 py-0.5 ${getStatusBadge(recipient.status)}`}>{recipient.status}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{transactionDetails.transaction.status === "SENT" && recipient.email === user.email && recipient.status === "PENDING" && (
|
{transactionDetails.transaction.status == "SENT" && recipient.email == user.email && recipient.status == "PENDING" && (
|
||||||
<button
|
<button
|
||||||
onClick={() => handleNavigateToSign(recipient.id)}
|
onClick={() => handleNavigateToSign(recipient.id)}
|
||||||
className="text-white rounded-sm bg-[var(--primary)] px-3 py-1 font-semibold text-xs hover:bg-opacity-90 transition cursor-pointer"
|
className="text-white rounded-sm bg-[var(--primary)] px-3 py-1 font-semibold text-xs hover:bg-opacity-90 transition cursor-pointer"
|
||||||
|
|
@ -229,7 +229,7 @@ const TransactionView = () => {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{recipient.status !== "PENDING" && (
|
{recipient.status != "PENDING" && (
|
||||||
<p className="text-xs text-gray-500">on {recipient.completedAt}</p>
|
<p className="text-xs text-gray-500">on {recipient.completedAt}</p>
|
||||||
)}
|
)}
|
||||||
{/* Optional signed document link */}
|
{/* Optional signed document link */}
|
||||||
|
|
@ -249,13 +249,13 @@ const TransactionView = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
{transactionDetails?.transaction?.subject !== "" &&
|
{transactionDetails?.transaction?.subject != "" &&
|
||||||
<div>
|
<div>
|
||||||
<h2 className='text-lg mt-4 font-semibold text-gray-800 cursor-pointer'>Subject</h2>
|
<h2 className='text-lg mt-4 font-semibold text-gray-800 cursor-pointer'>Subject</h2>
|
||||||
<p className='mt-2 text-slate-600'>{`${transactionDetails?.transaction?.subject ? transactionDetails?.transaction?.subject : "Not Found"} `}</p>
|
<p className='mt-2 text-slate-600'>{`${transactionDetails?.transaction?.subject ? transactionDetails?.transaction?.subject : "Not Found"} `}</p>
|
||||||
</div>}
|
</div>}
|
||||||
|
|
||||||
{transactionDetails?.transaction?.message !== "" &&
|
{transactionDetails?.transaction?.message != "" &&
|
||||||
<div>
|
<div>
|
||||||
<h2 className='text-lg mt-4 font-semibold text-gray-800 cursor-pointer'>Message</h2>
|
<h2 className='text-lg mt-4 font-semibold text-gray-800 cursor-pointer'>Message</h2>
|
||||||
<p className='mt-2 text-slate-600'>{`${transactionDetails?.transaction?.message ? transactionDetails?.transaction?.message : "Not Found"} `}</p>
|
<p className='mt-2 text-slate-600'>{`${transactionDetails?.transaction?.message ? transactionDetails?.transaction?.message : "Not Found"} `}</p>
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ const Transactions = () => {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
api.get<TransactionResponse>(
|
api.get<TransactionResponse>(
|
||||||
`api/transaction?transactionStatus=${filterParam === "all" ? "" : filterParam?.toUpperCase()}`
|
`api/transaction?transactionStatus=${filterParam == "all" ? "" : filterParam?.toUpperCase()}`
|
||||||
)
|
)
|
||||||
.then(res => setTransactionData(res.data.content))
|
.then(res => setTransactionData(res.data.content))
|
||||||
.catch(err => console.error(err));
|
.catch(err => console.error(err));
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ const DocView = () => {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let indx = fitObj[selFitIndx].value
|
let indx = fitObj[selFitIndx].value
|
||||||
if (indx === "FIT") {
|
if (indx == "FIT") {
|
||||||
indx = "100";
|
indx = "100";
|
||||||
}
|
}
|
||||||
zoom(Number(indx), 'zoom-con')
|
zoom(Number(indx), 'zoom-con')
|
||||||
|
|
@ -108,7 +108,7 @@ const DocView = () => {
|
||||||
|
|
||||||
className='flex items-center justify-between w-full'>
|
className='flex items-center justify-between w-full'>
|
||||||
<p className='whitespace-nowrap overflow-hidden text-ellipsis max-w-[12ch]'>{val.label}</p>
|
<p className='whitespace-nowrap overflow-hidden text-ellipsis max-w-[12ch]'>{val.label}</p>
|
||||||
{selFitIndx === indx && <FaCheck className='text-sm text-slate-400' />}
|
{selFitIndx == indx && <FaCheck className='text-sm text-slate-400' />}
|
||||||
</div>
|
</div>
|
||||||
</div>)
|
</div>)
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -46,22 +46,24 @@ let isRefreshing = false;
|
||||||
// Response interceptor
|
// Response interceptor
|
||||||
api.interceptors.response.use(
|
api.interceptors.response.use(
|
||||||
response => {
|
response => {
|
||||||
if (window.location.pathname === "/login" || window.location.pathname === "/register") {
|
if (window.location.pathname == "/login" || window.location.pathname == "/register") {
|
||||||
window.location.href = "/";
|
window.location.href = "/";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof response.data === 'string' && response.data.toLowerCase().includes('<!doctype html>')) {
|
if (response && (response.status == 301 || response.status == 302)) {
|
||||||
// Likely a full HTML page, handle accordinglys
|
|
||||||
window.location.href = response.request.responseURL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (response && (response.status === 301 || response.status === 302)) {
|
|
||||||
const redirectUrl = response.headers["location"];
|
const redirectUrl = response.headers["location"];
|
||||||
if (redirectUrl) {
|
if (redirectUrl) {
|
||||||
window.location.href = redirectUrl;
|
window.location.href = redirectUrl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (typeof response.data == 'string' && response.data.toLowerCase().includes('<!doctype html>')) {
|
||||||
|
// Likely a full HTML page, handle accordinglys
|
||||||
|
if("responseURL" in response.request && response.request.responseURL != null && response.request.responseURL != "" && response.request.responseURL != undefined) {
|
||||||
|
window.location.href = response.request.responseURL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
},
|
},
|
||||||
async error => {
|
async error => {
|
||||||
|
|
@ -72,7 +74,7 @@ api.interceptors.response.use(
|
||||||
|
|
||||||
// 🔹 Handle 301/302 manually
|
// 🔹 Handle 301/302 manually
|
||||||
|
|
||||||
if (error && (error.status === 301 || error.status === 302)) {
|
if (error && (error.status == 301 || error.status == 302)) {
|
||||||
const redirectUrl = error.headers["location"];
|
const redirectUrl = error.headers["location"];
|
||||||
if (redirectUrl) {
|
if (redirectUrl) {
|
||||||
window.location.href = redirectUrl;
|
window.location.href = redirectUrl;
|
||||||
|
|
@ -80,18 +82,18 @@ api.interceptors.response.use(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prevent multiple refresh attempts
|
// Prevent multiple refresh attempts
|
||||||
// if (error.response?.status === 401 || error.response?.status === 500) {
|
// if (error.response?.status == 401 || error.response?.status == 500) {
|
||||||
if (error.response?.status === 401 && !originalRequest._retry) {
|
if ((error.response?.status == 401 || error.response?.status == 502) && !originalRequest._retry) {
|
||||||
originalRequest._retry = true;
|
originalRequest._retry = true;
|
||||||
try {
|
try {
|
||||||
if (!isRefreshing) {
|
if (!isRefreshing) {
|
||||||
isRefreshing = true;
|
isRefreshing = true;
|
||||||
// Attempt to refresh the token
|
// Attempt to refresh the token
|
||||||
const refreshResponse = await api.patch("/api/v1/auth/refresh");
|
const refreshResponse = await api.patch("/api/v1/auth/refresh");
|
||||||
if (refreshResponse.status === 200) {
|
if (refreshResponse.status == 200) {
|
||||||
isRefreshing = false;
|
isRefreshing = false;
|
||||||
// Retry the original request
|
// Retry the original request
|
||||||
if (window.location.pathname === "/login" || window.location.pathname === "/register") {
|
if (window.location.pathname == "/login" || window.location.pathname == "/register") {
|
||||||
window.location.href = "/"; // Redirect to login page
|
window.location.href = "/"; // Redirect to login page
|
||||||
}
|
}
|
||||||
return api(originalRequest);
|
return api(originalRequest);
|
||||||
|
|
@ -99,7 +101,7 @@ api.interceptors.response.use(
|
||||||
}
|
}
|
||||||
} catch (refreshError) {
|
} catch (refreshError) {
|
||||||
console.error("Refresh token failed:", refreshError);
|
console.error("Refresh token failed:", refreshError);
|
||||||
if (window.location.pathname !== "/login" && window.location.pathname !== "/register") {
|
if (window.location.pathname != "/login" && window.location.pathname != "/register") {
|
||||||
window.location.href = "/login"; // Redirect to login page
|
window.location.href = "/login"; // Redirect to login page
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,24 +17,27 @@ const axiosInstance: AxiosInstance = axios.create({
|
||||||
axiosInstance.interceptors.response.use(
|
axiosInstance.interceptors.response.use(
|
||||||
(response) => {
|
(response) => {
|
||||||
|
|
||||||
if (typeof response.data === 'string' && response.data.toLowerCase().includes('<!doctype html>')) {
|
|
||||||
// Likely a full HTML page, handle accordingly
|
|
||||||
window.location.href = response.request.responseURL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (response && (response.status === 301 || response.status === 302)) {
|
if (response && (response.status == 301 || response.status == 302)) {
|
||||||
const redirectUrl = response.headers["location"];
|
const redirectUrl = response.headers["location"];
|
||||||
if (redirectUrl) {
|
if (redirectUrl) {
|
||||||
window.location.href = redirectUrl;
|
window.location.href = redirectUrl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (typeof response.data == 'string' && response.data.toLowerCase().includes('<!doctype html>')) {
|
||||||
|
// Likely a full HTML page, handle accordingly
|
||||||
|
if ("responseURL" in response.request && response.request.responseURL != null && response.request.responseURL != "" && response.request.responseURL != undefined) {
|
||||||
|
window.location.href = response.request.responseURL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Otherwise just continue as normal
|
// Otherwise just continue as normal
|
||||||
return response;
|
return response;
|
||||||
},
|
},
|
||||||
(error) => {
|
(error) => {
|
||||||
// Optionally handle backend 302 or 3xx here (if returned as error)
|
// Optionally handle backend 302 or 3xx here (if returned as error)
|
||||||
if (error.response?.status === 302 && error.response?.headers?.location) {
|
if (error.response?.status == 302 && error.response?.headers?.location) {
|
||||||
window.location.replace(error.response.headers.location);
|
window.location.replace(error.response.headers.location);
|
||||||
return Promise.reject({ redirected: true });
|
return Promise.reject({ redirected: true });
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -70,8 +70,8 @@ export const fetchDocuments = createAsyncThunk<
|
||||||
|
|
||||||
const data = response.data as Document[];
|
const data = response.data as Document[];
|
||||||
|
|
||||||
if (data.length === 0 && window.location.pathname.includes('/process-step-two')) {
|
if (data.length == 0 && window.location.pathname.includes('/review-and-tag')) {
|
||||||
window.location.href = window.location.href.replace("process-step-two", "process-step-one") // ✅ navigate using window
|
window.location.href = window.location.href.replace("review-and-tag", "setup-transaction") // ✅ navigate using window
|
||||||
}
|
}
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
|
|
@ -108,7 +108,7 @@ export const uploadDocuments = createAsyncThunk<
|
||||||
const currentFile = formData.getAll("file")[i] as File;
|
const currentFile = formData.getAll("file")[i] as File;
|
||||||
|
|
||||||
// ---- Client-side validation ----
|
// ---- Client-side validation ----
|
||||||
if (currentFile.type !== "application/pdf") {
|
if (currentFile.type != "application/pdf") {
|
||||||
response.push({
|
response.push({
|
||||||
error: true,
|
error: true,
|
||||||
docName: currentFile.name,
|
docName: currentFile.name,
|
||||||
|
|
@ -141,9 +141,9 @@ export const uploadDocuments = createAsyncThunk<
|
||||||
);
|
);
|
||||||
response.push(res.data);
|
response.push(res.data);
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
if (e instanceof AxiosError && (e.response?.status === 415)) {
|
if (e instanceof AxiosError && (e.response?.status == 415)) {
|
||||||
response.push({ error: true, docName: (formData.getAll("file")[i] as File).name, reason: DocumentErrorEnum.UNSUPPORTED_DOC_TYPE });
|
response.push({ error: true, docName: (formData.getAll("file")[i] as File).name, reason: DocumentErrorEnum.UNSUPPORTED_DOC_TYPE });
|
||||||
} else if (e instanceof AxiosError && (e.response?.status === 413)) {
|
} else if (e instanceof AxiosError && (e.response?.status == 413)) {
|
||||||
response.push({ error: true, docName: (formData.getAll("file")[i] as File).name, reason: DocumentErrorEnum.FILE_SIZE_EXCEEDED });
|
response.push({ error: true, docName: (formData.getAll("file")[i] as File).name, reason: DocumentErrorEnum.FILE_SIZE_EXCEEDED });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -190,7 +190,7 @@ export const handleMultipleTransactionThunk = createAsyncThunk<
|
||||||
dispatch(showLoader('Uploading documents...'));
|
dispatch(showLoader('Uploading documents...'));
|
||||||
|
|
||||||
// ---- Client-side validation ----
|
// ---- Client-side validation ----
|
||||||
if (currentFile.type !== "application/pdf") {
|
if (currentFile.type != "application/pdf") {
|
||||||
response.push({
|
response.push({
|
||||||
error: true,
|
error: true,
|
||||||
docName: currentFile.name,
|
docName: currentFile.name,
|
||||||
|
|
@ -223,9 +223,9 @@ export const handleMultipleTransactionThunk = createAsyncThunk<
|
||||||
);
|
);
|
||||||
response.push(res.data);
|
response.push(res.data);
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
if (e instanceof AxiosError && (e.response?.status === 415)) {
|
if (e instanceof AxiosError && (e.response?.status == 415)) {
|
||||||
response.push({ error: true, docName: (formData.getAll("file")[i] as File).name, reason: DocumentErrorEnum.UNSUPPORTED_DOC_TYPE });
|
response.push({ error: true, docName: (formData.getAll("file")[i] as File).name, reason: DocumentErrorEnum.UNSUPPORTED_DOC_TYPE });
|
||||||
} else if (e instanceof AxiosError && (e.response?.status === 413)) {
|
} else if (e instanceof AxiosError && (e.response?.status == 413)) {
|
||||||
response.push({ error: true, docName: (formData.getAll("file")[i] as File).name, reason: DocumentErrorEnum.FILE_SIZE_EXCEEDED });
|
response.push({ error: true, docName: (formData.getAll("file")[i] as File).name, reason: DocumentErrorEnum.FILE_SIZE_EXCEEDED });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -255,8 +255,8 @@ const documentsSlice = createSlice({
|
||||||
state.error = initialState.error;
|
state.error = initialState.error;
|
||||||
},
|
},
|
||||||
setDocProgComplete: (state, action: PayloadAction<string>) => {
|
setDocProgComplete: (state, action: PayloadAction<string>) => {
|
||||||
const docIndex = state.documents.findIndex(doc => doc.id === action.payload);
|
const docIndex = state.documents.findIndex(doc => doc.id == action.payload);
|
||||||
if (docIndex !== -1) {
|
if (docIndex != -1) {
|
||||||
state.documents[docIndex].isCompleted = true;
|
state.documents[docIndex].isCompleted = true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -264,7 +264,7 @@ const documentsSlice = createSlice({
|
||||||
state.documents = [];
|
state.documents = [];
|
||||||
},
|
},
|
||||||
deleteDocument: (state, action: PayloadAction<string>) => {
|
deleteDocument: (state, action: PayloadAction<string>) => {
|
||||||
state.documents = state.documents.filter(doc => doc.id !== action.payload);
|
state.documents = state.documents.filter(doc => doc.id != action.payload);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
extraReducers: (builder) => {
|
extraReducers: (builder) => {
|
||||||
|
|
|
||||||
|
|
@ -68,8 +68,8 @@ const droppedItemsSlice = createSlice({
|
||||||
const key = `${documentIndex}_${pageNumber}`;
|
const key = `${documentIndex}_${pageNumber}`;
|
||||||
|
|
||||||
if (state.droppedItems[key]) {
|
if (state.droppedItems[key]) {
|
||||||
const index = state.droppedItems[key].findIndex(item => item.label === label);
|
const index = state.droppedItems[key].findIndex(item => item.label == label);
|
||||||
if (index !== -1) {
|
if (index != -1) {
|
||||||
state.droppedItems[key][index] = action.payload; // Replace the existing item
|
state.droppedItems[key][index] = action.payload; // Replace the existing item
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -81,7 +81,7 @@ const droppedItemsSlice = createSlice({
|
||||||
const key = `${documentIndex}_${pageNumber}`;
|
const key = `${documentIndex}_${pageNumber}`;
|
||||||
|
|
||||||
if (state.droppedItems[key]) {
|
if (state.droppedItems[key]) {
|
||||||
state.droppedItems[key] = state.droppedItems[key].filter(item => item.label !== label);
|
state.droppedItems[key] = state.droppedItems[key].filter(item => item.label != label);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ const selectedDocumentsSlice = createSlice({
|
||||||
for (const document of action.payload) {
|
for (const document of action.payload) {
|
||||||
const docId = document.documentId;
|
const docId = document.documentId;
|
||||||
for (const [index, selDoc] of state.selectedDocuments.entries()) {
|
for (const [index, selDoc] of state.selectedDocuments.entries()) {
|
||||||
if (selDoc.id === docId) {
|
if (selDoc.id == docId) {
|
||||||
state.selectedDocuments[index].pages = document.pages;
|
state.selectedDocuments[index].pages = document.pages;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ export const addRecipientAsync = createAsyncThunk<
|
||||||
const state = getState() as { selectedRecipients: SelectedRecipientInt };
|
const state = getState() as { selectedRecipients: SelectedRecipientInt };
|
||||||
const toggle = state.selectedRecipients.transactionTemplateToggle;
|
const toggle = state.selectedRecipients.transactionTemplateToggle;
|
||||||
|
|
||||||
const updateRecipientsData = recipientsData.filter(recipient => recipient.id !== null);
|
const updateRecipientsData = recipientsData.filter(recipient => recipient.id != null);
|
||||||
const createRecipientsData = recipientsData.filter(recipient => recipient.id == null);
|
const createRecipientsData = recipientsData.filter(recipient => recipient.id == null);
|
||||||
|
|
||||||
const basePath = `/api/v1/accounts/${accountId}/${toggle}/${transactionId}/recipients`;
|
const basePath = `/api/v1/accounts/${accountId}/${toggle}/${transactionId}/recipients`;
|
||||||
|
|
@ -133,11 +133,11 @@ export const fetchRecipients = createAsyncThunk<
|
||||||
let data = response.data as Recipient[];
|
let data = response.data as Recipient[];
|
||||||
|
|
||||||
// data = data.filter((recipient, indx) => {
|
// data = data.filter((recipient, indx) => {
|
||||||
// return recipient.type !== "CC";
|
// return recipient.type != "CC";
|
||||||
// })
|
// })
|
||||||
|
|
||||||
// if (data.length === 0 && window.location.pathname.includes('/process-step-two')) {
|
// if (data.length == 0 && window.location.pathname.includes('/review-and-tag')) {
|
||||||
// window.location.href = window.location.href.replace("process-step-two", "process-step-one") // ✅ navigate using window
|
// window.location.href = window.location.href.replace("review-and-tag", "setup-transaction") // ✅ navigate using window
|
||||||
// }
|
// }
|
||||||
|
|
||||||
return data as Recipient[];
|
return data as Recipient[];
|
||||||
|
|
@ -152,7 +152,7 @@ const selectedRecipientsSlice = createSlice({
|
||||||
initialState,
|
initialState,
|
||||||
reducers: {
|
reducers: {
|
||||||
addRecipient: (state, action: PayloadAction<Recipient>) => {
|
addRecipient: (state, action: PayloadAction<Recipient>) => {
|
||||||
if (action.payload.type === recipientType.INPERSONSIGNER) {
|
if (action.payload.type == recipientType.INPERSONSIGNER) {
|
||||||
state.signingOrder = true;
|
state.signingOrder = true;
|
||||||
state.recipients = [action.payload, ...state.recipients];
|
state.recipients = [action.payload, ...state.recipients];
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -167,8 +167,8 @@ const selectedRecipientsSlice = createSlice({
|
||||||
},
|
},
|
||||||
setSelectedRecipients: (state, action: PayloadAction<Recipient[]>) => {
|
setSelectedRecipients: (state, action: PayloadAction<Recipient[]>) => {
|
||||||
for (const [index, recipient] of action.payload.entries()) {
|
for (const [index, recipient] of action.payload.entries()) {
|
||||||
if ((recipient.type === recipientType.INPERSONSIGNER && index > 0)
|
if ((recipient.type == recipientType.INPERSONSIGNER && index > 0)
|
||||||
&& action.payload[index - 1].type !== recipientType.INPERSONSIGNER) {
|
&& action.payload[index - 1].type != recipientType.INPERSONSIGNER) {
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -177,7 +177,7 @@ const selectedRecipientsSlice = createSlice({
|
||||||
},
|
},
|
||||||
setSigningOrder: (state, action: PayloadAction<boolean>) => {
|
setSigningOrder: (state, action: PayloadAction<boolean>) => {
|
||||||
for (const recipient of state.recipients) {
|
for (const recipient of state.recipients) {
|
||||||
if (recipient.type === recipientType.INPERSONSIGNER) {
|
if (recipient.type == recipientType.INPERSONSIGNER) {
|
||||||
if (state.signingOrder) return state;
|
if (state.signingOrder) return state;
|
||||||
state.signingOrder = true;
|
state.signingOrder = true;
|
||||||
return state;
|
return state;
|
||||||
|
|
@ -187,7 +187,7 @@ const selectedRecipientsSlice = createSlice({
|
||||||
state.signingOrder = action.payload;
|
state.signingOrder = action.payload;
|
||||||
},
|
},
|
||||||
removeSelectedRecipient: (state, action: PayloadAction<Recipient>) => {
|
removeSelectedRecipient: (state, action: PayloadAction<Recipient>) => {
|
||||||
state.recipients = state.recipients.filter((recipient) => recipient.uuid !== action.payload.uuid);
|
state.recipients = state.recipients.filter((recipient) => recipient.uuid != action.payload.uuid);
|
||||||
},
|
},
|
||||||
removeAllRecipients: (state) => {
|
removeAllRecipients: (state) => {
|
||||||
state.recipients = [];
|
state.recipients = [];
|
||||||
|
|
@ -200,7 +200,7 @@ const selectedRecipientsSlice = createSlice({
|
||||||
},
|
},
|
||||||
updateRecipientOrder: (state, action: PayloadAction<{ id: string; routingOrder: number }>) => {
|
updateRecipientOrder: (state, action: PayloadAction<{ id: string; routingOrder: number }>) => {
|
||||||
const { id, routingOrder } = action.payload;
|
const { id, routingOrder } = action.payload;
|
||||||
const recipient = state.recipients.find((r) => r.id === id || r.uuid === id);
|
const recipient = state.recipients.find((r) => r.id == id || r.uuid == id);
|
||||||
if (recipient) {
|
if (recipient) {
|
||||||
recipient.routingOrder = routingOrder;
|
recipient.routingOrder = routingOrder;
|
||||||
}
|
}
|
||||||
|
|
@ -230,17 +230,17 @@ const selectedRecipientsSlice = createSlice({
|
||||||
|
|
||||||
// First try matching by id
|
// First try matching by id
|
||||||
let index = state.recipients.findIndex(
|
let index = state.recipients.findIndex(
|
||||||
r => String(r.id) === payloadUuid
|
r => String(r.id) == payloadUuid
|
||||||
);
|
);
|
||||||
|
|
||||||
// If not found, try matching by uuid
|
// If not found, try matching by uuid
|
||||||
if (index === -1) {
|
if (index == -1) {
|
||||||
index = state.recipients.findIndex(
|
index = state.recipients.findIndex(
|
||||||
r => String(r.uuid) === payloadUuid
|
r => String(r.uuid) == payloadUuid
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index !== -1) {
|
if (index != -1) {
|
||||||
// Merge existing recipient with new values
|
// Merge existing recipient with new values
|
||||||
state.recipients[index] = {
|
state.recipients[index] = {
|
||||||
...state.recipients[index],
|
...state.recipients[index],
|
||||||
|
|
@ -292,7 +292,7 @@ const selectedRecipientsSlice = createSlice({
|
||||||
.addCase(removeRecipientAsync.pending, () => { })
|
.addCase(removeRecipientAsync.pending, () => { })
|
||||||
.addCase(removeRecipientAsync.fulfilled, (state, action: PayloadAction<string | number>) => {
|
.addCase(removeRecipientAsync.fulfilled, (state, action: PayloadAction<string | number>) => {
|
||||||
state.recipients = state.recipients.filter(
|
state.recipients = state.recipients.filter(
|
||||||
(recipient) => recipient.id !== action.payload && recipient.email !== action.payload
|
(recipient) => recipient.id != action.payload && recipient.email != action.payload
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
.addCase(removeRecipientAsync.rejected, (state, action) => {
|
.addCase(removeRecipientAsync.rejected, (state, action) => {
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@
|
||||||
|
|
||||||
// export const store = configureStore({
|
// export const store = configureStore({
|
||||||
// reducer: persistedReducer,
|
// reducer: persistedReducer,
|
||||||
// devTools: import.meta.env.VITE_NODE_ENV !== "production" || true,
|
// devTools: import.meta.env.VITE_NODE_ENV != "production" || true,
|
||||||
// middleware: (getDefaultMiddleware) =>
|
// middleware: (getDefaultMiddleware) =>
|
||||||
// getDefaultMiddleware({
|
// getDefaultMiddleware({
|
||||||
// serializableCheck: false,
|
// serializableCheck: false,
|
||||||
|
|
@ -87,7 +87,7 @@ const rootReducer = combineReducers({
|
||||||
|
|
||||||
export const store = configureStore({
|
export const store = configureStore({
|
||||||
reducer: rootReducer,
|
reducer: rootReducer,
|
||||||
devTools: import.meta.env.VITE_NODE_ENV !== "production" || true,
|
devTools: import.meta.env.VITE_NODE_ENV != "production" || true,
|
||||||
middleware: (getDefaultMiddleware) =>
|
middleware: (getDefaultMiddleware) =>
|
||||||
getDefaultMiddleware({
|
getDefaultMiddleware({
|
||||||
serializableCheck: false,
|
serializableCheck: false,
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ const JoyrideController = () => {
|
||||||
const tryStartTour = () => {
|
const tryStartTour = () => {
|
||||||
let currentSteps: Step[] = [];
|
let currentSteps: Step[] = [];
|
||||||
|
|
||||||
if (location.pathname === "/") {
|
if (location.pathname == "/") {
|
||||||
currentSteps = [
|
currentSteps = [
|
||||||
{
|
{
|
||||||
target: "body", // This makes the welcome step show in center of screen
|
target: "body", // This makes the welcome step show in center of screen
|
||||||
|
|
@ -64,7 +64,7 @@ const JoyrideController = () => {
|
||||||
disableBeacon: true,
|
disableBeacon: true,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
} else if (location.pathname.includes("/process-step-one")) {
|
} else if (location.pathname.includes("/setup-transaction")) {
|
||||||
currentSteps = [
|
currentSteps = [
|
||||||
{
|
{
|
||||||
target: "body", // This makes the welcome step show in center of screen
|
target: "body", // This makes the welcome step show in center of screen
|
||||||
|
|
@ -101,7 +101,7 @@ const JoyrideController = () => {
|
||||||
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
} else if (location.pathname.includes("/process-step-two")) {
|
} else if (location.pathname.includes("/review-and-tag")) {
|
||||||
currentSteps = [
|
currentSteps = [
|
||||||
{
|
{
|
||||||
target: "body", // This makes the welcome step show in center of screen
|
target: "body", // This makes the welcome step show in center of screen
|
||||||
|
|
@ -168,7 +168,7 @@ const JoyrideController = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const allTargetsExist = currentSteps.every((step) =>
|
const allTargetsExist = currentSteps.every((step) =>
|
||||||
step.target === "body" ? true : document.querySelector(step.target)
|
step.target == "body" ? true : document.querySelector(step.target)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (allTargetsExist) {
|
if (allTargetsExist) {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import api from "../config/api";
|
||||||
const downloadDocumentUtils = async (accountId: string, transactionId: string, type: string, includeCertificate: string | null = null) => {
|
const downloadDocumentUtils = async (accountId: string, transactionId: string, type: string, includeCertificate: string | null = null) => {
|
||||||
let documentId = type;
|
let documentId = type;
|
||||||
let url = `/api/v1/accounts/${accountId}/transactions/${transactionId}/documents/${documentId}`;
|
let url = `/api/v1/accounts/${accountId}/transactions/${transactionId}/documents/${documentId}`;
|
||||||
if (includeCertificate !== null) {
|
if (includeCertificate != null) {
|
||||||
url = url + includeCertificate;
|
url = url + includeCertificate;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -10,12 +10,12 @@ const type_last_four = (str: string, changeWith: string): string => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const type_credit_card = (str: string, changeWith: string): string => {
|
const type_credit_card = (str: string, changeWith: string): string => {
|
||||||
if (str.length !== 15 && str.length !== 16) return str;
|
if (str.length != 15 && str.length != 16) return str;
|
||||||
|
|
||||||
const last4 = str.slice(-4);
|
const last4 = str.slice(-4);
|
||||||
const masked = str.slice(0, -4).replace(/\d/g, changeWith);
|
const masked = str.slice(0, -4).replace(/\d/g, changeWith);
|
||||||
|
|
||||||
if (str.length === 16) {
|
if (str.length == 16) {
|
||||||
// Format: XXXX XXXX XXXX 1234
|
// Format: XXXX XXXX XXXX 1234
|
||||||
return masked.slice(0, 4) + " " + masked.slice(4, 8) + " " + masked.slice(8, 12) + " " + last4;
|
return masked.slice(0, 4) + " " + masked.slice(4, 8) + " " + masked.slice(8, 12) + " " + last4;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -34,7 +34,7 @@ const type_national_insurance = (str: string, changeWith: string): string => {
|
||||||
const type_social_security = (str: string, changeWith: string): string => {
|
const type_social_security = (str: string, changeWith: string): string => {
|
||||||
// Expecting 9-digit string like "123456789"
|
// Expecting 9-digit string like "123456789"
|
||||||
const cleaned = str.replace(/\D/g, ""); // remove non-digit characters
|
const cleaned = str.replace(/\D/g, ""); // remove non-digit characters
|
||||||
if (cleaned.length !== 9) return str;
|
if (cleaned.length != 9) return str;
|
||||||
|
|
||||||
const part3 = cleaned.slice(5);
|
const part3 = cleaned.slice(5);
|
||||||
return `${changeWith.repeat(3)}-${changeWith.repeat(2)}-${part3}`;
|
return `${changeWith.repeat(3)}-${changeWith.repeat(2)}-${part3}`;
|
||||||
|
|
@ -42,7 +42,7 @@ const type_social_security = (str: string, changeWith: string): string => {
|
||||||
|
|
||||||
const type_social_insurance = (str: string, changeWith: string): string => {
|
const type_social_insurance = (str: string, changeWith: string): string => {
|
||||||
const cleaned = str.replace(/\D/g, "");
|
const cleaned = str.replace(/\D/g, "");
|
||||||
if (cleaned.length !== 9) return str;
|
if (cleaned.length != 9) return str;
|
||||||
|
|
||||||
const part3 = cleaned.slice(6);
|
const part3 = cleaned.slice(6);
|
||||||
return `${changeWith.repeat(3)} ${changeWith.repeat(3)} ${part3}`;
|
return `${changeWith.repeat(3)} ${changeWith.repeat(3)} ${part3}`;
|
||||||
|
|
|
||||||
|
|
@ -23,11 +23,11 @@ const getGroupDimension = (
|
||||||
dimension.maxLeft = Math.max(dimension.maxLeft ?? 0, rect.right);
|
dimension.maxLeft = Math.max(dimension.maxLeft ?? 0, rect.right);
|
||||||
});
|
});
|
||||||
|
|
||||||
dimension.maxTop = dimension.maxTop !== null ? dimension.maxTop - containerRect.top + (offsetY - 10) : null;
|
dimension.maxTop = dimension.maxTop != null ? dimension.maxTop - containerRect.top + (offsetY - 10) : null;
|
||||||
dimension.minTop = dimension.minTop !== null ? dimension.minTop - containerRect.top - (offsetY - 10) : null;
|
dimension.minTop = dimension.minTop != null ? dimension.minTop - containerRect.top - (offsetY - 10) : null;
|
||||||
|
|
||||||
dimension.maxLeft = dimension.maxLeft !== null ? dimension.maxLeft - containerRect.left + (offsetX - 10) : null;
|
dimension.maxLeft = dimension.maxLeft != null ? dimension.maxLeft - containerRect.left + (offsetX - 10) : null;
|
||||||
dimension.minLeft = dimension.minLeft !== null ? dimension.minLeft - containerRect.left - (offsetX - 10) : null;
|
dimension.minLeft = dimension.minLeft != null ? dimension.minLeft - containerRect.left - (offsetX - 10) : null;
|
||||||
|
|
||||||
return dimension;
|
return dimension;
|
||||||
}
|
}
|
||||||
|
|
@ -40,28 +40,28 @@ const handleGroupBorderPosition = (groupElements: NodeListOf<HTMLElement>, conta
|
||||||
const borderBottom: HTMLElement | null = document.querySelector("[border-group='" + groupElements[0].getAttribute("group") + "'][border-pos='bottom']");
|
const borderBottom: HTMLElement | null = document.querySelector("[border-group='" + groupElements[0].getAttribute("group") + "'][border-pos='bottom']");
|
||||||
const borderLeft: HTMLElement | null = document.querySelector("[border-group='" + groupElements[0].getAttribute("group") + "'][border-pos='left']");
|
const borderLeft: HTMLElement | null = document.querySelector("[border-group='" + groupElements[0].getAttribute("group") + "'][border-pos='left']");
|
||||||
|
|
||||||
if (borderTop !== null && dimension.maxLeft !== null && dimension.minLeft !== null) {
|
if (borderTop != null && dimension.maxLeft != null && dimension.minLeft != null) {
|
||||||
borderTop.style.width = (dimension.maxLeft - dimension.minLeft) + "px";
|
borderTop.style.width = (dimension.maxLeft - dimension.minLeft) + "px";
|
||||||
borderTop.style.height = "1px";
|
borderTop.style.height = "1px";
|
||||||
borderTop.style.top = dimension.minTop + "px";
|
borderTop.style.top = dimension.minTop + "px";
|
||||||
borderTop.style.left = dimension.minLeft + "px";
|
borderTop.style.left = dimension.minLeft + "px";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (borderRight !== null && dimension.maxTop !== null && dimension.minTop !== null) {
|
if (borderRight != null && dimension.maxTop != null && dimension.minTop != null) {
|
||||||
borderRight.style.width = "1px";
|
borderRight.style.width = "1px";
|
||||||
borderRight.style.height = (dimension.maxTop - dimension.minTop) + "px";
|
borderRight.style.height = (dimension.maxTop - dimension.minTop) + "px";
|
||||||
borderRight.style.top = dimension.minTop + "px";
|
borderRight.style.top = dimension.minTop + "px";
|
||||||
borderRight.style.left = dimension.maxLeft + "px";
|
borderRight.style.left = dimension.maxLeft + "px";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (borderBottom !== null && dimension.maxLeft !== null && dimension.minLeft !== null) {
|
if (borderBottom != null && dimension.maxLeft != null && dimension.minLeft != null) {
|
||||||
borderBottom.style.width = (dimension.maxLeft - dimension.minLeft) + "px";
|
borderBottom.style.width = (dimension.maxLeft - dimension.minLeft) + "px";
|
||||||
borderBottom.style.height = "1px";
|
borderBottom.style.height = "1px";
|
||||||
borderBottom.style.top = dimension.maxTop + "px";
|
borderBottom.style.top = dimension.maxTop + "px";
|
||||||
borderBottom.style.left = dimension.minLeft + "px";
|
borderBottom.style.left = dimension.minLeft + "px";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (borderLeft !== null && dimension.maxTop !== null && dimension.minTop !== null) {
|
if (borderLeft != null && dimension.maxTop != null && dimension.minTop != null) {
|
||||||
borderLeft.style.width = "1px";
|
borderLeft.style.width = "1px";
|
||||||
borderLeft.style.height = (dimension.maxTop - dimension.minTop) + "px";
|
borderLeft.style.height = (dimension.maxTop - dimension.minTop) + "px";
|
||||||
borderLeft.style.top = dimension.minTop + "px";
|
borderLeft.style.top = dimension.minTop + "px";
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue