shoc-frontend-new/src/domain/work-orders/use-cases/use-work-order-mutations.ts
2026-07-23 17:44:53 -03:00

294 lines
9.6 KiB
TypeScript

import { useMutation, useQueryClient, type UseMutationResult } from "@tanstack/react-query";
import { useNavigate } from "react-router";
import { toast } from "react-toastify";
import { workOrdersApi } from "@/domain/work-orders/api/work-orders-api";
import type { WorkOrderFormSchemaValues } from "@/domain/work-orders/schemas/work-order-schema";
import type {
DispatchComment,
DispatchSignoff,
DispatchToVendorPayload,
UpdateDispatchPayload,
WorkOrderComment,
WorkOrderDetail,
WorkOrderFormValues,
WorkOrderVendorUpdatePayload,
} from "@/domain/work-orders/types/work-order";
import { queryKeys } from "@/infra/query-key/query-key";
function invalidateWorkOrders(queryClient: ReturnType<typeof useQueryClient>) {
void queryClient.invalidateQueries({ queryKey: queryKeys.workOrders.all });
}
interface AddWorkOrderCommentInput {
text: string;
commentType: "customer" | "internal";
}
export interface AddDispatchCommentInput {
text: string;
sendEmail: boolean;
}
export interface UpdateChecklistItemInput {
itemId: string | number;
isCompleted: boolean;
completedBy: string;
}
export interface AddDispatchSignoffInput {
signoffType: string;
name: string;
signature: string;
signatureMethod: string;
}
interface ChangeWorkOrderAssignmentInput {
userId: string | number;
userName: string;
}
interface UpdateWorkOrderVendorInput {
vendorId: string | number;
payload: WorkOrderVendorUpdatePayload;
}
export function useCreateWorkOrder(): UseMutationResult<
WorkOrderDetail,
Error,
WorkOrderFormSchemaValues | WorkOrderFormValues
> {
const queryClient = useQueryClient();
const navigate = useNavigate();
return useMutation({
mutationFn: (values: WorkOrderFormSchemaValues | WorkOrderFormValues) =>
workOrdersApi.create(values),
onSuccess: (data) => {
invalidateWorkOrders(queryClient);
toast.success("Work Order created successfully!");
navigate(`/workorders/${data.id}`);
},
onError: (error: Error) => {
toast.error(error.message || "Failed to create work order");
},
});
}
export function useUpdateWorkOrder(
id: string | number,
): UseMutationResult<WorkOrderDetail, Error, WorkOrderFormSchemaValues | WorkOrderFormValues> {
const queryClient = useQueryClient();
const navigate = useNavigate();
return useMutation({
mutationFn: (values: WorkOrderFormSchemaValues | WorkOrderFormValues) =>
workOrdersApi.update(id, values),
onSuccess: () => {
invalidateWorkOrders(queryClient);
void queryClient.invalidateQueries({ queryKey: queryKeys.workOrders.detail(id) });
toast.success("Work Order updated successfully!");
navigate(`/workorders/${id}`);
},
onError: (error: Error) => {
toast.error(error.message || "Failed to update work order");
},
});
}
export function useUpdateWorkOrderVendor(
workOrderId: string | number,
): UseMutationResult<void, Error, UpdateWorkOrderVendorInput> {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ vendorId, payload }) =>
workOrdersApi.updateVendorFromWorkOrder(vendorId, payload),
onSuccess: () => {
void queryClient.invalidateQueries({ queryKey: queryKeys.workOrders.detail(workOrderId) });
void queryClient.invalidateQueries({ queryKey: queryKeys.workOrders.all });
void queryClient.invalidateQueries({ queryKey: queryKeys.vendors.all });
toast.success("Vendor contact updated");
},
onError: (error: Error) => {
toast.error(error.message || "Failed to update vendor contact");
},
});
}
export function useAddWorkOrderComment(
workOrderId: string | number,
): UseMutationResult<WorkOrderComment, Error, AddWorkOrderCommentInput> {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ text, commentType }: AddWorkOrderCommentInput) =>
workOrdersApi.addComment(workOrderId, text, commentType),
onSuccess: () => {
void queryClient.invalidateQueries({ queryKey: queryKeys.workOrders.detail(workOrderId) });
},
onError: (error: Error) => {
toast.error(error.message || "Failed to add comment");
},
});
}
export function useChangeWorkOrderStatus(
workOrderId: string | number,
): UseMutationResult<void, Error, string> {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (status: string) => workOrdersApi.changeStatus(workOrderId, status),
onSuccess: (_data, status) => {
void queryClient.invalidateQueries({ queryKey: queryKeys.workOrders.detail(workOrderId) });
invalidateWorkOrders(queryClient);
toast.success(`Status changed to ${status}`);
},
onError: (error: Error) => {
toast.error(error.message || "Failed to update status");
},
});
}
export function useChangeWorkOrderAssignment(
workOrderId: string | number,
): UseMutationResult<string, Error, ChangeWorkOrderAssignmentInput> {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ userId, userName }: ChangeWorkOrderAssignmentInput) =>
workOrdersApi.changeAssignment(workOrderId, userId).then(() => userName),
onSuccess: (userName) => {
void queryClient.invalidateQueries({ queryKey: queryKeys.workOrders.detail(workOrderId) });
invalidateWorkOrders(queryClient);
toast.success(`Assigned to ${userName || "Unassigned"}`);
},
onError: (error: Error) => {
toast.error(error.message || "Failed to update assignment");
},
});
}
export function useDispatchToVendor(
workOrderId: string | number,
): UseMutationResult<void, Error, DispatchToVendorPayload> {
const queryClient = useQueryClient();
return useMutation({
mutationFn: workOrdersApi.dispatchToVendor,
onSuccess: () => {
void queryClient.invalidateQueries({ queryKey: queryKeys.workOrders.detail(workOrderId) });
invalidateWorkOrders(queryClient);
toast.success("Dispatched successfully");
},
onError: (error: Error) => {
toast.error(error.message || "Failed to dispatch");
},
});
}
export function useUpdateDispatch(
dispatchId: string | number,
workOrderId: string | number,
): UseMutationResult<void, Error, UpdateDispatchPayload> {
const queryClient = useQueryClient();
return useMutation({
mutationFn: workOrdersApi.updateDispatch,
onSuccess: () => {
void queryClient.invalidateQueries({ queryKey: queryKeys.workOrders.dispatch(dispatchId) });
void queryClient.invalidateQueries({ queryKey: queryKeys.workOrders.detail(workOrderId) });
toast.success("Dispatch updated");
},
onError: (error: Error) => {
toast.error(error.message || "Failed to update dispatch");
},
});
}
export function useAddDispatchComment(
dispatchId: string | number,
): UseMutationResult<DispatchComment, Error, AddDispatchCommentInput> {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ text, sendEmail }: AddDispatchCommentInput) =>
workOrdersApi.addDispatchComment(dispatchId, text, sendEmail),
onSuccess: () => {
void queryClient.invalidateQueries({ queryKey: queryKeys.workOrders.dispatch(dispatchId) });
},
onError: (error: Error) => {
toast.error(error.message || "Failed to send message");
},
});
}
export function useUpdateChecklistItem(
dispatchId: string | number,
): UseMutationResult<void, Error, UpdateChecklistItemInput> {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ itemId, isCompleted, completedBy }: UpdateChecklistItemInput) =>
workOrdersApi.updateChecklistItem(itemId, isCompleted, completedBy),
onSuccess: () => {
void queryClient.invalidateQueries({ queryKey: queryKeys.workOrders.dispatch(dispatchId) });
},
onError: (error: Error) => {
toast.error(error.message || "Failed to update checklist item");
},
});
}
export function useAddChecklistItem(
dispatchId: string | number,
): UseMutationResult<void, Error, string> {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (itemText: string) => workOrdersApi.addChecklistItem(dispatchId, itemText),
onSuccess: () => {
void queryClient.invalidateQueries({ queryKey: queryKeys.workOrders.dispatch(dispatchId) });
},
onError: (error: Error) => {
toast.error(error.message || "Failed to add checklist item");
},
});
}
export function useAddDispatchSignoff(
dispatchId: string | number,
): UseMutationResult<DispatchSignoff, Error, AddDispatchSignoffInput> {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ signoffType, name, signature, signatureMethod }: AddDispatchSignoffInput) =>
workOrdersApi.addDispatchSignoff(dispatchId, signoffType, name, signature, signatureMethod),
onSuccess: (_data, variables) => {
void queryClient.invalidateQueries({ queryKey: queryKeys.workOrders.dispatch(dispatchId) });
toast.success(`${variables.signoffType} sign-off collected`);
},
onError: (error: Error) => {
toast.error(error.message || "Failed to save sign-off");
},
});
}
export function useVerifyDispatch(
dispatchId: string | number,
workOrderId: string | number,
): UseMutationResult<void, Error, void> {
const queryClient = useQueryClient();
return useMutation({
mutationFn: () => workOrdersApi.verifyDispatch(dispatchId),
onSuccess: () => {
void queryClient.invalidateQueries({ queryKey: queryKeys.workOrders.dispatch(dispatchId) });
void queryClient.invalidateQueries({ queryKey: queryKeys.workOrders.detail(workOrderId) });
toast.success("Dispatch verified");
},
onError: (error: Error) => {
toast.error(error.message || "Failed to verify");
},
});
}