diff --git a/src/app/(protected)/workorders/_components/list/table/cells/use-vendor-dialog-save.ts b/src/app/(protected)/workorders/_components/list/table/cells/use-vendor-dialog-save.ts new file mode 100644 index 00000000..d29e02b0 --- /dev/null +++ b/src/app/(protected)/workorders/_components/list/table/cells/use-vendor-dialog-save.ts @@ -0,0 +1,72 @@ +import { isDraftVendorId } from "@/domain/vendors/utils/draft-vendor"; +import { vendorToDropdownItem } from "@/domain/vendors/utils/vendor-to-dropdown-item"; +import type { VendorDropdownItem } from "@/domain/work-orders/types/work-order"; +import type { VendorFormValues } from "@/domain/vendors/schemas/vendor-schema"; +import type { VendorPatch } from "@/app/(protected)/workorders/_components/list/table/cells/vendor-dialog-types"; +import type { useCreateVendor } from "@/domain/vendors/use-cases/use-create-vendor"; + +type UseVendorDialogSaveArgs = { + allVendors: VendorDropdownItem[]; + pendingCreates: Record; + selectedKey: string; + selectedVendor: VendorDropdownItem | undefined; + resolvedCompany: string; + anchorCompanyName: string; + tech: string; + phone: string; + createVendor: ReturnType; + onSave: (patch: VendorPatch) => void; + onOpenChange: (open: boolean) => void; + setSaveError: (error: string | null) => void; +}; + +export function useVendorDialogSave({ + allVendors, + pendingCreates, + selectedKey, + selectedVendor, + resolvedCompany, + anchorCompanyName, + tech, + phone, + createVendor, + onSave, + onOpenChange, + setSaveError, +}: UseVendorDialogSaveArgs) { + const resolveSaveVendor = () => + allVendors.find( + (vendor) => + vendor.contactName === tech && + vendor.companyName === (resolvedCompany || anchorCompanyName), + ) ?? + allVendors.find((vendor) => String(vendor.id) === selectedKey) ?? + selectedVendor; + + const handleSave = async () => { + setSaveError(null); + let saveVendor = resolveSaveVendor(); + const pendingPayload = saveVendor ? pendingCreates[String(saveVendor.id)] : undefined; + + if (saveVendor != null && isDraftVendorId(saveVendor.id) && pendingPayload) { + try { + const created = await createVendor.mutateAsync(pendingPayload); + saveVendor = vendorToDropdownItem(created); + } catch (error) { + const message = error instanceof Error ? error.message : "Failed to create technician"; + setSaveError(message); + return; + } + } + + onSave({ + vendorId: saveVendor ? String(saveVendor.id) : "", + company: resolvedCompany || anchorCompanyName, + tech, + techPhone: phone, + }); + onOpenChange(false); + }; + + return { handleSave }; +} diff --git a/src/app/(protected)/workorders/_components/list/table/cells/vendor-dialog-body.tsx b/src/app/(protected)/workorders/_components/list/table/cells/vendor-dialog-body.tsx new file mode 100644 index 00000000..5b58de5e --- /dev/null +++ b/src/app/(protected)/workorders/_components/list/table/cells/vendor-dialog-body.tsx @@ -0,0 +1,121 @@ +import { Wrench } from "lucide-react"; +import { + DLG_INPUT_CLS, + DLG_INPUT_STYLE, +} from "@/app/(protected)/workorders/_components/wizard/wizard-input-styles"; +import { WizardFieldSelect } from "@/app/(protected)/workorders/_components/wizard/wizard-field-select"; +import { Text } from "@/components/ui/text"; +import type { VendorDropdownItem } from "@/domain/work-orders/types/work-order"; +import { FieldLabel } from "@/app/(protected)/workorders/_components/list/table/cells/dialog-field-label"; +import { VendorDialogAddTechnician } from "@/app/(protected)/workorders/_components/list/table/cells/vendor-dialog-add-technician"; +import { VendorDialogCompanyCard } from "@/app/(protected)/workorders/_components/list/table/cells/vendor-dialog-company-card"; +import type { VendorFormValues } from "@/domain/vendors/schemas/vendor-schema"; +import type { TechnicianOption } from "@/app/(protected)/workorders/_components/list/table/cells/vendor-dialog-options"; + +type VendorDialogBodyProps = { + selectedKey: string; + technicianOptions: TechnicianOption[]; + anchorCompanyName: string; + companyVendorForAdd: VendorDropdownItem | undefined; + tech: string; + phone: string; + notes: string; + resolvedCompany: string; + selectedVendor: VendorDropdownItem | undefined; + saveError: string | null; + onPick: (key: string) => void; + onPhoneChange: (phone: string) => void; + onNotesChange: (notes: string) => void; + onTechnicianCreated: ( + created: VendorDropdownItem, + createdPhone: string, + payload: VendorFormValues, + ) => void; +}; + +export function VendorDialogBody({ + selectedKey, + technicianOptions, + anchorCompanyName, + companyVendorForAdd, + tech, + phone, + notes, + resolvedCompany, + selectedVendor, + saveError, + onPick, + onPhoneChange, + onNotesChange, + onTechnicianCreated, +}: VendorDialogBodyProps) { + return ( + <> +
+
+ Technician + + } + searchPlaceholder="Search technician…" + options={technicianOptions.map((option) => ({ + key: option.key, + label: option.label, + }))} + onPick={onPick} + /> + {companyVendorForAdd != null && ( +
+ +
+ )} +
+ + {Boolean(tech) && ( +
+ Technician Phone + onPhoneChange(e.target.value)} + className={DLG_INPUT_CLS} + style={DLG_INPUT_STYLE} + /> +
+ )} + + {Boolean(resolvedCompany) && ( +
+ Company + +
+ )} + +
+ Notes +