206 lines
6.5 KiB
JavaScript
206 lines
6.5 KiB
JavaScript
import React, { useState, useEffect } from "react";
|
|
import { formatDate } from "../../utils/dateUtils";
|
|
import { useForm } from "react-hook-form";
|
|
import { zodResolver } from "@hookform/resolvers/zod";
|
|
import { z } from "zod";
|
|
import showToast from "../../services/toastService";
|
|
import { TasksRepository } from "../../repositories/TaskRepository";
|
|
import { useReportTask } from "../../hooks/useTasks";
|
|
|
|
export const ReportTask = ({ report, closeModal }) => {
|
|
const { mutate: reportTask, isPending } = useReportTask({
|
|
onSuccessCallback: () => {
|
|
reset();
|
|
closeModal();
|
|
},
|
|
});
|
|
|
|
const maxPending =
|
|
report?.workItem?.plannedWork - report?.workItem?.completedWork;
|
|
|
|
const schema = z.object({
|
|
completedTask: 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(maxPending, {
|
|
message: `Completed task cannot exceed total pending tasks: ${maxPending}`,
|
|
})
|
|
),
|
|
comment: z.string().min(1, "Comment cannot be empty"),
|
|
});
|
|
|
|
const {
|
|
register,
|
|
handleSubmit,
|
|
formState: { errors },
|
|
reset,
|
|
} = useForm({
|
|
resolver: zodResolver(schema),
|
|
defaultValues: { completedTask: 0, comment: "" },
|
|
});
|
|
|
|
useEffect(() => {
|
|
if (report) {
|
|
reset({ completedTask: 0, comment: "" });
|
|
}
|
|
}, [report, reset]);
|
|
|
|
const onSubmit = (data) => {
|
|
|
|
const reportData = {
|
|
...data,
|
|
id: report?.id,
|
|
reportedDate: new Date().toISOString(),
|
|
checkList: [],
|
|
};
|
|
|
|
reportTask({
|
|
reportData,
|
|
workAreaId: report?.workItem?.workArea?.id,
|
|
buildingId: report?.workItem?.workArea?.floor?.building.id,
|
|
floorId: report?.workItem?.workArea?.floor?.id,
|
|
});
|
|
};
|
|
const handleClose = () => {
|
|
closeModal();
|
|
reset();
|
|
};
|
|
|
|
return (
|
|
<div className="container m-0">
|
|
<div className="text-center">
|
|
<p className="fs-6 fw-semibold">Report Task</p>
|
|
</div>
|
|
<div className="mb-1 row text-start">
|
|
<label htmlFor="html5-text-input" className="col-md-4 col-form-label">
|
|
Assigned Date :{" "}
|
|
</label>
|
|
<div className="col-md-8 text-start">
|
|
<label className="col-md-2 col-form-label">
|
|
{formatDate(report?.assignmentDate)}
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div className="mb-1 row text-start">
|
|
<label htmlFor="html5-search-input" className="col-md-4 col-form-label">
|
|
Assigned By :{" "}
|
|
</label>
|
|
<div className="col-md-8 text-start">
|
|
<label className=" col-form-label">{` ${report?.assignedBy.firstName} ${report?.assignedBy.lastName}`}</label>
|
|
</div>
|
|
</div>
|
|
<div className="mb-1 row text-start">
|
|
<label htmlFor="html5-email-input" className="col-md-4 col-form-label">
|
|
Wrok Area :
|
|
</label>
|
|
<div className="col-md-8 text-start text-wrap">
|
|
<label className=" col-form-label">
|
|
{" "}
|
|
{report?.workItem?.workArea?.floor?.building?.name}{" "}
|
|
<i className="bx bx-chevron-right"></i>{" "}
|
|
{report?.workItem?.workArea?.floor?.floorName}{" "}
|
|
<i className="bx bx-chevron-right"> </i>
|
|
{report?.workItem?.workArea?.areaName}
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div className="mb-1 row text-start">
|
|
<label htmlFor="html5-email-input" className="col-md-4 col-form-label">
|
|
Activity :
|
|
</label>
|
|
<div className="col-md-8 text-start text-wrap">
|
|
<label className=" col-form-label">
|
|
{report?.workItem?.activityMaster.activityName}
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div className="mb-1 row text-start">
|
|
<label htmlFor="html5-email-input" className="col-md-4 col-form-label">
|
|
Team Size :
|
|
</label>
|
|
<div className="col-md-8 text-start text-wrap">
|
|
<label className=" col-form-label">
|
|
{report?.teamMembers?.length}
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div className="mb-1 row text-start">
|
|
<label htmlFor="html5-email-input" className="col-md-4 col-form-label">
|
|
Assigned :
|
|
</label>
|
|
<div className="col-md-8 text-start text-wrap">
|
|
<label className=" col-form-label">
|
|
{report?.plannedTask} of{" "}
|
|
{report?.workItem.plannedWork - report?.workItem.completedWork}{" "}
|
|
Pending
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<form onSubmit={handleSubmit(onSubmit)}>
|
|
<div className="mb-1 row text-start">
|
|
<label
|
|
htmlFor="html5-email-input"
|
|
className="col-md-4 col-form-label"
|
|
>
|
|
Completed Work
|
|
</label>
|
|
<div className="col-md-8 text-start text-wrap">
|
|
<input
|
|
{...register("completedTask", { valueAsNumber: true })}
|
|
id="smallInput"
|
|
className="form-control form-control-sm"
|
|
type="number"
|
|
placeholder="Completed Work"
|
|
/>
|
|
{errors.completedTask && (
|
|
<div className="danger-text">{errors.completedTask.message}</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
<div className="mb-1 row text-start">
|
|
<label
|
|
htmlFor="html5-email-input"
|
|
className="col-md-4 col-form-label"
|
|
>
|
|
Comment
|
|
</label>
|
|
<div className="col-md-8 text-start text-wrap">
|
|
<textarea
|
|
{...register("comment")}
|
|
className="form-control"
|
|
id="exampleFormControlTextarea1"
|
|
rows="1"
|
|
placeholder="Enter comment"
|
|
/>
|
|
{errors.comment && (
|
|
<div className="danger-text">{errors.comment.message}</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
<div className="col-12 text-end my-2 mt-4">
|
|
<button
|
|
type="button"
|
|
className="btn btn-sm btn-label-secondary me-3"
|
|
onClick={handleClose}
|
|
disabled={isPending}
|
|
>
|
|
Cancel
|
|
</button>
|
|
<button type="submit" className="btn btn-sm btn-primary" disabled={isPending}>
|
|
{isPending ? "Please wait" : "Submit Report"}
|
|
</button>
|
|
|
|
</div>
|
|
</form>
|
|
</div>
|
|
);
|
|
};
|
|
export default ReportTask; |