268 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			268 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| import React, { useState } from "react";
 | |
| import {
 | |
|   useDocumentDetails,
 | |
|   useDocumentVersionList,
 | |
|   useVerifyDocument,
 | |
| } from "../../hooks/useDocument";
 | |
| import { getDocuementsStatus, useDocumentContext } from "./Documents";
 | |
| import { formatUTCToLocalTime } from "../../utils/dateUtils";
 | |
| import Avatar from "../common/Avatar";
 | |
| import {
 | |
|   DOWNLOAD_DOCUMENT,
 | |
|   ITEMS_PER_PAGE,
 | |
|   VERIFY_DOCUMENT,
 | |
| } from "../../utils/constants";
 | |
| import Pagination from "../common/Pagination";
 | |
| import VersionListSkeleton from "./VersionListSkeleton";
 | |
| import DocumentDetailsSkeleton from "./DocumentDetailsSkeleton ";
 | |
| import { useHasUserPermission } from "../../hooks/useHasUserPermission";
 | |
| 
 | |
| const ViewDocument = () => {
 | |
|   const { viewDoc, setViewDoc, setOpenDocument } = useDocumentContext();
 | |
|   const [currentPage, setCurrentPage] = useState(1);
 | |
|   const canVerifyDocument = useHasUserPermission(VERIFY_DOCUMENT);
 | |
|   const canDownloadDocument = useHasUserPermission(DOWNLOAD_DOCUMENT);
 | |
|   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);
 | |
|     }
 | |
|   };
 | |
| 
 | |
|   const { mutate: VerifyDoc, isPending } = useVerifyDocument();
 | |
|   const VerifyDocument = () => {
 | |
|     VerifyDoc({ documentId: viewDoc?.document, isVerify: true });
 | |
|   };
 | |
| 
 | |
|   if (isLoading) return <DocumentDetailsSkeleton />;
 | |
|   if (isError)
 | |
|     return (
 | |
|       <div>
 | |
|         <p>{error?.response?.data?.message || error?.message}</p>
 | |
|         <p className="danger-text">{error?.response?.status}</p>
 | |
|       </div>
 | |
|     );
 | |
