import { useMemo, useState } from "react"; import { useApproveUplift, useDenyUplift, useUpliftsForDispatch, } from "@/domain/uplifts/use-cases/use-uplift-actions"; import type { UpliftRequest } from "@/domain/uplifts/types/uplift"; import type { DispatchDetail } from "@/domain/work-orders/types/work-order"; import { useDispatchDetail } from "@/domain/work-orders/use-cases/use-work-order-detail"; import { useAddChecklistItem, useAddDispatchComment, useAddDispatchSignoff, useUpdateChecklistItem, useUpdateDispatch, useVerifyDispatch, } from "@/domain/work-orders/use-cases/use-work-order-mutations"; import { isDispatchLocked } from "@/domain/work-orders/utils/is-dispatch-locked"; import { useAuthContext } from "@/providers/auth-context"; import { toDateInputValue } from "@/lib/time-utils"; import { buildDispatchEditForm } from "@/app/(protected)/workorders/_components/dispatch/dispatch-detail/build-dispatch-edit-form"; import type { DispatchEditFormState } from "@/app/(protected)/workorders/_components/dispatch/dispatch-detail/dispatch-edit-form"; export function useDispatchDetailController( dispatchId: string | number, workOrderId: string | number, ) { const { user } = useAuthContext(); const { data: dispatch, isLoading } = useDispatchDetail(dispatchId); const { data: uplifts = [] } = useUpliftsForDispatch(dispatchId); const [editing, setEditing] = useState(false); const [form, setForm] = useState({ status: "", nteAmount: "", scheduledDate: "", completedDate: "", description: "", }); const [newChecklistItem, setNewChecklistItem] = useState(""); const [commentText, setCommentText] = useState(""); const [sendEmail, setSendEmail] = useState(true); const [sigCaptureType, setSigCaptureType] = useState(null); const [upliftAction, setUpliftAction] = useState<{ type: "approve" | "deny"; uplift: UpliftRequest; } | null>(null); const updateDispatchMutation = useUpdateDispatch(dispatchId, workOrderId); const addCommentMutation = useAddDispatchComment(dispatchId); const updateChecklistMutation = useUpdateChecklistItem(dispatchId); const addChecklistMutation = useAddChecklistItem(dispatchId); const addSignoffMutation = useAddDispatchSignoff(dispatchId); const verifyMutation = useVerifyDispatch(dispatchId, workOrderId); const approveUpliftMutation = useApproveUplift(dispatchId); const denyUpliftMutation = useDenyUplift(dispatchId); const userName = (typeof user?.name === "string" ? user.name : undefined) ?? (typeof user?.fullname === "string" ? user.fullname : undefined) ?? "User"; const isLocked = dispatch ? isDispatchLocked(dispatch) : false; const verifyState = useMemo(() => { if (!dispatch) { return { canVerify: false, missing: [] as string[] }; } const checklistTotal = dispatch.checklistItems.length; const checklistDone = dispatch.checklistItems.filter((item) => item.isCompleted).length; const signoffCount = dispatch.signoffs.length; const missing: string[] = []; if (checklistTotal > 0 && checklistDone < checklistTotal) { missing.push(`${checklistTotal - checklistDone} checklist item(s)`); } if (signoffCount < 2) { const types = dispatch.signoffs.map((signoff) => signoff.signoffType); if (!types.includes("Customer")) { missing.push("Customer sign-off"); } if (!types.includes("Vendor")) { missing.push("Vendor sign-off"); } } return { missing, canVerify: missing.length === 0 && (checklistTotal > 0 || signoffCount >= 2), }; }, [dispatch]); const beginEditing = () => { if (dispatch) { setForm(buildDispatchEditForm(dispatch)); } setEditing(true); }; const handleSave = () => { updateDispatchMutation.mutate( { id: dispatchId, status: form.status, nteAmount: form.nteAmount ? parseFloat(form.nteAmount) : null, scheduledDate: form.scheduledDate || null, completedDate: form.completedDate || null, description: form.description, }, { onSuccess: () => setEditing(false) }, ); }; const handleCancelDispatch = (current: DispatchDetail) => { if (!window.confirm("Are you sure you want to cancel this dispatch?")) { return; } updateDispatchMutation.mutate({ id: dispatchId, status: "Cancelled", nteAmount: current.nteAmount, scheduledDate: toDateInputValue(current.scheduledDate) || null, completedDate: toDateInputValue(current.completedDate) || null, description: current.description, }); }; const handleComment = (event: React.FormEvent) => { event.preventDefault(); if (!commentText.trim()) { return; } addCommentMutation.mutate( { text: commentText.trim(), sendEmail }, { onSuccess: () => setCommentText("") }, ); }; const handleUpliftConfirm = (note: string) => { if (!upliftAction) { return; } if (upliftAction.type === "approve") { approveUpliftMutation.mutate( { id: upliftAction.uplift.id, note }, { onSuccess: () => setUpliftAction(null) }, ); return; } denyUpliftMutation.mutate( { id: upliftAction.uplift.id, note }, { onSuccess: () => setUpliftAction(null) }, ); }; return { dispatch, isLoading, uplifts, editing, form, setForm, newChecklistItem, setNewChecklistItem, commentText, setCommentText, sendEmail, setSendEmail, sigCaptureType, setSigCaptureType, upliftAction, setUpliftAction, isLocked, userName, verifyState, beginEditing, handleSave, handleCancelDispatch, handleComment, handleUpliftConfirm, setEditing, updateDispatchMutation, updateChecklistMutation, addChecklistMutation, addSignoffMutation, verifyMutation, approveUpliftMutation, denyUpliftMutation, addCommentMutation, }; }