Merge branch 'Service_Project_Managment' of https://git.marcoaiot.com/admin/marco.pms.web into Service_Management_CardView

This commit is contained in:
Kartik Sharma 2025-11-18 12:15:25 +05:30
commit 31d340c645
4 changed files with 92 additions and 69 deletions

View File

@ -456,8 +456,3 @@ font-weight: normal;
.fs-md-xlarge { font-size: 170% !important; } .fs-md-xlarge { font-size: 170% !important; }
.fs-md-xxlarge { font-size: calc(1.725rem + 5.7vw) !important; } .fs-md-xxlarge { font-size: calc(1.725rem + 5.7vw) !important; }
} }
.me-16 {
/* margin-inline-end: -7.0625rem !important; */
margin-left: -7.0625rem !important;
}

View File

@ -6,11 +6,9 @@ import { ITEMS_PER_PAGE } from "../../utils/constants";
const ProjectCompletionChart = () => { const ProjectCompletionChart = () => {
const [currentPage, setCurrentPage] = useState(1); const [currentPage, setCurrentPage] = useState(1);
const { data: projects, isLoading: loading, isError, error } = useProjects(currentPage, ITEMS_PER_PAGE); const { data: projects, isLoading: loading, isError, error } = useProjects(ITEMS_PER_PAGE,currentPage);
console.log("Kartik", projects)
// Bar chart logic // Bar chart logic
const projectNames = projects?.map((p) => p.name) || []; const projectNames = projects?.data.map((p) => p.name) || [];
const projectProgress = const projectProgress =
projects?.map((p) => { projects?.map((p) => {
const completed = p.completedWork || 0; const completed = p.completedWork || 0;

View File

@ -45,20 +45,32 @@ const ManageJobTicket = ({ Job }) => {
return ( return (
<div className="row text-start"> <div className="row text-start">
<div className="col-12"> <div className="col-12">
<div className="d-flex justify-content-between align-items-center flex-wrap mb-2"> <h6 className="fs-5 fw-semibold">{data?.title}</h6>
{/* Job Id on left */} <div className="d-flex justify-content-between align-items-end flex-wrap mb-2">
<p className="mb-0"> <p className="mb-0">
<span className="fw-medium me-1">Job Id :</span> <span className="fw-medium me-1">Job Id :</span>
{data?.jobTicketUId || "N/A"} {data?.jobTicketUId || "N/A"}
</p> </p>
<div className="d-flex flex-column align-items-end gap-3 mb-3">
{/* Edit icon on right */} {data?.dueDate &&
(() => {
</div> const { days, color } = daysLeft(
data?.startDate,
<div className="d-flex justify-content-between align-items-center mb-3"> data?.dueDate
);
return (
<span>
<span className="fw-medium me-1">Days Left:</span>
<span className={`badge bg-${color}`}>
{days !== null ? `${days} days` : "N/A"}
</span>
</span>
);
})()}
<div className="d-flex flex-row gap-2"> <div className="d-flex flex-row gap-2">
<span className="badge bg-label-primary">{data?.status?.name}</span> <span className="badge bg-label-primary">
{data?.status?.name}
</span>
<HoverPopup <HoverPopup
id="STATUS_CHANEG" id="STATUS_CHANEG"
title="Change Status" title="Change Status"
@ -76,26 +88,13 @@ const ManageJobTicket = ({ Job }) => {
<i className="bx bx-edit bx-sm cursor-pointer"></i> <i className="bx bx-edit bx-sm cursor-pointer"></i>
</HoverPopup> </HoverPopup>
</div> </div>
{data?.dueDate &&
(() => {
const { days, color } = daysLeft(data?.startDate, data?.dueDate);
return (
<span style={{ fontSize: "12px" }}>
<span className="fw-medium me-1">Days Left :</span>
<span className={`badge bg-${color}`}>
{days !== null ? `${days} days` : "N/A"}
</span>
</span>
);
})()}
</div> </div>
<h6 className="fs-5 fw-semibold">{data?.title}</h6> </div>
<div className="d-flex flex-wrap"> <div className="d-flex flex-wrap">
<p> <p>{data?.description || "N/A"}</p>
<span className="fw-medium me-1">Description :</span>
{data?.description || "N/A"}
</p>
</div> </div>
<div className="d-flex justify-content-between mb-4"> <div className="d-flex justify-content-between mb-4">
@ -135,23 +134,28 @@ const ManageJobTicket = ({ Job }) => {
</small> </small>
</div> </div>
</div> </div>
<div className="d-flex align-items-center"> <div className="d-flex flex-wrap align-items-start align-items-md-center">
<small className="fs-6 fw-medium me-3">Assigned By</small> <small className="fs-6 fw-medium me-3">Assigned By</small>
<div className="d-flex flex-row gap-3"> <div className="row g-3 mt-md-1">
{data?.assignees?.map((emp) => ( {data?.assignees?.map((emp) => (
<div className="d-flex flex-row "> <div key={emp.id} className="col-6 col-sm-6 col-md-4 col-lg-4">
<div className="d-flex align-items-center gap-2">
<Avatar <Avatar
size="xs" size="xs"
firstName={emp.firstName} firstName={emp.firstName}
lastName={emp.lastName} lastName={emp.lastName}
/> />
<div className="d-flex flex-row align-items-center">
<p className="m-0">{`${emp.firstName} ${emp.lastName}`}</p> <div className="d-flex flex-column">
<small className="text-secondary ms-1"> <span className="fw-semibold">
({emp.jobRoleName}) {emp.firstName} {emp.lastName}
</span>
<small className="text-secondary">
{emp.jobRoleName}
</small> </small>
</div> </div>
</div> </div>
</div>
))} ))}
</div> </div>
</div> </div>

View File

@ -11,7 +11,7 @@ const HoverPopup = ({
title, title,
content, content,
children, children,
className, className = "",
Mode = "hover", Mode = "hover",
}) => { }) => {
const dispatch = useDispatch(); const dispatch = useDispatch();
@ -46,11 +46,33 @@ const HoverPopup = ({
dispatch(closePopup(id)); dispatch(closePopup(id));
} }
}; };
document.addEventListener("click", handleOutside); document.addEventListener("click", handleOutside);
return () => document.removeEventListener("click", handleOutside); return () => document.removeEventListener("click", handleOutside);
}, [visible, Mode, id]); }, [visible, Mode, id]);
useEffect(() => {
if (!visible || !popupRef.current) return;
const popup = popupRef.current;
const rect = popup.getBoundingClientRect();
popup.style.left = "50%";
popup.style.right = "auto";
popup.style.transform = "translateX(-50%)";
if (rect.right > window.innerWidth) {
popup.style.left = "auto";
popup.style.right = "0";
popup.style.transform = "none";
}
if (rect.left < 0) {
popup.style.left = "0";
popup.style.right = "auto";
popup.style.transform = "none";
}
}, [visible]);
return ( return (
<div className="d-inline-block position-relative"> <div className="d-inline-block position-relative">
<div <div
@ -66,8 +88,12 @@ const HoverPopup = ({
{visible && ( {visible && (
<div <div
ref={popupRef} ref={popupRef}
className={`bg-white border w-max rounded shadow-sm p-3 position-absolute top-100 mt-2 start-50 translate-middle-x ${className}`} className={`bg-white border rounded shadow-sm p-3 w-max position-absolute top-100 mt-2 ${className}`}
style={{ zIndex: 1000 }} style={{
zIndex: 2000,
left: "50%",
transform: "translateX(-50%)",
}}
onClick={(e) => e.stopPropagation()} onClick={(e) => e.stopPropagation()}
> >
{title && <h6 className="fw-semibold mb-2">{title}</h6>} {title && <h6 className="fw-semibold mb-2">{title}</h6>}