diff --git a/src/ModalProvider.jsx b/src/ModalProvider.jsx
index bb217139..8ef00bcd 100644
--- a/src/ModalProvider.jsx
+++ b/src/ModalProvider.jsx
@@ -5,21 +5,24 @@ import { useAuthModal, useModal } from "./hooks/useAuth";
import SwitchTenant from "./pages/authentication/SwitchTenant";
import ChangePasswordPage from "./pages/authentication/ChangePassword";
import NewCollection from "./components/collections/ManageCollection";
+import ServiceProjectTeamAllocation from "./components/ServiceProject/ServiceProjectTeam/ServiceProjectTeamAllocation";
const ModalProvider = () => {
const { isOpen, onClose } = useOrganizationModal();
const { isOpen: isAuthOpen } = useAuthModal();
- const {isOpen:isChangePass} = useModal("ChangePassword")
- const {isOpen:isCollectionNew} = useModal("newCollection");
+ const { isOpen: isChangePass } = useModal("ChangePassword");
+ const { isOpen: isCollectionNew } = useModal("newCollection");
+ const { isOpen: isServiceTeamAllocation } = useModal("ServiceTeamAllocation");
return (
<>
{isOpen && }
{isAuthOpen && }
- {isChangePass && }
- {isCollectionNew && }
+ {isChangePass && }
+ {isCollectionNew && }
+ {isServiceTeamAllocation && }
>
);
};
-export default ModalProvider;
\ No newline at end of file
+export default ModalProvider;
diff --git a/src/components/ServiceProject/ServiceProjectTeam/ProjectTeam.jsx b/src/components/ServiceProject/ServiceProjectTeam/ProjectTeam.jsx
new file mode 100644
index 00000000..6ce2a6fb
--- /dev/null
+++ b/src/components/ServiceProject/ServiceProjectTeam/ProjectTeam.jsx
@@ -0,0 +1,20 @@
+import React from 'react'
+import { useModal } from '../../../hooks/useAuth'
+
+
+const ProjectTeam = () => {
+const {onOpen} = useModal("ServiceTeamAllocation");
+
+ return (
+
+ )
+}
+
+export default ProjectTeam
diff --git a/src/components/ServiceProject/ServiceProjectTeam/ServiceProjectTeamAllocation.jsx b/src/components/ServiceProject/ServiceProjectTeam/ServiceProjectTeamAllocation.jsx
new file mode 100644
index 00000000..f2ac7a84
--- /dev/null
+++ b/src/components/ServiceProject/ServiceProjectTeam/ServiceProjectTeamAllocation.jsx
@@ -0,0 +1,52 @@
+import React, { useState } from "react";
+import { useModal } from "../../../hooks/useAuth";
+import Modal from "../../common/Modal";
+import Label from "../../common/Label";
+import { useTeamRole } from "../../../hooks/masterHook/useMaster";
+import SelectField from "../../common/Forms/SelectField";
+import SelectFieldServerSide from "../../common/Forms/SelectFieldServerSide";
+import SelectEmployeeServerSide from "../../common/Forms/SelectFieldServerSide";
+
+const ServiceProjectTeamAllocation = () => {
+ const { isOpen, onClose } = useModal("ServiceTeamAllocation");
+ const [selectedTeam, setSelectTeam] = useState(null);
+ const [selectedEmployees, setSelectedEmployees] = useState(null);
+ const { data, isLoading, isError, error } = useTeamRole();
+ console.log(selectedEmployees);
+ const TeamAllocation = (
+
+
+ setSelectTeam(e)}
+ isLoading={isLoading}
+ />
+
+
+
+
+
+ );
+ return (
+
+ );
+};
+
+export default ServiceProjectTeamAllocation;
diff --git a/src/components/ServiceProject/ServiceProjectTeam/ServiceProjectTeamList.jsx b/src/components/ServiceProject/ServiceProjectTeam/ServiceProjectTeamList.jsx
new file mode 100644
index 00000000..418fc093
--- /dev/null
+++ b/src/components/ServiceProject/ServiceProjectTeam/ServiceProjectTeamList.jsx
@@ -0,0 +1,12 @@
+import React from 'react'
+
+const ServiceProjectTeamList = () => {
+
+ return (
+
+
+
+ )
+}
+
+export default ServiceProjectTeamList
diff --git a/src/components/common/Forms/SelectFieldServerSide.jsx b/src/components/common/Forms/SelectFieldServerSide.jsx
index c0746775..c2014ed6 100644
--- a/src/components/common/Forms/SelectFieldServerSide.jsx
+++ b/src/components/common/Forms/SelectFieldServerSide.jsx
@@ -1,44 +1,108 @@
import React, { useEffect, useRef, useState } from "react";
import Label from "../Label";
import { useDebounce } from "../../../utils/appUtils";
+import { useEmployeesName } from "../../../hooks/useEmployees";
-const SelectFieldServerSide = ({
+const SelectEmployeeServerSide = ({
label = "Select",
- options = [],
- placeholder = "Select Option",
+ placeholder = "Select Employee",
required = false,
- value,
+ value = null,
onChange,
valueKey = "id",
- labelKey = "name",
- isLoading = false,
+ isFullObject = false,
+ isMultiple = false,
+ projectId = null,
+ isAllEmployee = false,
}) => {
- const [searchText,setSeachText] = useState("")
- const debounce = useDebounce(searchText,300);
-// const {} = use
+ const [searchText, setSearchText] = useState("");
+ const debounce = useDebounce(searchText, 300);
+
+ const { data, isLoading } = useEmployeesName(
+ projectId,
+ debounce,
+ isAllEmployee
+ );
+
+ const options = data?.data ?? [];
const [open, setOpen] = useState(false);
const dropdownRef = useRef(null);
+ const getDisplayName = (emp) => {
+ if (!emp) return "";
+ return `${emp.firstName || ""} ${emp.lastName || ""}`.trim();
+ };
+
+ /** -----------------------------
+ * SELECTED OPTION (SINGLE)
+ * ----------------------------- */
+ let selectedSingle = null;
+
+ if (!isMultiple) {
+ if (isFullObject && value) selectedSingle = value;
+ else if (!isFullObject && value)
+ selectedSingle = options.find((o) => o[valueKey] === value);
+ }
+
+ /** -----------------------------
+ * SELECTED OPTION (MULTIPLE)
+ * ----------------------------- */
+ let selectedList = [];
+
+ if (isMultiple && Array.isArray(value)) {
+ if (isFullObject) selectedList = value;
+ else {
+ selectedList = options.filter((opt) => value.includes(opt[valueKey]));
+ }
+ }
+
+ /** Main button label */
+ const displayText = !isMultiple
+ ? getDisplayName(selectedSingle) || placeholder
+ : selectedList.length > 0
+ ? selectedList.map((e) => getDisplayName(e)).join(", ")
+ : placeholder;
+
+ /** -----------------------------
+ * HANDLE OUTSIDE CLICK
+ * ----------------------------- */
useEffect(() => {
- const handleClickOutside = (event) => {
- if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
+ const handleClickOutside = (e) => {
+ if (dropdownRef.current && !dropdownRef.current.contains(e.target)) {
setOpen(false);
}
};
+
document.addEventListener("mousedown", handleClickOutside);
return () => document.removeEventListener("mousedown", handleClickOutside);
}, []);
- const selectedOption = options.find((opt) => opt[valueKey] === value);
-
- const displayText = selectedOption ? selectedOption[labelKey] : placeholder;
-
+ /** -----------------------------
+ * HANDLE SELECT
+ * ----------------------------- */
const handleSelect = (option) => {
- onChange(option[valueKey]);
- setOpen(false);
- };
+ if (!isMultiple) {
+ // SINGLE SELECT
+ if (isFullObject) onChange(option);
+ else onChange(option[valueKey]);
+ } else {
+ // MULTIPLE SELECT
+ let updated = [];
- const toggleDropdown = () => setOpen((prev) => !prev);
+ const exists = selectedList.some((e) => e[valueKey] === option[valueKey]);
+
+ if (exists) {
+ // remove
+ updated = selectedList.filter((e) => e[valueKey] !== option[valueKey]);
+ } else {
+ // add
+ updated = [...selectedList, option];
+ }
+
+ if (isFullObject) onChange(updated);
+ else onChange(updated.map((x) => x[valueKey]));
+ }
+ };
return (
@@ -48,22 +112,21 @@ const SelectFieldServerSide = ({
)}
+ {/* MAIN BUTTON */}
- {open && !isLoading && (
+ {/* DROPDOWN */}
+ {open && (
)}
);
};
-export default SelectFieldServerSide;
+export default SelectEmployeeServerSide;
diff --git a/src/components/common/Modal.jsx b/src/components/common/Modal.jsx
index 876ff0e8..e8292153 100644
--- a/src/components/common/Modal.jsx
+++ b/src/components/common/Modal.jsx
@@ -40,7 +40,7 @@ const Modal = ({
{/* Body */}
- {body}
+ {body}
diff --git a/src/hooks/masterHook/useMaster.js b/src/hooks/masterHook/useMaster.js
index 5e786adb..978bf30e 100644
--- a/src/hooks/masterHook/useMaster.js
+++ b/src/hooks/masterHook/useMaster.js
@@ -296,6 +296,25 @@ export const useOrganizationType = () => {
});
};
+export const useJobStatus=()=>{
+ return useQuery({
+ queryKey:["Job_Staus"],
+ queryFn:async()=>{
+ const resp = await MasterRespository.getJobStatus();
+ return resp.data;
+ }
+ })
+}
+
+export const useTeamRole=()=>{
+ return useQuery({
+ queryKey:["Team_Role"],
+ queryFn:async()=>{
+ const resp = await MasterRespository.getTeamRole();
+ return resp.data;
+ }
+ })
+}
//#region ==Get Masters==
const fetchMasterData = async (masterType) => {
switch (masterType) {
@@ -385,6 +404,8 @@ const useMaster = () => {
export default useMaster;
//#endregion
+
+
// ================================Mutation====================================
//#region Job Role
@@ -435,6 +456,9 @@ export const useCreateJobRole = (onSuccessCallback) => {
//#endregion Job Role
+
+
+
//#region Application Role
export const useCreateApplicationRole = (onSuccessCallback) => {
const queryClient = useQueryClient();
@@ -480,6 +504,10 @@ export const useUpdateApplicationRole = (onSuccessCallback) => {
};
//#endregion
+
+
+
+
//#region Create work Category
export const useCreateWorkCategory = (onSuccessCallback) => {
const queryClient = useQueryClient();
@@ -525,6 +553,11 @@ export const useUpdateWorkCategory = (onSuccessCallback) => {
};
//#endregion
+
+
+
+
+
//#region Contact Category
export const useCreateContactCategory = (onSuccessCallback) => {
@@ -575,6 +608,10 @@ export const useUpdateContactCategory = (onSuccessCallback) => {
//#endregion
+
+
+
+
//#region Contact Tag
export const useCreateContactTag = (onSuccessCallback) => {
@@ -621,6 +658,10 @@ export const useUpdateContactTag = (onSuccessCallback) => {
};
//#endregion
+
+
+
+
//#region Expense Category
export const useCreateExpenseCategory = (onSuccessCallback) => {
const queryClient = useQueryClient();
@@ -666,6 +707,11 @@ export const useUpdateExpenseCategory = (onSuccessCallback) => {
//#endregion
+
+
+
+
+
//#region Payment Mode
export const useCreatePaymentMode = (onSuccessCallback) => {
@@ -712,6 +758,10 @@ export const useUpdatePaymentMode = (onSuccessCallback) => {
//#endregion
+
+
+
+
// Services-------------------------------
// export const useCreateService = (onSuccessCallback) => {
@@ -793,6 +843,10 @@ export const useUpdateService = (onSuccessCallback) => {
//#endregion
+
+
+
+
//#region Activity Grouph
export const useCreateActivityGroup = (onSuccessCallback) => {
@@ -857,6 +911,10 @@ export const useUpdateActivityGroup = (onSuccessCallback) => {
//#endregion
+
+
+
+
//#region Activities
export const useCreateActivity = (onSuccessCallback) => {
const queryClient = useQueryClient();
@@ -911,6 +969,11 @@ export const useUpdateActivity = (onSuccessCallback) => {
//#endregion
+
+
+
+
+
//#region Expense Status
export const useCreateExpenseStatus = (onSuccessCallback) => {
const queryClient = useQueryClient();
@@ -954,6 +1017,10 @@ export const useUpdateExpenseStatus = (onSuccessCallback) => {
};
//#endregion
+
+
+
+
//#region Document-Category
export const useCreateDocumentCatgory = (onSuccessCallback) => {
const queryClient = useQueryClient();
@@ -1000,6 +1067,11 @@ export const useUpdateDocumentCategory = (onSuccessCallback) => {
};
//#endregion
+
+
+
+
+
//#region Document-Type
export const useCreateDocumentType = (onSuccessCallback) => {
const queryClient = useQueryClient();
@@ -1044,6 +1116,10 @@ export const useUpdateDocumentType = (onSuccessCallback) => {
};
//#endregion
+
+
+
+
//#region Payment Adjustment Head
export const useCreatePaymentAjustmentHead = (onSuccessCallback) => {
const queryClient = useQueryClient();
@@ -1087,6 +1163,10 @@ export const useUpdatePaymentAjustmentHead = (onSuccessCallback) => {
};
//#endregion
+
+
+
+
//#region ==Delete Master==
export const useDeleteMasterItem = () => {
const queryClient = useQueryClient();
@@ -1122,6 +1202,8 @@ export const useDeleteMasterItem = () => {
//#endregion
+
+
export const useDeleteServiceGroup = () => {
const queryClient = useQueryClient();
diff --git a/src/hooks/useServiceProject.jsx b/src/hooks/useServiceProject.jsx
index 8cff3238..a8fd799e 100644
--- a/src/hooks/useServiceProject.jsx
+++ b/src/hooks/useServiceProject.jsx
@@ -103,6 +103,26 @@ export const useActiveInActiveServiceProject = (onSuccessCallback) => {
},
});
};
+
+export const useAllocationTeam=()=>{
+ const queryClient = useQueryClient();
+ return useMutation({
+ mutationFn:async(paylaod)=> await ServiceProjectRepository.AllocateEmployee(paylaod),
+ onSuccess: (data, variables) => {
+ // queryClient.invalidateQueries({ queryKey: ["serviceProjects"] });
+ if (onSuccessCallback) onSuccessCallback();
+ showToast(`${variables?.length} employee allocated successfully`, "success");
+ },
+ onError: (error) => {
+ showToast(
+ error?.response?.data?.message ||
+ error.message ||
+ "Failed to update project",
+ "error"
+ );
+ },
+ })
+}
//#endregion
//#region Service Jobs
diff --git a/src/pages/ServiceProject/ServiceProjectDetail.jsx b/src/pages/ServiceProject/ServiceProjectDetail.jsx
index 8708970f..ac5eecc5 100644
--- a/src/pages/ServiceProject/ServiceProjectDetail.jsx
+++ b/src/pages/ServiceProject/ServiceProjectDetail.jsx
@@ -4,6 +4,7 @@ import ServiceProjectNav from "../../components/ServiceProject/ServiceProjectNav
import { ComingSoonPage } from "../Misc/ComingSoonPage";
import ServiceProjectProfile from "../../components/ServiceProject/ServiceProjectProfile";
import Jobs from "../../components/ServiceProject/Jobs";
+import ProjectTeam from "../../components/ServiceProject/ServiceProjectTeam/ProjectTeam";
const ServiceProjectDetail = () => {
const [activePill, setActivePill] = useState(
@@ -17,6 +18,8 @@ const ServiceProjectDetail = () => {
switch (activePill) {
case "profile":
return ;
+ case "teams":
+ return ;
case "jobs":
return ;
default:
diff --git a/src/repositories/MastersRepository.jsx b/src/repositories/MastersRepository.jsx
index 9542300d..72cb91d9 100644
--- a/src/repositories/MastersRepository.jsx
+++ b/src/repositories/MastersRepository.jsx
@@ -149,5 +149,9 @@ export const MasterRespository = {
getCurrencies: () => api.get(`/api/Master/currencies/list`),
- getRecurringStatus:()=>api.get(`/api/Master/recurring-status/list`)
+ getRecurringStatus: () => api.get(`/api/Master/recurring-status/list`),
+
+ getJobStatus: () => api.get("/api/Master/job-status/list"),
+
+ getTeamRole:()=> api.get(`/api/Master/team-roles/list`),
};
diff --git a/src/repositories/ServiceProjectRepository.jsx b/src/repositories/ServiceProjectRepository.jsx
index 4632e86b..20b5aa8e 100644
--- a/src/repositories/ServiceProjectRepository.jsx
+++ b/src/repositories/ServiceProjectRepository.jsx
@@ -11,7 +11,7 @@ export const ServiceProjectRepository = {
api.put(`/api/ServiceProject/edit/${id}`, data),
DeleteServiceProject: (id, isActive = false) =>
api.delete(`/api/ServiceProject/delete/${id}?isActive=${isActive}`),
-
+ AllocateEmployee: (data) => api.post(`/api/ServiceProject/manage/allocation`),
//#region Job
CreateJob: (data) => api.post(`/api/ServiceProject/job/create`, data),