shoc-frontend-new/src/app/(protected)/vendors/_components/use-vendor-deactivation.ts
Codex Review Integration 22b03b8ac0 fix(vendors): deactivation dialog follows the approved design (SH-254)
The dialog's wording, its actions and its behaviour all diverged from the
design prototype. It refused deactivation outright when the vendor had
open work orders, which SH-44 and SH-82 left as an open question rather
than a decided requirement.

Deactivation with open work orders now proceeds on explicit confirmation:
the design's title and body copy, the affected work orders listed as
links, and "Deactivate anyway" in place of a disabled button. The API
call carries confirmOpenWorkOrders so the server-side guard is cleared
deliberately rather than removed.
2026-08-19 13:36:37 -03:00

66 lines
1.9 KiB
TypeScript

import { useState } from "react";
import { useDeleteVendor } from "@/domain/vendors/use-cases/use-delete-vendor";
import { useVendorDeactivationImpact } from "@/domain/vendors/use-cases/use-vendor-deactivation-impact";
import type { VendorDeactivationImpact, VendorListItem } from "@/domain/vendors/types/vendor";
export interface VendorDeactivationState {
target: VendorListItem | null;
error: string | null;
impact: VendorDeactivationImpact | undefined;
isLoading: boolean;
impactError: Error | null;
isSaving: boolean;
open: (row: VendorListItem) => void;
close: () => void;
confirm: () => void;
}
export function useVendorDeactivation(onSuccess?: () => void): VendorDeactivationState {
const [target, setTarget] = useState<VendorListItem | null>(null);
const [error, setError] = useState<string | null>(null);
const deleteVendor = useDeleteVendor();
const {
data: impact,
isLoading,
error: impactError,
} = useVendorDeactivationImpact(target?.id ?? undefined);
const open = (row: VendorListItem) => {
setTarget(row);
setError(null);
};
const close = () => {
setTarget(null);
setError(null);
};
const confirm = () => {
if (!target || target.id == null) return;
setError(null);
// The dialog has shown whatever open work orders exist, so confirming here is
// the explicit confirmation the API requires to deactivate past them (SH-254).
deleteVendor.mutate(
{ id: target.id, confirmOpenWorkOrders: (impact?.openWorkOrders.length ?? 0) > 0 },
{
onSuccess: () => {
setTarget(null);
onSuccess?.();
},
onError: (err: Error) => setError(err.message || "Failed to deactivate vendor"),
},
);
};
return {
target,
error,
impact,
isLoading,
impactError,
isSaving: deleteVendor.isPending,
open,
close,
confirm,
};
}