marco.pms.web/src/pages/project/ProjectListView.jsx

208 lines
6.8 KiB
JavaScript

import React, { useState, useEffect } from "react";
import moment from "moment";
import { useProjects } from "../../hooks/useProjects";
import {
getProjectStatusName,
getProjectStatusColor,
} from "../../utils/projectStatus";
import ProgressBar from "../../components/common/ProgressBar";
import { useNavigate } from "react-router-dom";
import ManageProject from "../../components/Project/ManageProject";
import ProjectRepository from "../../repositories/ProjectRepository";
import { MANAGE_PROJECT } from "../../utils/constants";
import { useHasUserPermission } from "../../hooks/useHasUserPermission";
import ManageProjectInfo from "../../components/Project/ManageProjectInfo";
import showToast from "../../services/toastService";
import { getCachedData, cacheData } from "../../slices/apiDataManager";
const ProjectListView = ({ projectData, recall }) => {
const [projectInfo, setProjectInfo] = useState(projectData);
const [projectDetails, setProjectDetails] = useState(null);
const [showModal, setShowModal] = useState(false);
const navigate = useNavigate();
const ManageProject = useHasUserPermission(MANAGE_PROJECT);
const handleShow = async () => {
try {
const response = await ProjectRepository.getProjectByprojectId(
projectInfo.id
);
setProjectDetails(response.data);
setShowModal(true);
} catch (error) {
showToast("Failed to load project details", "error");
}
};
const getProgress = (planned, completed) => {
return (completed * 100) / planned + "%";
};
const getProgressInNumber = (planned, completed) => {
return (completed * 100) / planned;
};
const handleClose = () => setShowModal(false);
const handleViewProject = () => {
navigate(`/projects/${projectData.id}`);
};
const handleFormSubmit = (updatedProject) => {
if (projectInfo?.id) {
ProjectRepository.updateProject(projectInfo.id, updatedProject)
.then((response) => {
const updatedProjectData = {
...projectInfo,
...response.data,
building: projectDetails?.building,
};
setProjectInfo(updatedProjectData);
if (getCachedData(`projectinfo-${projectInfo.id}`)) {
cacheData(`projectinfo-${projectInfo.id}`, updatedProjectData);
}
const projects_list = getCachedData("projectslist");
if (projects_list) {
const updatedProjectsList = projects_list.map((project) =>
project.id === projectInfo.id
? {
...project,
...response.data,
// tenant: project.tenant
}
: project
);
cacheData("projectslist", updatedProjectsList);
}
recall(getCachedData("projectslist"));
showToast("Project updated successfully.", "success");
setShowModal(false);
})
.catch((error) => {
showToast(error.message, "error");
});
}
};
return (
<>
{showModal && projectDetails && (
<tr>
<td
className="modal fade show"
tabIndex="-1"
role="dialog"
style={{ display: "block" }}
aria-hidden="false"
>
<ManageProjectInfo
project={projectDetails}
handleSubmitForm={handleFormSubmit}
onClose={handleClose}
/>
</td>
</tr>
)}
<tr className="py-8">
<td className="text-start" colSpan={5}>
<span
className="text-primary cursor-pointer"
onClick={() => navigate(`/projects/${projectInfo.id}`)}
>
{projectInfo.shortName
? `${projectInfo.name} (${projectInfo.shortName})`
: projectInfo.name}
</span>
</td>
<td className="text-start small">{projectInfo.contactPerson}</td>
<td className="small text-center">
<small>
{projectInfo.startDate
? moment(projectInfo.startDate).format("DD-MMM-YYYY")
: "NA"}
</small>
</td>
<td className="mx-2 text-center small">
{projectInfo.endDate
? moment(projectInfo.endDate).format("DD-MMM-YYYY")
: "NA"}
</td>
<td className="mx-2 text-center small">{projectInfo.plannedWork}</td>
<td className="py-6 mx-2 text-start small align-items-center">
<ProgressBar
plannedWork={projectInfo.plannedWork}
completedWork={projectInfo.completedWork}
className="mb-0"
height="4px"
/>
</td>
<td className="mx-3">
<p className="mb-0">
<span
className={`badge ${getProjectStatusColor(
projectInfo.projectStatusId
)}`}
>
{getProjectStatusName(projectInfo.projectStatusId)}
</span>
</p>
</td>
<td className={`mx-2 ${ManageProject ? "d-sm-table-cell" : "d-none"}`}>
<div className="dropdown z-2">
<button
type="button"
className="btn btn-icon btn-text-secondary rounded-pill dropdown-toggle hide-arrow p-0"
data-bs-toggle="dropdown"
aria-expanded="false"
>
<i
className="bx bx-dots-vertical-rounded bx-sm text-muted"
data-bs-toggle="tooltip"
data-bs-offset="0,8"
data-bs-placement="top"
data-bs-custom-class="tooltip-dark"
title="More Action"
></i>
</button>
<ul className="dropdown-menu dropdown-menu-end">
<li>
<a
aria-label="click to View details"
className="dropdown-item"
onClick={() => navigate(`/projects/${projectInfo.id}`)}
>
<i className="bx bx-detail me-2"></i>
<span className="align-left">View details</span>
</a>
</li>
<li onClick={handleShow}>
<a className="dropdown-item">
<i className="bx bx-pencil me-2"></i>
<span className="align-left">Modify</span>
</a>
</li>
<li
onClick={() =>
navigate(`/activities/records?project=${projectInfo.id}`)
}
>
<a className="dropdown-item">
<i className="bx bx-task me-2"></i>
<span className="align-left">Activities</span>
</a>
</li>
</ul>
</div>
</td>
</tr>
</>
);
};
export default ProjectListView;