Minor Fixes + Download Audit added

This commit is contained in:
Bhagwan Singh 2026-06-08 13:07:20 +05:30
parent 42bbf5ad66
commit ad297b763a
6 changed files with 178 additions and 138 deletions

View File

@ -79,11 +79,18 @@ const CompletionScreen: React.FC<CompletionScreenProps> = ({
{message}
</p>
<div className="flex gap-2">
<p
onClick={() => { handleDownloadDocument(recipientId || "") }}
className="text-white bg-[var(--mainPrimaryBtn)] px-3 py-2 rounded-sm mt-4 cursor-pointer">
Download Signed Documents
</p>
<p
onClick={() => { handleDownloadDocument(recipientId || "", true) }}
className="text-white bg-[var(--mainPrimaryBtn)] px-3 py-2 rounded-sm mt-4 cursor-pointer">
Download Audit
</p>
</div>
{/* <button className="flex items-center gap-2 mt-6 bg-blue-600 text-white px-6 py-2 rounded-md hover:bg-blue-700 transition">
@ -119,7 +126,7 @@ const CompletionScreen: React.FC<CompletionScreenProps> = ({
Boost Efficiency with Our Apps
</h2>
<div className="w-full flex flex-col sm:flex-row gap-4 justify-center items-stretch 2xl:gap-6 2xl:mt-6">
<div className="w-full flex flex-col sm:flex-row gap-4 justify-center items-stretch 2xl:gap-6 2xl:mt-6">
{/* Forms Made Easy */}
<div className="bg-white rounded-lg shadow p-4 2xl:p-6">
@ -187,7 +194,7 @@ const CompletionScreen: React.FC<CompletionScreenProps> = ({
</div>
</div>
</div>
</div>
</section>
</main>

View File

@ -14,11 +14,14 @@ export default function ConsentScreen({ onConsent, onDecline }: ConsentScreenPro
return (
<>
<div className="absolute top-0 left-0 w-[100vw] h-[100vh] bg-slate-100 opacity-50 backdrop-filter backdrop-blur-2xl z-50"></div>
<div className="absolute top-0 left-0 w-full h-screen flex items-center justify-center p-6 z-50">
<div className="bg-white shadow-xl rounded-2xl p-8 max-w-lg w-full border border-gray-200">
{/* Glassmorphism backdrop */}
<div className="fixed inset-0 bg-black/10 backdrop-blur-sm backdrop-saturate-100 z-[100]" />
{/* Modal container */}
<div className="fixed inset-0 flex items-center justify-center p-6 z-[100]">
<div className="bg-white shadow-xl rounded-md p-8 max-w-lg w-full border border-gray-200">
{/* Header */}
<div className="flex items-center gap-3 mb-6">
<div className="flex items-center gap-3 mb-4">
<FaSignature className="text-blue-600 text-3xl" />
<h2 className="text-2xl font-semibold text-gray-800">
Consent for E-Signature
@ -27,7 +30,7 @@ export default function ConsentScreen({ onConsent, onDecline }: ConsentScreenPro
{/* Info */}
<div className="flex items-start gap-3 mb-6 text-gray-600">
<MdOutlinePrivacyTip className="text-xl text-blue-500 mt-1" />
<p className="text-sm leading-relaxed">
By providing your electronic signature, you agree that it is the legal
equivalent of your manual signature on this document. Please review the
@ -51,7 +54,7 @@ export default function ConsentScreen({ onConsent, onDecline }: ConsentScreenPro
{/* Buttons */}
<div className="flex gap-4 flex-row-reverse">
<button
className={`flex-1 cursor-pointer flex items-center justify-center gap-2 rounded-xl py-2 font-medium transition-colors
className={`flex-1 cursor-pointer flex items-center justify-center gap-2 rounded-md py-2 font-medium transition-colors
${accepted ? "bg-blue-600 text-white hover:bg-blue-700" : "bg-gray-300 text-gray-500 cursor-not-allowed"}
`}
disabled={!accepted}

View File

@ -1313,7 +1313,7 @@ const SignDocument = () => {
onClick={() => handleTagNavClick("N")}
>
<svg width="100" height="35" viewBox="0 0 112 45" fill="none" xmlns="http://www.w3.org/2000/svg">
<svg width="100" height="27" viewBox="0 0 112 45" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M1.87927 20.8542L15.0554 2.53357C15.7668 1.54438 16.9108 0.958008 18.1292 0.958008H108.049C110.14 0.958008 111.835 2.65317 111.835 4.74426V41.0235C111.835 43.1146 110.14 44.8098 108.049 44.8098H18.1084C16.9016 44.8098 15.7671 44.2345 15.054 43.261L1.89871 25.3024C0.930133 23.9802 0.92229 22.1849 1.87927 20.8542Z" fill="#005AB5" />
{/* <path d="M53.2649 16.7474V28.3838H51.3899L45.907 20.4577H45.8104V28.3838H43.7024V16.7474H45.5888L51.0661 24.6792H51.1683V16.7474H53.2649ZM58.8545 28.5542C57.9795 28.5542 57.2238 28.3724 56.5875 28.0088C55.9549 27.6414 55.4682 27.1224 55.1272 26.452C54.7863 25.7777 54.6159 24.9842 54.6159 24.0713C54.6159 23.1736 54.7863 22.3857 55.1272 21.7077C55.4719 21.0258 55.953 20.4955 56.5704 20.1167C57.1879 19.7342 57.9132 19.5429 58.7466 19.5429C59.2844 19.5429 59.792 19.63 60.2693 19.8042C60.7504 19.9747 61.1746 20.2398 61.542 20.5997C61.9132 20.9595 62.2049 21.4179 62.417 21.9747C62.6291 22.5277 62.7352 23.1868 62.7352 23.952V24.5827H55.5818V23.1963H60.7636C60.7598 22.8023 60.6746 22.452 60.5079 22.1452C60.3413 21.8345 60.1083 21.5902 59.8091 21.4122C59.5136 21.2342 59.1689 21.1452 58.775 21.1452C58.3545 21.1452 57.9852 21.2474 57.667 21.452C57.3488 21.6527 57.1007 21.9179 56.9227 22.2474C56.7485 22.5732 56.6594 22.9311 56.6557 23.3213V24.5315C56.6557 25.0391 56.7485 25.4747 56.9341 25.8383C57.1197 26.1982 57.3791 26.4747 57.7125 26.6679C58.0458 26.8573 58.436 26.952 58.8829 26.952C59.1822 26.952 59.453 26.9103 59.6954 26.827C59.9379 26.7398 60.1481 26.613 60.3261 26.4463C60.5041 26.2796 60.6386 26.0732 60.7295 25.827L62.65 26.0429C62.5288 26.5505 62.2977 26.9936 61.9568 27.3724C61.6197 27.7474 61.1879 28.0391 60.6613 28.2474C60.1348 28.452 59.5325 28.5542 58.8545 28.5542ZM65.4896 19.6565L67.2509 22.8781L69.0407 19.6565H71.2168L68.5862 24.0202L71.2623 28.3838H69.0975L67.2509 25.2417L65.4214 28.3838H63.2396L65.8987 24.0202L63.3078 19.6565H65.4896ZM76.6857 19.6565V21.2474H71.6687V19.6565H76.6857ZM72.9073 17.5656H74.9641V25.7588C74.9641 26.0353 75.0058 26.2474 75.0891 26.3952C75.1762 26.5391 75.2899 26.6376 75.43 26.6906C75.5702 26.7436 75.7255 26.7702 75.8959 26.7702C76.0247 26.7702 76.1421 26.7607 76.2482 26.7417C76.3581 26.7228 76.4414 26.7058 76.4982 26.6906L76.8448 28.2986C76.735 28.3364 76.5778 28.3781 76.3732 28.4236C76.1725 28.469 75.9262 28.4955 75.6346 28.5031C75.1194 28.5183 74.6554 28.4406 74.2425 28.2702C73.8296 28.0959 73.502 27.827 73.2596 27.4633C73.0209 27.0997 72.9035 26.6452 72.9073 26.0997V17.5656Z" fill="white" /> */}
@ -1475,12 +1475,12 @@ const SignDocument = () => {
px-2.5 transition-all duration-500 ease-in-out
${requiredFilled ? "translate-y-0" : "translate-y-full hidden"}`}
>
<div className="py-5 sm:py-6 text-white">
<p className="text-lg sm:text-2xl font-semibold leading-snug">
<div className="py-5 sm:py-5 text-white">
<p className="text-lg sm:text-xl font-semibold leading-snug">
All Set to Wrap This Up?
</p>
<p className="text-xs sm:text-sm leading-relaxed mt-2 max-w-md">
<p className="text-xs sm:text-sm leading-relaxed max-w-md">
You've completed the required fields. Review your work, then select Finish.
</p>
</div>

View File

@ -349,7 +349,7 @@ const TagsCon: React.FC<TagsConProps> = ({
top: `${item.dimensions.top * scaleY}px`,
width: `${item.dimensions.width * scaleX}px`,
height: `${item.dimensions.height * scaleY}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'}`
}}
// style={{
@ -401,93 +401,94 @@ const TagsCon: React.FC<TagsConProps> = ({
</>
{/* TEXT FIELD - START */}
{
item.type == "TEXT" &&
{item.type == "TEXT" && (
<div
id={item.navigationOrder}
tabIndex={1}
className={`h-full text-[14px] font-medium w-full border-slate-100 rounded ${(transparentTags || hideTags) ? "pointer-events-nones" : "bg-slate-200 shadow-sm opacity-80"} flex justify-start items-end overflow-hidden`}
// style={{ height: item.dimensions.height + "px" }}
className={`h-full w-full rounded border-slate-100 ${transparentTags || hideTags
? "pointer-events-none"
: "bg-slate-200 shadow-sm opacity-80"
}`}
style={{ overflow: "hidden" }} // clip content to container
>
{/* <input
name={item.id}
className="w-full px-2 outline-none"
>
</input> */}
{
!item.multiLine && !item.maskType && <p
// name={item.id}
// style={{ height: item.dimensions.height + "px" }}
onChange={(e) => {
const val = e.currentTarget.textContent;
handleTagUpdate(item.originalIndex, val as string);
}}
onKeyDown={(e) => {
if (e.key == "Enter") e.preventDefault();
}}
contentEditable={true}
className={`outline-none whitespace-nowrap w-full`}
style={{
color: item.styles.color,
fontSize: `${item.styles?.textSize}px`,
fontStyle: item.styles.italic ? "italic" : "normal",
fontWeight: item.styles.bold ? "600" : "400",
textDecoration: item.styles.underline ? "underline" : "none"
}}
>{item.value ?? ""}</p>
}
{
item.multiLine && !item.maskType && <p
{/* Single-line (no mask, no multiLine) */}
{!item.multiLine && !item.maskType && (
<p
contentEditable
suppressContentEditableWarning
onBlur={(e) => {
const val = e.currentTarget.textContent;
handleTagUpdate(item.originalIndex, val as string);
}}
contentEditable={true}
className={`w-full outline-none`}
onKeyDown={(e) => { if (e.key === "Enter") e.preventDefault(); }}
onBlur={(e) => handleTagUpdate(item.originalIndex, e.currentTarget.textContent as string)}
className="outline-none w-full h-full m-0 p-0"
style={{
color: item.styles.color,
fontSize: `${item.styles?.textSize}px`,
fontStyle: item.styles.italic ? "italic" : "normal",
fontWeight: item.styles.bold ? "600" : "400",
textDecoration: item.styles.underline ? "underline" : "none"
textDecoration: item.styles.underline ? "underline" : "none",
whiteSpace: "nowrap",
overflow: "hidden", // don't let text push container
display: "block",
lineHeight: "1",
}}
>{item.value ?? ""}</p>
}
{
"maskType" in item && "maskCharacter" in item && item.maskType && <p
// onBlur={(e) => {
// const val = e.currentTarget.textContent;
// handleTagUpdate(item.originalIndex, val as string);
// }}
onKeyDown={(e) => {
if (e.key == "Enter") e.preventDefault();
>
{item.value ?? ""}
</p>
)}
{/* Multiline / paragraph */}
{item.multiLine && !item.maskType && (
<p
contentEditable
suppressContentEditableWarning
onBlur={(e) => handleTagUpdate(item.originalIndex, e.currentTarget.textContent as string)}
className="outline-none w-full h-full m-0 p-0"
style={{
color: item.styles.color,
fontSize: `${item.styles?.textSize}px`,
fontStyle: item.styles.italic ? "italic" : "normal",
fontWeight: item.styles.bold ? "600" : "400",
textDecoration: item.styles.underline ? "underline" : "none",
whiteSpace: "pre-wrap", // respects newlines, wraps within width
wordBreak: "break-word",
overflowY: "auto", // scroll if paragraph overflows height
overflowX: "hidden",
display: "block",
}}
// onFocus={() => {
// }}
>
{item.value ?? ""}
</p>
)}
{/* Masked input */}
{"maskType" in item && "maskCharacter" in item && item.maskType && (
<p
contentEditable
suppressContentEditableWarning
onKeyDown={(e) => { if (e.key === "Enter") e.preventDefault(); }}
onBlur={(e) => {
let val = e.target.textContent;
handleTagUpdate(item.originalIndex, val as string);
if (typeof item.maskType == "string" && typeof val == "string" && item.maskCharacter) {
let val = e.target.textContent as string;
handleTagUpdate(item.originalIndex, val);
if (typeof item.maskType === "string" && val && item.maskCharacter) {
val = val.replace(/ /g, "");
e.target.textContent = maskUtils(item.maskType, val, item.maskCharacter)
e.target.textContent = maskUtils(item.maskType, val, item.maskCharacter);
}
}}
contentEditable={true}
className={`outline-none whitespace-nowrap w-full`}
className="outline-none w-full h-full m-0 p-0"
style={{
color: item.styles.color,
fontSize: `${item.styles?.textSize}px`,
fontStyle: item.styles.italic ? "italic" : "normal",
fontWeight: item.styles.bold ? "600" : "400",
textDecoration: item.styles.underline ? "underline" : "none"
textDecoration: item.styles.underline ? "underline" : "none",
whiteSpace: "nowrap",
overflow: "hidden",
display: "block",
lineHeight: "1",
}}
></p>
}
/>
)}
</div>
}
)}
{/* TEXT FIELD - END */}
{/* EMAIL FIELD - START */}

View File

@ -591,7 +591,9 @@ const DocumentContainer = forwardRef<DocumentContainerRef, DocumentContainerProp
prepData.currentTimeStamp = true;
}
if (prepData.type.toLowerCase() == "text") {
prepData.multiLine = true
}
if (prepData.type.toLowerCase() == "number") {
prepData.decimalPlace = 0;

View File

@ -1,7 +1,34 @@
import axiosInstance from "../config/axiosInstance";
const handleDownloadDocument = async (recipientId: string): Promise<void> => {
const handleDownloadDocument = async (recipientId: string, isCertDownload = false): Promise<void> => {
try {
if (isCertDownload) {
const response = await axiosInstance.get(
`/api/v1/sign/${recipientId}/certificate`,
{
responseType: "blob",
headers: {
"Content-Type": "application/json",
},
}
);
const blob = new Blob([response.data]);
const url = window.URL.createObjectURL(blob);
const link = document.createElement("a");
link.href = url;
// IMPORTANT
link.download = "sme_audit_certificate.pdf";
document.body.appendChild(link);
link.click();
link.remove();
window.URL.revokeObjectURL(url);
} else {
const response = await axiosInstance.get(
`/api/v1/sign/${recipientId}/documents`,
{
@ -24,7 +51,7 @@ const handleDownloadDocument = async (recipientId: string): Promise<void> => {
link.remove();
window.URL.revokeObjectURL(url);
}
} catch (err) {
console.error(err);
}