added mutiple contact person inside branch

This commit is contained in:
pramod.mahajan 2025-11-20 12:49:56 +05:30
parent d167c57ab0
commit 047e563505
9 changed files with 238 additions and 272 deletions

View File

@ -2,15 +2,19 @@ import React, { useState } from "react";
import HorizontalBarChart from "../Charts/HorizontalBarChart"; import HorizontalBarChart from "../Charts/HorizontalBarChart";
import { useProjects } from "../../hooks/useProjects"; import { useProjects } from "../../hooks/useProjects";
import { ITEMS_PER_PAGE } from "../../utils/constants"; import { ITEMS_PER_PAGE } from "../../utils/constants";
import { useProjectCompletionStatus } from "../../hooks/useDashboard_Data";
const ProjectCompletionChart = () => { const ProjectCompletionChart = () => {
const [currentPage, setCurrentPage] = useState(1); const [currentPage, setCurrentPage] = useState(1);
const { data: projects, isLoading: loading, isError, error } = useProjects(50,currentPage); const {
// Bar chart logic data: projects,
const projectNames = projects?.data?.map((p) => p.name) || []; isLoading: loading,
isError,
error,
} = useProjectCompletionStatus();
const projectNames = projects?.map((p) => p.name) || [];
const projectProgress = const projectProgress =
projects?.data?.map((p) => { projects?.map((p) => {
const completed = p.completedWork || 0; const completed = p.completedWork || 0;
const planned = p.plannedWork || 1; const planned = p.plannedWork || 1;
const percent = planned ? (completed / planned) * 100 : 0; const percent = planned ? (completed / planned) * 100 : 0;

View File

@ -27,59 +27,34 @@ const BranchDetails = ({ branch }) => {
</div> </div>
); );
return ( return (
<div className=""> <>
<div className="d-flex mb-2"> <div className="d-flex mb-2">
<span className="fs-6 fw-medium"> <span className="fs-6 fw-medium">
<i className="bx bx-sm me-2 bx-buildings"></i>Branch Details <i className="bx bx-sm me-2 bx-buildings"></i>Branch Details
</span> </span>
</div> </div>
<div className="row mb-1"> <div className="row mb-1">
<div className="col-4 col-md-4 text-secondary">Name:</div> <div className="col-4 text-secondary">Contact No:</div>
<div className="col-8 col-md-8">{data?.branchName}</div> <div className="col-8">{data?.contactInformation}</div>
</div> </div>
<div className="row mb-1"> <div className="row mb-1">
<div className="col-4 col-md-4 text-secondary">Type:</div> <div className="col-4 text-secondary">Type:</div>
<div className="col-8 col-md-8">{data?.branchType}</div> <div className="col-8">{data?.branchType}</div>
</div>
<div className="row mb-1">
<div className="col-4 col-md-4 text-secondary">Contact No:</div>
<div className="col-8 col-md-8">{data?.contactInformation}</div>
</div> </div>
<div className="row mb-1"> <div className="row mb-1">
<div className="col-4 col-md-4 text-secondary">Address:</div> <div className="col-4 text-secondary">Email:</div>
<div className="col-8 col-md-8">{data?.address}</div> <div className="col-8">{data?.email}</div>
</div> </div>
{googleMapUrl && (
<div className="row mb-1"> <div className="row mb-1">
<div className="col-4 col-md-4 text-secondary">Map:</div> <div className="col-4 text-secondary">Address:</div>
<div className="col-8">{data?.address}</div>
<div className="col-8 col-md-8 d-flex align-items-center gap-2">
<a
href={googleMapUrl}
target="_blank"
rel="noopener noreferrer"
className="text-primary text-decoration-underline text-break"
style={{ wordBreak: "break-all" }}
>
Open in Google Maps
</a>
<i
className={`bx ${
copied ? "bx-check-double text-secondry " : "bx-copy"
}`}
style={{ cursor: "pointer" }}
onClick={handleCopy}
></i>
{copied && <span className="text-secondry small">Copied!</span>}
</div>
</div>
)}
</div> </div>
</>
); );
}; };

View File

@ -26,7 +26,6 @@ const ServiceBranch = () => {
const { data, isLoading, isError, error } = useBranches( const { data, isLoading, isError, error } = useBranches(
projectId, projectId,
// true,
!showInactive, !showInactive,
ITEMS_PER_PAGE - 10, ITEMS_PER_PAGE - 10,
currentPage, currentPage,
@ -78,18 +77,17 @@ const ServiceBranch = () => {
<div className="card-datatable" id="payment-request-table"> <div className="card-datatable" id="payment-request-table">
{/* Header Section */} {/* Header Section */}
<div className="row align-items-center justify-content-between mt-3 mx-1"> <div className="row align-items-center justify-content-between mt-3 mx-1">
<div className="col-md-6 col-sm-12 ms-n3 text-start "> <div className="col-md-4 col-sm-12 ms-n3 text-start ">
<h5 className="mb-0"> <h5 className="mb-0">
<i className="bx bx-buildings text-primary"></i> <i className="bx bx-buildings text-primary"></i>
<span className="ms-2 fw-bold">Branch</span> <span className="ms-2 fw-bold">Branchs</span>
</h5> </h5>
</div> </div>
{/* Flex container for toggle + button */} {/* Flex container for toggle + button */}
<div className="col-md-6 col-sm-12 text-end"> <div className="col-md-8 col-sm-12 text-end">
<div className="d-flex flex-column flex-md-row align-items-md-center justify-content-md-end gap-2"> <div className="d-flex flex-column flex-md-row align-items-md-center gap-2">
{/* Toggle Switch */}
<div className="form-check form-switch d-inline-flex align-items-center"> <div className="form-check form-switch d-inline-flex align-items-center">
<input <input
type="checkbox" type="checkbox"
@ -98,12 +96,14 @@ const ServiceBranch = () => {
checked={showInactive} checked={showInactive}
onChange={() => setShowInactive(!showInactive)} onChange={() => setShowInactive(!showInactive)}
/> />
<label htmlFor="inactiveEmployeesCheckbox" className="ms-2 mt-1"> <label
htmlFor="inactiveEmployeesCheckbox"
className="ms-2 mt-1"
>
Show Deleted Branches Show Deleted Branches
</label> </label>
</div> </div>
<div className="d-flex justify-content-end">
{/* Add Branch Button */}
<button <button
className="btn btn-sm btn-primary" className="btn btn-sm btn-primary"
type="button" type="button"
@ -115,11 +115,12 @@ const ServiceBranch = () => {
} }
> >
<i className="bx bx-sm bx-plus-circle me-2"></i> <i className="bx bx-sm bx-plus-circle me-2"></i>
<span className="d-none d-md-inline-block">Add Branch</span> Add Branch
</button> </button>
</div> </div>
</div> </div>
</div> </div>
</div>
<div className="mx-2 mt-3"> <div className="mx-2 mt-3">
<table className="table border-top text-nowrap align-middle table-borderless"> <table className="table border-top text-nowrap align-middle table-borderless">
@ -152,7 +153,6 @@ const ServiceBranch = () => {
</tr> </tr>
)} )}
{isError && ( {isError && (
<tr> <tr>
<td <td
@ -215,7 +215,6 @@ const ServiceBranch = () => {
</ul> </ul>
</div> </div>
</td> </td>
</tr> </tr>
))} ))}
@ -247,7 +246,9 @@ const ServiceBranch = () => {
<GlobalModel <GlobalModel
isOpen isOpen
size="md" size="md"
closeModal={() => setManageState({ IsOpen: false, branchId: null })} closeModal={() =>
setManageState({ IsOpen: false, branchId: null })
}
> >
<ManageBranch <ManageBranch
key={manageState.branchId ?? "new"} key={manageState.branchId ?? "new"}
@ -256,7 +257,6 @@ const ServiceBranch = () => {
setManageState({ IsOpen: false, branchId: null }) setManageState({ IsOpen: false, branchId: null })
} }
/> />
</GlobalModel> </GlobalModel>
)} )}
</div> </div>

