refactor: streamline modal handling and improve floor management functionality

This commit is contained in:
Vaibhav Surve 2025-04-07 17:02:15 +05:30 committed by Vikas Nale
parent 6c0b92606a
commit c595930640
3 changed files with 172 additions and 92 deletions

View File

@ -106,12 +106,7 @@ const FloorModel = ({
<div className="modal-content">
<div className="modal-body">
<div className="row">
<button
type="button"
className="btn-close"
data-bs-dismiss="modal"
aria-label="Close"
></button>
<button type="button" className="btn-close" aria-label="Close" onClick={onClose}/>
<div className="text-center mb-1">
<h5 className="mb-1">Manage Floors - {project.name}</h5>
</div>
@ -155,7 +150,7 @@ const FloorModel = ({
onChange={handleFloorChange}
>
<option value="0">Add New Floor</option>
{selectedBuilding.floors.map((floor) => (
{selectedBuilding?.floors?.map((floor) => (
<option key={floor.id} value={floor.id}>
{floor.floorName}
</option>
@ -192,10 +187,9 @@ const FloorModel = ({
: "Add Floor"}
</button>
<button
type="reset"
type="button"
className="btn btn-label-secondary"
data-bs-dismiss="modal"
aria-label="Close"
onClick={onClose}
>
Cancel
</button>

View File

@ -1,69 +1,154 @@
import {useEffect, useState} from "react";
import { useEffect, useState } from "react";
import Building from "./Building";
import Floor from "./Floor";
import FloorModel from "./FloorModel";
import showToast from "../../../services/toastService";
import ProjectRepository from "../../../repositories/ProjectRepository";
const InfraTable = ( {buildings,assign} ) =>
{
const [projectBuiling,setProjectBuilding] = useState([])
const [expandedBuildings, setExpandedBuildings] = useState([]);
const toggleBuilding = (buildingId) => {
setExpandedBuildings((prevExpanded) =>
prevExpanded.includes(buildingId)
? prevExpanded.filter((id) => id !== buildingId)
: [...prevExpanded, buildingId]
);
};
const InfraTable = ({ buildings }) => {
const [projectBuilding, setProjectBuilding] = useState([]);
const [expandedBuildings, setExpandedBuildings] = useState([]);
const [showFloorModal, setShowFloorModal] = useState(false);
const [selectedBuilding, setSelectedBuilding] = useState(null);
const [clearTrigger, setClearTrigger] = useState(false);
const getContent = (building) => {
return building.floors.length > 0 ? (
building.floors.map((floor) => <Floor forBuilding={building} key={floor.id} floor={floor} workAreas={floor.workAreas} />)
) : (
<tr>
<td colSpan="4">
<div className="alert alert-warning text-center mb-0" role="alert">
<p>No floors have been added yet. Please add floors to start managing your building.</p>
<button
type="button"
className="btn btn-xs btn-primary"
data-bs-toggle="modal"
data-bs-target="#addFloorModal"
onClick={() => openModal('addFloor')}
>
<i className="bx bx-plus-circle me-2"></i>
Add Floors
</button>
</div>
</td>
</tr>
);
};
useEffect( () =>
{
setProjectBuilding(buildings)
},[buildings])
return (
<div className="col-12 overflow-auto">
{projectBuiling && projectBuiling.length > 0 && (
<table className="table table-bordered">
<tbody>
{projectBuiling.map((building) => (
<Building
key={building.id}
building={building}
toggleBuilding={toggleBuilding}
expandedBuildings={expandedBuildings}
getContent={getContent}
/>
))}
</tbody>
</table>
)}
</div>
const toggleBuilding = (buildingId) => {
setExpandedBuildings((prevExpanded) =>
prevExpanded.includes(buildingId)
? prevExpanded.filter((id) => id !== buildingId)
: [...prevExpanded, buildingId]
);
};
export default InfraTable
const handleAddFloor = (building) => {
setSelectedBuilding(building);
setShowFloorModal(true);
};
const handleFloorSubmit = async (data) => {
try {
const payload = [
{
building: null,
floor: {
id: data.id || "0",
floorName: data.floorName,
buildingId: data.buildingId,
},
workArea: null,
},
];
const res = await ProjectRepository.manageProjectInfra(payload);
if (res?.success) {
showToast("Floor saved successfully!", "success");
// Find and update the correct building
const updatedBuildings = projectBuilding.map((b) => {
if (b.id === parseInt(data.buildingId)) {
const newFloor = {
id: res.data?.[0]?.floor?.id || Math.random(),
floorName: res.data?.[0]?.floor?.floorName || data.floorName,
workAreas: [],
};
return {
...b,
floors: [...(b.floors || []), newFloor],
};
}
return b;
});
setProjectBuilding(updatedBuildings);
setShowFloorModal(false);
setClearTrigger(true);
} else {
showToast("Failed to save floor", "error");
}
} catch (err) {
console.error("Error adding floor", err);
showToast("Error occurred while saving floor", "error");
}
};
const handleClearComplete = () => {
setClearTrigger(false);
};
const getContent = (building) => {
return building.floors?.length > 0 ? (
building.floors.map((floor) => (
<Floor
key={floor.id}
forBuilding={building}
floor={floor}
workAreas={floor.workAreas}
/>
))
) : (
<tr>
<td colSpan="4">
<div className="alert alert-warning text-center mb-0" role="alert">
<p>No floors have been added yet. Please add floors to start managing your building.</p>
<button
type="button"
className="btn btn-xs btn-primary"
onClick={() => handleAddFloor(building)}
>
<i className="bx bx-plus-circle me-2"></i>
Add Floors
</button>
</div>
</td>
</tr>
);
};
useEffect(() => {
setProjectBuilding(buildings);
}, [buildings]);
return (
<div >
{projectBuilding && projectBuilding.length > 0 && (
<table className="table table-bordered">
<tbody>
{projectBuilding.map((building) => (
<Building
key={building.id}
building={building}
toggleBuilding={toggleBuilding}
expandedBuildings={expandedBuildings}
getContent={getContent}
/>
))}
</tbody>
</table>
)}
{showFloorModal && selectedBuilding && (
<div
className="modal fade show"
id="floor-model"
tabIndex="-1"
style={{ display: "block" }}
aria-modal="true"
role="dialog"
>
<FloorModel
project={{
buildings: [selectedBuilding]
}}
onClose={() => setShowFloorModal(false)}
onSubmit={handleFloorSubmit}
onClearComplete={handleClearComplete}
/>
</div>
)}
</div>
);
};
export default InfraTable;

View File

@ -312,12 +312,12 @@ const ProjectInfra = ({ data, activityMaster, onDataChange,eachSiteEngineer }) =
}
const openModal = () => {
const modalElement = document.getElementById('building-model');
const modal = new Modal(modalElement, {
backdrop: false,
keyboard: true,
focus: true
});
modal.show()
const modal = new Modal(modalElement, {
backdrop: false,
keyboard: true,
focus: true
});
modal.show()
};
const closeModal = () => {
setIsModalOpen(false);
@ -364,10 +364,12 @@ const ProjectInfra = ({ data, activityMaster, onDataChange,eachSiteEngineer }) =
</div>
{isFloorModalOpen && (
<div
className={`modal fade `}
className="modal fade show"
id="floor-model"
tabIndex="-1"
aria-hidden="true"
role="dialog"
style={{ display: 'block' }}
aria-hidden="false"
>
<FloorModel
project={data}
@ -375,7 +377,7 @@ const ProjectInfra = ({ data, activityMaster, onDataChange,eachSiteEngineer }) =
onSubmit={handleFloorModelFormSubmit}
clearTrigger={clearFormTrigger}
onClearComplete={() => setClearFormTrigger(false)}
></FloorModel>
/>
</div>
)}
@ -437,15 +439,14 @@ const ProjectInfra = ({ data, activityMaster, onDataChange,eachSiteEngineer }) =
Manage Building
</button>
<button
type="button"
data-bs-toggle="modal"
className="link-button m-1"
data-bs-target="#floor-model"
onClick={() => openFloorModel()}
>
<i className="bx bx-plus-circle me-2"></i>
Manage Floors
</button>
type="button"
className="link-button m-1"
onClick={() => openFloorModel()}
>
<i className="bx bx-plus-circle me-2"></i>
Manage Floors
</button>
<button
type="button"
@ -470,7 +471,7 @@ const ProjectInfra = ({ data, activityMaster, onDataChange,eachSiteEngineer }) =
</div>
</div>
<div className="row ">
<InfraTable buildings={project.buildings}/>
<InfraTable buildings={project.buildings} project={data}/>
</div>
</div>
</div>