231 lines
7.2 KiB
JavaScript

import React, { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { string, z } from "zod";
import {
useActivitiesMaster,
useWorkCategoriesMaster,
} from "../../hooks/masterHook/useMaster";
import showToast from "../../services/toastService";
import ProjectRepository from "../../repositories/ProjectRepository";
import { useTaskById } from "../../hooks/useTasks";
const subTaskSchema = z.object({
activityId: z.string().min(1, "Activity is required"),
workCategoryId: z.string().min(1, "Category is required"),
plannedWork: z.number().min(1, "Planned work is required"),
completedWork: z.number().min(0, "Completed work cannot be negative"),
comment: z.string().min(1, "Comment is required"),
});
const SubTask = ({ activity, onClose }) => {
const [selectedCategory, setSelectedCategory] = useState(null);
const [categoryData, setCategoryData] = useState([]);
const { activities, loading } = useActivitiesMaster();
const { categories, categoryLoading } = useWorkCategoriesMaster();
const [isSubmitting, setIsSubmitting] = useState(false);
const { Task, loading: TaskLoading } = useTaskById(activity?.id);
const {
register,
handleSubmit,
formState: { errors },
reset,
setValue,
watch,
} = useForm({
resolver: zodResolver(subTaskSchema),
});
const selectedActivityId = watch("activityId");
const selectedActivity = activities?.find((a) => a.id === selectedActivityId);
// Set categories when fetched
useEffect(() => {
setCategoryData(categories);
}, [categories]);
// Set initial values from activity
useEffect(() => {
if (Task?.workItem) {
reset({
workCategoryId: Task?.workItem?.workCategoryId || "",
activityId: Task?.workItem?.activityId || "",
plannedWork: Number(Task.notApprovedTask || Task.workItem?.plannedWork),
completedWork: 0,
comment: "",
});
}
}, [Task, reset]);
const handleCategoryChange = (e) => {
const value = e.target.value;
const category = categoryData.find((b) => b.id === String(value));
setSelectedCategory(category);
setValue("workCategoryId", value);
};
const onSubmitForm = async (formData) => {
let payload = {
workAreaID: Task.workItem.workAreaId,
workCategoryId: formData.workCategoryId,
activityID: formData.activityId,
plannedWork: formData.plannedWork,
completedWork: formData.completedWork,
parentTaskId: activity?.id,
comment: formData.comment,
};
setIsSubmitting(true);
try {
await ProjectRepository.manageProjectTasks([payload]);
showToast("SubTask Created Successfully", "success");
setIsSubmitting(false);
reset();
onClose();
} catch (error) {
setIsSubmitting(false);
const msg =
error.response.message ||
error.message ||
"Error occured during API calling";
showToast(msg, "error");
}
};
return (
<div className="container-xxl my-1">
<p className="fw-semibold">Create Sub Task</p>
<form className="row g-2" onSubmit={handleSubmit(onSubmitForm)}>
<div className="col-6">
<label className="form-label">Building</label>
<input
type="text"
className="form-control form-control-sm"
value={activity?.workItem?.workArea?.floor?.building?.name || ""}
disabled
/>
</div>
<div className="col-6">
<label className="form-label">Floor</label>
<input
type="text"
className="form-control form-control-sm"
value={activity?.workItem?.workArea?.floor?.floorName || ""}
disabled
/>
</div>
<div className="col-12">
<label className="form-label">Work Area</label>
<input
type="text"
className="form-control form-control-sm"
value={activity?.workItem?.workArea?.areaName || ""}
disabled
/>
</div>
<div className="col-12">
<label className="form-label">Work Category</label>
<select
className="form-select form-select-sm"
{...register("workCategoryId")}
onChange={handleCategoryChange}
>
<option value="">-- Select Category --</option>
{categoryData.map((category) => (
<option key={category.id} value={category.id}>
{category.name}
</option>
))}
</select>
{errors.workCategoryId && (
<div className="danger-text">{errors.workCategoryId.message}</div>
)}
</div>
<div className="col-12">
<label className="form-label">Select Activity</label>
<select
className="form-select form-select-sm"
{...register("activityId")}
>
<option value="">
{categoryLoading ? "Loading..." : "--Select Activity--"}
</option>
{activities?.map((activity) => (
<option key={activity.id} value={activity.id}>
{activity.activityName}
</option>
))}
</select>
{errors.activityId && (
<div className="danger-text">{errors.activityId.message}</div>
)}
</div>
<div className="col-4">
<label className="form-label">Planned Work</label>
<input
type="number"
className="form-control form-control-sm"
{...register("plannedWork", { valueAsNumber: true })}
/>
{errors.plannedWork && (
<div className="danger-text">{errors.plannedWork.message}</div>
)}
</div>
<div className="col-4">
<label className="form-label">Completed Work</label>
<input
type="number"
className="form-control form-control-sm"
{...register("completedWork")}
/>
{errors.completedWork && (
<div className="danger-text">{errors.completedWork.message}</div>
)}
</div>
<div className="col-4">
<label className="form-label">Unit</label>
<input
type="text"
className="form-control form-control-sm"
value={selectedActivity?.unitOfMeasurement || ""}
disabled
/>
</div>
<div className="col-12">
<label className="form-label">Comment</label>
<textarea
className="form-control"
rows="2"
{...register("comment")}
/>
{errors.comment && (
<div className="danger-text">{errors.comment.message}</div>
)}
</div>
<div className="col-12 text-center">
<button type="submit" className="btn btn-sm btn-primary me-2">
{isSubmitting ? "Please wait..." : "Submit"}
</button>
<button
type="button"
className="btn btn-sm btn-secondary"
onClick={() => onClose()}
disabled={isSubmitting}
>
Cancel
</button>
</div>
</form>
</div>
);
};
export default SubTask;