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-10,
|
|
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;
|