diff --git a/src/components/Documents/DocumentDetailsSkeleton .jsx b/src/components/Documents/DocumentDetailsSkeleton .jsx
new file mode 100644
index 00000000..c647dedf
--- /dev/null
+++ b/src/components/Documents/DocumentDetailsSkeleton .jsx
@@ -0,0 +1,88 @@
+import React from "react";
+import VersionListSkeleton from "./VersionListSkeleton";
+
+const SkeletonLine = ({ height = 16, width = "100%", className = "" }) => (
+
+);
+
+const DocumentDetailsSkeleton = () => {
+ return (
+
+
Document Details
+
+ {/* Row 1 */}
+
+
+ {/* Row 2 */}
+
+
+ {/* Row 3 */}
+
+
+
+
+ {/* Row 6 - Description */}
+
+
+ {/* Version list skeleton */}
+
+
+
+
+ );
+};
+
+export default DocumentDetailsSkeleton;
diff --git a/src/components/Documents/Documents.jsx b/src/components/Documents/Documents.jsx
index 44c95195..fbb89d69 100644
--- a/src/components/Documents/Documents.jsx
+++ b/src/components/Documents/Documents.jsx
@@ -13,6 +13,7 @@ import {
} from "./DocumentSchema";
import { zodResolver } from "@hookform/resolvers/zod";
import ManageDocument from "./ManageDocument";
+import ViewDocument from "./ViewDocument";
// Context
export const DocumentContext = createContext();
@@ -24,6 +25,24 @@ export const useDocumentContext = () => {
return context;
};
+
+export const getDocuementsStatus = (status) => {
+ switch (status) {
+ case true:
+ return (
+ Verified
+ );
+ case false:
+ return (
+ Rejected
+ );
+ case null:
+ default:
+ return (
+ Pending
+ );
+ }
+};
const Documents = ({ Document_Entity, Entity }) => {
const [searchText, setSearchText] = useState("");
const [filters, setFilter] = useState();
@@ -35,6 +54,10 @@ const Documents = ({ Document_Entity, Entity }) => {
document: null,
isOpen: false,
});
+ const [viewDoc, setViewDoc] = useState({
+ document: null,
+ isOpen: false,
+ });
const { setOffcanvasContent, setShowTrigger } = useFab();
@@ -67,6 +90,8 @@ const Documents = ({ Document_Entity, Entity }) => {
const contextValues = {
ManageDoc,
setManageDoc,
+ viewDoc,
+ setViewDoc
}
useEffect(()=>{
@@ -93,7 +118,7 @@ const Documents = ({ Document_Entity, Entity }) => {
{/* Actions */}
- {
@@ -108,7 +133,7 @@ const Documents = ({ Document_Entity, Entity }) => {
isRefetching ? "bx-spin" : ""
}`}
>
-
+ */}
diff --git a/src/components/Documents/VersionListSkeleton.jsx b/src/components/Documents/VersionListSkeleton.jsx
new file mode 100644
index 00000000..d239315c
--- /dev/null
+++ b/src/components/Documents/VersionListSkeleton.jsx
@@ -0,0 +1,47 @@
+import React from "react";
+
+const SkeletonLine = ({ height = 16, width = "100%", className = "" }) => (
+
+);
+
+const VersionListSkeleton = ({ items = 5 }) => {
+ return (
+
+ {[...Array(items)].map((_, idx) => (
+
+ {/* Top row: document name + version/status */}
+
+
+ {/* Upload by row */}
+
+
+
+
+
+ {/* Updated at row */}
+
+
+
+
+ ))}
+
+ );
+};
+
+export default VersionListSkeleton;
diff --git a/src/components/Documents/ViewDocument.jsx b/src/components/Documents/ViewDocument.jsx
new file mode 100644
index 00000000..f22e836e
--- /dev/null
+++ b/src/components/Documents/ViewDocument.jsx
@@ -0,0 +1,223 @@
+import React, { useState } from "react";
+import {
+ useDocumentDetails,
+ useDocumentVersionList,
+} from "../../hooks/useDocument";
+import { getDocuementsStatus, useDocumentContext } from "./Documents";
+import { formatUTCToLocalTime } from "../../utils/dateUtils";
+import Avatar from "../common/Avatar";
+import { ITEMS_PER_PAGE } from "../../utils/constants";
+import Pagination from "../common/Pagination";
+import VersionListSkeleton from "./VersionListSkeleton";
+import DocumentDetailsSkeleton from "./DocumentDetailsSkeleton ";
+
+const ViewDocument = () => {
+ const { viewDoc, setViewDoc } = useDocumentContext();
+ const [currentPage, setCurrentPage] = useState(1);
+ const { data, isLoading, isError, error } = useDocumentDetails(
+ viewDoc?.document
+ );
+ const {
+ data: versionList,
+ isError: isVersionError,
+ isLoading: versionLoding,
+ error: versionError,
+ } = useDocumentVersionList(
+ data?.parentAttachmentId,
+ ITEMS_PER_PAGE,
+ currentPage
+ );
+ const paginate = (page) => {
+ if (page >= 1 && page <= (versionList?.totalPages ?? 1)) {
+ setCurrentPage(page);
+ }
+ };
+
+ if (isLoading) return ;
+ if (isError) return {error.message}
;
+ return (
+
+
Document Details
+
+ {/* Row 1 */}
+ {/* Row 1 */}
+
+
+
+
+ Document Name:
+
+ {data.name || "-"}
+
+
+
+
+
+ Document ID:
+
+ {data.documentId || "-"}
+
+
+
+
+ {/* Row 2 */}
+
+
+
+
+ Version:
+
+ {data.version || "-"}
+
+
+
+
+
+ Uploaded At:
+
+
+ {formatUTCToLocalTime(data.uploadedAt)}
+
+
+
+
+
+ {/* Row 3 */}
+
+
+
+
+ Uploaded By:
+
+
+ {data.uploadedBy?.firstName || "-"}
+
+
+
+
+
+
+ Updated At:
+
+
+ {formatUTCToLocalTime(data.updatedAt) || "-"}
+
+
+
+
+
+ {/* Row 4 */}
+
+
+
+
+ Category:
+
+
+ {data.documentType?.documentCategory?.name || "-"}
+
+
+
+
+
+
+ Type:
+
+ {data.documentType?.name || "-"}
+
+
+
+
+ {/* Row 5 - Tags full width */}
+
+
+
+
+ Tags:
+
+
+ {data.tags?.length > 0 ? (
+ data.tags.map((t, i) => (
+
+ {t.name}
+
+ ))
+ ) : (
+ -
+ )}
+
+
+
+
+
+ {/* Row 6 - Description full width */}
+
+
+
+
+ Description:
+
+ {data.description || "-"}
+
+
+
+
+
+
Documents
+ {versionLoding &&
}
+ {!versionLoding &&()}
+ {!versionLoding && versionList?.data?.length > 0 && (
+
+ )}
+
+
+ );
+};
+
+export default ViewDocument;
diff --git a/src/hooks/useDocument.js b/src/hooks/useDocument.js
index abdee444..609955c6 100644
--- a/src/hooks/useDocument.js
+++ b/src/hooks/useDocument.js
@@ -1,4 +1,4 @@
-import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"
+import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import showToast from "../services/toastService";
import { DocumentRepository } from "../repositories/DocumentRepository";
@@ -6,7 +6,12 @@ import { DocumentRepository } from "../repositories/DocumentRepository";
const cleanFilter = (filter) => {
const cleaned = { ...filter };
- ["uploadedByIds", "documentCategoryIds", "documentTypeIds", "documentTagIds"].forEach((key) => {
+ [
+ "uploadedByIds",
+ "documentCategoryIds",
+ "documentTypeIds",
+ "documentTagIds",
+ ].forEach((key) => {
if (Array.isArray(cleaned[key]) && cleaned[key].length === 0) {
delete cleaned[key];
}
@@ -20,73 +25,112 @@ const cleanFilter = (filter) => {
return cleaned;
};
-export const useDocumentListByEntityId=(entityTypeId,entityId,pageSize, pageNumber, filter,searchString="")=>{
+export const useDocumentListByEntityId = (
+ entityTypeId,
+ entityId,
+ pageSize,
+ pageNumber,
+ filter,
+ searchString = ""
+) => {
return useQuery({
- queryKey:["DocumentList",entityTypeId,entityId,pageSize, pageNumber, filter,searchString],
- queryFn:async()=>{
+ queryKey: [
+ "DocumentList",
+ entityTypeId,
+ entityId,
+ pageSize,
+ pageNumber,
+ filter,
+ searchString,
+ ],
+ queryFn: async () => {
const cleanedFilter = cleanFilter(filter);
- const resp = await DocumentRepository.getDocumentList(entityTypeId,entityId,pageSize, pageNumber,cleanedFilter,searchString);
- return resp.data;
+ const resp = await DocumentRepository.getDocumentList(
+ entityTypeId,
+ entityId,
+ pageSize,
+ pageNumber,
+ cleanedFilter,
+ searchString
+ );
+ return resp.data
+
},
- enabled:!!entityTypeId && !! entityId
- })
-}
+ enabled: !!entityTypeId && !!entityId,
+ });
+};
-export const useDocumentFilterEntities =(entityTypeId)=>{
+export const useDocumentFilterEntities = (entityTypeId) => {
return useQuery({
- queryKey:["DFilter",entityTypeId],
- queryFn:async()=> await DocumentRepository.getFilterEntities(entityTypeId)
- })
-}
+ queryKey: ["DFilter", entityTypeId],
+ queryFn: async () =>
+ await DocumentRepository.getFilterEntities(entityTypeId),
+ });
+};
-export const useDocumentDetails =(documentId)=>{
+export const useDocumentDetails = (documentId) => {
return useQuery({
- queryKey:["Document",documentId],
- queryFn:async()=> {
+ queryKey: ["Document", documentId],
+ queryFn: async () => {
const resp = await DocumentRepository.getDocumentById(documentId);
return resp.data;
},
- enabled:!!documentId
- })
+ enabled: !!documentId,
+ });
+};
-}
+export const useDocumentVersionList = (parentAttachmentId,pageSize,pageNumber) => {
+ return useQuery({
+ queryKey: ["DocumentVersionList", parentAttachmentId,pageSize,pageNumber],
+ queryFn: async () => {
+ const resp = await DocumentRepository.getDocumentVersionList(parentAttachmentId,pageSize,pageNumber);
+ return resp.data
+ },
+
+ enabled: !!parentAttachmentId,
+ });
+};
//----------------------- MUTATION -------------------------
-export const useUploadDocument =(onSuccessCallBack)=>{
- const queryClient = useQueryClient()
- return useMutation(({
- mutationFn:async(DocumentPayload)=>DocumentRepository.uploadDocument(DocumentPayload),
- onSuccess:(data,variables)=>{
- queryClient.invalidateQueries({queryKey:["DocumentList"]});
-
- if(onSuccessCallBack) onSuccessCallBack()
- },
- onError: (error) => {
- console.log(error)
- showToast(
- error.response.data.message || "Something went wrong please try again !",
+export const useUploadDocument = (onSuccessCallBack) => {
+ const queryClient = useQueryClient();
+ return useMutation({
+ mutationFn: async (DocumentPayload) =>
+ DocumentRepository.uploadDocument(DocumentPayload),
+ onSuccess: (data, variables) => {
+ queryClient.invalidateQueries({ queryKey: ["DocumentList"] });
+
+ if (onSuccessCallBack) onSuccessCallBack();
+ },
+ onError: (error) => {
+ console.log(error);
+ showToast(
+ error.response.data.message ||
+ "Something went wrong please try again !",
"error"
);
},
- }))
-}
-export const useUpdateDocument =(onSuccessCallBack)=>{
- const queryClient = useQueryClient()
- return useMutation(({
- mutationFn:async({documentId,DocumentPayload})=>DocumentRepository.UpdateDocument(documentId,DocumentPayload),
- onSuccess:(data,variables)=>{
- const {documentId} = variables;
- queryClient.invalidateQueries({queryKey:["DocumentList"]});
- queryClient.invalidateQueries({queryKey:["Document",documentId]})
- if(onSuccessCallBack) onSuccessCallBack()
- },
- onError: (error) => {
- console.log(error)
- showToast(
- error.response.data.message || "Something went wrong please try again !",
+ });
+};
+export const useUpdateDocument = (onSuccessCallBack) => {
+ const queryClient = useQueryClient();
+ return useMutation({
+ mutationFn: async ({ documentId, DocumentPayload }) =>
+ DocumentRepository.UpdateDocument(documentId, DocumentPayload),
+ onSuccess: (data, variables) => {
+ const { documentId } = variables;
+ queryClient.invalidateQueries({ queryKey: ["DocumentList"] });
+ queryClient.invalidateQueries({ queryKey: ["Document", documentId] });
+ if (onSuccessCallBack) onSuccessCallBack();
+ },
+ onError: (error) => {
+ console.log(error);
+ showToast(
+ error.response.data.message ||
+ "Something went wrong please try again !",
"error"
);
},
- }))
-}
\ No newline at end of file
+ });
+};
diff --git a/src/repositories/DocumentRepository.jsx b/src/repositories/DocumentRepository.jsx
index be75b9eb..b26a5fa3 100644
--- a/src/repositories/DocumentRepository.jsx
+++ b/src/repositories/DocumentRepository.jsx
@@ -10,5 +10,15 @@ export const DocumentRepository = {
getFilterEntities:(entityTypeId)=>api.get(`/api/Document/get/filter/${entityTypeId}`),
- UpdateDocument:(documentId,data)=>api.put(`/api/Document/edit/${documentId}`,data)
+ UpdateDocument:(documentId,data)=>api.put(`/api/Document/edit/${documentId}`,data),
+
+ getDocumentVersionList:(parentAttachmentId,pageSize,pageNumber)=>api.get(`/api/Document/list/versions/${parentAttachmentId}/?pageSize=${pageSize}&pageNumber=${pageNumber}`),
+
+ getDocumentVersion:(id)=>api.get(`/api/Document/get/version/${id}`),
+
+ verifyDocument:(id)=>api.post(`/api/Document/verify/${id}`),
+
+ deleteDocument:(id)=>api.delete(`/api/Document/delete/${id}`)
+
+
}
\ No newline at end of file