Merge pull request 'Service_Project_ListView :- Creating List view for service Project.' (#518) from Service_Project_ListView into Project_Branch_Management

Reviewed-on: #518
Merged
This commit is contained in:
pramod.mahajan 2025-11-24 11:16:57 +00:00
commit 965fce1587
11 changed files with 375 additions and 131 deletions

View File

@ -8,7 +8,12 @@ const ProjectCardView = ({ data, currentPage, totalPages, paginate }) => {
return ( return (
<div className="row page-min-h"> <div className="row page-min-h">
{data?.length === 0 && ( {data?.length === 0 && (
<p className="text-center text-muted">No projects found.</p> <div
className="col-12 d-flex justify-content-center align-items-center"
style={{ minHeight: "250px" }}
>
<p className="text-center text-muted m-0">No Infra projects found.</p>
</div>
)} )}
{data?.map((project) => ( {data?.map((project) => (

View File

@ -126,8 +126,8 @@ const ProjectListView = ({ data, currentPage, totalPages, paginate }) => {
return ( return (
<div className="card page-min-h py-4 px-6 shadow-sm"> <div className="card page-min-h py-4 px-6 shadow-sm">
<div className="table-responsive text-nowrap page-min-h"> <div className="table-responsive text-nowrap">
<table className="table table-hover align-middle m-0"> <table className="table table-hover align-middle m-0">
<thead className="border-bottom "> <thead className="border-bottom ">
<tr> <tr>
{projectColumns.map((col) => ( {projectColumns.map((col) => (
@ -143,77 +143,94 @@ const ProjectListView = ({ data, currentPage, totalPages, paginate }) => {
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{data?.map((project) => ( {data?.length > 0 ? (
<tr key={project.id}> data?.map((project) => (
{projectColumns.map((col) => ( <tr key={project.id}>
<td {projectColumns.map((col) => (
key={col.key} <td
colSpan={col.colSpan} key={col.key}
className={`${col.className} py-5`} colSpan={col.colSpan}
style={{ paddingTop: "20px", paddingBottom: "20px" }} className={`${col.className} py-5`}
> style={{ paddingTop: "20px", paddingBottom: "20px" }}
{col.getValue
? col.getValue(project)
: project[col.key] || "N/A"}
</td>
))}
<td
className={`mx-2 ${
canManageProject ? "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 {col.getValue
className="bx bx-dots-vertical-rounded bx-sm text-muted" ? col.getValue(project)
data-bs-toggle="tooltip" : project[col.key] || "N/A"}
data-bs-offset="0,8" </td>
data-bs-placement="top" ))}
data-bs-custom-class="tooltip-dark" <td
title="More Action" className={`mx-2 ${canManageProject ? "d-sm-table-cell" : "d-none"
></i> }`}
</button> >
<ul className="dropdown-menu dropdown-menu-end"> <div className="dropdown z-2">
<li> <button
<a type="button"
aria-label="click to View details" className="btn btn-icon btn-text-secondary rounded-pill dropdown-toggle hide-arrow p-0"
className="dropdown-item cursor-pointer" data-bs-toggle="dropdown"
> aria-expanded="false"
<i className="bx bx-detail me-2"></i> >
<span className="align-left">View details</span> <i
</a> className="bx bx-dots-vertical-rounded bx-sm text-muted"
</li> 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 cursor-pointer"
>
<i className="bx bx-detail me-2"></i>
<span className="align-left">View details</span>
</a>
</li>
<li> <li>
<a <a
className="dropdown-item cursor-pointer" className="dropdown-item cursor-pointer"
onClick={() => onClick={() =>
setMangeProject({ setMangeProject({
isOpen: true, isOpen: true,
Project: project.id, Project: project.id,
}) })
} }
> >
<i className="bx bx-pencil me-2"></i> <i className="bx bx-pencil me-2"></i>
<span className="align-left">Modify</span> <span className="align-left">Modify</span>
</a> </a>
</li> </li>
<li onClick={() => handleViewActivities(project.id)}> <li onClick={() => handleViewActivities(project.id)}>
<a className="dropdown-item cursor-pointer"> <a className="dropdown-item cursor-pointer">
<i className="bx bx-task me-2"></i> <i className="bx bx-task me-2"></i>
<span className="align-left">Activities</span> <span className="align-left">Activities</span>
</a> </a>
</li> </li>
</ul> </ul>
</div> </div>
</td>
</tr>
))
) : (
<tr
className="no-hover"
style={{
pointerEvents: "none",
backgroundColor: "transparent",
}}
>
<td
colSpan={projectColumns.length + 1}
className="text-center align-middle"
style={{ height: "300px", borderBottom: "none" }}
>
No Infra projects available
</td> </td>
</tr> </tr>
))} )}
</tbody> </tbody>
</table> </table>
</div> </div>

View File

@ -26,13 +26,6 @@ const ServiceProjectCard = ({ project, isCore = true }) => {
const ManageProject = useHasUserPermission(MANAGE_PROJECT); const ManageProject = useHasUserPermission(MANAGE_PROJECT);
const { setMangeProject, setManageServiceProject } = useProjectContext(); const { setMangeProject, setManageServiceProject } = useProjectContext();
const getProgress = (planned, completed) => {
return (completed * 100) / planned + "%";
};
const getProgressInNumber = (planned, completed) => {
return (completed * 100) / planned;
};
const handleClose = () => setShowModal(false); const handleClose = () => setShowModal(false);
const handleViewProject = () => { const handleViewProject = () => {
@ -43,10 +36,6 @@ const ServiceProjectCard = ({ project, isCore = true }) => {
navigate(`/service-projects/${project.id}`); navigate(`/service-projects/${project.id}`);
} }
}; };
const handleViewActivities = () => {
dispatch(setProjectId(project.id));
navigate(`/activities/records?project=${project.id}`);
};
const handleManage = () => { const handleManage = () => {
if (isCore) { if (isCore) {
setMangeProject({ setMangeProject({
@ -68,6 +57,8 @@ const ServiceProjectCard = ({ project, isCore = true }) => {
DeleteProject(projectId, false); DeleteProject(projectId, false);
}; };
return ( return (
<> <>
<ConfirmModal <ConfirmModal
@ -138,14 +129,6 @@ const ServiceProjectCard = ({ project, isCore = true }) => {
<span className="align-left">Modify</span> <span className="align-left">Modify</span>
</a> </a>
</li> </li>
{isCore && (
<li onClick={handleViewActivities}>
<a className="dropdown-item">
<i className="bx bx-task me-2"></i>
<span className="align-left">Activities</span>
</a>
</li>
)}
{!isCore && ( {!isCore && (
<li <li
onClick={() => onClick={() =>

View File

@ -0,0 +1,209 @@
import React, { useState } from "react";
import { MANAGE_PROJECT, PROJECT_STATUS } from "../../../utils/constants";
import { useProjects } from "../../../hooks/useProjects";
import { formatNumber, formatUTCToLocalTime } from "../../../utils/dateUtils";
import ProgressBar from "../../common/ProgressBar";
import {
getProjectStatusColor,
getProjectStatusName,
} from "../../../utils/projectStatus";
import { useDispatch } from "react-redux";
import { setProjectId } from "../../../slices/localVariablesSlice";
import { useNavigate } from "react-router-dom";
import { useHasUserPermission } from "../../../hooks/useHasUserPermission";
import { useProjectContext } from "../../../pages/project/ProjectPage";
import usePagination from "../../../hooks/usePagination";
import Pagination from "../../common/Pagination";
const ServiceProjectList = ({
data,
currentPage,
totalPages,
paginate,
isCore = true,
}) => {
const dispatch = useDispatch();
const navigate = useNavigate();
const { setMangeProject, setManageServiceProject } = useProjectContext();
const handleClose = () => setShowModal(false);
// check Permissions
const canManageProject = useHasUserPermission(MANAGE_PROJECT);
const projectColumns = [
{
key: "projectName",
label: "Project Name",
className: "text-start py-3",
getValue: (p) => (
<div
className="text-primary cursor-pointer fw-bold py-3"
onClick={() => {
dispatch(setProjectId(p.id));
navigate(`/service-projects/${p.id}`);
}}
>
{p.shortName ? `${p.name} (${p.shortName})` : p.name}
</div>
),
},
{
key: "client.contactPerson",
label: "Contact Person",
className: "text-start small",
getValue: (p) => p.client?.contactPerson || "N/A",
},
{
key: "assignedDate",
label: "Assign Date",
className: "text-center small",
getValue: (p) => formatUTCToLocalTime(p.assignedDate),
},
{
key: "status",
label: "Status",
className: "text-center small",
getValue: (p) => (
<span className={`badge ${getProjectStatusColor(p.status?.id)}`}>
{p.status?.status}
</span>
),
},
];
const handleViewProject = (p) => {
if (isCore) {
dispatch(setProjectId(p.id));
navigate(`/projects/details`);
} else {
navigate(`/service-projects/${p.id}`);
}
};
const handleManage = (p) => {
if (isCore) {
setMangeProject({
isOpen: true,
Project: p.id,
});
} else {
setManageServiceProject({
isOpen: true,
project: p.id,
});
}
};
return (
<div>
<div className="card page-min-h py-4 px-6 shadow-sm">
<div className="table-responsive text-nowrap page-min-h">
<table className="table table-hover align-middle m-0">
<thead className="border-bottom ">
<tr>
{projectColumns.map((col) => (
<th
key={col.key}
colSpan={col.colSpan}
className={`${col.className} table_header_border`}
>
{col.label}
</th>
))}
<th className="text-center py-3">Action</th>
</tr>
</thead>
<tbody>
{data?.length > 0 ? (
data.map((project) => (
<tr key={project.id}>
{projectColumns.map((col) => (
<td
key={col.key}
colSpan={col.colSpan}
className={`${col.className} py-5`}
style={{ paddingTop: "20px", paddingBottom: "20px" }}
>
{col.getValue
? col.getValue(project)
: project[col.key] || "N/A"}
</td>
))}
<td
className={`mx-2 ${
canManageProject ? "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={() => handleViewProject(project)}
>
<i className="bx bx-detail me-2"></i>
<span className="align-left">View details</span>
</a>
</li>
<li>
<a
className="dropdown-item"
onClick={() => handleManage(project)}
>
<i className="bx bx-pencil me-2"></i>
<span className="align-left">Modify</span>
</a>
</li>
</ul>
</div>
</td>
</tr>
))
) : (
<tr
className="no-hover"
style={{
pointerEvents: "none",
backgroundColor: "transparent",
}}
>
<td
colSpan={projectColumns.length + 1}
className="text-center align-middle"
style={{ height: "300px", borderBottom: "none" }}
>
No Service projects available
</td>
</tr>
)}
</tbody>
</table>
</div>
<Pagination
currentPage={currentPage}
totalPages={totalPages}
paginate={paginate}
/>
</div>
</div>
);
};
export default ServiceProjectList;

View File

@ -20,14 +20,15 @@ export const useCurrentService = () => {
// ------------------------------Query------------------- // ------------------------------Query-------------------
export const useProjects = (pageSize, pageNumber) => { export const useProjects = (pageSize, pageNumber,searchString) => {
const loggedUser = useSelector((store) => store.globalVariables.loginUser); const loggedUser = useSelector((store) => store.globalVariables.loginUser);
return useQuery({ return useQuery({
queryKey: ["ProjectsList", pageSize, pageNumber], queryKey: ["ProjectsList", pageSize, pageNumber,searchString],
queryFn: async () => { queryFn: async () => {
const response = await ProjectRepository.getProjectList( const response = await ProjectRepository.getProjectList(
pageSize, pageSize,
pageNumber pageNumber,
searchString,
); );
return response?.data; return response?.data;
}, },

View File

@ -8,13 +8,14 @@ import { ServiceProjectRepository } from "../repositories/ServiceProjectReposito
import showToast from "../services/toastService"; import showToast from "../services/toastService";
//#region Service Project //#region Service Project
export const useServiceProjects = (pageSize, pageNumber) => { export const useServiceProjects = (pageSize, pageNumber, searchString) => {
return useQuery({ return useQuery({
queryKey: ["serviceProjects", pageSize, pageNumber], queryKey: ["serviceProjects", pageSize, pageNumber, searchString],
queryFn: async () => { queryFn: async () => {
const response = await ServiceProjectRepository.GetServiceProjects( const response = await ServiceProjectRepository.GetServiceProjects(
pageSize, pageSize,
pageNumber pageNumber,
searchString
); );
return response.data; return response.data;
}, },

View File

@ -11,14 +11,18 @@ import GlobalModel from "../../components/common/GlobalModel";
import ManageServiceProject from "../../components/ServiceProject/ManageServiceProject"; import ManageServiceProject from "../../components/ServiceProject/ManageServiceProject";
import { SpinnerLoader } from "../../components/common/Loader"; import { SpinnerLoader } from "../../components/common/Loader";
import ServiceProjectCard from "../../components/ServiceProject/ServiceProjectTeam/ServiceProjectCard"; import ServiceProjectCard from "../../components/ServiceProject/ServiceProjectTeam/ServiceProjectCard";
import ServiceProjectList from "../../components/ServiceProject/ServiceProjectTeam/ServiceProjectList";
import { useDebounce } from "../../utils/appUtils";
const ServiceProjectDisplay = ({ listView ,selectedStatuses }) => { const ServiceProjectDisplay = ({ listView, selectedStatuses, searchTerm }) => {
const [currentPage, setCurrentPage] = useState(1); const [currentPage, setCurrentPage] = useState(1);
const { manageServiceProject, setManageServiceProject } = useProjectContext(); const { manageServiceProject, setManageServiceProject } = useProjectContext();
const debouncedSearch = useDebounce(searchTerm, 500);
const { data, isLoading, isError, error } = useServiceProjects( const { data, isLoading, isError, error } = useServiceProjects(
ITEMS_PER_PAGE, ITEMS_PER_PAGE,
currentPage currentPage,
debouncedSearch
); );
const paginate = (page) => { const paginate = (page) => {
if (page >= 1 && page <= (data?.totalPages ?? 1)) { if (page >= 1 && page <= (data?.totalPages ?? 1)) {
@ -47,15 +51,20 @@ const ServiceProjectDisplay = ({ listView ,selectedStatuses }) => {
</div> </div>
); );
return ( return (
<div className="row"> <div className="">
<div className="row">
{listView ? ( {listView ? (
<p>List</p> <ServiceProjectList data={filteredProjects}
) : ( currentPage={currentPage}
totalPages={data?.totalPages}
paginate={paginate}
isCore={false} />
) : filteredProjects?.length > 0 ? (
filteredProjects?.map((project) => ( filteredProjects?.map((project) => (
<ServiceProjectCard key={project.id} project={project} isCore={false} /> <ServiceProjectCard key={project.id} project={project} isCore={false} />
)) ))
)} ):(<div className="d-flex justify-content-center align-items-center page-min-h "><p>No Service projects available</p></div>)}
<div className="col-12 d-flex justify-content-start mt-3"> <div className="col-12 d-flex justify-content-start mt-3">
<Pagination <Pagination
@ -82,6 +91,7 @@ const ServiceProjectDisplay = ({ listView ,selectedStatuses }) => {
</GlobalModel> </GlobalModel>
)} )}
</div> </div>
</div>
); );
}; };

View File

@ -41,10 +41,11 @@ const ProjectPage = () => {
const [listView, setListView] = useState(false); const [listView, setListView] = useState(false);
const [searchTerm, setSearchTerm] = useState(""); const [searchTerm, setSearchTerm] = useState("");
const [coreProjects, setCoreProjects] = useState(() => { const [coreProjects, setCoreProjects] = useState(() => {
const storedValue = sessionStorage.getItem('whichProjectDisplay'); const storedValue = sessionStorage.getItem("whichProjectDisplay");
return storedValue === 'true'; return storedValue === "true";
}); });
const HasManageProject = useHasUserPermission(MANAGE_PROJECT); const HasManageProject = useHasUserPermission(MANAGE_PROJECT);
const [currentPage, setCurrentPage] = useState(1);
const [selectedStatuses, setSelectedStatuses] = useState( const [selectedStatuses, setSelectedStatuses] = useState(
PROJECT_STATUS.map((s) => s.id) PROJECT_STATUS.map((s) => s.id)
@ -64,13 +65,11 @@ const ProjectPage = () => {
manageServiceProject, manageServiceProject,
}; };
const handleToggleProject = (value) => { const handleToggleProject = (value) => {
setCoreProjects(value); setCoreProjects(value);
sessionStorage.setItem("whichProjectDisplay", String(value)); sessionStorage.setItem("whichProjectDisplay", String(value));
}; };
return ( return (
<ProjectContext.Provider value={contextDispatcher}> <ProjectContext.Provider value={contextDispatcher}>
<div className="container-fluid"> <div className="container-fluid">
@ -90,8 +89,9 @@ const ProjectPage = () => {
{/* Service Project Button */} {/* Service Project Button */}
<button <button
type="button" type="button"
className={`btn px-2 py-1 rounded-0 text-tiny ${!coreProjects ? "btn-primary text-white" : "" className={`btn px-2 py-1 rounded-0 text-tiny ${
}`} !coreProjects ? "btn-primary text-white" : ""
}`}
onClick={() => handleToggleProject(false)} onClick={() => handleToggleProject(false)}
> >
Service Project Service Project
@ -99,20 +99,18 @@ const ProjectPage = () => {
{/* Organization Project Button */} {/* Organization Project Button */}
<button <button
type="button" type="button"
className={`btn px-2 py-1 rounded-0 text-tiny ${coreProjects ? "btn-primary text-white" : "" className={`btn px-2 py-1 rounded-0 text-tiny ${
}`} coreProjects ? "btn-primary text-white" : ""
}`}
onClick={() => handleToggleProject(true)} onClick={() => handleToggleProject(true)}
> >
Infra Project Infra Project
</button> </button>
</div> </div>
</div> </div>
{/* RIGHT SIDE — SEARCH + CARD/LIST + DROPDOWN */} {/* RIGHT SIDE — SEARCH + CARD/LIST + DROPDOWN */}
<div className="d-flex flex-wrap align-items-center justify-content-end"> <div className="d-flex flex-wrap align-items-center justify-content-end">
{/* Search */} {/* Search */}
<div className="me-2" style={{ minWidth: "200px" }}> <div className="me-2" style={{ minWidth: "200px" }}>
<input <input
@ -131,7 +129,9 @@ const ProjectPage = () => {
<div className="d-flex gap-2"> <div className="d-flex gap-2">
<button <button
type="button" type="button"
className={`btn btn-sm p-1 ${!listView ? "btn-primary" : "btn-outline-primary"}`} className={`btn btn-sm p-1 ${
!listView ? "btn-primary" : "btn-outline-primary"
}`}
onClick={() => setListView(false)} onClick={() => setListView(false)}
title="Card View" title="Card View"
> >
@ -140,7 +140,9 @@ const ProjectPage = () => {
<button <button
type="button" type="button"
className={`btn btn-sm p-1 ${listView ? "btn-primary" : "btn-outline-primary"}`} className={`btn btn-sm p-1 ${
listView ? "btn-primary" : "btn-outline-primary"
}`}
onClick={() => setListView(true)} onClick={() => setListView(true)}
title="List View" title="List View"
> >
@ -180,10 +182,14 @@ const ProjectPage = () => {
<button <button
type="button" type="button"
className="btn btn-primary btn-sm d-flex align-items-center my-2" className="btn btn-primary btn-sm d-flex align-items-center my-2"
onClick={() => onClick={
coreProjects () =>
? setMangeProject({ isOpen: true, Project: null }) // Organization Project Infra coreProjects
: setManageServiceProject({ isOpen: true, Project: null }) // Service Project ? setMangeProject({ isOpen: true, Project: null }) // Organization Project Infra
: setManageServiceProject({
isOpen: true,
Project: null,
}) // Service Project
} }
> >
<i className="bx bx-plus-circle me-2"></i> <i className="bx bx-plus-circle me-2"></i>
@ -195,11 +201,22 @@ const ProjectPage = () => {
</div> </div>
</div> </div>
{coreProjects ? <ProjectsDisplay listView={listView} {coreProjects ? (
searchTerm={searchTerm} <ProjectsDisplay
selectedStatuses={selectedStatuses} listView={listView}
handleStatusChange={handleStatusChange} /> : <ServiceProjectDisplay listView={listView} searchTerm={searchTerm}
selectedStatuses={selectedStatuses} />} selectedStatuses={selectedStatuses}
handleStatusChange={handleStatusChange}
currentPage={currentPage}
setCurrentPage={setCurrentPage}
/>
) : (
<ServiceProjectDisplay
listView={listView}
searchTerm={searchTerm}
selectedStatuses={selectedStatuses}
/>
)}
</div> </div>
</ProjectContext.Provider> </ProjectContext.Provider>
); );

View File

@ -10,6 +10,7 @@ import { useServiceProjects } from "../../hooks/useServiceProject";
import { ITEMS_PER_PAGE, PROJECT_STATUS } from "../../utils/constants"; import { ITEMS_PER_PAGE, PROJECT_STATUS } from "../../utils/constants";
import usePagination from "../../hooks/usePagination"; import usePagination from "../../hooks/usePagination";
import ManageProjectInfo from "../../components/Project/ManageProjectInfo"; import ManageProjectInfo from "../../components/Project/ManageProjectInfo";
import { useDebounce } from "../../utils/appUtils";
const ProjectsDisplay = ({ const ProjectsDisplay = ({
listView, listView,
@ -26,8 +27,8 @@ const ProjectsDisplay = ({
} = useProjectContext(); } = useProjectContext();
const [projectList, setProjectList] = useState([]); const [projectList, setProjectList] = useState([]);
const debouncedSearch = useDebounce(searchTerm, 500);
const { data, isLoading, isError, error } = useProjects(ITEMS_PER_PAGE, 1); const { data, isLoading, isError, error } = useProjects(ITEMS_PER_PAGE, 1, debouncedSearch);
const filteredProjects = const filteredProjects =
data?.data?.filter((project) => { data?.data?.filter((project) => {
@ -98,7 +99,7 @@ const ProjectsDisplay = ({
); );
return ( return (
<div className="row"> <div className="">
{listView ? ( {listView ? (
<ProjectListView <ProjectListView
data={projectList} data={projectList}

View File

@ -2,8 +2,8 @@ import { api } from "../utils/axiosClient";
const ProjectRepository = { const ProjectRepository = {
getProjectList: (pageSize, pageNumber) => getProjectList: (pageSize, pageNumber,searchString) =>
api.get(`/api/project/list?pageSize=${pageSize}&pageNumber=${pageNumber}`), api.get(`/api/project/list?pageSize=${pageSize}&pageNumber=${pageNumber}&searchString=${searchString}`),
getProjectByprojectId: (projetid) => getProjectByprojectId: (projetid) =>
api.get(`/api/project/details/${projetid}`), api.get(`/api/project/details/${projetid}`),

View File

@ -4,9 +4,9 @@ import { api } from "../utils/axiosClient";
export const ServiceProjectRepository = { export const ServiceProjectRepository = {
//#region Service Project //#region Service Project
CreateServiceProject: (data) => api.post("/api/ServiceProject/create", data), CreateServiceProject: (data) => api.post("/api/ServiceProject/create", data),
GetServiceProjects: (pageSize, pageNumber) => GetServiceProjects: (pageSize, pageNumber,searchString) =>
api.get( api.get(
`/api/ServiceProject/list?pageSize=${pageSize}&pageNumber=${pageNumber}` `/api/ServiceProject/list?pageSize=${pageSize}&pageNumber=${pageNumber}&searchString=${searchString}`
), ),
GetServiceProject: (id) => api.get(`/api/ServiceProject/details/${id}`), GetServiceProject: (id) => api.get(`/api/ServiceProject/details/${id}`),
UpdateServiceProject: (id, data) => UpdateServiceProject: (id, data) =>