343 lines
11 KiB
JavaScript

import React, { useState, useEffect } from "react";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import { useActivitiesMaster } from "../../../hooks/masterHook/useMaster";
import { useProjectDetails } from "../../../hooks/useProjects";
import { useDispatch, useSelector } from "react-redux";
import ProjectRepository from "../../../repositories/ProjectRepository";
import {
cacheData,
clearCacheKey,
getCachedData,
} from "../../../slices/apiDataManager";
import { refreshData } from "../../../slices/localVariablesSlice";
import showToast from "../../../services/toastService";
const taskSchema = z
.object({
activityID: z.string().min(1, "Activity is required"),
plannedWork: z.number().min(1, "Planned Work must be greater than 0"),
completedWork: z.number().min(0, "Completed Work must be greater than 0"),
})
.refine(
(data) =>
data.completedWork === undefined ||
data.completedWork <= data.plannedWork,
{
message: "Completed Work cannot be greater than Planned Work",
path: ["completedWork"], // error will show next to this field
}
);
const EditActivityModal = ({
workItem,
workArea,
building,
floor,
onClose,
}) => {
const selectedProject = useSelector(
(store) => store.localVariables.projectId
);
const defaultModel = {
activityID: 0,
plannedWork: 0,
completedWork: 0,
};
const { projects_Details, refetch } = useProjectDetails(selectedProject);
const { activities, loading, error } = useActivitiesMaster();
const [formData, setFormData] = useState(defaultModel);
const [selectedActivity, setSelectedActivity] = useState(null);
const [isSubmitting, setIsSubmitting] = useState(false);
const [activityData, setActivityData] = useState([]);
const dispatch = useDispatch();
const {
register,
handleSubmit,
formState: { errors },
reset,
setValue,
getValues,
watch,
} = useForm({
resolver: zodResolver(taskSchema),
defaultValues: defaultModel,
});
const handleActivityChange = (e) => {
const selectedId = Number(e.target.value);
const selected = activityData.find((a) => a.id === selectedId);
setSelectedActivity(selected || null);
setValue("activityID", selectedId);
};
const onSubmitForm = async (data) => {
const updatedProject = { ...projects_Details };
const finalData = {
...data,
id: workItem?.workItem?.id ?? workItem?.id,
buildingID: building?.id,
floorId: floor?.id,
workAreaId: workArea?.id,
};
ProjectRepository.manageProjectTasks([finalData])
.then((response) => {
if (response?.data[0]) {
const { workItemId, workItem } = response.data[0];
let finalUpdatedWorkItem = null;
const newProject = {
...updatedProject,
buildings: updatedProject.buildings.map((building) =>
building.id === finalData.buildingID
? {
...building,
floors: building.floors.map((floor) =>
floor.id === finalData.floorId
? {
...floor,
workAreas: floor.workAreas.map((workArea) =>
workArea.id === workItem?.workAreaId
? {
...workArea,
workItems: (() => {
const exists = workArea.workItems.some(
(item) =>
String(
item?.workItem?.id ?? item?.id
) === String(finalData.id)
);
finalUpdatedWorkItem = workItem;
return exists
? workArea.workItems.map((item) =>
String(
item?.workItem?.id ?? item?.id
) === String(finalData.id)
? workItem
: item
)
: [...workArea.workItems, workItem];
})(),
}
: workArea
),
}
: floor
),
}
: building
),
};
cacheData("projectInfo", {
projectId: newProject.id,
data: newProject,
});
resetForm();
dispatch( refreshData( true ) );
showToast("Activity Updated Successfully","success")
onClose();
}
})
.catch((error) => {
showToast(error.message, "error");
});
};
const resetForm = () => {
setFormData(defaultModel);
setSelectedActivity(null);
reset(defaultModel);
};
useEffect(() => {
reset({
activityID: workItem?.workItem?.activityId || workItem?.activityId || 0,
plannedWork:
workItem?.workItem?.plannedWork || workItem?.plannedWork || 0,
completedWork:
workItem?.workItem?.completedWork || workItem?.completedWork || 0,
});
return () => reset();
}, [activities, workItem]);
const ISselectedActivity = watch("activityID");
useEffect(() => {
const selected = activities.find((a) => a.id === ISselectedActivity);
setSelectedActivity(selected || null);
}, [ISselectedActivity]);
return (
<div className="modal-dialog modal-lg modal-simple modal-edit-user">
<div className="modal-content">
<div className="modal-body">
<div className="row">
<button
type="button"
className="btn-close"
aria-label="Close"
onClick={onClose}
/>
<div className="text-center mb-1">
<h5 className="mb-1">Manage Task</h5>
</div>
<form className="row g-2" onSubmit={handleSubmit(onSubmitForm)}>
{/* Select Building */}
<div className="col-6 col-md-6">
<label className="form-label" htmlFor="buildingID">
Select Building
</label>
<input
type="text"
className="form-control form-control-sm"
value={building?.name}
disabled
/>
</div>
{/* Select Floor */}
<div className="col-6 col-md-6">
<label className="form-label" htmlFor="floorId">
Select Floor
</label>
<input
type="text"
className="form-control form-control-sm"
value={floor?.floorName}
disabled
/>
</div>
<div className="col-12 col-md-12">
<label className="form-label" htmlFor="workAreaId">
Select Work Area
</label>
<input
type="text"
className="form-control form-control-sm"
value={workArea?.areaName}
disabled
/>
</div>
{/* Select Activity */}
<div className="col-12 col-md-12">
<label className="form-label" htmlFor="activityID">
Select Activity
</label>
<select
id="activityID"
className="form-select form-select-sm"
{...register("activityID")}
>
{loading ? (
<option value="">Loading...</option>
) : (
<option disabled>Select Activity</option>
)}
{activities &&
activities.length > 0 &&
activities
.slice()
.sort((a, b) =>
(a.activityName || "").localeCompare(
b.activityName || ""
)
)
.map((activity) => (
<option key={activity.id} value={activity.id}>
{activity.activityName}
</option>
))}
{!loading && activityData.length === 0 && (
<option disabled>No activities available</option>
)}
</select>
{errors.activityID && (
<p className="danger-text">{errors.activityID.message}</p>
)}
</div>
{/* Planned Work */}
{/* {ISselectedActivity && ( */}
<div className="col-5 col-md-5">
<label className="form-label" htmlFor="plannedWork">
Planned Work
</label>
<input
{...register("plannedWork", { valueAsNumber: true })}
type="number"
className="form-control form-control-sm me-2"
placeholder="Planned Work"
/>
{errors.plannedWork && (
<p className="danger-text">{errors.plannedWork.message}</p>
)}
</div>
{/* )} */}
{/* Completed Work */}
{/* {ISselectedActivity && ( */}
<div className="col-5 col-md-5">
<label className="form-label" htmlFor="completedWork">
Completed Work
</label>
<input
{...register("completedWork", { valueAsNumber: true })}
type="number"
className="form-control form-control-sm me-2"
placeholder="Completed Work"
/>
{errors.completedWork && (
<p className="danger-text">{errors.completedWork.message}</p>
)}
</div>
{/* )} */}
{/* Unit */}
{/* {ISselectedActivity && ( */}
<div className="col-2 col-md-2">
<label className="form-label" htmlFor="unit">
Unit
</label>
<input
type="text"
disabled
className="form-control form-control-sm me-2"
value={selectedActivity?.unitOfMeasurement || ""}
/>
</div>
{/* )} */}
<div className="col-12 text-center">
<button type="submit" className="btn btn-sm btn-primary me-3">
{isSubmitting ? "Please Wait.." : "Edit Task"}
</button>
<button
type="button"
className="btn btn-sm btn-label-secondary"
onClick={onClose}
>
Cancel
</button>
</div>
</form>
</div>
</div>
</div>
</div>
);
};
export default EditActivityModal;