|   return (
 | |
|     <div className="p-1">
 | |
|       <p className="fw-bold fs-6">Document Details</p>
 | |
| 
 | |
|       <div className="row mb-2">
 | |
|         <div className="col-12 col-md-6">
 | |
|           <div className="d-flex text-start">
 | |
|             <span className="fw-semibold me-2" style={{ minWidth: "130px" }}>
 | |
|               Document Name:
 | |
|             </span>
 | |
|             <span className="text-muted">{data.name || "-"}</span>
 | |
|           </div>
 | |
|         </div>
 | |
|         <div className="col-12 col-md-6">
 | |
|           <div className="d-flex text-start">
 | |
|             <span className="fw-semibold me-2" style={{ minWidth: "130px" }}>
 | |
|               Document ID:
 | |
|             </span>
 | |
|             <span className="text-muted">{data.documentId || "-"}</span>
 | |
|           </div>
 | |
|         </div>
 | |
|       </div>
 | |
| 
 | |
|       {/* Row 2 */}
 | |
|       <div className="row mb-2">
 | |
|         <div className="col-12 col-md-6 text-start">
 | |
|           <div className="d-flex">
 | |
|             <span className="fw-semibold me-2" style={{ minWidth: "130px" }}>
 | |
|               Version:
 | |
|             </span>
 | |
|             <span className="text-muted">{data.version || "-"}</span>
 | |
|           </div>
 | |
|         </div>
 | |
|         <div className="col-12 col-md-6 text-start">
 | |
|           <div className="d-flex">
 | |
|             <span className="fw-semibold me-2" style={{ minWidth: "130px" }}>
 | |
|               Uploaded At:
 | |
|             </span>
 | |
|             <span className="text-muted">
 | |
|               {formatUTCToLocalTime(data.uploadedAt)}
 | |
|             </span>
 | |
|           </div>
 | |
|         </div>
 | |
|       </div>
 | |
| 
 | |
|       {/* Row 3 */}
 | |
|       <div className="row mb-2 text-start">
 | |
|         <div className="col-12 col-md-6">
 | |
|           <div className="d-flex">
 | |
|             <span className="fw-semibold me-2" style={{ minWidth: "130px" }}>
 | |
|               Uploaded By:
 | |
|             </span>
 | |
|             <span className="text-muted">
 | |
|               {data.uploadedBy?.firstName || "-"}
 | |
|             </span>
 | |
|           </div>
 | |
|         </div>
 | |
|         <div className="col-12 col-md-6">
 | |
|           <div className="d-flex">
 | |
|             <span className="fw-semibold me-2" style={{ minWidth: "130px" }}>
 | |
|               Updated At:
 | |
|             </span>
 | |
|             <span className="text-muted">
 | |
|               {formatUTCToLocalTime(data.updatedAt) || "-"}
 | |
|             </span>
 | |
|           </div>
 | |
|         </div>
 | |
|       </div>
 | |
| 
 | |
|       {/* Row 4 */}
 | |
|       <div className="row mb-2 text-start">
 | |
|         <div className="col-12 col-md-6">
 | |
|           <div className="d-flex">
 | |
|             <span className="fw-semibold me-2" style={{ minWidth: "130px" }}>
 | |
|               Category:
 | |
|             </span>
 | |
|             <span className="text-muted">
 | |
|               {data.documentType?.documentCategory?.name || "-"}
 | |
|             </span>
 | |
|           </div>
 | |
|         </div>
 | |
|         <div className="col-12 col-md-6">
 | |
|           <div className="d-flex">
 | |
|             <span className="fw-semibold me-2" style={{ minWidth: "130px" }}>
 | |
|               Type:
 | |
|             </span>
 | |
|             <span className="text-muted">{data.documentType?.name || "-"}</span>
 | |
|           </div>
 | |
|         </div>
 | |
|       </div>
 | |
| 
 | |
|       {/* Row 5 - Tags full width */}
 | |
|       <div className="row mb-2 text-start">
 | |
|         <div className="col-12">
 | |
|           <div className="d-flex">
 | |
|             <span className="fw-semibold me-2" style={{ minWidth: "130px" }}>
 | |
|               Tags:
 | |
|             </span>
 | |
|             <div className="d-flex flex-wrap gap-2">
 | |
|               {data.tags?.length > 0 ? (
 | |
|                 data.tags.map((t, i) => (
 | |
|                   <span
 | |
|                     key={i}
 | |
|                     className="badge rounded-pill bg-label-secondary"
 | |
|                   >
 | |
|                     {t.name}
 | |
|                   </span>
 | |
|                 ))
 | |
|               ) : (
 | |
|                 <span className="text-muted">-</span>
 | |
|               )}
 | |
|             </div>
 | |
|           </div>
 | |
|         </div>
 | |
|       </div>
 | |
| 
 | |
|       {/* Row 6 - Description full width */}
 | |
|       <div className="row mb-2 text-start">
 | |
|         <div className="col-12">
 | |
|           <div className="d-flex">
 | |
|             <span className="fw-semibold me-2" style={{ minWidth: "130px" }}>
 | |
|               Description:
 | |
|             </span>
 | |
|             <span className="text-muted">{data.description || "-"}</span>
 | |
|           </div>
 | |
|         </div>
 | |
|       </div>
 | |
| 
 | |
|       <div className="row text-start py-2">
 | |
|         <p className="m-0  fw-semibold : ">Documents</p>
 | |
|         {versionLoding && <VersionListSkeleton items={2} />}
 | |
|         {!versionLoding && (
 | |
|           <div className="list-group mx-0">
 | |
|             {versionList?.data.map((document) => (
 | |
|               <a
 | |
|                 className="list-group-item list-group-item-action  py-1  border border-bottom border-top-0 border-start-0 border-end-0"
 | |
|                 key={document.id}
 | |
|               >
 | |
|                 <div className="d-flex w-100 justify-content-between m-0">
 | |
|                   <p className="m-0">
 | |
|                     {document.name}{" "}
 | |
|                     <em className="text-secondary ms-3">
 | |
|                       {formatUTCToLocalTime(document?.uploadedAt)}
 | |
|                     </em>
 | |
|                   </p>
 | |
|                   <div className="d-flex align-items-center gap-1">
 | |
|                     <small>Version {document.version}</small>
 | |
|                     <small>{getDocuementsStatus(document.isVerified)}</small>
 | |
|                   </div>
 | |
|                 </div>
 | |
|                 <div className="d-flex align-items-center justify-content-between text-secondary">
 | |
|                   <div className="d-flex align-items-center">
 | |
|                     Upload By
 | |
|                     <Avatar
 | |
|                       size="xs"
 | |
|                       classAvatar="m-0"
 | |
|                       firstName={document.uploadedBy?.firstName}
 | |
|                       lastName={document.uploadedBy?.lastName}
 | |
|                     />
 | |
|                     <span className="text-truncate m-0 ">
 | |
|                       {`${document.uploadedBy?.firstName ?? ""} ${
 | |
|                         document.uploadedBy?.lastName ?? ""
 | |
|                       }`.trim() || "N/A"}
 | |
|                     </span>
 | |
|                   </div>
 | |
|                   <div className="d-flex text-primary align-items-center gap-2 ">
 | |
|                     {document.isVerified == null &&
 | |
|                       canVerifyDocument &&
 | |
|                       (isPending ? (
 | |
|                         <div
 | |
|                           class="spinner-border spinner-border-sm text-primary"
 | |
|                           role="status"
 | |
|                         >
 | |
|                           <span class="visually-hidden">Loading...</span>
 | |
|                         </div>
 | |
|                       ) : (
 | |
|                         <span
 | |
|                           className="cursor-pointer"
 | |
|                           onClick={VerifyDocument}
 | |
|                         >
 | |
|                           verify
 | |
|                         </span>
 | |
|                       ))}
 | |
|                     {canDownloadDocument && (
 | |
|                       <span
 | |
|                         className="cursor-pointer text-decoration-underline"
 | |
|                         onClick={() => setOpenDocument(true)}
 | |
|                       >
 | |
|                         <small>view</small>{" "}
 | |
|                         <i className="bx bx-sm bx-link-external"></i>
 | |
|                       </span>
 | |
|                     )}
 | |
|                   </div>
 | |
|                 </div>
 | |
|               </a>
 | |
|             ))}
 | |
|           </div>
 | |
|         )}
 | |
|         {!versionLoding && versionList?.data?.length > 0 && (
 | |
|           <Pagination
 | |
|             currentPage={currentPage}
 | |
|             totalPages={versionList?.totalPages}
 | |
|             onPageChange={paginate}
 | |
|           />
 | |
|         )}
 | |
|       </div>
 | |
|     </div>
 | |
|   );
 | |
| };
 | |
| 
 | |
| export default ViewDocument;
 |