184 lines
5.0 KiB
JavaScript
184 lines
5.0 KiB
JavaScript
import React, { useEffect, useMemo } from "react";
|
|
import { useForm } from "react-hook-form";
|
|
import { z } from "zod";
|
|
import { zodResolver } from "@hookform/resolvers/zod";
|
|
import { useSelector } from "react-redux";
|
|
import { getCachedData } from "../../../slices/apiDataManager";
|
|
import showToast from "../../../services/toastService";
|
|
import { useManageProjectInfra } from "../../../hooks/useProjects";
|
|
import useSelect from "../../common/useSelect";
|
|
import Label from "../../common/Label";
|
|
|
|
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, editingBuilding = null }) => {
|
|
const selectedProject = useSelector(
|
|
(store) => store.localVariables.projectId
|
|
);
|
|
const {
|
|
register,
|
|
handleSubmit,
|
|
formState: { errors },
|
|
setValue,
|
|
watch,
|
|
reset,
|
|
} = useForm({
|
|
resolver: zodResolver(buildingSchema),
|
|
defaultValues: {
|
|
Id: "0",
|
|
name: "",
|
|
description: "",
|
|
},
|
|
});
|
|
const watchedId = watch("Id");
|
|
|
|
const { mutate: ManageBuilding, isPending } = useManageProjectInfra({
|
|
onSuccessCallback: (data, variables) => {
|
|
showToast(
|
|
watchedId != "0"
|
|
? "Building updated Successfully"
|
|
: "Building created Successfully",
|
|
"success"
|
|
);
|
|
reset({ Id: "0", name: "", description: "" });
|
|
// onClose?.();
|
|
},
|
|
});
|
|
|
|
const sortedBuildings = useMemo(() => {
|
|
return (project || [])
|
|
.filter((b) => b?.buildingName)
|
|
.sort((a, b) => a.buildingName.localeCompare(b?.buildingName));
|
|
}, [project]);
|
|
|
|
useEffect(() => {
|
|
if (!watchedId || watchedId === "0") {
|
|
setValue("name", "");
|
|
setValue("description", "");
|
|
} else {
|
|
const selected = sortedBuildings.find((b) => String(b.id) === watchedId);
|
|
if (selected) {
|
|
setValue("name", selected.buildingName || "");
|
|
setValue("description", selected.description || "");
|
|
}
|
|
}
|
|
}, [watchedId, sortedBuildings, setValue]);
|
|
|
|
useEffect(() => {
|
|
if (editingBuilding) {
|
|
reset({
|
|
Id: String(editingBuilding.id),
|
|
name: editingBuilding.name,
|
|
description: editingBuilding.description,
|
|
});
|
|
}
|
|
}, [editingBuilding]);
|
|
|
|
const onSubmitHandler = (data) => {
|
|
const payload = {
|
|
...data,
|
|
Id: data.Id === "0" ? null : data.Id,
|
|
projectId: selectedProject,
|
|
};
|
|
|
|
let infraObject = [
|
|
{
|
|
building: payload,
|
|
floor: null,
|
|
workArea: null,
|
|
},
|
|
];
|
|
ManageBuilding({ infraObject, projectId: selectedProject });
|
|
};
|
|
|
|
return (
|
|
<form onSubmit={handleSubmit(onSubmitHandler)} className="row g-2">
|
|
<h5 className="text-center mb-2">Manage Buildings</h5>
|
|
<div className="col-12 text-start">
|
|
<label className="form-label">Select Building</label>
|
|
<select
|
|
{...register("Id")}
|
|
className="select2 form-select form-select-sm"
|
|
>
|
|
<option value="0">Add New Building</option>
|
|
{sortedBuildings.length > 0 ? (
|
|
sortedBuildings.map((b) => (
|
|
<option key={b.id} value={b.id}>
|
|
{b.buildingName}
|
|
</option>
|
|
))
|
|
) : (
|
|
<option disabled>No buildings found</option>
|
|
)}
|
|
</select>
|
|
{errors.Id && <span className="danger-text">{errors.Id.message}</span>}
|
|
</div>
|
|
|
|
{/* Name */}
|
|
<div className="col-12 text-start">
|
|
<Label className="form-label" required>
|
|
{watchedId !== "0" ? "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>
|
|
|
|
{/* Description */}
|
|
<div className="col-12 text-start">
|
|
<Label className="form-label" required>Description</Label>
|
|
<textarea
|
|
{...register("description")}
|
|
rows="5"
|
|
maxLength="160"
|
|
className="form-control form-control-sm"
|
|
/>
|
|
{errors.description && (
|
|
<span className="danger-text">{errors.description.message}</span>
|
|
)}
|
|
</div>
|
|
|
|
<div className="col-12 text-end mt-6 my-2">
|
|
<button
|
|
type="reset"
|
|
className="btn btn-sm btn-label-secondary me-3"
|
|
disabled={isPending}
|
|
onClick={() => {
|
|
onClose();
|
|
reset();
|
|
}}
|
|
>
|
|
Cancel
|
|
</button>
|
|
<button
|
|
type="submit"
|
|
className="btn btn-sm btn-primary"
|
|
disabled={isPending}
|
|
>
|
|
{isPending
|
|
? "Please wait..."
|
|
: watchedId !== "0"
|
|
? "Edit Building"
|
|
: "Add Building"}
|
|
</button>
|
|
|
|
|
|
</div>
|
|
</form>
|
|
);
|
|
};
|
|
|
|
export default BuildingModel;
|