From 1bc0da40e773daebaa056baf01d03b703b6833f2 Mon Sep 17 00:00:00 2001 From: Dave Date: Wed, 16 Sep 2026 11:04:39 +0200 Subject: [PATCH] feat(customers): lift active/inactive toggle to top of customer form MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The active/inactive customer switch was buried under the 'Details' section after the sales rep and description — easy to miss when the only thing the operator wants to do is mark a customer as inactive. Moved it to the second row of the form, immediately after the customer name field, where it's the first decision the operator makes. Visual treatment bumped to match the new prominence: a green-tinted container when active, muted grey when inactive, so the state is readable from across the room instead of requiring the operator to read the trigger label. state semantics (unchanged from bbfa888): - 'status' is a PB bool, true = active, false = inactive - new customers default to true via the form's 'status: customer?.status ?? true' initializer - legacy rows with status undefined render as Active on both the detail and list pages (same default-active contract on read) — no migration needed - the only way to render an inactive customer is to flip the switch and save it; PB then stores false --- src/components/customer-form.tsx | 104 ++++++++++++++++++++----------- 1 file changed, 69 insertions(+), 35 deletions(-) diff --git a/src/components/customer-form.tsx b/src/components/customer-form.tsx index c4c4050..aef7845 100644 --- a/src/components/customer-form.tsx +++ b/src/components/customer-form.tsx @@ -24,6 +24,7 @@ import { CheckCircle2, XCircle, } from "lucide-react"; +import { cn } from "@/lib/utils"; import getPocketBase from "@/lib/pocketbase"; import { getAllCompanies, findCustomerDuplicates } from "@/lib/pb-helpers"; import { CompanySearch } from "@/components/ui/company-search"; @@ -384,6 +385,68 @@ export function CustomerForm({ open, onOpenChange, customer, onSaved }: Customer /> + {/* + Active/Inactive customer toggle — lifted to the top of the + form (2026-09) so the operator can flip the flag without + scrolling past company / sales rep / description. State + semantics: `status` is a PB bool, true = active, false = + inactive; legacy rows that pre-date the field come back + as `undefined` and collapse to `true` via `?? true` in + `buildCustomerFormState`, so untouched existing customers + read as Active on first edit. + + Visual: the switch has a coloured background that flips + with state — green when active, muted when inactive — so + the answer is one glance from across the room, not "did + I read the trigger label right?". The icon (Check / + X-circle) reinforces the same answer for screen-reader + users. + */} +
+
+ {form.status ? ( + + ) : ( + + )} +
+ +

+ New customers are active by default. Flip this + off when the customer stops working for the + mine — historical quotes and orders stay + attached, but the customer drops off the + active pickers. +

+
+
+ + setForm({ ...form, status: checked === true }) + } + aria-label={form.status ? "Active customer" : "Inactive customer"} + /> +
{/* - Active-customer toggle (added 2026-09). PB `status` is a - bool: true = active, false = inactive (e.g. the mine - stopped trading, customer moved to a different mine). - Existing customers the operator creates without touching - this row will land as `true` — see `?? true` in - `buildCustomerFormState`. The icon flips with state so - the meaning is clear even without the label colour. + Active/Inactive toggle used to live here, but it was + buried past company / rep / description and easy to + miss. It's now the second row of the form (right + under the customer name) so flipping the flag is one + tap. Keeping the Save layer in `performSave` unchanged + — `status: !!form.status` already shipped 2026-09. */} -
-
- -

- Turn off when this customer no longer works for - the mine. Historical quotes and orders are kept; - the customer stops appearing on active pickers. -

-
- - setForm({ ...form, status: checked === true }) - } - aria-label="Active customer" - /> -