WFDASH-WEBAPP/src/lib/order-rep.ts

57 lines
2 KiB
TypeScript
Raw Normal View History

import type { User } from "@/lib/types";
const POCKETBASE_RECORD_ID = /^[a-z0-9]{15}$/i;
type RepUser = Pick<User, "id" | "name" | "email">;
export interface ResolveRepDisplayNameOptions {
/** Expanded `customer.rep` record, when PocketBase returned it. */
expandedCustomerRep?: Partial<RepUser> | null;
/** Raw relation id stored in `customer.rep`. */
customerRepId?: string | null;
/** Legacy/free-text snapshot stored in `orders.rep`. */
orderRep?: string | null;
/** Admin-resolved users, keyed by PocketBase user id. */
usersById?: ReadonlyMap<string, RepUser>;
}
function userLabel(user?: Partial<RepUser> | null): string {
return (user?.name || user?.email || "").trim();
}
/**
* Resolves the sales rep shown on order surfaces without ever leaking an
* opaque PocketBase record id into the UI.
*
* Customer ownership is authoritative, so its expanded/user-map value wins.
* `orders.rep` remains the fallback because company-only and older orders can
* carry a manually entered name there. Some older rows stored a user id in
* that text field; those ids are resolved through `usersById`, or hidden when
* the related user no longer exists.
*/
export function resolveRepDisplayName({
expandedCustomerRep,
customerRepId,
orderRep,
usersById,
}: ResolveRepDisplayNameOptions): string {
const expandedLabel = userLabel(expandedCustomerRep);
if (expandedLabel) return expandedLabel;
const customerRef = (customerRepId || "").trim();
if (customerRef) {
const customerUserLabel = userLabel(usersById?.get(customerRef));
if (customerUserLabel) return customerUserLabel;
}
const orderValue = (orderRep || "").trim();
if (!orderValue) return "";
const orderUserLabel = userLabel(usersById?.get(orderValue));
if (orderUserLabel) return orderUserLabel;
// A free-text name is safe to show. An unresolved PB id is not useful to
// an operator, so suppress it instead of regressing to the old ID display.
return POCKETBASE_RECORD_ID.test(orderValue) ? "" : orderValue;
}