added delete service project

This commit is contained in:
pramod.mahajan 2025-11-12 19:38:04 +05:30
parent 1bba9ab68a
commit d7f00898a0
7 changed files with 124 additions and 79 deletions

View File

@ -21,8 +21,14 @@ import GlobalModel from "../common/GlobalModel";
import { useDispatch } from "react-redux"; import { useDispatch } from "react-redux";
import { setProjectId } from "../../slices/localVariablesSlice"; import { setProjectId } from "../../slices/localVariablesSlice";
import { useProjectContext } from "../../pages/project/ProjectPage"; import { useProjectContext } from "../../pages/project/ProjectPage";
import { useActiveInActiveServiceProject } from "../../hooks/useServiceProject";
import ConfirmModal from "../common/ConfirmModal";
const ProjectCard = ({ project, isCore = true }) => { const ProjectCard = ({ project, isCore = true }) => {
const [deleteProject, setDeleteProject] = useState({
project: null,
isOpen: false,
});
const dispatch = useDispatch(); const dispatch = useDispatch();
const navigate = useNavigate(); const navigate = useNavigate();
const ManageProject = useHasUserPermission(MANAGE_PROJECT); const ManageProject = useHasUserPermission(MANAGE_PROJECT);
@ -62,8 +68,25 @@ const ProjectCard = ({ project, isCore = true }) => {
}); });
} }
}; };
const { mutate: DeleteProject, isPending } = useActiveInActiveServiceProject(
() => setDeleteProject({ project: null, isOpen: false })
);
const handleActiveInactive = (projectId) => {
DeleteProject(projectId, false);
};
return ( return (
<> <>
<ConfirmModal
type="delete"
header="Delete Project"
message="Are you sure you want delete?"
onSubmit={handleActiveInactive}
onClose={() => setDeleteProject({ project: null, isOpen: false })}
loading={isPending}
paramData={project.id}
isOpen={deleteProject.isOpen}
/>
<div className="col-md-6 col-lg-4 col-xl-4 order-0 mb-4"> <div className="col-md-6 col-lg-4 col-xl-4 order-0 mb-4">
<div className={`card cursor-pointer`}> <div className={`card cursor-pointer`}>
<div className="card-header pb-4"> <div className="card-header pb-4">
@ -130,6 +153,18 @@ const ProjectCard = ({ project, isCore = true }) => {
</a> </a>
</li> </li>
)} )}
{!isCore && (
<li
onClick={() =>
setDeleteProject({ project: project, isOpen: true })
}
>
<a className="dropdown-item">
<i className="bx bx-trash me-2"></i>
<span className="align-left">Delete</span>
</a>
</li>
)}
</ul> </ul>
</div> </div>
</div> </div>
@ -150,7 +185,7 @@ const ProjectCard = ({ project, isCore = true }) => {
</p> </p>
<p className="mb-1"> <p className="mb-1">
<span className="text-heading fw-medium"> <span className="text-heading fw-medium">
{isCore ? "Start Date:" : "Assigned Date"}{" "} {isCore ? "Start Date:" : "Start Date"}{" "}
</span> </span>
{formatUTCToLocalTime( {formatUTCToLocalTime(
isCore ? project?.startDate : project.assignedDate isCore ? project?.startDate : project.assignedDate

View File

@ -113,33 +113,7 @@ const ManageServiceProject = ({ serviceProjectId, onClose }) => {
<h5>{serviceProjectId ? "Update Project":"Create Project"}</h5> <h5>{serviceProjectId ? "Update Project":"Create Project"}</h5>
</div> </div>
<div className="row text-start"> <div className="row text-start">
<div className="col-12 mb-2"> <div className="col-12 mb-2">
<Label htmlFor="name" required>
Project Name
</Label>
<input
type="text"
className="form-control form-control-sm"
{...register("name")}
/>
{errors?.name && (
<span className="danger-text">{errors.name.message}</span>
)}
</div>
<div className="col-12 mb-2">
<Label htmlFor="name" required>
Short Name (Short Project Name)
</Label>
<input
type="text"
className="form-control form-control-sm"
{...register("shortName")}
/>
{errors?.shortName && (
<span className="danger-text">{errors.shortName.message}</span>
)}
</div>
<div className="col-12 mb-2">
<Label htmlFor="name" required> <Label htmlFor="name" required>
Client Client
</Label> </Label>
@ -169,19 +143,32 @@ const ManageServiceProject = ({ serviceProjectId, onClose }) => {
)} )}
</div> </div>
<div className="col-12 mb-2"> <div className="col-12 mb-2">
<SelectMultiple <Label htmlFor="name" required>
options={data?.data} Project Name
isLoading={isLoading} </Label>
name="services" <input
labelKey="name" type="text"
valueKey="id" className="form-control form-control-sm"
label="Select Service" {...register("name")}
/> />
{errors?.services && ( {errors?.name && (
<span className="danger-text">{errors.services.message}</span> <span className="danger-text">{errors.name.message}</span>
)} )}
</div> </div>
<div className="col-12 mb-2"> <div className="col-12 col-md-6 mb-2">
<Label htmlFor="name" required>
Short Name (Short Project Name)
</Label>
<input
type="text"
className="form-control form-control-sm"
{...register("shortName")}
/>
{errors?.shortName && (
<span className="danger-text">{errors.shortName.message}</span>
)}
</div>
<div className="col-12 col-md-6 mb-2">
<Label htmlFor="name" required> <Label htmlFor="name" required>
Select Status Select Status
</Label> </Label>
@ -198,6 +185,20 @@ const ManageServiceProject = ({ serviceProjectId, onClose }) => {
<span className="danger-text">{errors.statusId.message}</span> <span className="danger-text">{errors.statusId.message}</span>
)} )}
</div> </div>
<div className="col-12 mb-2">
<SelectMultiple
options={data?.data}
isLoading={isLoading}
name="services"
labelKey="name"
valueKey="id"
label="Select Service"
/>
{errors?.services && (
<span className="danger-text">{errors.services.message}</span>
)}
</div>
<div className="col-12 col-md-6 mb-2"> <div className="col-12 col-md-6 mb-2">
<Label htmlFor="name" required> <Label htmlFor="name" required>
Contact Name Contact Name

