document can inside open in browser
This commit is contained in:
parent
809f2ef726
commit
ef00f83c44
27
src/components/Documents/DocumentViewerModal.jsx
Normal file
27
src/components/Documents/DocumentViewerModal.jsx
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import React, { useEffect } from "react";
|
||||||
|
import { useDocumentVersion } from "../../hooks/useDocument";
|
||||||
|
import { useDocumentContext } from "./Documents";
|
||||||
|
import { error } from "pdf-lib";
|
||||||
|
|
||||||
|
const DocumentViewerModal = () => {
|
||||||
|
const { viewDoc,setOpenDocument } = useDocumentContext();
|
||||||
|
const { data, isLoading, isError,error } = useDocumentVersion(viewDoc.document);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (data?.data) {
|
||||||
|
const fileUrl = data.data;
|
||||||
|
window.open(fileUrl, "_blank");
|
||||||
|
setOpenDocument(false)
|
||||||
|
}
|
||||||
|
}, [data]);
|
||||||
|
|
||||||
|
if (isLoading) return <p>Loading document...</p>;
|
||||||
|
if (isError) return <div>
|
||||||
|
<p className="danger-text">{error.message}</p>
|
||||||
|
</div>;
|
||||||
|
|
||||||
|
// Nothing to render inside modal since we redirect
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DocumentViewerModal;
|
||||||
@ -14,6 +14,7 @@ import {
|
|||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
import ManageDocument from "./ManageDocument";
|
import ManageDocument from "./ManageDocument";
|
||||||
import ViewDocument from "./ViewDocument";
|
import ViewDocument from "./ViewDocument";
|
||||||
|
import DocumentViewerModal from "./DocumentViewerModal";
|
||||||
|
|
||||||
// Context
|
// Context
|
||||||
export const DocumentContext = createContext();
|
export const DocumentContext = createContext();
|
||||||
@ -50,6 +51,7 @@ const Documents = ({ Document_Entity, Entity }) => {
|
|||||||
const [refetchFn, setRefetchFn] = useState(null);
|
const [refetchFn, setRefetchFn] = useState(null);
|
||||||
const [DocumentEntity,setDocumentEntity] = useState(Document_Entity)
|
const [DocumentEntity,setDocumentEntity] = useState(Document_Entity)
|
||||||
const { employeeId } = useParams();
|
const { employeeId } = useParams();
|
||||||
|
const [OpenDocument,setOpenDocument] = useState(false)
|
||||||
const [ManageDoc, setManageDoc] = useState({
|
const [ManageDoc, setManageDoc] = useState({
|
||||||
document: null,
|
document: null,
|
||||||
isOpen: false,
|
isOpen: false,
|
||||||
@ -91,7 +93,9 @@ const Documents = ({ Document_Entity, Entity }) => {
|
|||||||
ManageDoc,
|
ManageDoc,
|
||||||
setManageDoc,
|
setManageDoc,
|
||||||
viewDoc,
|
viewDoc,
|
||||||
setViewDoc
|
setViewDoc,
|
||||||
|
setOpenDocument,
|
||||||
|
OpenDocument
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(()=>{
|
useEffect(()=>{
|
||||||
@ -189,6 +193,13 @@ const Documents = ({ Document_Entity, Entity }) => {
|
|||||||
<ViewDocument />
|
<ViewDocument />
|
||||||
</GlobalModel>
|
</GlobalModel>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{OpenDocument && (
|
||||||
|
<GlobalModel isOpen={OpenDocument} closeModal={()=>setOpenDocument(false)}>
|
||||||
|
<DocumentViewerModal/>
|
||||||
|
</GlobalModel>
|
||||||
|
)}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</DocumentContext.Provider>
|
</DocumentContext.Provider>
|
||||||
|
|
||||||
|
|||||||
@ -9,7 +9,6 @@ import { DocumentTableSkeleton } from "./DocumentSkeleton";
|
|||||||
import { getDocuementsStatus, useDocumentContext } from "./Documents";
|
import { getDocuementsStatus, useDocumentContext } from "./Documents";
|
||||||
import Pagination from "../common/Pagination";
|
import Pagination from "../common/Pagination";
|
||||||
|
|
||||||
|
|
||||||
const DocumentsList = ({
|
const DocumentsList = ({
|
||||||
Document_Entity,
|
Document_Entity,
|
||||||
Entity,
|
Entity,
|
||||||
@ -19,7 +18,7 @@ const DocumentsList = ({
|
|||||||
setRefetchFn,
|
setRefetchFn,
|
||||||
}) => {
|
}) => {
|
||||||
const debouncedSearch = useDebounce(searchText, 500);
|
const debouncedSearch = useDebounce(searchText, 500);
|
||||||
const [currentPage,setCurrentPage] = useState(1)
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
const { data, isError, isLoading, error, refetch, isFetching } =
|
const { data, isError, isLoading, error, refetch, isFetching } =
|
||||||
useDocumentListByEntityId(
|
useDocumentListByEntityId(
|
||||||
Document_Entity,
|
Document_Entity,
|
||||||
@ -40,19 +39,20 @@ const DocumentsList = ({
|
|||||||
setIsRefetching(isFetching);
|
setIsRefetching(isFetching);
|
||||||
}, [isFetching, setIsRefetching]);
|
}, [isFetching, setIsRefetching]);
|
||||||
|
|
||||||
const {setManageDoc,setViewDoc} = useDocumentContext()
|
const { setManageDoc, setViewDoc } = useDocumentContext();
|
||||||
|
|
||||||
// check no data scenarios
|
const paginate = (page) => {
|
||||||
const noData = !isLoading && !isError && data?.data.length === 0;
|
|
||||||
const isSearchEmpty = noData && !!debouncedSearch;
|
|
||||||
const isFilterEmpty = noData && false;
|
|
||||||
const isInitialEmpty = noData && !debouncedSearch;
|
|
||||||
const paginate = (page) => {
|
|
||||||
if (page >= 1 && page <= (data?.totalPages ?? 1)) {
|
if (page >= 1 && page <= (data?.totalPages ?? 1)) {
|
||||||
setCurrentPage(page);
|
setCurrentPage(page);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (isLoading || isFetching) return <DocumentTableSkeleton />
|
|
||||||
|
const noData = !isLoading && !isError && data?.data.length === 0;
|
||||||
|
const isSearchEmpty = noData && !!debouncedSearch;
|
||||||
|
const isFilterEmpty = noData && !!filters && Object.keys(filters).length > 0;
|
||||||
|
const isInitialEmpty = noData && !debouncedSearch && !isFilterEmpty;
|
||||||
|
|
||||||
|
if (isLoading || isFetching) return <DocumentTableSkeleton />;
|
||||||
if (isError)
|
if (isError)
|
||||||
return <div>Error: {error?.message || "Something went wrong"}</div>;
|
return <div>Error: {error?.message || "Something went wrong"}</div>;
|
||||||
if (isInitialEmpty) return <div>No documents found yet.</div>;
|
if (isInitialEmpty) return <div>No documents found yet.</div>;
|
||||||
@ -137,9 +137,19 @@ const DocumentsList = ({
|
|||||||
))}
|
))}
|
||||||
<td className="text-center">
|
<td className="text-center">
|
||||||
<div className="d-flex justify-content-center gap-2">
|
<div className="d-flex justify-content-center gap-2">
|
||||||
<i className="bx bx-show text-primary cursor-pointer" onClick={()=>setViewDoc({document:doc?.id,isOpen:true})}></i>
|
<i
|
||||||
|
className="bx bx-show text-primary cursor-pointer"
|
||||||
|
onClick={() =>
|
||||||
|
setViewDoc({ document: doc?.id, isOpen: true })
|
||||||
|
}
|
||||||
|
></i>
|
||||||
|
|
||||||
<i className="bx bx-edit text-secondary cursor-pointer" onClick={()=>setManageDoc({document:doc?.id,isOpen:true})}></i>
|
<i
|
||||||
|
className="bx bx-edit text-secondary cursor-pointer"
|
||||||
|
onClick={() =>
|
||||||
|
setManageDoc({ document: doc?.id, isOpen: true })
|
||||||
|
}
|
||||||
|
></i>
|
||||||
|
|
||||||
<i className="bx bx-trash text-danger cursor-pointer"></i>
|
<i className="bx bx-trash text-danger cursor-pointer"></i>
|
||||||
</div>
|
</div>
|
||||||
@ -149,12 +159,12 @@ const DocumentsList = ({
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
{data?.data?.length > 0 && (
|
{data?.data?.length > 0 && (
|
||||||
<Pagination
|
<Pagination
|
||||||
currentPage={currentPage}
|
currentPage={currentPage}
|
||||||
totalPages={data?.totalPages}
|
totalPages={data?.totalPages}
|
||||||
onPageChange={paginate}
|
onPageChange={paginate}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -12,7 +12,7 @@ import VersionListSkeleton from "./VersionListSkeleton";
|
|||||||
import DocumentDetailsSkeleton from "./DocumentDetailsSkeleton ";
|
import DocumentDetailsSkeleton from "./DocumentDetailsSkeleton ";
|
||||||
|
|
||||||
const ViewDocument = () => {
|
const ViewDocument = () => {
|
||||||
const { viewDoc, setViewDoc } = useDocumentContext();
|
const { viewDoc, setViewDoc,setOpenDocument } = useDocumentContext();
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
const { data, isLoading, isError, error } = useDocumentDetails(
|
const { data, isLoading, isError, error } = useDocumentDetails(
|
||||||
viewDoc?.document
|
viewDoc?.document
|
||||||
@ -39,8 +39,7 @@ const ViewDocument = () => {
|
|||||||
<div className="p-1">
|
<div className="p-1">
|
||||||
<p className="fw-bold fs-6">Document Details</p>
|
<p className="fw-bold fs-6">Document Details</p>
|
||||||
|
|
||||||
{/* Row 1 */}
|
|
||||||
{/* Row 1 */}
|
|
||||||
<div className="row mb-2">
|
<div className="row mb-2">
|
||||||
<div className="col-12 col-md-6">
|
<div className="col-12 col-md-6">
|
||||||
<div className="d-flex text-start">
|
<div className="d-flex text-start">
|
||||||
@ -184,8 +183,9 @@ const ViewDocument = () => {
|
|||||||
<small>{getDocuementsStatus(document.isVerified)}</small>
|
<small>{getDocuementsStatus(document.isVerified)}</small>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="d-flex align-items-center text-secondary">
|
<div className="d-flex align-items-center justify-content-between text-secondary">
|
||||||
Upload By
|
<div className="d-flex align-items-center">
|
||||||
|
Upload By
|
||||||
<Avatar
|
<Avatar
|
||||||
size="xs"
|
size="xs"
|
||||||
classAvatar="m-0"
|
classAvatar="m-0"
|
||||||
@ -197,14 +197,18 @@ const ViewDocument = () => {
|
|||||||
document.uploadedBy?.lastName ?? ""
|
document.uploadedBy?.lastName ?? ""
|
||||||
}`.trim() || "N/A"}
|
}`.trim() || "N/A"}
|
||||||
</span>
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="d-flex text-primary align-items-center cursor-pointer"onClick={()=>setOpenDocument(true)} >
|
||||||
|
<small >view</small> <i className='bx bx-sm bx-link-external'></i>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="d-flex gap-2">
|
{/* <div className="d-flex gap-2">
|
||||||
{document?.updatedAt && (
|
{document?.updatedAt && (
|
||||||
<span className="small text-secondary">
|
<span className="small text-secondary">
|
||||||
Updated At : {formatUTCToLocalTime(document.updatedAt)}
|
Updated At : {formatUTCToLocalTime(document.updatedAt)}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div> */}
|
||||||
</a>
|
</a>
|
||||||
))}
|
))}
|
||||||
</div>)}
|
</div>)}
|
||||||
|
|||||||
@ -91,6 +91,14 @@ export const useDocumentVersionList = (parentAttachmentId,pageSize,pageNumber) =
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export const useDocumentVersion = (id)=>{
|
||||||
|
return useQuery({
|
||||||
|
queryKey:["DocumentVersion",id],
|
||||||
|
queryFn:async()=> await DocumentRepository.getDocumentVersion(id),
|
||||||
|
enabled:!!id
|
||||||
|
})
|
||||||
|
}
|
||||||
//----------------------- MUTATION -------------------------
|
//----------------------- MUTATION -------------------------
|
||||||
|
|
||||||
export const useUploadDocument = (onSuccessCallBack) => {
|
export const useUploadDocument = (onSuccessCallBack) => {
|
||||||
|
|||||||
@ -86,12 +86,12 @@ const LoginPage = () => {
|
|||||||
}
|
}
|
||||||
}, [IsLoginWithOTP]);
|
}, [IsLoginWithOTP]);
|
||||||
|
|
||||||
useEffect(() => {
|
// useEffect(() => {
|
||||||
const token = localStorage.getItem("jwtToken");
|
// const token = localStorage.getItem("jwtToken");
|
||||||
if (token) {
|
// if (token) {
|
||||||
navigate("/dashboard");
|
// navigate("/dashboard");
|
||||||
}
|
// }
|
||||||
}, [navigate]);
|
// }, [navigate]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AuthWrapper>
|
<AuthWrapper>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user