272 lines
7.6 KiB
JavaScript

import React, { useEffect, useState } from "react";
import Breadcrumb from "../common/Breadcrumb";
import Label from "../common/Label";
import { zodResolver } from "@hookform/resolvers/zod";
import { defaultJobValue, jobSchema } from "./ServiceProjectSchema";
import {
useCreateServiceProjectJob,
useJobTags,
useServiceProjectJobDetails,
useServiceProjects,
useUpdateServiceProjectJob,
} from "../../hooks/useServiceProject";
import { ITEMS_PER_PAGE } from "../../utils/constants";
import DatePicker from "../common/DatePicker";
import PmsEmployeeInputTag from "../common/PmsEmployeeInputTag";
import TagInput from "../common/TagInput";
import { localToUtc } from "../../utils/appUtils";
import SelectField from "../common/Forms/SelectField";
import {
AppFormController,
AppFormProvider,
useAppForm,
} from "../../hooks/appHooks/useAppForm";
import { useParams } from "react-router-dom";
import { useDispatch } from "react-redux";
import { useJobStatus } from "../../hooks/masterHook/useMaster";
import { useServiceProjectJobContext } from "./Jobs";
const ManageJob = ({ Job }) => {
const { setManageJob, setSelectedJob } = useServiceProjectJobContext();
const { projectId } = useParams();
const dispatch = useDispatch();
const methods = useAppForm({
resolver: zodResolver(jobSchema),
defaultValues: defaultJobValue,
});
const {
register,
control,
watch,
handleSubmit,
reset,
formState: { errors },
} = methods;
const {
data: JobTags,
isLoading: isTagLoading,
isError: isTagError,
error: tagError,
} = useJobTags();
const {
data: JobData,
isLoading: isJobLoading,
isError: isJobError,
error: jobError,
} = useServiceProjectJobDetails(Job);
const { data, isLoading, isError, error } = useJobStatus(
JobData?.status?.id,
projectId
);
const { mutate: CreateJob, isPending } = useCreateServiceProjectJob(() => {
reset();
});
const { mutate: UpdateJob, isPending: Updating } = useUpdateServiceProjectJob(
() => {
setManageJob({ isOpen: false, jobId: null });
setSelectedJob({ showCanvas: true, job: Job });
}
);
const onSubmit = (formData) => {
if (Job) {
const existingEmployeeIds = JobData?.assignees?.map((e) => e.id) || [];
const oldEmployees = JobData.assignees.map((e) => ({
employeeId: e.id,
isActive: formData.assignees.includes(e.id),
}));
const newEmployees = formData.assignees
.filter((id) => !existingEmployeeIds.includes(id))
.map((id) => ({
employeeId: id,
isActive: true,
}));
const updatedEmployees = [...oldEmployees, ...newEmployees];
const payload = [
{
op: "replace",
path: "/title",
value: formData.title,
},
{
op: "replace",
path: "/description",
value: formData.description,
},
{
op: "replace",
path: "/startDate",
value: localToUtc(formData.startDate) ?? JobData.startDate,
},
{
op: "replace",
path: "/dueDate",
value: localToUtc(formData.dueDate) ?? JobData.dueDate,
},
{
op: "replace",
path: "/tags",
value: formData.tags,
},
{
op: "replace",
path: "/assignees",
value: updatedEmployees,
},
{
op: "replace",
path: "/statusId",
value: formData.statusId,
},
];
UpdateJob({ id: Job, payload });
} else {
formData.assignees = formData.assignees.map((emp) => ({
employeeId: emp,
isActive: true,
}));
formData.startDate = localToUtc(formData.startDate);
formData.dueDate = localToUtc(formData.dueDate);
formData.projectId = projectId;
CreateJob(formData);
}
};
useEffect(() => {
if (!JobData && !Job) {
reset({
...defaultJobValue,
projectId: projectId,
});
return;
}
if (!JobData || !Job) return;
const assignedEmployees = (JobData.assignees || []).map((e) => e.id);
reset({
title: JobData.title ?? "",
description: JobData.description ?? "",
projectId: JobData.project?.id ?? projectId,
assignees: assignedEmployees,
startDate: JobData.startDate ?? null,
dueDate: JobData.dueDate ?? null,
tags: JobData.tags ?? [],
statusId: JobData.status.id,
});
}, [JobData, Job, projectId]);
return (
<div className="container">
<AppFormProvider {...methods}>
<form className="row text-start" onSubmit={handleSubmit(onSubmit)}>
<div className="col-12 col-md-12 mb-2 ">
<Label required>Title</Label>
<input
type="text"
{...register("title")}
className="form-control form-control"
placeholder="Enter Title"
/>
</div>
<div className="col-12 col-md-6 mb-2 mb-md-4">
<Label required>Start Date</Label>
<DatePicker
name="startDate"
control={control}
placeholder="DD-MM-YYYY"
className="w-full"
size="md"
/>
</div>
<div className="col-12 col-md-6 mb-2 mb-md-4">
<Label required>Due Date</Label>
<DatePicker
control={control}
minDate={watch("startDate")}
name="dueDate"
className="w-full"
size="md"
/>
</div>
<div className="col-12 col-md-6 mb-2 mb-md-4">
<Label required>Select Employee</Label>
<PmsEmployeeInputTag
control={control}
name="assignees"
placeholder="Select employee"
/>
</div>
{Job && (
<div className="col-12 col-md-6 mb-2 mb-md-4">
<AppFormController
name="statusId"
control={control}
render={({ field }) => (
<SelectField
label="Select Status"
options={data ?? []}
placeholder="Choose a Status"
required
labelKeyKey="name"
valueKeyKey="id"
value={field.value}
onChange={field.onChange}
isLoading={isLoading}
className="m-0"
/>
)}
/>
{errors.statusId && (
<small className="danger-text">{errors.statusId.message}</small>
)}
</div>
)}
<div className="col-12 col-md-6 mb-2 mb-md-4">
<TagInput
options={JobTags?.data}
name="tags"
label="Tag"
placeholder="Enter Tag"
required
/>
</div>
<div className="col-12">
<Label required>Description</Label>
<textarea
{...register("description")}
className="form-control form-control-sm"
rows={3}
/>
</div>
<div className="d-flex flex-row-reverse my-4">
<button
type="submit"
className="btn btn-sm btn-primary"
disabled={isPending || Updating}
>
{isPending || Updating
? "Please wait..."
: Job
? "Update"
: "Submit"}
</button>
</div>
</form>
</AppFormProvider>
</div>
);
};
export default ManageJob;