diff --git a/src/pages/tenant/ViewDocument.tsx b/src/pages/tenant/ViewDocument.tsx index 85a5836..2aa2a99 100644 --- a/src/pages/tenant/ViewDocument.tsx +++ b/src/pages/tenant/ViewDocument.tsx @@ -4,6 +4,7 @@ import { Layout } from "@/components/layout/Layout"; import { DataTable, FormSelect, + FormField, Modal, PrimaryButton, SecondaryButton, @@ -76,7 +77,8 @@ const ViewDocument = (): ReactElement => { >([]); const [actionComment, setActionComment] = useState(""); const [effectiveDate, setEffectiveDate] = useState(""); - const [signatureId, setSignatureId] = useState(""); + const [actionPassword, setActionPassword] = useState(""); + const [actionPin, setActionPin] = useState(""); const [showNewVersionForm, setShowNewVersionForm] = useState(false); const [newVersionContent, setNewVersionContent] = useState(""); const [newVersionContentHtml, setNewVersionContentHtml] = useState(""); @@ -310,7 +312,8 @@ const ViewDocument = (): ReactElement => { setWorkflowDefinitionId(""); setActionComment(""); setEffectiveDate(""); - setSignatureId(""); + setActionPassword(""); + setActionPin(""); setWorkflowOptions([]); setActionErrors({}); }; @@ -356,8 +359,13 @@ const ViewDocument = (): ReactElement => { if (action === "reject" && !actionComment.trim()) { localErrors.comment = "Reason is required for reject"; } - if (action === "effective" && !effectiveDate) { - localErrors.effective_date = "Effective date is required"; + if (action === "effective") { + if (!effectiveDate) { + localErrors.effective_date = "Effective date is required"; + } + if (!actionPassword.trim()) { + localErrors.password = "Password is required for electronic signature"; + } } if (action === "obsolete" && !actionComment.trim()) { localErrors.comment = "Reason is required to obsolete"; @@ -381,10 +389,39 @@ const ViewDocument = (): ReactElement => { await documentService.reject(id, actionComment.trim()); } if (action === "effective") { + const currentVersionObj = versions.find( + (v) => v.version_number === document?.current_version + ) || versions[0]; + const currentVersionId = currentVersionObj?.id; + + if (!currentVersionId) { + showToast.error("Current document version could not be resolved."); + return; + } + + // Generate electronic signature + const signRes = await electronicSignatureService.sign({ + resource_type: "document_version", + resource_id: currentVersionId, + resource_name: `${document?.document_number || "Document"} - Version ${document?.current_version || "1.0"} - Make Effective`, + action: "RELEASE", + meaning: "I authorize the release of this record", + password: actionPassword.trim(), + pin: actionPin.trim() || null, + auth_method: actionPin.trim() ? "password_pin" : "password", + }); + + const finalSignatureId = signRes.data?.id || signRes.data?.signature?.id; + + if (!finalSignatureId) { + showToast.error("Failed to generate electronic signature."); + return; + } + await documentService.makeEffective( id, effectiveDate, - signatureId.trim(), + finalSignatureId, ); } if (action === "obsolete") { @@ -1782,46 +1819,57 @@ const ViewDocument = (): ReactElement => { )} {activeAction === "effective" && ( -
- {actionErrors.effective_date} -
- )} -+ Electronic Signature Verification +
++ Enter your credentials below to electronically sign this document and authorize its release. +
+ +