View File

@ -150,7 +150,7 @@ const JobComments = ({ data }) => {
type="submit" type="submit"
disabled={!watch("comment")?.trim() || isPending} disabled={!watch("comment")?.trim() || isPending}
> >
Submit Send
</button> </button>
</div> </div>
</form> </form>

View File

@ -47,7 +47,11 @@ const ManageJobTicket = ({ Job }) => {
</div> </div>
); );
return ( return (
<div className="row text-start" ref={drawerRef}> <div
className=" text-start position-relative"
ref={drawerRef}
style={{ overflow: "visible" }}
>
<div className="col-12"> <div className="col-12">
<h6 className="fs-5 fw-semibold">{data?.title}</h6> <h6 className="fs-5 fw-semibold">{data?.title}</h6>
<div className="d-flex justify-content-between align-items-start flex-wrap mb-2"> <div className="d-flex justify-content-between align-items-start flex-wrap mb-2">
@ -56,7 +60,7 @@ const ManageJobTicket = ({ Job }) => {
{data?.jobTicketUId || "N/A"} {data?.jobTicketUId || "N/A"}
</p> </p>
<div className="d-flex flex-column align-items-end gap-3 mb-3"> <div className="d-flex flex-column align-items-end gap-3 mb-3">
<div className="d-flex flex-row gap-2"> <div className="d-flex flex-row gap-2 position-relative">
<span className={`badge ${getJobStatusBadge(data?.status?.id)}`}> <span className={`badge ${getJobStatusBadge(data?.status?.id)}`}>
{data?.status?.displayName} {data?.status?.displayName}
</span> </span>
@ -65,6 +69,7 @@ const ManageJobTicket = ({ Job }) => {
id="STATUS_CHANEG" id="STATUS_CHANEG"
Mode="click" Mode="click"
className="" className=""
align="right"
content={ content={
<ChangeStatus <ChangeStatus
statusId={data?.status?.id} statusId={data?.status?.id}
@ -91,23 +96,33 @@ const ManageJobTicket = ({ Job }) => {
<p>{data?.description || "N/A"}</p> <p>{data?.description || "N/A"}</p>
</div> </div>
<div className="d-flex justify-content-between mb-4"> <div className="d-flex justify-content-between align-items-center mb-4">
<div className="d-flex flex-row gap-1 fw-medium"> <div className="d-flex flex-row gap-1 text-secondry">
<i className="bx bx-calendar"></i>{" "} <i className="bx bx-calendar"></i>{" "}
<span> <span>
Created Date : {formatUTCToLocalTime(data?.createdAt, true)} Created Date : {formatUTCToLocalTime(data?.createdAt, true)}
</span> </span>
</div> </div>
<div className="d-flex flex-row gap-2 text-wraps">
{data?.tags?.map((tag, ind) => (
<span
key={`${ind}0-${tag?.name}`}
className="badge bg-label-primary"
>
{tag?.name}
</span>
))}
</div>
</div> </div>
<div className="d-flex justify-content-md-between "> <div className="d-flex justify-content-md-between ">
<div className="d-flex flex-row gap-5"> <div className="d-flex flex-row gap-5">
<span className="fw-medium"> <span className="text-secondry">
<i className="bx bx-calendar"></i> Start Date :{" "} <i className="bx bx-calendar"></i> Start Date :{" "}
{formatUTCToLocalTime(data?.startDate)} {formatUTCToLocalTime(data?.startDate)}
</span>{" "} </span>{" "}
<i className="bx bx-right-arrow-alt"></i>{" "} <i className="bx bx-right-arrow-alt"></i>{" "}
<span className="fw-medium"> <span className="text-secondry">
<i className="bx bx-calendar"></i> Due on :{" "} <i className="bx bx-calendar"></i> Due on :{" "}
{formatUTCToLocalTime(data?.startDate)} {formatUTCToLocalTime(data?.startDate)}
</span> </span>
@ -117,7 +132,7 @@ const ManageJobTicket = ({ Job }) => {
const { days, color } = daysLeft(data?.startDate, data?.dueDate); const { days, color } = daysLeft(data?.startDate, data?.dueDate);
return ( return (
<span> <span>
<span className="fw-medium me-1">Days Left:</span> <span className="text-secondry me-1">Days Left:</span>
<span className={`badge bg-${color}`}> <span className={`badge bg-${color}`}>
{days !== null ? `${days} days` : "N/A"} {days !== null ? `${days} days` : "N/A"}
</span> </span>
@ -125,28 +140,79 @@ const ManageJobTicket = ({ Job }) => {
); );
})()} })()}
</div> </div>
{data?.projectBranch && ( {/* {data?.projectBranch && (
<div className="d-flex flex-row gap-3 my-2"> <div className="d-flex gap-3 my-2 position-relative" ref={drawerRef} style={{ overflow: "visible" }}>
<span className="fw-semibold"> <span className="text-secondary">
<i className="bx bx-buildings me-1"></i> Branch Name : <i className="bx bx-buildings"></i> Branch Name:
</span> </span>
<HoverPopup <HoverPopup
id="BRANCH_DETAILS" id="BRANCH_DETAILS"
Mode="click" Mode="click"
align="auto" align="auto"
boundaryRef={drawerRef} boundaryRef={drawerRef} // drawer has position-relative
content={<BranchDetails branch={data?.projectBranch?.id} />} content={<BranchDetails branch={data?.projectBranch?.id} />}
> >
<span className="text text-decoration-underline "> <span className="text-decoration-underline cursor-pointer">
{data?.projectBranch?.branchName} {data?.projectBranch?.branchName}
</span> </span>
</HoverPopup> </HoverPopup>
</div> </div>
)} )} */}
<div className="card shadow-none border "> <div className="border-top">
<span className="text-secondry">People</span> <p className="m-0 py-1">
<i className="bx bx-group"></i> Peoples
</p>
{/* Created By */}
<div className="d-flex justify-content-between align-items-start w-100">
<p className="text-secondary m-0 me-3">Created By</p>
<div className="flex-grow-1 d-flex align-items-center gap-2">
<Avatar
size="xs"
firstName={data?.createdBy?.firstName}
lastName={data?.createdBy?.lastName}
/>
<div className="d-flex flex-column">
<p className="m-0 text-truncate">
{data?.createdBy?.firstName} {data?.createdBy?.lastName}
</p>
<small className="text-secondary text-xs">
{data?.createdBy?.jobRoleName}
</small>
</div>
</div>
</div>
{/* Assigned To */}
<div className="d-flex flex-column flex-md-row align-items-start w-100 mt-2">
<p className="text-secondary m-0 me-3">Assigned To</p>
<div className="flex-grow-1">
<div className="d-flex flex-wrap gap-3">
{data?.assignees?.map((emp) => (
<div key={emp.id} className="d-flex align-items-center">
<Avatar
size="xs"
firstName={emp.firstName}
lastName={emp.lastName}
/>
<div className="d-flex flex-column ms-2 text-truncate">
<span className="text-truncate">
{emp.firstName} {emp.lastName}
</span>
<small className="text-secondary text-xs text-truncate">
{emp.jobRoleName}
</small>
</div>
</div>
))}
</div>
</div>
</div>
</div> </div>
</div> </div>

View File

@ -1,6 +1,10 @@
import React, { useEffect, useRef } from "react"; import React, { useEffect, useRef } from "react";
import { useDispatch, useSelector } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
import { closePopup, openPopup, togglePopup } from "../../slices/localVariablesSlice"; import {
closePopup,
openPopup,
togglePopup,
} from "../../slices/localVariablesSlice";
/** /**
* align: "auto" | "left" | "right" * align: "auto" | "left" | "right"
@ -63,7 +67,8 @@ const HoverPopup = ({
const popup = popupRef.current; const popup = popupRef.current;
// choose boundary: provided boundaryRef or nearest positioned parent (popup.parentElement) // choose boundary: provided boundaryRef or nearest positioned parent (popup.parentElement)
const boundaryEl = (boundaryRef && boundaryRef.current) || popup.parentElement; const boundaryEl =
(boundaryRef && boundaryRef.current) || popup.parentElement;
if (!boundaryEl) return; if (!boundaryEl) return;
const boundaryRect = boundaryEl.getBoundingClientRect(); const boundaryRect = boundaryEl.getBoundingClientRect();
@ -75,15 +80,12 @@ const HoverPopup = ({
popup.style.transform = ""; popup.style.transform = "";
popup.style.top = ""; popup.style.top = "";
// default: place below trigger and center horizontally relative to parent
// We'll use absolute positioning with respect to the positioned parent container.
// Ensure popup is positioned using left/right in parent's coordinate system.
// Compute desired left (centered under trigger)
const popupRect = popup.getBoundingClientRect(); const popupRect = popup.getBoundingClientRect();
const parentRect = boundaryRect; // alias const parentRect = boundaryRect; // alias
// Convert trigger center to parent coordinates // Convert trigger center to parent coordinates
const triggerCenterX = triggerRect.left + triggerRect.width / 2 - parentRect.left; const triggerCenterX =
triggerRect.left + triggerRect.width / 2 - parentRect.left;
// preferred left so popup center aligns to trigger center: // preferred left so popup center aligns to trigger center:
const preferredLeft = triggerCenterX - popupRect.width / 2; const preferredLeft = triggerCenterX - popupRect.width / 2;
@ -111,10 +113,19 @@ const HoverPopup = ({
setRight(0); setRight(0);
return; return;
} }
if (align === "center") {
popup.style.left = "50%";
popup.style.right = "auto";
popup.style.transform = "translateX(-50%)";
return;
}
// align === "auto": try preferred centered position, but flip fully if overflow // align === "auto": try preferred centered position, but flip fully if overflow
// clamp preferredLeft to boundaries so it doesn't render partially outside // clamp preferredLeft to boundaries so it doesn't render partially outside
const leftIfCentered = Math.max(0, Math.min(preferredLeft, parentRect.width - popupRect.width)); const leftIfCentered = Math.max(
0,
Math.min(preferredLeft, parentRect.width - popupRect.width)
);
// if centered fits, use it // if centered fits, use it
if (leftIfCentered === preferredLeft) { if (leftIfCentered === preferredLeft) {
@ -142,8 +153,17 @@ const HoverPopup = ({
}, [visible, align, boundaryRef]); }, [visible, align, boundaryRef]);
return ( return (
<div className="d-inline-block position-relative">
<div <div
className="d-inline-block "
style={{
maxWidth: "calc(700px - 100px)",
width: "100%",
wordWrap: "break-word",
overflow: "hidden",
}}
>
<div
className="d-inline-block"
ref={triggerRef} ref={triggerRef}
onMouseEnter={handleMouseEnter} onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave} onMouseLeave={handleMouseLeave}

View File

@ -2,7 +2,6 @@ import { useState, useEffect } from "react";
import GlobalRepository from "../repositories/GlobalRepository"; import GlobalRepository from "../repositories/GlobalRepository";
import { useQuery } from "@tanstack/react-query"; import { useQuery } from "@tanstack/react-query";
export const useDashboard_Data = ({ days, FromDate, projectId }) => { export const useDashboard_Data = ({ days, FromDate, projectId }) => {
const [dashboard_data, setDashboard_Data] = useState([]); const [dashboard_data, setDashboard_Data] = useState([]);
const [isLineChartLoading, setLoading] = useState(false); const [isLineChartLoading, setLoading] = useState(false);
@ -18,11 +17,13 @@ export const useDashboard_Data = ({ days, FromDate, projectId }) => {
try { try {
const payload = { const payload = {
days, days,
FromDate: FromDate || '', FromDate: FromDate || "",
projectId: projectId || null, projectId: projectId || null,
}; };
const response = await GlobalRepository.getDashboardProgressionData(payload); const response = await GlobalRepository.getDashboardProgressionData(
payload
);
setDashboard_Data(response.data); setDashboard_Data(response.data);
} catch (err) { } catch (err) {
setError("Failed to fetch dashboard data."); setError("Failed to fetch dashboard data.");
@ -38,123 +39,6 @@ export const useDashboard_Data = ({ days, FromDate, projectId }) => {
return { dashboard_data, loading: isLineChartLoading, error }; return { dashboard_data, loading: isLineChartLoading, error };
}; };
// export const useDashboard_AttendanceData = (date, projectId) => {
// const [dashboard_Attendancedata, setDashboard_AttendanceData] = useState([]);
// const [isLineChartLoading, setLoading] = useState(false);
// const [error, setError] = useState("");
// useEffect(() => {
// const fetchData = async () => {
// setLoading(true);
// setError("");
// try {
// const response = await GlobalRepository.getDashboardAttendanceData(date, projectId); // date in 2nd param
// setDashboard_AttendanceData(response.data);
// } catch (err) {
// setError("Failed to fetch dashboard data.");
// console.error(err);
// } finally {
// setLoading(false);
// }
// };
// if (date && projectId !== null) {
// fetchData();
// }
// }, [date, projectId]);
// return { dashboard_Attendancedata, isLineChartLoading: isLineChartLoading, error };
// };
// 🔹 Dashboard Projects Card Data Hook
// export const useDashboardProjectsCardData = () => {
// const [projectsCardData, setProjectsData] = useState([]);
// const [loading, setLoading] = useState(false);
// const [error, setError] = useState("");
// useEffect(() => {
// const fetchProjectsData = async () => {
// setLoading(true);
// setError("");
// try {
// const response = await GlobalRepository.getDashboardProjectsCardData();
// setProjectsData(response.data);
// } catch (err) {
// setError("Failed to fetch projects card data.");
// console.error(err);
// } finally {
// setLoading(false);
// }
// };
// fetchProjectsData();
// }, []);
// return { projectsCardData, loading, error };
// };
// 🔹 Dashboard Teams Card Data Hook
// export const useDashboardTeamsCardData = (projectId) => {
// const [teamsCardData, setTeamsData] = useState({});
// const [loading, setLoading] = useState(false);
// const [error, setError] = useState("");
// useEffect(() => {
// const fetchTeamsData = async () => {
// setLoading(true);
// setError("");
// try {
// const response = await GlobalRepository.getDashboardTeamsCardData(projectId);
// setTeamsData(response.data || {});
// } catch (err) {
// setError("Failed to fetch teams card data.");
// console.error("Error fetching teams card data:", err);
// setTeamsData({});
// } finally {
// setLoading(false);
// }
// };
// fetchTeamsData();
// }, [projectId]);
// return { teamsCardData, loading, error };
// };
// export const useDashboardTasksCardData = (projectId) => {
// const [tasksCardData, setTasksData] = useState({});
// const [loading, setLoading] = useState(false);
// const [error, setError] = useState("");
// useEffect(() => {
// const fetchTasksData = async () => {
// setLoading(true);
// setError("");
// try {
// const response = await GlobalRepository.getDashboardTasksCardData(projectId);
// setTasksData(response.data);
// } catch (err) {
// setError("Failed to fetch tasks card data.");
// console.error(err);
// setTasksData({});
// } finally {
// setLoading(false);
// }
// };
// fetchTasksData();
// }, [projectId]);
// return { tasksCardData, loading, error };
// };
export const useAttendanceOverviewData = (projectId, days) => { export const useAttendanceOverviewData = (projectId, days) => {
const [attendanceOverviewData, setAttendanceOverviewData] = useState([]); const [attendanceOverviewData, setAttendanceOverviewData] = useState([]);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
@ -167,7 +51,10 @@ export const useAttendanceOverviewData = (projectId, days) => {
setError(""); setError("");
try { try {
const response = await GlobalRepository.getAttendanceOverview(projectId, days); const response = await GlobalRepository.getAttendanceOverview(
projectId,
days
);
setAttendanceOverviewData(response.data); setAttendanceOverviewData(response.data);
} catch (err) { } catch (err) {
setError("Failed to fetch attendance overview data."); setError("Failed to fetch attendance overview data.");
@ -182,7 +69,6 @@ export const useAttendanceOverviewData = (projectId, days) => {
return { attendanceOverviewData, loading, error }; return { attendanceOverviewData, loading, error };
}; };
// -------------------Query---------------------------- // -------------------Query----------------------------
// export const useDashboard_Data = (days, FromDate, projectId)=>{ // export const useDashboard_Data = (days, FromDate, projectId)=>{
@ -199,39 +85,47 @@ export const useAttendanceOverviewData = (projectId, days) => {
// } // }
// }) // })
// } // }
export const useProjectCompletionStatus = () => {
return useQuery({
queryKey: ["projectCompletionStatus"],
queryFn: async () => {
const resp = await await GlobalRepository.getProjectCompletionStatus();
return resp.data;
},
});
};
export const useDashboard_AttendanceData = (date, projectId) => { export const useDashboard_AttendanceData = (date, projectId) => {
return useQuery({ return useQuery({
queryKey: ["dashboardAttendances", date, projectId], queryKey: ["dashboardAttendances", date, projectId],
queryFn: async () => { queryFn: async () => {
const resp = await await GlobalRepository.getDashboardAttendanceData(
const resp = await await GlobalRepository.getDashboardAttendanceData(date, projectId) date,
projectId
);
return resp.data; return resp.data;
} },
}) });
} };
export const useDashboardTeamsCardData = (projectId) => { export const useDashboardTeamsCardData = (projectId) => {
return useQuery({ return useQuery({
queryKey: ["dashboardTeams", projectId], queryKey: ["dashboardTeams", projectId],
queryFn: async () => { queryFn: async () => {
const resp = await GlobalRepository.getDashboardTeamsCardData(projectId);
const resp = await GlobalRepository.getDashboardTeamsCardData(projectId)
return resp.data; return resp.data;
} },
}) });
} };
export const useDashboardTasksCardData = (projectId) => { export const useDashboardTasksCardData = (projectId) => {
return useQuery({ return useQuery({
queryKey: ["dashboardTasks", projectId], queryKey: ["dashboardTasks", projectId],
queryFn: async () => { queryFn: async () => {
const resp = await GlobalRepository.getDashboardTasksCardData(projectId);
const resp = await GlobalRepository.getDashboardTasksCardData(projectId)
return resp.data; return resp.data;
} },
}) });
} };
// export const useAttendanceOverviewData = (projectId, days) => { // export const useAttendanceOverviewData = (projectId, days) => {
// return useQuery({ // return useQuery({
// queryKey:["dashboardAttendanceOverView",projectId], // queryKey:["dashboardAttendanceOverView",projectId],
@ -247,24 +141,25 @@ export const useDashboardProjectsCardData = () => {
return useQuery({ return useQuery({
queryKey: ["dashboardProjects"], queryKey: ["dashboardProjects"],
queryFn: async () => { queryFn: async () => {
const resp = await GlobalRepository.getDashboardProjectsCardData(); const resp = await GlobalRepository.getDashboardProjectsCardData();
return resp.data; return resp.data;
} },
}) });
} };
export const useExpenseAnalysis = (projectId, startDate, endDate) => { export const useExpenseAnalysis = (projectId, startDate, endDate) => {
const hasBothDates = !!startDate && !!endDate; const hasBothDates = !!startDate && !!endDate;
const noDatesSelected = !startDate && !endDate; const noDatesSelected = !startDate && !endDate;
const shouldFetch = const shouldFetch = noDatesSelected || hasBothDates;
noDatesSelected ||
hasBothDates;
return useQuery({ return useQuery({
queryKey: ["expenseAnalysis", projectId, startDate, endDate], queryKey: ["expenseAnalysis", projectId, startDate, endDate],
queryFn: async () => { queryFn: async () => {
const resp = await GlobalRepository.getExpenseData(projectId, startDate, endDate); const resp = await GlobalRepository.getExpenseData(
projectId,
startDate,
endDate
);
return resp.data; return resp.data;
}, },
enabled: shouldFetch, enabled: shouldFetch,
@ -280,17 +175,20 @@ export const useExpenseStatus = (projectId) => {
queryFn: async () => { queryFn: async () => {
const resp = await GlobalRepository.getExpenseStatus(projectId); const resp = await GlobalRepository.getExpenseStatus(projectId);
return resp.data; return resp.data;
} },
}) });
} };
export const useExpenseDataByProject = (projectId, categoryId, months) => { export const useExpenseDataByProject = (projectId, categoryId, months) => {
return useQuery({ return useQuery({
queryKey: ["expenseByProject", projectId, categoryId, months], queryKey: ["expenseByProject", projectId, categoryId, months],
queryFn: async () => { queryFn: async () => {
const resp = await GlobalRepository.getExpenseDataByProject(projectId, categoryId, months); const resp = await GlobalRepository.getExpenseDataByProject(
projectId,
categoryId,
months
);
return resp.data; return resp.data;
}, },
}); });
}; };

View File

@ -18,6 +18,8 @@ const GlobalRepository = {
return api.get(`/api/Dashboard/Progression?${params.toString()}`); return api.get(`/api/Dashboard/Progression?${params.toString()}`);
}, },
getProjectCompletionStatus:()=>api.get(`/api/Dashboard/project-completion-status`),
getDashboardAttendanceData: (date, projectId) => { getDashboardAttendanceData: (date, projectId) => {

View File

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