added logic for audit activity as well as comment

This commit is contained in:
Pramod Mahajan 2025-06-16 19:41:35 +05:30
parent e1037c8322
commit 407680fa9b

View File

@ -9,28 +9,48 @@ import Avatar from "../common/Avatar";
import { getBgClassFromHash } from "../../utils/projectStatus";
import { cacheData, getCachedData } from "../../slices/apiDataManager";
import ImagePreview from "../common/ImagePreview";
import { useAuditStatus } from "../../hooks/useTasks";
const schema = z.object({
comment: z.string().min(1, "Comment cannot be empty"),
});
const ReportTaskComments = ({
commentsData,
closeModal,
actionAllow = false,
}) => {
const schema = actionAllow
? z.object({
comment: z.string().min(1, "Comment cannot be empty"),
workStatus: z.string().nonempty({ message: "Audit status is required" }).default(''),
approvedTask: z.preprocess(
(val) =>
val === "" || val === null || Number.isNaN(val)
? undefined
: Number(val),
z
.number({
required_error: "Completed Work must be a number",
invalid_type_error: "Completed Work must be a number",
})
.min(0, "Completed Work must be greater than 0")
.max(commentsData?.completedTask, {
message: `Completed task cannot exceed : ${commentsData?.completedTask}`,
})
),
})
: z.object({
comment: z.string().min(1, "Comment cannot be empty"),
});
/**
* ReportTaskComments component for displaying and adding comments to a task.
* It also shows a summary of the activity and task details.
*
* @param {object} props - The component props.
* @param {object} props.commentsData - Data related to the task and its comments, including the description.
* @param {function} props.closeModal - Callback function to close the modal.
*/
const ReportTaskComments = ({ commentsData, closeModal }) => {
const [loading, setloading] = useState(false);
const [comments, setComment] = useState([]);
const { status, loading: auditStatusLoading } = useAuditStatus();
const {
watch,
register,
handleSubmit,
setValue,
formState: { errors },
reset, // Destructure reset from useForm
reset,
} = useForm({
resolver: zodResolver(schema),
});
@ -64,14 +84,18 @@ const ReportTaskComments = ({ commentsData, closeModal }) => {
}, [comments]);
const onSubmit = async (data) => {
let sendComment = {
let payload = {
...data,
taskAllocationId: commentsData?.id,
commentDate: new Date().toISOString(),
[actionAllow ? "id" : "taskAllocationId"]: commentsData?.id,
...(actionAllow ? {} : { commentDate: new Date().toISOString() }),
};
try {
setloading(true);
const resp = await TasksRepository.taskComments(sendComment);
const resp = actionAllow
? await TasksRepository.auditTask(payload)
: await TasksRepository.taskComments(payload);
setComment((prevItems) => [...prevItems, resp.data]);
@ -108,12 +132,15 @@ const ReportTaskComments = ({ commentsData, closeModal }) => {
);
}
};
const selectedAuditStatus = watch("workStatus");
return (
<div className="p-1">
<div className="p-2 p-sm-1">
<div className="modal-body p-sm-4 p-0">
<h5 className=" text-center mb-2">Activity Summary</h5>
<p className="fw-bold my-2 text-start">
<i className="bx bx-map me-2 bx-sm"></i>
Location :
<span className="fw-normal ms-2 text-start">
{`${commentsData?.workItem?.workArea?.floor?.building?.name}`}{" "}
@ -127,6 +154,7 @@ const ReportTaskComments = ({ commentsData, closeModal }) => {
</p>
<p className="fw-bold my-2 text-start">
<i className="bx bx-user me-2 bx-sm"></i>
Assigned By :
<span className=" ms-2">
{commentsData?.assignedBy?.firstName +
@ -136,23 +164,19 @@ const ReportTaskComments = ({ commentsData, closeModal }) => {
</p>
<p className="fw-bold my-2 text-start">
Reported By :
<span className=" ms-2">
{" "}
-
{/* {commentsData?.assignedBy?.firstName +
" " +
commentsData?.assignedBy?.lastName} */}
</span>{" "}
<i className="bx bx-user-check bx-lg me-1"></i>
Reported By :<span className=" ms-2">-</span>
</p>
<p className="fw-bold my-2 text-start">
{" "}
<i className="fa fa-tasks fs-6 me-3"></i>
Planned Work: {commentsData?.plannedTask}{" "}
{commentsData?.workItem?.activityMaster?.unitOfMeasurement}
</p>
{commentsData?.reportedDate != null && (
<p className="fw-bold my-2 text-start">
{" "}
<i className="bx bx-task me-2"></i>
Completed Work : {commentsData?.completedTask}{" "}
{commentsData?.workItem?.activityMaster?.unitOfMeasurement}
</p>
@ -161,7 +185,9 @@ const ReportTaskComments = ({ commentsData, closeModal }) => {
<p className="fw-bold my-2 text-start"> Completed Work : &nbsp;-</p>
)}
<div className="d-flex align-items-center flex-wrap">
<p className="fw-bold text-start m-0 me-1">Team :</p>
<p className="fw-bold text-start m-0 me-1">
<i className="fa-solid me-2 fs-6 fa-users-gear"></i>Team :
</p>
<div className="d-flex flex-wrap align-items-center gap-2">
{commentsData?.teamMembers?.map((member, idx) => (
<span key={idx} className="d-flex align-items-center">
@ -176,7 +202,9 @@ const ReportTaskComments = ({ commentsData, closeModal }) => {
</div>
</div>
<div className="fw-bold my-2 text-start d-flex">
<span>Note:</span>
<span>
<i className="fa-solid fa-note-sticky me-3 fs-6"></i>Note:
</span>
<div
className="fw-normal ms-2"
dangerouslySetInnerHTML={{ __html: commentsData?.description }}
@ -184,15 +212,71 @@ const ReportTaskComments = ({ commentsData, closeModal }) => {
</div>
{commentsData?.reportedPreSignedUrls?.length > 0 && (
<div className=" text-start">
<p className="fw-bold m-0">Attachment</p>
<ImagePreview
IsReported={true}
images={commentsData?.reportedPreSignedUrls}
/>
</div>
<>
<p className="fw-bold m-0 text-start">
<i className="fa-solid fs-6 fa-paperclip me-3"></i>Attachment :
</p>
<div className=" text-start ms-3">
<ImagePreview
IsReported={true}
images={commentsData?.reportedPreSignedUrls}
/>
</div>
</>
)}
<form onSubmit={handleSubmit(onSubmit)} className="text-start">
{/* Taking Action Reported Task */}
{actionAllow && (
<div className="row align-items-end my-1">
<div className="col-6 col-sm-4 text-start">
<label>Completed</label>
<input
className="form-control form-control-sm"
{...register("approvedTask")}
type="number"
/>
{errors.approvedTask && (
<p className="danger-text m-0">
{errors.approvedTask.message}
</p>
)}
</div>
<div className="col-6 col-sm-8 text-end align-items-end m-0">
<div class="btn-group dropdown">
<button
type="button"
className="btn btn-sm btn-primary dropdown-toggle"
data-bs-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
>
{selectedAuditStatus
? status.find((s) => s.id === selectedAuditStatus)?.name
: "Select Status"}
</button>
<ul className="dropdown-menu">
{auditStatusLoading && (
<li className="dropdown-item">Loading...</li>
)}
{status.map((stat) => (
<li key={stat.id} className="py-1 cursor-pointer">
<a
className="dropdown-item py-1"
onClick={() => setValue("workStatus", stat.id)}
>
{stat.name}
</a>
</li>
))}
</ul>
</div>
{errors.workStatus && ( <p className="m-0 danger-text">{ errors.workStatus.message}</p>)}
</div>
</div>
)}
<i className="bx bx-comment-detail me-2"></i>
<label className="fw-bold text-start my-1">Add comment :</label>
<textarea
{...register("comment")}
@ -203,7 +287,7 @@ const ReportTaskComments = ({ commentsData, closeModal }) => {
{errors.comment && (
<div className="danger-text">{errors.comment.message}</div>
)}
<div className="text-end my-1">
<div className="text-end mt-2">
<button
type="button"
className="btn btn-sm btn-secondary"
@ -217,7 +301,13 @@ const ReportTaskComments = ({ commentsData, closeModal }) => {
className="btn btn-sm btn-primary ms-2"
disabled={loading}
>
{loading ? "Sending..." : "Comment"}
{loading
? actionAllow
? "Please Wait..."
: "Send..."
: actionAllow
? "Submit"
: "Comment"}
</button>
</div>
</form>
@ -254,7 +344,7 @@ const ReportTaskComments = ({ commentsData, closeModal }) => {
<div
className={`d-flex align-items-center justify-content-start`}
>
<p className={`mb-0 text-muted me-2`}>{fullName}</p>
<p className={`mb-0 fw-semibold me-2`}>{fullName}</p>
<p
className={`text-secondary m-0`}
style={{ fontSize: "10px" }}
@ -263,11 +353,11 @@ const ReportTaskComments = ({ commentsData, closeModal }) => {
</p>
</div>
</div>
<p className={`ms-6 text-start mb-0 text-body`}>
<p className={`ms-7 text-start mb-0 text-body`}>
{data?.comment}
</p>
{data?.preSignedUrls?.length > 0 && (
<div className="ps-6 text-start">
<div className="ps-7 text-start ">
<small className="">Attachment</small>
<ImagePreview
images={data?.preSignedUrls}