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

This commit is contained in:
pramod mahajan 2025-09-20 12:14:40 +05:30
commit 158c934a9f
8 changed files with 357 additions and 157 deletions

View File

@ -55,7 +55,7 @@ const InfraPlanning = () => {
if (isFetched && (!projectInfra || projectInfra.length === 0)) { if (isFetched && (!projectInfra || projectInfra.length === 0)) {
return ( return (
<div className="card text-center"> <div className="text-center">
<p className="my-3">No Result Found</p> <p className="my-3">No Result Found</p>
</div> </div>
); );
@ -63,14 +63,12 @@ const InfraPlanning = () => {
return ( return (
<div className="col-md-12 col-lg-12 col-xl-12 order-0 mb-4"> <div className="col-md-12 col-lg-12 col-xl-12 order-0 mb-4">
<div className="card">
<div className="card-body" style={{ padding: "0.5rem" }}> <div className="card-body" style={{ padding: "0.5rem" }}>
<div className="row"> <div className="row">
<InfraTable buildings={projectInfra} projectId={selectedProject} /> <InfraTable buildings={projectInfra} projectId={selectedProject} />
</div> </div>
</div> </div>
</div> </div>
</div>
); );
}; };

View File

@ -143,7 +143,7 @@ const InfraTable = ({ buildings, projectId}) => {
// }, [handler]); // }, [handler]);
return ( return (
<div> <div className="px-6">
{projectBuilding && projectBuilding.length > 0 && ( {projectBuilding && projectBuilding.length > 0 && (
<table className="table table-bordered"> <table className="table table-bordered">
<tbody> <tbody>

View File

@ -6,9 +6,10 @@ import {
useActivitiesMaster, useActivitiesMaster,
useWorkCategoriesMaster, useWorkCategoriesMaster,
} from "../../../hooks/masterHook/useMaster"; } from "../../../hooks/masterHook/useMaster";
import { useManageTask } from "../../../hooks/useProjects"; import { useManageTask, useProjectAssignedServices } from "../../../hooks/useProjects";
import showToast from "../../../services/toastService"; import showToast from "../../../services/toastService";
import Label from "../../common/Label"; import Label from "../../common/Label";
import { useSelectedProject } from "../../../slices/apiDataManager";
const taskSchema = z.object({ const taskSchema = z.object({
buildingID: z.string().min(1, "Building is required"), buildingID: z.string().min(1, "Building is required"),
@ -37,6 +38,15 @@ const TaskModel = ({ project, onSubmit, onClose }) => {
const { activities, loading: activityLoading } = useActivitiesMaster(); const { activities, loading: activityLoading } = useActivitiesMaster();
const { categories, categoryLoading } = useWorkCategoriesMaster(); const { categories, categoryLoading } = useWorkCategoriesMaster();
const projectId = useSelectedProject();
const { data: assignedServices, isLoading: servicesLoading } = useProjectAssignedServices(projectId);
const [selectedService, setSelectedService] = useState("");
const handleServiceChange = (e) => {
setSelectedService(e.target.value);
};
const { const {
register, register,
handleSubmit, handleSubmit,
@ -97,9 +107,11 @@ const TaskModel = ({ project, onSubmit, onClose }) => {
const onSubmitForm = async (data) => { const onSubmitForm = async (data) => {
const payload = [data]; const payload = [data];
CreateTask({payload:payload,buildingId: data.buildingID, CreateTask({
payload: payload, buildingId: data.buildingID,
floorId: data.floorId, floorId: data.floorId,
workAreaId: data.workAreaId, PreviousPlannedWork:0,previousCompletedWork:0}); workAreaId: data.workAreaId, PreviousPlannedWork: 0, previousCompletedWork: 0
});
}; };
return ( return (
@ -150,6 +162,7 @@ const TaskModel = ({ project, onSubmit, onClose }) => {
</div> </div>
)} )}
{/* Work Area Selection */}
{selectedFloor && ( {selectedFloor && (
<div className="col-12 text-start"> <div className="col-12 text-start">
<Label className="form-label" required>Select Work Area</Label> <Label className="form-label" required>Select Work Area</Label>
@ -172,6 +185,32 @@ const TaskModel = ({ project, onSubmit, onClose }) => {
</div> </div>
)} )}
{/* Services Selection */}
{selectedWorkArea && (
<div className="col-12 text-start">
<Label className="form-label">Select Services</Label>
<select
name="DataTables_Table_0_length"
aria-controls="DataTables_Table_0"
className="form-select form-select-sm"
aria-label="Select Service"
value={selectedService}
onChange={handleServiceChange}
>
{servicesLoading && <option>Loading...</option>}
{assignedServices?.map((service) => (
<option key={service.id} value={service.id}>
{service.name}
</option>
))}
</select>
{errors.buildingID && (
<p className="danger-text">{errors.buildingID.message}</p>
)}
</div>
)}
{/* Activity Selection */}
{selectedWorkArea && ( {selectedWorkArea && (
<div className="col-12 text-start"> <div className="col-12 text-start">
<Label className="form-label" required>Select Activity</Label> <Label className="form-label" required>Select Activity</Label>
@ -192,6 +231,7 @@ const TaskModel = ({ project, onSubmit, onClose }) => {
</div> </div>
)} )}
{selectedWorkArea && ( {selectedWorkArea && (
<div className="col-12 text-start"> <div className="col-12 text-start">
<label className="form-label">Select Work Category</label> <label className="form-label">Select Work Category</label>

View File

@ -17,22 +17,21 @@ import {
getCachedData, getCachedData,
useSelectedProject, useSelectedProject,
} from "../../slices/apiDataManager"; } from "../../slices/apiDataManager";
import { useProjectDetails, useProjectInfra } from "../../hooks/useProjects"; import { useProjectAssignedServices, useProjectDetails, useProjectInfra } from "../../hooks/useProjects";
import { useDispatch, useSelector } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
import { refreshData } from "../../slices/localVariablesSlice"; import { refreshData } from "../../slices/localVariablesSlice";
import eventBus from "../../services/eventBus"; import eventBus from "../../services/eventBus";
import {useParams} from "react-router-dom"; import { useParams } from "react-router-dom";
import GlobalModel from "../common/GlobalModel"; import GlobalModel from "../common/GlobalModel";
const ProjectInfra = ( {data, onDataChange, eachSiteEngineer} ) => const ProjectInfra = ({ data, onDataChange, eachSiteEngineer }) => {
{
// const projectId = useSelector((store)=>store.localVariables.projectId) // const projectId = useSelector((store)=>store.localVariables.projectId)
const projectId = useSelectedProject(); const projectId = useSelectedProject();
const reloadedData = useSelector((store) => store.localVariables.reload); const reloadedData = useSelector((store) => store.localVariables.reload);
const [ expandedBuildings, setExpandedBuildings ] = useState( [] ); const [expandedBuildings, setExpandedBuildings] = useState([]);
const {projectInfra,isLoading,error} = useProjectInfra(projectId) const { projectInfra, isLoading, error } = useProjectInfra(projectId)
const { projects_Details, refetch, loading } = useProjectDetails(data?.id); const { projects_Details, refetch, loading } = useProjectDetails(data?.id);
const [ project, setProject ] = useState( projects_Details ); const [project, setProject] = useState(projects_Details);
const ManageInfra = useHasUserPermission(MANAGE_PROJECT_INFRA); const ManageInfra = useHasUserPermission(MANAGE_PROJECT_INFRA);
const ManageTask = useHasUserPermission(MANAGE_TASK) const ManageTask = useHasUserPermission(MANAGE_TASK)
const [showModalFloor, setshowModalFloor] = useState(false); const [showModalFloor, setshowModalFloor] = useState(false);
@ -40,46 +39,45 @@ const ProjectInfra = ( {data, onDataChange, eachSiteEngineer} ) =>
const [showModalTask, setshowModalTask] = useState(false); const [showModalTask, setshowModalTask] = useState(false);
const [showModalBuilding, setshowModalBuilding] = useState(false); const [showModalBuilding, setshowModalBuilding] = useState(false);
const dispatch = useDispatch(); const dispatch = useDispatch();
const { data: assignedServices, isLoading: servicesLoading } = useProjectAssignedServices(projectId);
const [selectedService, setSelectedService] = useState("");
const handleServiceChange = (e) => {
setSelectedService(e.target.value);
};
useEffect(() => { useEffect(() => {
setProject(projectInfra); setProject(projectInfra);
}, [data, projects_Details]); }, [data, projects_Details]);
// useEffect(() => {
// if (reloadedData) {
// refetch();
// dispatch(refreshData(false));
// }
// }, [reloadedData]);
const signalRHandler = (response) => { const signalRHandler = (response) => {
setProject(response); setProject(response);
} }
return ( return (
<> <>
{showModalBuilding && <GlobalModel isOpen={showModalBuilding} size="md" closeModal={() => setshowModalBuilding( false )}> {showModalBuilding && <GlobalModel isOpen={showModalBuilding} size="md" closeModal={() => setshowModalBuilding(false)}>
<BuildingModel <BuildingModel
project={projectInfra} project={projectInfra}
onClose={() => setshowModalBuilding( false )} onClose={() => setshowModalBuilding(false)}
/> />
</GlobalModel>} </GlobalModel>}
{showModalFloor && <GlobalModel isOpen={showModalFloor} size="md" closeModal={()=>setshowModalFloor(false)}> {showModalFloor && <GlobalModel isOpen={showModalFloor} size="md" closeModal={() => setshowModalFloor(false)}>
<FloorModel <FloorModel
project={projectInfra} project={projectInfra}
onClose={()=>setshowModalFloor(false)} onClose={() => setshowModalFloor(false)}
/> />
</GlobalModel>} </GlobalModel>}
{showModalWorkArea && <GlobalModel isOpen={showModalWorkArea} size="lg" closeModal={()=>setshowModalWorkArea(false)} > {showModalWorkArea && <GlobalModel isOpen={showModalWorkArea} size="lg" closeModal={() => setshowModalWorkArea(false)} >
<WorkAreaModel <WorkAreaModel
project={projectInfra} project={projectInfra}
onClose={()=>setshowModalWorkArea(false)} onClose={() => setshowModalWorkArea(false)}
/> />
</GlobalModel>} </GlobalModel>}
{showModalTask && ( <GlobalModel isOpen={showModalTask} size="lg" closeModal={()=>setshowModalTask(false)}> {showModalTask && (<GlobalModel isOpen={showModalTask} size="lg" closeModal={() => setshowModalTask(false)}>
<TaskModel <TaskModel
project={projectInfra} project={projectInfra}
onClose={()=>setshowModalTask(false)} onClose={() => setshowModalTask(false)}
/> />
</GlobalModel>)} </GlobalModel>)}
<div className="col-md-12 col-lg-12 col-xl-12 order-0 mb-4"> <div className="col-md-12 col-lg-12 col-xl-12 order-0 mb-4">
@ -88,13 +86,48 @@ const ProjectInfra = ( {data, onDataChange, eachSiteEngineer} ) =>
<div className="align-items-center"> <div className="align-items-center">
<div className="row "> <div className="row ">
<div <div
className={`col-12 text-end mb-1 `} className="dataTables_length text-start py-2 px-6 col-md-4 col-12"
id="DataTables_Table_0_length"
> >
{ManageInfra && (<> {servicesLoading ? (
<span></span>
) : assignedServices?.length > 1 ? (
<label>
<select
name="DataTables_Table_0_length"
aria-controls="DataTables_Table_0"
className="form-select form-select-sm"
aria-label="Select Service"
value={selectedService}
onChange={handleServiceChange}
>
{assignedServices.map((service) => (
<option key={service.id} value={service.id}>
{service.name}
</option>
))}
</select>
</label>
) : (
<div
style={{
}}
>
{assignedServices?.length === 1
? <h5>{ assignedServices[0].name}</h5>
: "No service available"}
</div>
)}
</div>
{/* Buttons Section (aligned to right) */}
<div className="col-md-8 col-12 text-end mb-1">
{ManageInfra && (
<>
<button <button
type="button" type="button"
className="link-button btn btn-xs rounded-md link-button-sm m-1 btn-primary" className="link-button btn btn-xs rounded-md link-button-sm m-1 btn-primary"
onClick={()=>setshowModalBuilding(true)} onClick={() => setshowModalBuilding(true)}
> >
<i className="bx bx-plus-circle me-2"></i> <i className="bx bx-plus-circle me-2"></i>
Manage Building Manage Building
@ -102,7 +135,7 @@ const ProjectInfra = ( {data, onDataChange, eachSiteEngineer} ) =>
<button <button
type="button" type="button"
className="link-button btn btn-xs rounded-md m-1 btn-primary" className="link-button btn btn-xs rounded-md m-1 btn-primary"
onClick={()=>setshowModalFloor(true)} onClick={() => setshowModalFloor(true)}
> >
<i className="bx bx-plus-circle me-2"></i> <i className="bx bx-plus-circle me-2"></i>
Manage Floors Manage Floors
@ -119,7 +152,7 @@ const ProjectInfra = ( {data, onDataChange, eachSiteEngineer} ) =>
{(ManageTask || ManageInfra) && (<button {(ManageTask || ManageInfra) && (<button
type="button" type="button"
className="link-button btn btn-xs rounded-md m-1 btn-primary" className="link-button btn btn-xs rounded-md m-1 btn-primary"
onClick={()=>setshowModalTask(true)} onClick={() => setshowModalTask(true)}
> >
<i className="bx bx-plus-circle me-2"></i> <i className="bx bx-plus-circle me-2"></i>
Create Tasks Create Tasks

View File

@ -17,12 +17,11 @@ import eventBus from "../../services/eventBus";
import { import {
useEmployeesByProjectAllocated, useEmployeesByProjectAllocated,
useManageProjectAllocation, useManageProjectAllocation,
useProjectAssignedServices,
} from "../../hooks/useProjects"; } from "../../hooks/useProjects";
import { useSelectedProject } from "../../slices/apiDataManager"; import { useSelectedProject } from "../../slices/apiDataManager";
const Teams = () => { const Teams = () => {
// const {projectId} = useParams()
// const projectId = useSelector((store)=>store.localVariables.projectId)
const projectId = useSelectedProject(); const projectId = useSelectedProject();
const dispatch = useDispatch(); const dispatch = useDispatch();
@ -37,6 +36,14 @@ const Teams = () => {
const [activeEmployee, setActiveEmployee] = useState(true); const [activeEmployee, setActiveEmployee] = useState(true);
const [deleteEmployee, setDeleteEmplyee] = useState(null); const [deleteEmployee, setDeleteEmplyee] = useState(null);
const [searchTerm, setSearchTerm] = useState(""); // State for search term const [searchTerm, setSearchTerm] = useState(""); // State for search term
const { data: assignedServices, isLoading: servicesLoading } = useProjectAssignedServices(projectId);
const handleToggleActive = e => setActiveEmployee(e.target.checked);
const [selectedService, setSelectedService] = useState("");
const handleServiceChange = (e) => {
setSelectedService(e.target.value);
};
const navigate = useNavigate(); const navigate = useNavigate();
@ -136,7 +143,6 @@ const Teams = () => {
useEffect(() => { useEffect(() => {
if (projectEmployees) { if (projectEmployees) {
setEmployees(projectEmployees); setEmployees(projectEmployees);
//setFilteredEmployees(projectEmployees?.filter((emp) => emp.isActive));
const filtered = projectEmployees.filter((emp) => emp.isActive); const filtered = projectEmployees.filter((emp) => emp.isActive);
setFilteredEmployees(filtered); setFilteredEmployees(filtered);
} }
@ -179,13 +185,6 @@ const Teams = () => {
const handleFilterEmployee = (e) => { const handleFilterEmployee = (e) => {
const filterValue = e.target.value; const filterValue = e.target.value;
// if (filterValue === "true") {
// setActiveEmployee(true);
// setFilteredEmployees(employees.filter((emp) => emp.isActive));
// } else {
// setFilteredEmployees(employees.filter((emp) => !emp.isActive));
// setActiveEmployee(false);
// }
setActiveEmployee(filterValue === "true"); setActiveEmployee(filterValue === "true");
setSearchTerm(""); setSearchTerm("");
}; };
@ -264,6 +263,66 @@ const Teams = () => {
<div className="card-body"> <div className="card-body">
<div className="row d-flex justify-content-between mb-4"> <div className="row d-flex justify-content-between mb-4">
<div className="col-md-6 col-12 d-flex align-items-center"> <div className="col-md-6 col-12 d-flex align-items-center">
<div className="dataTables_length text-start py-1 px-0 col-md-4 col-12">
{servicesLoading ? (
<span></span>
) : assignedServices?.length > 1 ? (
<label>
<select
name="DataTables_Table_0_length"
aria-controls="DataTables_Table_0"
className="form-select form-select-sm"
aria-label="Select Service"
value={selectedService}
onChange={handleServiceChange}
style={{ fontSize: "0.875rem", height: "32px", width: "190px" }}
>
{assignedServices.map((service) => (
<option key={service.id} value={service.id}>
{service.name}
</option>
))}
</select>
</label>
) : (
<div
style={{
}}
>
{/* fier fitting */}
{assignedServices?.length === 1
?<h5>{ assignedServices[0].name}</h5>
: "No service available"}
</div>
)}
</div>
{/* <div className="dataTables_filter d-inline-flex align-items-center ms-2">
<input
type="search"
className="form-control form-control-sm me-4"
placeholder="Search by Name or Role"
aria-controls="DataTables_Table_0"
value={searchTerm}
onChange={handleSearch}
/>
</div> */}
</div>
<div className="col-md-6 col-12 d-flex justify-content-end align-items-center">
<div className="form-check form-switch me-2 mt-2">
<input
type="checkbox"
className="form-check-input"
checked={activeEmployee}
onChange={handleToggleActive}
id="activeEmployeeSwitch"
/>
<label className="form-check-label ms-0 " htmlFor="activeEmployeeSwitch">
{activeEmployee ? "Active Employees" : "Inactive Employees"}
</label>
</div>
<div className="dataTables_filter d-inline-flex align-items-center ms-2"> <div className="dataTables_filter d-inline-flex align-items-center ms-2">
<input <input
type="search" type="search"
@ -274,31 +333,10 @@ const Teams = () => {
onChange={handleSearch} onChange={handleSearch}
/> />
</div> </div>
</div>
<div className="col-md-6 col-12 d-flex justify-content-end align-items-center">
<div
className="dataTables_length text-start py-2 px-2"
id="DataTables_Table_0_length"
>
<label>
<select
name="DataTables_Table_0_length"
aria-controls="DataTables_Table_0"
className="form-select form-select-sm"
onChange={handleFilterEmployee}
// value={false}
aria-label=""
defaultValue="true"
>
<option value="true">Active Employee</option>
<option value="false">In-Active Employee</option>
</select>
</label>
</div>
<button <button
type="button" type="button"
className={`link-button btn-primary btn-sm ${ className={`link-button btn-primary btn-sm ${HasAssignUserPermission ? "" : "d-none"
HasAssignUserPermission ? "" : "d-none"
}`} }`}
data-bs-toggle="modal" data-bs-toggle="modal"
data-bs-target="#user-model" data-bs-target="#user-model"
@ -319,6 +357,7 @@ const Teams = () => {
<th> <th>
<div className="text-start ms-5">Name</div> <div className="text-start ms-5">Name</div>
</th> </th>
<th>Organization</th>
<th>Assigned Date</th> <th>Assigned Date</th>
{!activeEmployee && <th>Release Date</th>} {!activeEmployee && <th>Release Date</th>}
<th>Project Role</th> <th>Project Role</th>
@ -334,7 +373,7 @@ const Teams = () => {
<Avatar <Avatar
firstName={item.firstName} firstName={item.firstName}
lastName={item.lastName} lastName={item.lastName}
></Avatar> />
<div className="d-flex flex-column"> <div className="d-flex flex-column">
<a <a
onClick={() => onClick={() =>
@ -352,18 +391,16 @@ const Teams = () => {
</div> </div>
</div> </div>
</td> </td>
<td>{item.organizationName || "N/A"}</td>
<td> <td>
{" "} {moment(item.allocationDate).format("DD-MMM-YYYY")}
{moment(item.allocationDate).format(
"DD-MMM-YYYY"
)}{" "}
</td> </td>
{!activeEmployee && ( {!activeEmployee && (
<td> <td>
{item.reAllocationDate {item.reAllocationDate
? moment(item.reAllocationDate).format( ? moment(item.reAllocationDate).format("DD-MMM-YYYY")
"DD-MMM-YYYY"
)
: "Present"} : "Present"}
</td> </td>
)} )}
@ -373,7 +410,7 @@ const Teams = () => {
</span> </span>
</td> </td>
<td> <td>
{item.isActive && ( {item.isActive ? (
<button <button
aria-label="Delete" aria-label="Delete"
type="button" type="button"
@ -381,27 +418,26 @@ const Teams = () => {
className="btn p-0 dropdown-toggle hide-arrow" className="btn p-0 dropdown-toggle hide-arrow"
onClick={() => deleteModalOpen(item)} onClick={() => deleteModalOpen(item)}
> >
{" "}
{removingEmployeeId === item.id ? ( {removingEmployeeId === item.id ? (
<div <div
className="spinner-border spinner-border-sm text-primary" className="spinner-border spinner-border-sm text-primary"
role="status" role="status"
> >
<span className="visually-hidden"> <span className="visually-hidden">Loading...</span>
Loading...
</span>
</div> </div>
) : ( ) : (
<i className="bx bx-trash me-1 text-danger"></i> <i className="bx bx-trash me-1 text-danger"></i>
)} )}
</button> </button>
) : (
<span>Not in project</span>
)} )}
{!item.isActive && <span>Not in project</span>}
</td> </td>
</tr> </tr>
))} ))}
</tbody> </tbody>
</table> </table>
)} )}
{!employeeLodaing && filteredEmployees.length === 0 && ( {!employeeLodaing && filteredEmployees.length === 0 && (
<div className="text-center text-muted py-3"> <div className="text-center text-muted py-3">

View File

@ -203,7 +203,7 @@ const FilterIcon = ({
<> <>
<li><hr className="my-1" /></li> <li><hr className="my-1" /></li>
<li> <li>
<div className="fw-bold text-dark mb-1">Floors</div> <div className="fw-bold text-dark mb-2 mt-2">Floors</div>
<div className="row"> <div className="row">
{uniqueFloors.length > 0 ? ( {uniqueFloors.length > 0 ? (
uniqueFloors.map((floor, idx) => ( uniqueFloors.map((floor, idx) => (
@ -235,7 +235,7 @@ const FilterIcon = ({
<> <>
<li><hr className="my-1" /></li> <li><hr className="my-1" /></li>
<li> <li>
<div className="fw-bold text-dark mb-1">Activities</div> <div className="fw-bold text-dark mb-2 mt-2">Activities</div>
<div className="row"> <div className="row">
{uniqueActivities.length > 0 ? ( {uniqueActivities.length > 0 ? (
uniqueActivities.map((activity, idx) => ( uniqueActivities.map((activity, idx) => (

View File

@ -1,7 +1,7 @@
import React, { useEffect, useMemo, useState } from "react"; import React, { useEffect, useMemo, useState } from "react";
import { useDispatch } from "react-redux"; import { useDispatch } from "react-redux";
import { useTaskList } from "../../hooks/useTasks"; import { useTaskList } from "../../hooks/useTasks";
import { useProjectName } from "../../hooks/useProjects"; import { useProjectAssignedServices, useProjectName } from "../../hooks/useProjects";
import { setProjectId } from "../../slices/localVariablesSlice"; import { setProjectId } from "../../slices/localVariablesSlice";
import Breadcrumb from "../../components/common/Breadcrumb"; import Breadcrumb from "../../components/common/Breadcrumb";
import DateRangePicker from "../../components/common/DateRangePicker"; import DateRangePicker from "../../components/common/DateRangePicker";
@ -24,6 +24,14 @@ const DailyTask = () => {
const ApprovedTaskRights = useHasUserPermission(APPROVE_TASK); const ApprovedTaskRights = useHasUserPermission(APPROVE_TASK);
const ReportTaskRights = useHasUserPermission(ASSIGN_REPORT_TASK); const ReportTaskRights = useHasUserPermission(ASSIGN_REPORT_TASK);
const { data: assignedServices, isLoading: servicesLoading } = useProjectAssignedServices(selectedProject);
const [selectedService, setSelectedService] = useState("");
const handleServiceChange = (e) => {
setSelectedService(e.target.value);
};
const [filters, setFilters] = useState({ const [filters, setFilters] = useState({
selectedBuilding: "", selectedBuilding: "",
selectedFloors: [], selectedFloors: [],
@ -38,7 +46,6 @@ const DailyTask = () => {
dateRange?.endDate || null dateRange?.endDate || null
); );
// Ensure project is set
useEffect(() => { useEffect(() => {
if (!selectedProject && projectNames.length > 0) { if (!selectedProject && projectNames.length > 0) {
debugger debugger
@ -46,7 +53,6 @@ const DailyTask = () => {
} }
}, [selectedProject, projectNames, dispatch]); }, [selectedProject, projectNames, dispatch]);
// 🔹 Reset filters when project changes
useEffect(() => { useEffect(() => {
setFilters({ setFilters({
selectedBuilding: "", selectedBuilding: "",
@ -55,7 +61,6 @@ const DailyTask = () => {
}); });
}, [selectedProject]); }, [selectedProject]);
// Memoized filtering
const filteredTasks = useMemo(() => { const filteredTasks = useMemo(() => {
if (!TaskList) return []; if (!TaskList) return [];
return TaskList.filter((task) => { return TaskList.filter((task) => {
@ -69,7 +74,6 @@ const DailyTask = () => {
}); });
}, [TaskList, filters]); }, [TaskList, filters]);
// Memoized dates
const groupedTasks = useMemo(() => { const groupedTasks = useMemo(() => {
const groups = {}; const groups = {};
filteredTasks.forEach((task) => { filteredTasks.forEach((task) => {
@ -82,13 +86,11 @@ const DailyTask = () => {
.map((date) => ({ date, tasks: groups[date] })); .map((date) => ({ date, tasks: groups[date] }));
}, [filteredTasks]); }, [filteredTasks]);
// --- Modal State
const [modal, setModal] = useState({ type: null, data: null }); const [modal, setModal] = useState({ type: null, data: null });
const openModal = (type, data = null) => setModal({ type, data }); const openModal = (type, data = null) => setModal({ type, data });
const closeModal = () => setModal({ type: null, data: null }); const closeModal = () => setModal({ type: null, data: null });
// --- Render helpers
const renderTeamMembers = (task, refIndex) => ( const renderTeamMembers = (task, refIndex) => (
<div <div
key={refIndex} key={refIndex}
@ -133,7 +135,6 @@ const DailyTask = () => {
return ( return (
<> <>
{/* --- Modals --- */}
{modal.type === "report" && ( {modal.type === "report" && (
<GlobalModel isOpen size="md" closeModal={closeModal}> <GlobalModel isOpen size="md" closeModal={closeModal}>
<ReportTask report={modal.data} closeModal={closeModal} /> <ReportTask report={modal.data} closeModal={closeModal} />
@ -161,12 +162,54 @@ const DailyTask = () => {
<div className="container-fluid"> <div className="container-fluid">
<Breadcrumb data={[{ label: "Home", link: "/dashboard" }, { label: "Daily Progress Report" }]} /> <Breadcrumb data={[{ label: "Home", link: "/dashboard" }, { label: "Daily Progress Report" }]} />
<div className="card card-action mb-6"> <div className="card card-action mb-6 p-5">
<div className="card-body p-1 p-sm-2"> <div className="card-body p-1 p-sm-2">
{!selectedProject && (<div className="text-center text-muted">Please Select Project</div>)} {!selectedProject && (<div className="text-center text-muted">Please Select Project</div>)}
{/* --- Filters --- */}
<div className="d-flex align-items-center mb-2"> <div className="d-flex align-items-center justify-content-between mb-2">
<DateRangePicker onRangeChange={setDateRange} endDateMode="today" DateDifference="6" dateFormat="DD-MM-YYYY" />
{/* --- Left: Service Dropdown + Filter Icon --- */}
<div className="d-flex align-items-center gap-6">
<div className="me-3">
{servicesLoading ? (
<span></span>
) : assignedServices?.length > 1 ? (
<select
name="serviceSelect"
className="form-select form-select-sm"
value={selectedService}
onChange={handleServiceChange}
style={{ fontSize: "0.875rem", height: "32px", minWidth: "190px" }}
>
{assignedServices.map((service) => (
<option key={service.id} value={service.id}>
{service.name}
</option>
))}
</select>
) : (
<div
className="ms-4 mt-2"
>
{assignedServices?.length === 1
? <h5>{assignedServices[0].name}</h5>
: "No service available"}
</div>
)}
</div>
{/* <FilterIcon
taskListData={TaskList}
onApplyFilters={setFilters}
currentSelectedBuilding={filters.selectedBuilding}
currentSelectedFloors={filters.selectedFloors}
currentSelectedActivities={filters.selectedActivities}
selectedProject={selectedProject}
/> */}
</div>
{/* --- Right: DateRangePicker --- */}
<div className="d-flex justify-content-end align-items-center gap-3 me-3">
<FilterIcon <FilterIcon
taskListData={TaskList} taskListData={TaskList}
onApplyFilters={setFilters} onApplyFilters={setFilters}
@ -175,8 +218,15 @@ const DailyTask = () => {
currentSelectedActivities={filters.selectedActivities} currentSelectedActivities={filters.selectedActivities}
selectedProject={selectedProject} selectedProject={selectedProject}
/> />
<DateRangePicker
onRangeChange={setDateRange}
endDateMode="today"
DateDifference="6"
dateFormat="DD-MM-YYYY"
/>
</div> </div>
</div>
{/* --- Table --- */} {/* --- Table --- */}
<div className="table-responsive text-nowrap mt-3" style={{ minHeight: "200px" }}> <div className="table-responsive text-nowrap mt-3" style={{ minHeight: "200px" }}>
<table className="table"> <table className="table">

View File

@ -1,22 +1,31 @@
import React,{useEffect,useRef} from "react"; import React, { useEffect, useState } from "react";
import Breadcrumb from "../../components/common/Breadcrumb"; import Breadcrumb from "../../components/common/Breadcrumb";
import InfraPlanning from "../../components/Activities/InfraPlanning"; import InfraPlanning from "../../components/Activities/InfraPlanning";
import { useProjectName } from "../../hooks/useProjects"; import { useProjectName } from "../../hooks/useProjects";
import { useDispatch, useSelector } from "react-redux"; import { useDispatch } from "react-redux";
import { setProjectId } from "../../slices/localVariablesSlice"; import { setProjectId } from "../../slices/localVariablesSlice";
import { useSelectedProject } from "../../slices/apiDataManager"; import { useSelectedProject } from "../../slices/apiDataManager";
import { useProjectAssignedServices } from "../../hooks/useProjects";
const TaskPlannng = () => { const TaskPlannng = () => {
const selectedProject = useSelectedProject(); const selectedProject = useSelectedProject();
const dispatch = useDispatch(); const dispatch = useDispatch();
const { projectNames = [], loading: projectLoading } = useProjectName(); const { projectNames = [], loading: projectLoading } = useProjectName();
useEffect(() => { // Service dropdown state
if (!selectedProject) { const { data: assignedServices, isLoading: servicesLoading } =
useProjectAssignedServices(selectedProject);
const [selectedService, setSelectedService] = useState("");
useEffect(() => {
if (!selectedProject && projectNames?.length > 0) {
dispatch(setProjectId(projectNames[0]?.id)); dispatch(setProjectId(projectNames[0]?.id));
} }
}, [projectNames, selectedProject?.id, dispatch]); }, [projectNames, selectedProject, dispatch]);
const handleServiceChange = (e) => {
setSelectedService(e.target.value);
};
return ( return (
<div className="container-fluid"> <div className="container-fluid">
@ -26,12 +35,46 @@ useEffect(() => {
{ label: "Daily Task Planning" }, { label: "Daily Task Planning" },
]} ]}
/> />
<div className="card">
<div className="card-body">
{/* Service Dropdown */}
<div className="mb-1 ms-2">
{assignedServices?.length > 1 ? (
<select
id="serviceSelect"
className="form-select"
value={selectedService}
onChange={handleServiceChange}
style={{ fontSize: "0.875rem", height: "35px", width: "190px" }}
>
{assignedServices.map((service) => (
<option key={service.id} value={service.id}>
{service.name}
</option>
))}
</select>
) : (
<div
className="text-start"
>
{assignedServices?.length === 1
? <h5>{ assignedServices[0].name}</h5>
: "No service available"}
</div>
)}
</div>
{/* Infra Planning Component */}
{selectedProject ? ( {selectedProject ? (
<InfraPlanning /> <InfraPlanning selectedService={selectedService} />
) : ( ) : (
<div className="text-center">Please Select Project</div> <div className="text-center">Please Select Project</div>
)} )}
</div> </div>
</div>
</div>
); );
}; };