diff --git a/src/app/(protected)/vendors/_components/vendor-detail-drawer.tsx b/src/app/(protected)/vendors/_components/vendor-detail-drawer.tsx index 74d6ef02..fdb627be 100644 --- a/src/app/(protected)/vendors/_components/vendor-detail-drawer.tsx +++ b/src/app/(protected)/vendors/_components/vendor-detail-drawer.tsx @@ -254,10 +254,13 @@ function DrawerEditor({ const selectedIndex = technicians.findIndex( (technician) => technician.id != null && String(technician.id) === String(vendor.id), ); - const selectedTotalJobs = - roster?.technicians.find( - (technician) => technician.id != null && String(technician.id) === String(vendor.id), - )?.totalJobs ?? vendor.totalJobs; + const persistedTechnician = roster?.technicians.find( + (technician) => technician.id != null && String(technician.id) === String(vendor.id), + ); + const selectedTotalJobs = persistedTechnician?.totalJobs ?? vendor.totalJobs; + // Deactivation is a property of the saved vendor, not of the toggle: flipping an + // inactive vendor on and back off without saving must not ask to deactivate it. + const persistedIsActive = persistedTechnician?.isActive ?? vendor.isActive; if (form.isLoading) { return ; @@ -310,7 +313,7 @@ function DrawerEditor({ checked={Boolean(field.value)} slotProps={{ input: { "aria-label": "Active status" } }} onChange={(_event, checked) => { - if (field.value && !checked) onRequestDeactivation(vendor); + if (persistedIsActive && !checked) onRequestDeactivation(vendor); else field.onChange(checked); }} /> diff --git a/src/test/app/(protected)/vendors/vendor-detail-drawer.test.tsx b/src/test/app/(protected)/vendors/vendor-detail-drawer.test.tsx index df329a4a..3029e06c 100644 --- a/src/test/app/(protected)/vendors/vendor-detail-drawer.test.tsx +++ b/src/test/app/(protected)/vendors/vendor-detail-drawer.test.tsx @@ -1,4 +1,5 @@ import { screen } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; import { describe, expect, it, vi } from "vitest"; import { VendorDetailDrawer } from "@/app/(protected)/vendors/_components/vendor-detail-drawer"; import { renderWithProviders } from "@/test/test-utils"; @@ -134,3 +135,60 @@ describe("VendorDetailDrawer selected-technician display", () => { expect(screen.queryByRole("switch", { name: "Active status" })).not.toBeInTheDocument(); }); }); + +describe("VendorDetailDrawer deactivation prompt", () => { + const inactiveVendor: VendorListItem = { ...vendor, isActive: false }; + + it("does not prompt to deactivate a saved-inactive vendor toggled on and back off", async () => { + useVendorCompanyRoster.mockReturnValue( + rosterWith([ + { id: 1, contactName: "Adam", phone: "314-555-0198", isActive: false, totalJobs: 5 }, + ]), + ); + const onRequestDeactivation = vi.fn(); + + renderWithProviders( + , + { route: "/vendors", withAuth: false }, + ); + + const toggle = screen.getByRole("switch", { name: "Active status" }); + await userEvent.click(toggle); + expect(toggle).toBeChecked(); + + await userEvent.click(toggle); + + expect(toggle).not.toBeChecked(); + expect(onRequestDeactivation).not.toHaveBeenCalled(); + }); + + it("prompts to deactivate a saved-active vendor when the toggle is switched off", async () => { + useVendorCompanyRoster.mockReturnValue( + rosterWith([ + { id: 1, contactName: "Adam", phone: "314-555-0198", isActive: true, totalJobs: 5 }, + ]), + ); + const onRequestDeactivation = vi.fn(); + + renderWithProviders( + , + { route: "/vendors", withAuth: false }, + ); + + await userEvent.click(screen.getByRole("switch", { name: "Active status" })); + + expect(onRequestDeactivation).toHaveBeenCalledWith(vendor); + }); +});