diff --git a/e2e/__screenshots__/work-orders/work-orders.visual.spec.ts/wo-detail.png b/e2e/__screenshots__/work-orders/work-orders.visual.spec.ts/wo-detail.png index fb36ec63..52d00495 100644 Binary files a/e2e/__screenshots__/work-orders/work-orders.visual.spec.ts/wo-detail.png and b/e2e/__screenshots__/work-orders/work-orders.visual.spec.ts/wo-detail.png differ diff --git a/e2e/__screenshots__/work-orders/work-orders.visual.spec.ts/wo-filters.png b/e2e/__screenshots__/work-orders/work-orders.visual.spec.ts/wo-filters.png index 21809dbd..f9ab4659 100644 Binary files a/e2e/__screenshots__/work-orders/work-orders.visual.spec.ts/wo-filters.png and b/e2e/__screenshots__/work-orders/work-orders.visual.spec.ts/wo-filters.png differ diff --git a/e2e/__screenshots__/work-orders/work-orders.visual.spec.ts/wo-list.png b/e2e/__screenshots__/work-orders/work-orders.visual.spec.ts/wo-list.png index a7109395..bf2ebed4 100644 Binary files a/e2e/__screenshots__/work-orders/work-orders.visual.spec.ts/wo-list.png and b/e2e/__screenshots__/work-orders/work-orders.visual.spec.ts/wo-list.png differ diff --git a/e2e/__screenshots__/work-orders/work-orders.visual.spec.ts/wo-mobile.png b/e2e/__screenshots__/work-orders/work-orders.visual.spec.ts/wo-mobile.png index 6e98e3fa..5311388e 100644 Binary files a/e2e/__screenshots__/work-orders/work-orders.visual.spec.ts/wo-mobile.png and b/e2e/__screenshots__/work-orders/work-orders.visual.spec.ts/wo-mobile.png differ diff --git a/e2e/__screenshots__/work-orders/work-orders.visual.spec.ts/wo-new.png b/e2e/__screenshots__/work-orders/work-orders.visual.spec.ts/wo-new.png index 9edaccd5..d54bc0b4 100644 Binary files a/e2e/__screenshots__/work-orders/work-orders.visual.spec.ts/wo-new.png and b/e2e/__screenshots__/work-orders/work-orders.visual.spec.ts/wo-new.png differ diff --git a/src/domain/work-orders/utils/wizard-date-utils.ts b/src/domain/work-orders/utils/wizard-date-utils.ts index 1d1f757b..48a5ddfd 100644 --- a/src/domain/work-orders/utils/wizard-date-utils.ts +++ b/src/domain/work-orders/utils/wizard-date-utils.ts @@ -151,6 +151,13 @@ export function parseApptTime(appt: string): { start: string; end: string } { } return { start: `${pad2(h)}:${single[2]}`, end: "" }; } + const startOnly = appt.trim().match(/^(\d{1,2}):(\d{2})$/); + if (startOnly) { + return { + start: `${startOnly[1].padStart(2, "0")}:${startOnly[2]}`, + end: "", + }; + } return { start: "", end: "" }; } diff --git a/src/test/app/(protected)/workorders/appt-time-cell.test.tsx b/src/test/app/(protected)/workorders/appt-time-cell.test.tsx index 396d72a9..15aea687 100644 --- a/src/test/app/(protected)/workorders/appt-time-cell.test.tsx +++ b/src/test/app/(protected)/workorders/appt-time-cell.test.tsx @@ -35,6 +35,12 @@ describe("commitApptTimeSelection", () => { expect(onSave).not.toHaveBeenCalled(); }); + it("clears a stored start-only time when Start is empty", () => { + const onSave = vi.fn(); + commitApptTimeSelection("", "", "09:00", onSave); + expect(onSave).toHaveBeenCalledWith(""); + }); + it("saves start only when end is omitted", () => { const onSave = vi.fn(); commitApptTimeSelection("09:00", "", "", onSave); @@ -93,4 +99,16 @@ describe("ApptTimeCell", () => { expect(onSave).not.toHaveBeenCalled(); }); + + it("hydrates start-only stored times so Done can clear them", async () => { + const user = userEvent.setup(); + const onSave = vi.fn(); + render(); + + await user.click(screen.getByRole("button", { name: fmt12("09:00") })); + expect(await screen.findByText("Pick end (optional)")).toBeInTheDocument(); + await user.click(screen.getByRole("button", { name: /^done$/i })); + + expect(onSave).toHaveBeenCalledWith("09:00"); + }); }); diff --git a/src/test/domain/work-orders/utils/wizard-date-utils.test.ts b/src/test/domain/work-orders/utils/wizard-date-utils.test.ts index 8f63bbbf..acf1ce97 100644 --- a/src/test/domain/work-orders/utils/wizard-date-utils.test.ts +++ b/src/test/domain/work-orders/utils/wizard-date-utils.test.ts @@ -3,10 +3,21 @@ import { fmtDateRange, fmtShortDate, pad2, + parseApptTime, rangeDayCount, todayIso, } from "@/domain/work-orders/utils/wizard-date-utils"; +describe("parseApptTime", () => { + it("parses a 24-hour start-only value", () => { + expect(parseApptTime("09:00")).toEqual({ start: "09:00", end: "" }); + }); + + it("leaves free-text labels unparsed", () => { + expect(parseApptTime("AM before 2pm")).toEqual({ start: "", end: "" }); + }); +}); + describe("fmtShortDate", () => { it("formats ISO dates as Mon D", () => { expect(fmtShortDate("2026-06-08")).toBe("Jun 8");