View File

@ -99,7 +99,7 @@
.multi-select-dropdown-option.selected { .multi-select-dropdown-option.selected {
background-color: #dbe7ff; background-color: #dbe7ff;
color: #0d6efd; color: #696cff;
} }
.multi-select-dropdown-option input[type="checkbox"] { .multi-select-dropdown-option input[type="checkbox"] {

View File

@ -8,24 +8,29 @@ const SelectMultiple = ({
name, name,
options = [], options = [],
label = "Select options", label = "Select options",
labelKey = "name", labelKey = "name",
valueKey = "id", valueKey = "id",
placeholder = "Please select...", placeholder = "Please select...",
IsLoading = false,required = false IsLoading = false,
required = false,
}) => { }) => {
const { setValue, watch,register } = useFormContext(); const { setValue, watch, register } = useFormContext();
useEffect(() => { useEffect(() => {
register(name, { value: [] }); register(name, { value: [] });
}, [register, name]); }, [register, name]);
const selectedValues = watch(name) || []; const selectedValues = watch(name) || [];
const [isOpen, setIsOpen] = useState(false); const [isOpen, setIsOpen] = useState(false);
const [searchText, setSearchText] = useState(""); const [searchText, setSearchText] = useState("");
const containerRef = useRef(null); const containerRef = useRef(null);
const dropdownRef = useRef(null); const dropdownRef = useRef(null);
const [dropdownStyles, setDropdownStyles] = useState({ top: 0, left: 0, width: 0 }); const [dropdownStyles, setDropdownStyles] = useState({
top: 0,
left: 0,
width: 0,
});
useEffect(() => { useEffect(() => {
const handleClickOutside = (e) => { const handleClickOutside = (e) => {
@ -65,13 +70,12 @@ const selectedValues = watch(name) || [];
}; };
const filteredOptions = (options || []).filter((item) => { const filteredOptions = (options || []).filter((item) => {
const label = getLabel(item); const label = getLabel(item);
return ( return (
typeof label === "string" && typeof label === "string" &&
label.toLowerCase().includes(searchText.toLowerCase()) label.toLowerCase().includes(searchText.toLowerCase())
); );
}); });
const dropdownElement = ( const dropdownElement = (
<div <div
@ -109,8 +113,14 @@ const selectedValues = watch(name) || [];
return ( return (
<div <div
key={valueVal} key={valueVal}
className={`multi-select-dropdown-option ${isChecked ? "selected" : ""}`} className={`multi-select-dropdown-option ${
style={{ display: "flex", alignItems: "center", padding: "4px 8px" }} isChecked ? "selected" : ""
}`}
style={{
display: "flex",
alignItems: "center",
padding: "4px 8px",
}}
> >
<input <input
type="checkbox" type="checkbox"
@ -139,7 +149,11 @@ const selectedValues = watch(name) || [];
return ( return (
<> <>
<div ref={containerRef} className="multi-select-dropdown-container" style={{ position: "relative" }}> <div
ref={containerRef}
className="multi-select-dropdown-container"
style={{ position: "relative" }}
>
<label className="form-label mb-1">{label}</label> <label className="form-label mb-1">{label}</label>
<Label className={name} required={required}></Label> <Label className={name} required={required}></Label>
@ -150,7 +164,9 @@ const selectedValues = watch(name) || [];
> >
<span <span
className={ className={
selectedValues.length > 0 ? "placeholder-style-selected" : "placeholder-style" selectedValues.length > 0
? "placeholder-style-selected"
: "placeholder-style"
} }
> >
<div className="selected-badges-container"> <div className="selected-badges-container">
@ -159,7 +175,10 @@ const selectedValues = watch(name) || [];
const found = options.find((opt) => opt[valueKey] === val); const found = options.find((opt) => opt[valueKey] === val);
const label = found ? getLabel(found) : ""; const label = found ? getLabel(found) : "";
return ( return (
<span key={val} className="badge badge-selected-item mx-1 mb-1"> <span
key={val}
className="badge bg-label-primary mx-1 py-2 mb-1"
>
{label} {label}
</span> </span>
); );

View File

@ -72,7 +72,9 @@ export const useUpdateServiceProject = (onSuccessCallback) => {
}); });
}; };
export const useActiveInActiveServiceProject = () => { export const useActiveInActiveServiceProject = (onSuccessCallback) => {
const queryClient = useQueryClient();
return useMutation({ return useMutation({
mutationFn: async (id, status) => { mutationFn: async (id, status) => {
return await ServiceProjectRepository.DeleteServiceProject(id, status); return await ServiceProjectRepository.DeleteServiceProject(id, status);
@ -81,7 +83,7 @@ export const useActiveInActiveServiceProject = () => {
queryClient.invalidateQueries({ queryKey: ["serviceProjects"] }); queryClient.invalidateQueries({ queryKey: ["serviceProjects"] });
if (onSuccessCallback) onSuccessCallback(); if (onSuccessCallback) onSuccessCallback();
showToast( showToast(
`Project ${updated ? "restored" : "deleted"} successfully`, `Project ${status ? "restored" : "deleted"} successfully`,
"success" "success"
); );
}, },

View File

@ -1,6 +1,9 @@
import React, { useState } from "react"; import React, { useState } from "react";
import { useProjectContext } from "../project/ProjectPage"; import { useProjectContext } from "../project/ProjectPage";
import { useActiveInActiveServiceProject, useServiceProjects } from "../../hooks/useServiceProject"; import {
useActiveInActiveServiceProject,
useServiceProjects,
} from "../../hooks/useServiceProject";
import { ITEMS_PER_PAGE } from "../../utils/constants"; import { ITEMS_PER_PAGE } from "../../utils/constants";
import ProjectCard from "../../components/Project/ProjectCard"; import ProjectCard from "../../components/Project/ProjectCard";
import Pagination from "../../components/common/Pagination"; import Pagination from "../../components/common/Pagination";
@ -21,10 +24,7 @@ const ServiceProjectDisplay = ({ listView }) => {
setCurrentPage(page); setCurrentPage(page);
} }
}; };
const {mutate:DeleteProject,isPending} = useActiveInActiveServiceProject()
const handleActiveInactive =(projectId)=>{
}
if (isLoading) if (isLoading)
return ( return (
@ -44,18 +44,6 @@ const ServiceProjectDisplay = ({ listView }) => {
); );
return ( return (
<div className="row"> <div className="row">
{/* <ConfirmModal
type="delete"
header="Delete Project"
message="Are you sure you want delete?"
onSubmit={handleActiveInactive}
onClose={() => setDeleteContact({ contactId: null, Open: false })}
loading={isPending}
paramData={deleteContact.contactId}
isOpen={deleteContact.Open}
/> */}
{listView ? ( {listView ? (
<p>List</p> <p>List</p>
) : ( ) : (
@ -64,8 +52,6 @@ const ServiceProjectDisplay = ({ listView }) => {
)) ))
)} )}
<div className="col-12 d-flex justify-content-start mt-3"> <div className="col-12 d-flex justify-content-start mt-3">
<Pagination <Pagination
currentPage={currentPage} currentPage={currentPage}
@ -84,7 +70,9 @@ const ServiceProjectDisplay = ({ listView }) => {
> >
<ManageServiceProject <ManageServiceProject
serviceProjectId={manageServiceProject?.project} serviceProjectId={manageServiceProject?.project}
onClose={()=>setManageServiceProject({ isOpen: false, project: null })} onClose={() =>
setManageServiceProject({ isOpen: false, project: null })
}
/> />
</GlobalModel> </GlobalModel>
)} )}