202 lines
6.2 KiB
JavaScript
202 lines
6.2 KiB
JavaScript
import React, { useState, useEffect } from "react";
|
|
import { useForm } from "react-hook-form";
|
|
import { z } from "zod";
|
|
import { zodResolver } from "@hookform/resolvers/zod";
|
|
import ProjectRepository from "../../../repositories/ProjectRepository";
|
|
import { useSelector } from "react-redux";
|
|
import { useProjectDetails } from "../../../hooks/useProjects";
|
|
import { getCachedData } from "../../../slices/apiDataManager";
|
|
import showToast from "../../../services/toastService";
|
|
|
|
// Zod validation schema
|
|
const buildingSchema = z.object({
|
|
Id: z.string().optional(),
|
|
name: z.string().min(1, "Building name is required"),
|
|
description: z
|
|
.string()
|
|
.min(1, "Description is required")
|
|
.max(160, "Description cannot exceed 160 characters"),
|
|
});
|
|
|
|
const BuildingModel = ({
|
|
project,
|
|
onClose,
|
|
onSubmit,
|
|
clearTrigger,
|
|
onClearComplete,
|
|
editingBuilding = null,
|
|
}) => {
|
|
const selectedProject = useSelector(
|
|
(store) => store.localVariables.projectId
|
|
);
|
|
const [buildings, setBuildings] = useState([]);
|
|
const projects_Details = getCachedData("projectInfo");
|
|
const [formData, setFormData] = useState({
|
|
id: "",
|
|
name: "",
|
|
description: "",
|
|
projectId: project?.id,
|
|
});
|
|
|
|
useEffect(() => {
|
|
if (clearTrigger) {
|
|
setFormData({ id: null, name: "", description: "", projectId: project.id });
|
|
onClearComplete();
|
|
} else if (editingBuilding) {
|
|
setFormData({ ...editingBuilding, projectId: project.id });
|
|
}
|
|
|
|
return () => {
|
|
setValue("name", null);
|
|
};
|
|
}, [clearTrigger, onClearComplete, editingBuilding, project?.id]);
|
|
|
|
const {
|
|
register,
|
|
handleSubmit,
|
|
formState: { errors },
|
|
setValue,
|
|
reset,
|
|
getValues,
|
|
} = useForm({
|
|
resolver: zodResolver(buildingSchema),
|
|
defaultValues: formData, // Set default values from formData state
|
|
});
|
|
|
|
const handleBuildingChange = (e) => {
|
|
const selectedBuilding = project.buildings.find(
|
|
(b) => b.id === +e.target.value
|
|
);
|
|
if (selectedBuilding) {
|
|
setFormData({ ...selectedBuilding, projectId: project.id });
|
|
setValue("name", selectedBuilding.name); // Update name field
|
|
setValue("description", selectedBuilding.description); // Update description field
|
|
} else {
|
|
setFormData({ id: null, name: "", description: "", projectId: project.id });
|
|
setValue("name", "");
|
|
setValue("description", "");
|
|
}
|
|
};
|
|
|
|
const onSubmitHandler = async (data) => {
|
|
if (String(data.Id) === "0") {
|
|
data.Id = null;
|
|
}
|
|
onSubmit({ ...data, projectId: project.id });
|
|
reset({
|
|
Id: "0",
|
|
name: "",
|
|
description: "",
|
|
});
|
|
if (data.Id !== null) {
|
|
showToast("Building updated successfully.", "success");
|
|
} else {
|
|
showToast("Building created successfully.", "success");
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
setBuildings(projects_Details.data?.buildings);
|
|
}, [projects_Details]);
|
|
return (
|
|
<div className="modal-dialog modal-lg modal-simple modal-edit-user">
|
|
<div className="modal-content">
|
|
<div className="modal-body">
|
|
<button
|
|
type="button"
|
|
className="btn-close"
|
|
data-bs-dismiss="modal"
|
|
aria-label="Close"
|
|
onClick={onClose}
|
|
></button>
|
|
<h5 className="text-center mb-2">
|
|
Manage Buildings - {project?.name}
|
|
</h5>
|
|
<form onSubmit={handleSubmit(onSubmitHandler)} className="row g-2">
|
|
<div className="col-12">
|
|
<label className="form-label">Select Building</label>
|
|
<select
|
|
{...register("Id")}
|
|
className="select2 form-select form-select-sm"
|
|
onChange={(e) => {
|
|
handleBuildingChange(e);
|
|
}}
|
|
>
|
|
<option value="0">Add New Building</option>
|
|
|
|
{project?.buildings?.length > 0 ? (
|
|
project.buildings
|
|
.filter((building) => building?.name)
|
|
.sort((a, b) => {
|
|
const nameA = a.name || "";
|
|
const nameB = b.name || "";
|
|
return nameA?.localeCompare(nameB);
|
|
})
|
|
.map((building) => (
|
|
<option key={building.id} value={building.id}>
|
|
{building.name}
|
|
</option>
|
|
))
|
|
) : (
|
|
<option disabled>No buildings found</option>
|
|
)}
|
|
</select>
|
|
{errors.Id && (
|
|
<span className="danger-text">{errors.Id.message}</span>
|
|
)}
|
|
</div>
|
|
|
|
<div className="col-12">
|
|
<label className="form-label">
|
|
{formData.id ? "Rename Building Name" : "New Building Name"}
|
|
</label>
|
|
<input
|
|
{...register("name")}
|
|
type="text"
|
|
className="form-control form-control-sm"
|
|
/>
|
|
{errors.name && (
|
|
<span className="danger-text">{errors.name.message}</span>
|
|
)}
|
|
</div>
|
|
|
|
<div className="col-12">
|
|
<label className="form-label">Description</label>
|
|
<textarea
|
|
{...register("description")}
|
|
maxLength="160"
|
|
rows="5"
|
|
className="form-control form-control-sm"
|
|
/>
|
|
{errors.description && (
|
|
<span className="danger-text">
|
|
{errors.description.message}
|
|
</span>
|
|
)}
|
|
</div>
|
|
|
|
<div className="col-12 text-center">
|
|
<button type="submit" className="btn btn-sm btn-primary me-3">
|
|
{formData.id && getValues("name")
|
|
? "Edit Building"
|
|
: "Add Building"}
|
|
</button>
|
|
<button
|
|
type="reset"
|
|
className="btn btn-sm btn-label-secondary"
|
|
data-bs-dismiss="modal"
|
|
aria-label="Close"
|
|
onClick={onClose}
|
|
>
|
|
Cancel
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default BuildingModel;
|