diff --git a/src/components/Documents/DocumentVersionList.jsx b/src/components/Documents/DocumentVersionList.jsx new file mode 100644 index 00000000..ddc6da92 --- /dev/null +++ b/src/components/Documents/DocumentVersionList.jsx @@ -0,0 +1,170 @@ +import React from "react"; +import VersionListSkeleton from "./VersionListSkeleton"; +import { getDocuementsStatus } from "./Documents"; +import Avatar from "../common/Avatar"; +import { formatUTCToLocalTime } from "../../utils/dateUtils"; +import { useHasUserPermission } from "../../hooks/useHasUserPermission"; +import { DOWNLOAD_DOCUMENT, VERIFY_DOCUMENT } from "../../utils/constants"; +import { FileIcon } from "../../utils/FileIcon"; + +const DocumentVersionList = ({ + versionLoding, + versionList, + isPending, + setOpenDocument, + VerifyDocument, +}) => { + const canVerifyDocument = useHasUserPermission(VERIFY_DOCUMENT); + const canDownloadDocument = useHasUserPermission(DOWNLOAD_DOCUMENT); + const handleOpenDocument = () => { + if (canDownloadDocument) { + setOpenDocument(true); + } + }; + const contentTypeIcons = { + "application/pdf": "fa-solid fa-file-pdf text-primary", + "application/msword": "fa-solid fa-file-word text-primary", + "application/vnd.openxmlformats-officedocument.wordprocessingml.document": + "fa-solid fa-file-word text-primary", + "application/vnd.ms-excel": "fa-solid fa-file-excel text-success", + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": + "fa-solid fa-file-excel text-primary", + "application/vnd.ms-powerpoint": "fa-solid fa-file-powerpoint text-primary", + "application/vnd.openxmlformats-officedocument.presentationml.presentation": + "fa-solid fa-file-powerpoint text-primary", + "image/jpg": "fa-solid fa-file-image text-primary", + "image/jpeg": "fa-solid fa-file-image text-primary", + "image/png": "fa-solid fa-file-image text-primary", + "image/gif": "fa-solid fa-file-image text-primary", + "text/plain": "fa-solid fa-file-lines text-primary", + "text/csv": "fa-solid fa-file-csv text-primary", + "application/json": "fa-solid fa-file-code text-primary", + default: "fa-solid fa-file text-primary", + }; + + const getIcon = (fileName = "") => { + const ext = fileName.split(".").pop().toLowerCase(); + return contentTypeIcons[ext] || contentTypeIcons.default; + }; + + const sortedVersions = versionList?.data + ? [...versionList.data].sort((a, b) => b.version - a.version) + : []; + + if (versionLoding) { + return ; + } + + if (!sortedVersions.length) { + return

No documents available.

; + } + + const latestDoc = sortedVersions[0]; + + return ( +
+
+

+ +

+
+
+
+ {sortedVersions.map((document, index) => ( +
0 ? "ms-4" : "" // indent only older versions + }`} + > + + +
+
+ {document.name} + + Version-{document.version} + {" "} + + fileSize: {document.fileSize} Kb + +
+
+
+
+ {formatUTCToLocalTime(document?.uploadedAt)} | + Uploaded by{" "} +
+ + + {`${document.uploadedBy?.firstName ?? ""} ${ + document.uploadedBy?.lastName ?? "" + }`.trim() || "N/A"} + +
+
+ + {document?.updatedAt && ( +
+ {formatUTCToLocalTime(document?.updatedAt)} | + Updated by{" "} +
+ + + {`${document.updatedBy?.firstName ?? ""} ${ + document.updatedBy?.lastName ?? "" + }`.trim() || "N/A"} + +
+
+ )} +
+ +
+ {getDocuementsStatus(document.isVerified)} +
+
+
+
+ ))} +
+
+
+
+
+ ); +}; + +export default DocumentVersionList; diff --git a/src/components/Documents/Documents.jsx b/src/components/Documents/Documents.jsx index 612e18f0..488023ae 100644 --- a/src/components/Documents/Documents.jsx +++ b/src/components/Documents/Documents.jsx @@ -113,18 +113,34 @@ const Documents = ({ Document_Entity, Entity }) => {
{/* Search */} -
- +
setSearchText(e.target.value)} className="form-control form-control-sm" placeholder="Search Document" - /> + />
+
+ {/* Actions */} -
+
{/* { }`} > */} - + {canUploadDocument && (
); diff --git a/src/components/Documents/ViewDocument.jsx b/src/components/Documents/ViewDocument.jsx index f870a5a9..8a6f1cde 100644 --- a/src/components/Documents/ViewDocument.jsx +++ b/src/components/Documents/ViewDocument.jsx @@ -16,6 +16,7 @@ import Pagination from "../common/Pagination"; import VersionListSkeleton from "./VersionListSkeleton"; import DocumentDetailsSkeleton from "./DocumentDetailsSkeleton "; import { useHasUserPermission } from "../../hooks/useHasUserPermission"; +import DocumentVersionList from "./DocumentVersionList"; const ViewDocument = () => { const { viewDoc, setViewDoc, setOpenDocument } = useDocumentContext(); @@ -32,7 +33,7 @@ const ViewDocument = () => { error: versionError, } = useDocumentVersionList( data?.parentAttachmentId, - ITEMS_PER_PAGE-10, + ITEMS_PER_PAGE - 10, currentPage ); const paginate = (page) => { @@ -45,6 +46,9 @@ const ViewDocument = () => { const VerifyDocument = () => { VerifyDoc({ documentId: viewDoc?.document, isVerify: true }); }; + const RejectDocument = () => { + VerifyDoc({ documentId: viewDoc?.document, isVerify: false }); + }; if (isLoading) return ; if (isError) @@ -106,12 +110,22 @@ const ViewDocument = () => { Uploaded By: - - {data.uploadedBy?.firstName || "-"} - +
+ + + {`${data.uploadedBy?.firstName ?? ""} ${ + data.uploadedBy?.lastName ?? "" + }`.trim() || "N/A"} + +
-
+ {data.updatedAt && (
Updated At: @@ -120,7 +134,8 @@ const ViewDocument = () => { {formatUTCToLocalTime(data.updatedAt) || "-"}
-
+ )}{" "} +
{/* Row 4 */} @@ -170,7 +185,6 @@ const ViewDocument = () => { - {/* Row 6 - Description full width */}
@@ -181,85 +195,38 @@ const ViewDocument = () => {
- -
-

Documents

- {versionLoding && } - {!versionLoding && ( -
- {versionList?.data.map((document) => ( - -
-

- {document.name}{" "} - - {formatUTCToLocalTime(document?.uploadedAt)} - -

-
- Version {document.version} - {getDocuementsStatus(document.isVerified)} -
-
-
-
- Upload By - - - {`${document.uploadedBy?.firstName ?? ""} ${ - document.uploadedBy?.lastName ?? "" - }`.trim() || "N/A"} - -
-
- {document.isVerified == null && - canVerifyDocument && - (isPending ? ( -
- Loading... -
- ) : ( - - verify - - ))} - {canDownloadDocument && ( - setOpenDocument(true)} - > - view{" "} - - - )} -
-
-
- ))} + {data.isVerified === null && ( +
+
+ {" "} + {isPending ? ( + "Please Wait..." + ) : ( + + )}
- )} - {!versionLoding && versionList?.data?.length > 0 && ( - - )} -
+
+ )} +
); }; diff --git a/src/hooks/useDocument.js b/src/hooks/useDocument.js index b5f9044c..fc07f21d 100644 --- a/src/hooks/useDocument.js +++ b/src/hooks/useDocument.js @@ -162,6 +162,7 @@ export const useVerifyDocument = ()=>{ onSuccess: (data, variables) => { queryClient.invalidateQueries({ queryKey: ["DocumentVersionList"] }); queryClient.invalidateQueries({ queryKey: ["DocumentList"] }); + queryClient.invalidateQueries({ queryKey: ["Document"] }); showToast( data.response.data.message || "Document Successfully Verified !", diff --git a/src/utils/FileIcon.jsx b/src/utils/FileIcon.jsx new file mode 100644 index 00000000..67088713 --- /dev/null +++ b/src/utils/FileIcon.jsx @@ -0,0 +1,26 @@ +const contentTypeIcons = { + "application/pdf": "fa-solid fa-file-pdf text-danger", + "application/msword": "fa-solid fa-file-word text-primary", + "application/vnd.openxmlformats-officedocument.wordprocessingml.document": + "fa-solid fa-file-word text-primary", + "application/vnd.ms-excel": "fa-solid fa-file-excel text-success", + "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": + "fa-solid fa-file-excel text-success", + "application/vnd.ms-powerpoint": "fa-solid fa-file-powerpoint text-warning", + "application/vnd.openxmlformats-officedocument.presentationml.presentation": + "fa-solid fa-file-powerpoint text-warning", + "image/jpg": "fa-solid fa-file-image text-info", + "image/jpeg": "fa-solid fa-file-image text-info", + "image/png": "fa-solid fa-file-image text-info", + "image/gif": "fa-solid fa-file-image text-info", + "text/plain": "fa-solid fa-file-lines text-secondary", + "text/csv": "fa-solid fa-file-csv text-success", + "application/json": "fa-solid fa-file-code text-dark", + folder: "fa-solid fa-folder text-warning", // special for folders + default: "fa-solid fa-file text-muted", +}; + +export const FileIcon = ({ type, size = "fs-4", className = "" }) => { + const iconClass = contentTypeIcons[type] || contentTypeIcons.default; + return ; +}; \ No newline at end of file