210 lines
6.8 KiB
JavaScript
210 lines
6.8 KiB
JavaScript
import React, { useState, useEffect } from "react";
|
|
import ProjectCard from "../../components/Project/ProjectCard";
|
|
import ManageProjectInfo from "../../components/Project/ManageProjectInfo";
|
|
import Breadcrumb from "../../components/common/Breadcrumb";
|
|
import ProjectRepository from "../../repositories/ProjectRepository";
|
|
import { useProjects } from "../../hooks/useProjects";
|
|
import { useDispatch } from "react-redux";
|
|
import showToast from "../../services/toastService";
|
|
import { getCachedData, cacheData} from "../../slices/apiDataManager";
|
|
import {useHasUserPermission} from "../../hooks/useHasUserPermission"
|
|
import { useProfile } from "../../hooks/useProfile";
|
|
import {MANAGE_PROJECT} from "../../utils/constants";
|
|
|
|
const ProjectList = () =>
|
|
{
|
|
|
|
const {profile: loginUser} = useProfile();
|
|
const [showModal, setShowModal] = useState(false);
|
|
const {projects, loading, error, refetch} = useProjects();
|
|
const [refresh, setRefresh] = useState(false);
|
|
const [ projectList, setProjectList ] = useState( [] );
|
|
const HasManageProjectPermission = useHasUserPermission( MANAGE_PROJECT )
|
|
const[HasManageProject,setHasManageProject] = useState(HasManageProjectPermission)
|
|
const dispatch = useDispatch();
|
|
const [currentPage, setCurrentPage] = useState(1);
|
|
const [itemsPerPage] = useState(6);
|
|
|
|
|
|
const handleShow = () => setShowModal(true);
|
|
const handleClose = () => setShowModal( false );
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
setProjectList( projects )
|
|
|
|
}, [ projects, loginUser?.projects, loading ] );
|
|
|
|
useEffect(() => {
|
|
if (loginUser) {
|
|
setHasManageProject(HasManageProjectPermission);
|
|
} else {
|
|
setHasManageProject(false); }
|
|
}, [loginUser, HasManageProjectPermission]);
|
|
|
|
|
|
|
|
const handleSubmitForm = (newProject) => {
|
|
ProjectRepository.manageProject(newProject)
|
|
.then( ( response ) =>
|
|
{
|
|
|
|
const cachedProjects_list = getCachedData( "projectslist" ) || [];
|
|
|
|
const updated_Projects_list = [ ...cachedProjects_list, response.data ];
|
|
|
|
cacheData("projectslist", updated_Projects_list);
|
|
setProjectList((prevProjectList) => [...prevProjectList, response.data]);
|
|
|
|
showToast("Project Created successfully.", "success");
|
|
setShowModal(false)
|
|
})
|
|
.catch((error) => {
|
|
closeModal();
|
|
showToast(error.message, "error");
|
|
});
|
|
};
|
|
|
|
const handleReFresh = () => {
|
|
if (!projects || projects.length === 0) {
|
|
refetch();
|
|
}
|
|
setRefresh((prev) => !prev);
|
|
};
|
|
|
|
const indexOfLastItem = currentPage * itemsPerPage;
|
|
const indexOfFirstItem = indexOfLastItem - itemsPerPage;
|
|
const currentItems = Array.isArray(projectList)
|
|
? projectList.slice(indexOfFirstItem, indexOfLastItem)
|
|
: [];
|
|
|
|
const paginate = (pageNumber) => setCurrentPage(pageNumber);
|
|
const totalPages = Array.isArray(projectList)
|
|
? Math.ceil(projectList.length / itemsPerPage)
|
|
: 0;
|
|
|
|
|
|
return (
|
|
<>
|
|
<div
|
|
className={`modal fade ${showModal ? 'show' : ''}`}
|
|
tabIndex="-1"
|
|
role="dialog"
|
|
style={{ display: showModal ? 'block' : 'none' }}
|
|
aria-hidden={!showModal}
|
|
>
|
|
<ManageProjectInfo
|
|
project={null}
|
|
handleSubmitForm={handleSubmitForm}
|
|
onClose={handleClose}
|
|
></ManageProjectInfo>
|
|
</div>
|
|
|
|
<div className="container-xxl flex-grow-1 container-p-y">
|
|
<Breadcrumb
|
|
data={[
|
|
{ label: "Home", link: "/dashboard" },
|
|
{ label: "Projects", link: null },
|
|
]}
|
|
></Breadcrumb>
|
|
|
|
<div className="row">
|
|
<div
|
|
className={`col-md-12 col-lg-12 col-xl-12 order-0 mb-4 ${
|
|
!error && !projects ? "text-center" : "text-end"
|
|
}`}
|
|
>
|
|
{" "}
|
|
<button
|
|
type="button"
|
|
className={`btn btn-sm btn-primary ${!HasManageProject && 'd-none' }`}
|
|
data-bs-toggle="modal"
|
|
data-bs-target="#create-project-model"
|
|
onClick={handleShow}
|
|
>
|
|
<i className="bx bx-plus-circle me-2"></i>
|
|
Create New Project
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
{((error && !loading) || !projects) && (
|
|
<p className="text-center text-body-secondary">
|
|
There was an error loading the projects. Please try again.
|
|
</p>
|
|
)}
|
|
|
|
{(!projects || projects.length === 0 || projectList.length == 0) &&
|
|
!loading &&
|
|
error && (
|
|
<div className="text-center">
|
|
<button
|
|
className="btn btn-xs btn-label-secondary"
|
|
onClick={handleReFresh}
|
|
>
|
|
Retry Fetching Projects
|
|
</button>
|
|
</div>
|
|
)}
|
|
|
|
<div className="row">
|
|
{loading && <p className="text-center">Loading...</p>}
|
|
{currentItems &&
|
|
currentItems.sort((a, b) => b.id - a.id).map((item) => (
|
|
<ProjectCard projectData={item} key={item.id}></ProjectCard>
|
|
))}
|
|
</div>
|
|
{/* Pagination */}
|
|
{!loading && (
|
|
<nav aria-label="Page ">
|
|
<ul className="pagination pagination-sm justify-content-end py-1">
|
|
<li
|
|
className={`page-item ${
|
|
currentPage === 1 ? "disabled" : ""
|
|
}`}
|
|
>
|
|
<button
|
|
className="page-link btn-xs"
|
|
onClick={() => paginate(currentPage - 1)}
|
|
>
|
|
«
|
|
</button>
|
|
</li>
|
|
{[...Array(totalPages)]?.map((_, index) => (
|
|
<li
|
|
key={index}
|
|
className={`page-item ${
|
|
currentPage === index + 1 ? "active" : ""
|
|
}`}
|
|
>
|
|
<button
|
|
className="page-link "
|
|
onClick={() => paginate(index + 1)}
|
|
>
|
|
{index + 1}
|
|
</button>
|
|
</li>
|
|
))}
|
|
<li
|
|
className={`page-item ${
|
|
currentPage === totalPages ? "disabled" : ""
|
|
}`}
|
|
>
|
|
<button
|
|
className="page-link "
|
|
onClick={() => paginate(currentPage + 1)}
|
|
>
|
|
»
|
|
</button>
|
|
</li>
|
|
</ul>
|
|
</nav>
|
|
)}
|
|
</div>
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default ProjectList;
|