@mindbill/react 0.9.1 → 0.9.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -2,10 +2,10 @@
2
2
 
3
3
  // src/index.tsx
4
4
  import "@mindbill/embed";
5
- import { createElement, useEffect as useEffect4, useRef as useRef3 } from "react";
5
+ import { createElement, useEffect as useEffect4, useRef as useRef4 } from "react";
6
6
 
7
7
  // src/native-bill-review.tsx
8
- import { useEffect, useId, useMemo, useState } from "react";
8
+ import { useEffect, useId, useMemo, useRef, useState } from "react";
9
9
  import { jsx, jsxs } from "react/jsx-runtime";
10
10
  var EMPTY_BILLING_PROVIDER = {
11
11
  name: "",
@@ -37,6 +37,35 @@ var DOCUMENT_LABELS = {
37
37
  appeal: "Appeal or review support",
38
38
  other: "Other supporting document"
39
39
  };
40
+ var US_STATES = ["AL", "AK", "AZ", "AR", "CA", "CO", "CT", "DE", "FL", "GA", "HI", "ID", "IL", "IN", "IA", "KS", "KY", "LA", "ME", "MD", "MA", "MI", "MN", "MS", "MO", "MT", "NE", "NV", "NH", "NJ", "NM", "NY", "NC", "ND", "OH", "OK", "OR", "PA", "RI", "SC", "SD", "TN", "TX", "UT", "VT", "VA", "WA", "WV", "WI", "WY", "DC"];
41
+ var PROCEDURES = [
42
+ ["ML200", "Missed med-legal appointment"],
43
+ ["ML201", "Comprehensive med-legal evaluation"],
44
+ ["ML202", "Follow-up med-legal evaluation"],
45
+ ["ML203", "Supplemental med-legal evaluation"],
46
+ ["ML204", "Medical-legal testimony"],
47
+ ["ML205", "Sub rosa recording review"],
48
+ ["MLPRR", "Medical record review"]
49
+ ];
50
+ var MODIFIERS = [
51
+ ["92", "Primary treating physician"],
52
+ ["93", "Interpreter required"],
53
+ ["94", "Agreed medical evaluator (AME)"],
54
+ ["95", "Qualified medical evaluator (QME)"],
55
+ ["96", "Psychiatric or psychological evaluation"],
56
+ ["97", "Toxicology evaluation"],
57
+ ["98", "Oncology evaluation"]
58
+ ];
59
+ var MANAGED_EVALUATOR_MODIFIERS = /* @__PURE__ */ new Set(["94", "95", "96"]);
60
+ var MODIFIER_CODES = {
61
+ "92": ["ML201", "ML202", "ML203"],
62
+ "93": ["ML201", "ML202"],
63
+ "94": ["ML201", "ML202", "ML203"],
64
+ "95": ["ML200", "ML201", "ML202", "ML203", "MLPRR"],
65
+ "96": ["ML201", "ML202", "ML203"],
66
+ "97": ["ML201", "ML202", "ML203"],
67
+ "98": ["ML201", "ML202", "ML203"]
68
+ };
40
69
  function withoutId(value) {
41
70
  const result = { ...value };
42
71
  delete result.id;
@@ -44,7 +73,20 @@ function withoutId(value) {
44
73
  }
45
74
  function toDraft(data) {
46
75
  const snapshot = data.bill.billingSnapshot;
76
+ const nameParts = data.patient.name.trim().split(/\s+/);
47
77
  return {
78
+ claimsAdminId: data.injury.claimsAdminId || "",
79
+ claimsAdminName: data.injury.claimsAdminName || "",
80
+ patientFirstName: data.patient.firstName || nameParts[0] || "",
81
+ patientMiddleName: data.patient.middleName || (nameParts.length > 2 ? nameParts.slice(1, -1).join(" ") : ""),
82
+ patientLastName: data.patient.lastName || (nameParts.length > 1 ? nameParts.at(-1) || "" : ""),
83
+ patientDob: data.patient.dob || "",
84
+ claimNumber: data.injury.claimNumber || "",
85
+ employer: data.injury.employer || "",
86
+ doi: data.injury.doi || "",
87
+ injuryEndDate: data.injury.injuryEndDate || "",
88
+ cumulativeTrauma: Boolean(data.injury.cumulativeTrauma),
89
+ adjNumber: data.injury.adjNumber || "",
48
90
  dos: data.bill.dos || "",
49
91
  dosEnd: data.bill.dosEnd || "",
50
92
  authorizationNumber: data.bill.authorizationNumber || "",
@@ -59,6 +101,21 @@ function toDraft(data) {
59
101
  }
60
102
  function buildBillReviewSaveInput(draft) {
61
103
  return {
104
+ claimsAdminId: draft.claimsAdminId,
105
+ patientOverrides: {
106
+ firstName: draft.patientFirstName.trim(),
107
+ ...draft.patientMiddleName.trim() ? { middleName: draft.patientMiddleName.trim() } : {},
108
+ lastName: draft.patientLastName.trim(),
109
+ ...draft.patientDob ? { dob: draft.patientDob } : {}
110
+ },
111
+ injuryOverrides: {
112
+ ...draft.claimNumber.trim() ? { claimNumber: draft.claimNumber.trim() } : {},
113
+ ...draft.employer.trim() ? { employer: draft.employer.trim() } : {},
114
+ ...draft.doi ? { doi: draft.doi } : {},
115
+ ...draft.injuryEndDate ? { injuryEndDate: draft.injuryEndDate } : {},
116
+ cumulativeTrauma: draft.cumulativeTrauma,
117
+ ...draft.adjNumber.trim() ? { adjNumber: draft.adjNumber.trim().toUpperCase().replace(/\s+/g, "") } : {}
118
+ },
62
119
  dos: draft.dos,
63
120
  dosEnd: draft.dosEnd || null,
64
121
  authorizationNumber: draft.authorizationNumber.trim() || null,
@@ -68,7 +125,7 @@ function buildBillReviewSaveInput(draft) {
68
125
  renderingProvider: withoutId(draft.clinician),
69
126
  ...draft.location.id ? { placeOfServiceId: draft.location.id } : {},
70
127
  placeOfService: withoutId(draft.location),
71
- lineItems: draft.lineItems.map(({ id, code, modifiers, units }) => ({
128
+ lineItems: draft.lineItems.filter((line) => line.code.trim()).map(({ id, code, modifiers, units }) => ({
72
129
  ...id ? { id } : {},
73
130
  code: code.trim().toUpperCase(),
74
131
  modifiers,
@@ -100,7 +157,9 @@ function Field({
100
157
  onChange,
101
158
  type = "text",
102
159
  optional,
103
- required
160
+ required,
161
+ disabled,
162
+ hint
104
163
  }) {
105
164
  return /* @__PURE__ */ jsxs("label", { className: "mb-native-field", children: [
106
165
  /* @__PURE__ */ jsxs("span", { children: [
@@ -114,11 +173,128 @@ function Field({
114
173
  type,
115
174
  value,
116
175
  required,
176
+ disabled,
177
+ autoComplete: "off",
117
178
  onChange: (event) => onChange(event.target.value)
118
179
  }
119
- )
180
+ ),
181
+ hint ? /* @__PURE__ */ jsx("small", { className: "mb-native-hint", children: hint }) : null
182
+ ] });
183
+ }
184
+ function Combobox({ label, value, options, onChange, placeholder, required, disabled, name }) {
185
+ const listId = useId();
186
+ const root = useRef(null);
187
+ const [open, setOpen] = useState(false);
188
+ const [active, setActive] = useState(0);
189
+ const filtered = useMemo(() => {
190
+ const query = value.trim().toLowerCase();
191
+ return options.filter((option) => !query || option.label.toLowerCase().includes(query) || option.value.toLowerCase().includes(query)).slice(0, 40);
192
+ }, [options, value]);
193
+ useEffect(() => {
194
+ const close = (event) => {
195
+ if (!root.current?.contains(event.target)) setOpen(false);
196
+ };
197
+ document.addEventListener("mousedown", close);
198
+ return () => document.removeEventListener("mousedown", close);
199
+ }, []);
200
+ const select = (option) => {
201
+ onChange(option.value, option);
202
+ setOpen(false);
203
+ setActive(0);
204
+ };
205
+ const keyDown = (event) => {
206
+ if (event.key === "ArrowDown") {
207
+ event.preventDefault();
208
+ setOpen(true);
209
+ setActive((value2) => Math.min(value2 + 1, filtered.length - 1));
210
+ }
211
+ if (event.key === "ArrowUp") {
212
+ event.preventDefault();
213
+ setActive((value2) => Math.max(value2 - 1, 0));
214
+ }
215
+ if (event.key === "Enter" && open && filtered[active]) {
216
+ event.preventDefault();
217
+ select(filtered[active]);
218
+ }
219
+ if (event.key === "Escape") setOpen(false);
220
+ };
221
+ return /* @__PURE__ */ jsxs("div", { className: "mb-native-combo", ref: root, children: [
222
+ /* @__PURE__ */ jsxs("label", { className: "mb-native-field", children: [
223
+ /* @__PURE__ */ jsx("span", { children: label }),
224
+ /* @__PURE__ */ jsx(
225
+ "input",
226
+ {
227
+ role: "combobox",
228
+ "aria-autocomplete": "list",
229
+ "aria-controls": listId,
230
+ "aria-expanded": open && filtered.length > 0,
231
+ "aria-activedescendant": open && filtered[active] ? `${listId}-${active}` : void 0,
232
+ name: name || "mindbill-search-value",
233
+ autoComplete: "new-password",
234
+ "data-1p-ignore": "true",
235
+ "data-lpignore": "true",
236
+ value,
237
+ placeholder,
238
+ required,
239
+ disabled,
240
+ onFocus: () => setOpen(true),
241
+ onKeyDown: keyDown,
242
+ onChange: (event) => {
243
+ onChange(event.target.value);
244
+ setOpen(true);
245
+ setActive(0);
246
+ }
247
+ }
248
+ )
249
+ ] }),
250
+ open && filtered.length ? /* @__PURE__ */ jsx("ul", { id: listId, role: "listbox", className: "mb-native-combo-list", children: filtered.map((option, index) => /* @__PURE__ */ jsx("li", { id: `${listId}-${index}`, role: "option", "aria-selected": index === active, children: /* @__PURE__ */ jsxs("button", { type: "button", className: index === active ? "active" : "", onMouseDown: (event) => event.preventDefault(), onClick: () => select(option), children: [
251
+ /* @__PURE__ */ jsx("strong", { children: option.label }),
252
+ option.detail ? /* @__PURE__ */ jsx("span", { children: option.detail }) : null
253
+ ] }) }, `${option.value}-${index}`)) }) : null
120
254
  ] });
121
255
  }
256
+ function StateCombobox({ label, value, onChange, required, disabled }) {
257
+ return /* @__PURE__ */ jsx(
258
+ Combobox,
259
+ {
260
+ label,
261
+ value,
262
+ onChange: (next) => onChange(next.toUpperCase().slice(0, 2)),
263
+ options: US_STATES.map((state) => ({ value: state, label: state })),
264
+ ...required === void 0 ? {} : { required },
265
+ ...disabled === void 0 ? {} : { disabled },
266
+ name: "mindbill-state-value"
267
+ }
268
+ );
269
+ }
270
+ function inferPreset(lines) {
271
+ const modifiers = new Set(lines.flatMap((line) => line.modifiers));
272
+ return modifiers.has("94") ? "ame" : modifiers.has("96") ? "psych_qme" : "qme";
273
+ }
274
+ function presetModifiersForCode(preset, code) {
275
+ if (code === "MLPRR") return ["95"];
276
+ if (preset === "qme" && ["ML200", "ML201", "ML202", "ML203"].includes(code)) return ["95"];
277
+ if (preset === "ame" && ["ML201", "ML202", "ML203"].includes(code)) return ["94"];
278
+ if (preset === "psych_qme") {
279
+ if (code === "ML200") return ["95"];
280
+ if (["ML201", "ML202", "ML203"].includes(code)) return ["96"];
281
+ }
282
+ return [];
283
+ }
284
+ function modifierAppliesToCode(modifier, code) {
285
+ return !code || (MODIFIER_CODES[modifier]?.includes(code) ?? true);
286
+ }
287
+ function applyPreset(lines, preset) {
288
+ return lines.map((line) => {
289
+ const preserved = line.modifiers.filter(
290
+ (value) => !MANAGED_EVALUATOR_MODIFIERS.has(value) && modifierAppliesToCode(value, line.code)
291
+ );
292
+ return {
293
+ ...line,
294
+ modifiers: [.../* @__PURE__ */ new Set([...presetModifiersForCode(preset, line.code), ...preserved])]
295
+ };
296
+ });
297
+ }
122
298
  function BillReviewForm({
123
299
  data,
124
300
  onSave,
@@ -126,12 +302,19 @@ function BillReviewForm({
126
302
  onAddAttachment,
127
303
  onRemoveAttachment,
128
304
  onOpenAttachment,
305
+ onSearchClaimsAdministrators,
129
306
  className,
130
307
  style,
131
308
  appearance,
309
+ features,
132
310
  disabled = false
133
311
  }) {
134
312
  const [draft, setDraft] = useState(() => toDraft(data));
313
+ const [payerQuery, setPayerQuery] = useState(
314
+ () => data.injury.claimsAdminName || ""
315
+ );
316
+ const [payerResults, setPayerResults] = useState([]);
317
+ const [payerBusy, setPayerBusy] = useState(false);
135
318
  const [route, setRoute] = useState("ebill");
136
319
  const [file, setFile] = useState(null);
137
320
  const [documentType, setDocumentType] = useState("other");
@@ -140,13 +323,56 @@ function BillReviewForm({
140
323
  const [notice, setNotice] = useState("");
141
324
  const routeName = useId();
142
325
  const editable = data.bill.status === "incomplete" && !disabled;
143
- useEffect(() => setDraft(toDraft(data)), [data]);
144
- const canSubmit = useMemo(
145
- () => Boolean(
146
- draft.dos && draft.billingProvider.name.trim() && draft.billingProvider.taxId.trim() && draft.billingProvider.npi.trim() && draft.clinician.name.trim() && draft.clinician.npi.trim() && draft.location.name.trim() && draft.location.street.trim() && draft.location.city.trim() && draft.location.state.trim() && draft.location.zip.trim() && draft.lineItems.length && draft.lineItems.every((line) => line.code.trim() && line.units > 0)
147
- ),
148
- [draft]
149
- );
326
+ useEffect(() => {
327
+ setDraft(toDraft(data));
328
+ setPayerQuery(data.injury.claimsAdminName || "");
329
+ }, [data]);
330
+ useEffect(() => {
331
+ if (!onSearchClaimsAdministrators || payerQuery.trim().length < 2) {
332
+ setPayerResults([]);
333
+ setPayerBusy(false);
334
+ return;
335
+ }
336
+ let current = true;
337
+ const timer = window.setTimeout(() => {
338
+ setPayerBusy(true);
339
+ void onSearchClaimsAdministrators(payerQuery.trim()).then((results) => {
340
+ if (current) setPayerResults(results);
341
+ }).catch((cause) => {
342
+ if (current) {
343
+ setPayerResults([]);
344
+ setError(
345
+ cause instanceof Error ? cause.message : "Claims administrator search is unavailable."
346
+ );
347
+ }
348
+ }).finally(() => {
349
+ if (current) setPayerBusy(false);
350
+ });
351
+ }, 200);
352
+ return () => {
353
+ current = false;
354
+ window.clearTimeout(timer);
355
+ };
356
+ }, [onSearchClaimsAdministrators, payerQuery]);
357
+ const adjFormatValid = !draft.adjNumber || /^ADJ\d{7,}$/i.test(draft.adjNumber.replace(/[\s-]/g, ""));
358
+ const blockers = useMemo(() => {
359
+ const result = [];
360
+ if (!draft.patientFirstName.trim() || !draft.patientLastName.trim()) result.push("Patient name");
361
+ if (!draft.claimsAdminId) result.push("Claims administrator");
362
+ if (!draft.claimNumber.trim()) result.push("Claim number");
363
+ if (!draft.doi) result.push("Date of injury");
364
+ if (!adjFormatValid) result.push("Valid WCAB / ADJ number");
365
+ if (!draft.dos) result.push("Date of service");
366
+ if (!draft.billingProvider.name.trim()) result.push("Practice name");
367
+ if (!draft.billingProvider.taxId.trim()) result.push("Tax ID");
368
+ if (!draft.billingProvider.npi.trim()) result.push("Billing NPI");
369
+ if (!draft.clinician.name.trim() || !draft.clinician.npi.trim()) result.push("Clinician and NPI");
370
+ if (![draft.location.name, draft.location.street, draft.location.city, draft.location.state, draft.location.zip].every((value) => value.trim())) result.push("Service location");
371
+ const completedLines = draft.lineItems.filter((line) => line.code.trim());
372
+ if (!completedLines.length || completedLines.some((line) => line.units <= 0)) result.push("Valid procedure line");
373
+ return result;
374
+ }, [adjFormatValid, draft]);
375
+ const canSubmit = blockers.length === 0;
150
376
  const updateBillingProvider = (key, value) => setDraft((current) => ({
151
377
  ...current,
152
378
  billingProvider: { ...current.billingProvider, [key]: value }
@@ -168,7 +394,7 @@ function BillReviewForm({
168
394
  setNotice(action === "save" ? "Changes saved." : "Bill submitted.");
169
395
  } catch (cause) {
170
396
  setError(
171
- cause instanceof Error ? cause.message : "MindBill could not complete this request."
397
+ cause instanceof Error ? cause.message : "The billing request could not be completed."
172
398
  );
173
399
  } finally {
174
400
  setBusy("");
@@ -223,30 +449,90 @@ function BillReviewForm({
223
449
  /* @__PURE__ */ jsxs("dl", { className: "mb-native-summary", children: [
224
450
  /* @__PURE__ */ jsxs("div", { children: [
225
451
  /* @__PURE__ */ jsx("dt", { children: "Patient" }),
226
- /* @__PURE__ */ jsx("dd", { children: data.patient.name || "\u2014" })
452
+ /* @__PURE__ */ jsx("dd", { children: [draft.patientFirstName, draft.patientMiddleName, draft.patientLastName].filter(Boolean).join(" ") || "\u2014" })
227
453
  ] }),
228
454
  /* @__PURE__ */ jsxs("div", { children: [
229
455
  /* @__PURE__ */ jsx("dt", { children: "Claim" }),
230
- /* @__PURE__ */ jsx("dd", { children: data.injury.claimNumber || "\u2014" })
456
+ /* @__PURE__ */ jsx("dd", { children: draft.claimNumber || "\u2014" })
231
457
  ] }),
232
458
  /* @__PURE__ */ jsxs("div", { children: [
233
459
  /* @__PURE__ */ jsx("dt", { children: "Employer" }),
234
- /* @__PURE__ */ jsx("dd", { children: data.injury.employer || "\u2014" })
460
+ /* @__PURE__ */ jsx("dd", { children: draft.employer || "\u2014" })
235
461
  ] }),
236
462
  /* @__PURE__ */ jsxs("div", { children: [
237
463
  /* @__PURE__ */ jsx("dt", { children: "Date of injury" }),
238
- /* @__PURE__ */ jsx("dd", { children: data.injury.doi || "\u2014" })
464
+ /* @__PURE__ */ jsx("dd", { children: draft.doi || "\u2014" })
465
+ ] })
466
+ ] }),
467
+ /* @__PURE__ */ jsxs("section", { className: sectionClass, children: [
468
+ /* @__PURE__ */ jsxs("div", { className: "mb-native-section-head", children: [
469
+ /* @__PURE__ */ jsxs("div", { children: [
470
+ /* @__PURE__ */ jsx("h3", { children: "Claims administrator" }),
471
+ /* @__PURE__ */ jsx("p", { children: "Select the carrier or administrator that should receive this bill." })
472
+ ] }),
473
+ draft.claimsAdminId ? /* @__PURE__ */ jsx("span", { children: "Selected" }) : /* @__PURE__ */ jsx("span", { children: "Required" })
474
+ ] }),
475
+ /* @__PURE__ */ jsxs("div", { className: "mb-native-payer-picker", children: [
476
+ /* @__PURE__ */ jsx(
477
+ Combobox,
478
+ {
479
+ label: "Insurance company or claims administrator",
480
+ value: payerQuery,
481
+ disabled: !editable,
482
+ placeholder: "Search by payer or administrator name",
483
+ name: "mindbill-payer-query",
484
+ options: payerResults.map((payer) => ({ value: payer.id, label: payer.name, detail: payer.hasElectronic ? "Electronic billing available" : "Billing route confirmed after review" })),
485
+ onChange: (value, option) => {
486
+ if (option) {
487
+ setDraft((current) => ({ ...current, claimsAdminId: option.value, claimsAdminName: option.label }));
488
+ setPayerQuery(option.label);
489
+ setPayerResults([]);
490
+ setNotice("Claims administrator selected. Save changes to keep it on this bill.");
491
+ } else {
492
+ setPayerQuery(value);
493
+ setDraft((current) => value === current.claimsAdminName ? current : { ...current, claimsAdminId: "", claimsAdminName: "" });
494
+ }
495
+ }
496
+ }
497
+ ),
498
+ payerBusy ? /* @__PURE__ */ jsx("span", { className: "mb-native-payer-help", children: "Searching\u2026" }) : null,
499
+ !payerBusy && payerQuery.trim().length > 1 && payerResults.length === 0 && !draft.claimsAdminId ? /* @__PURE__ */ jsx("span", { className: "mb-native-payer-help", children: "No matching administrator selected yet." }) : null
500
+ ] })
501
+ ] }),
502
+ /* @__PURE__ */ jsxs("section", { className: sectionClass, children: [
503
+ /* @__PURE__ */ jsxs("div", { className: "mb-native-section-head", children: [
504
+ /* @__PURE__ */ jsxs("div", { children: [
505
+ /* @__PURE__ */ jsx("h3", { children: "Patient and claim" }),
506
+ /* @__PURE__ */ jsx("p", { children: "Prefilled from the case. Correct anything that should print differently on this bill." })
507
+ ] }),
508
+ /* @__PURE__ */ jsx("span", { children: "Editable" })
509
+ ] }),
510
+ /* @__PURE__ */ jsxs("div", { className: "mb-native-grid three", children: [
511
+ /* @__PURE__ */ jsx(Field, { label: "Patient first name", required: true, disabled: !editable, value: draft.patientFirstName, onChange: (patientFirstName) => setDraft((current) => ({ ...current, patientFirstName })) }),
512
+ /* @__PURE__ */ jsx(Field, { label: "Middle name", optional: true, disabled: !editable, value: draft.patientMiddleName, onChange: (patientMiddleName) => setDraft((current) => ({ ...current, patientMiddleName })) }),
513
+ /* @__PURE__ */ jsx(Field, { label: "Patient last name", required: true, disabled: !editable, value: draft.patientLastName, onChange: (patientLastName) => setDraft((current) => ({ ...current, patientLastName })) }),
514
+ /* @__PURE__ */ jsx(Field, { label: "Date of birth", type: "date", required: true, disabled: !editable, value: draft.patientDob, onChange: (patientDob) => setDraft((current) => ({ ...current, patientDob })) }),
515
+ /* @__PURE__ */ jsx(Field, { label: "Claim number", required: true, disabled: !editable, value: draft.claimNumber, onChange: (claimNumber) => setDraft((current) => ({ ...current, claimNumber })), ...data.injury.claimPatternStatus?.detail || data.injury.claimPatternStatus?.label ? { hint: data.injury.claimPatternStatus?.detail || data.injury.claimPatternStatus?.label || "" } : {} }),
516
+ /* @__PURE__ */ jsx(Field, { label: "Employer", disabled: !editable, value: draft.employer, onChange: (employer) => setDraft((current) => ({ ...current, employer })) }),
517
+ /* @__PURE__ */ jsx(Field, { label: "Date of injury", type: "date", required: true, disabled: !editable, value: draft.doi, onChange: (doi) => setDraft((current) => ({ ...current, doi })) }),
518
+ draft.cumulativeTrauma ? /* @__PURE__ */ jsx(Field, { label: "Cumulative trauma end date", type: "date", required: true, disabled: !editable, value: draft.injuryEndDate, onChange: (injuryEndDate) => setDraft((current) => ({ ...current, injuryEndDate })) }) : null,
519
+ features?.wcabNumber === false ? null : /* @__PURE__ */ jsx(Field, { label: "WCAB / ADJ number", optional: true, disabled: !editable, value: draft.adjNumber, onChange: (adjNumber) => setDraft((current) => ({ ...current, adjNumber })), hint: adjFormatValid ? "Use the EAMS case number shown as ADJ followed by digits." : "Expected format: ADJ followed by at least 7 digits." })
520
+ ] }),
521
+ features?.wcabNumber === false ? null : /* @__PURE__ */ jsxs("p", { className: "mb-native-eams", children: [
522
+ "EAMS lookup requires California DWC verification. ",
523
+ /* @__PURE__ */ jsx("a", { href: "https://eams.dwc.ca.gov/WebEnhancement/", target: "_blank", rel: "noreferrer", children: "Verify in EAMS" }),
524
+ "."
239
525
  ] })
240
526
  ] }),
241
527
  /* @__PURE__ */ jsxs("section", { className: sectionClass, children: [
242
528
  /* @__PURE__ */ jsx("div", { className: "mb-native-section-head", children: /* @__PURE__ */ jsxs("div", { children: [
243
- /* @__PURE__ */ jsx("h3", { children: "Claim and service" }),
244
- /* @__PURE__ */ jsx("p", { children: "These values print on the bill." })
529
+ /* @__PURE__ */ jsx("h3", { children: "Service" }),
530
+ /* @__PURE__ */ jsx("p", { children: "The service date and optional payer authorization printed on this bill." })
245
531
  ] }) }),
246
- /* @__PURE__ */ jsxs("div", { className: "mb-native-grid three", children: [
247
- /* @__PURE__ */ jsx(Field, { label: "Date of service", type: "date", required: true, value: draft.dos, onChange: (dos) => setDraft((current) => ({ ...current, dos })) }),
248
- /* @__PURE__ */ jsx(Field, { label: "End date", type: "date", optional: true, value: draft.dosEnd, onChange: (dosEnd) => setDraft((current) => ({ ...current, dosEnd })) }),
249
- /* @__PURE__ */ jsx(Field, { label: "Authorization number", optional: true, value: draft.authorizationNumber, onChange: (authorizationNumber) => setDraft((current) => ({ ...current, authorizationNumber })) })
532
+ /* @__PURE__ */ jsxs("div", { className: `mb-native-grid ${features?.serviceDateRange || features?.authorizationNumber !== false ? "three" : "one"}`, children: [
533
+ /* @__PURE__ */ jsx(Field, { label: "Date of service", type: "date", required: true, disabled: !editable, value: draft.dos, onChange: (dos) => setDraft((current) => ({ ...current, dos })) }),
534
+ features?.serviceDateRange ? /* @__PURE__ */ jsx(Field, { label: "Service end date", type: "date", optional: true, disabled: !editable, value: draft.dosEnd, onChange: (dosEnd) => setDraft((current) => ({ ...current, dosEnd })) }) : null,
535
+ features?.authorizationNumber === false ? null : /* @__PURE__ */ jsx(Field, { label: "Authorization number", optional: true, disabled: !editable, value: draft.authorizationNumber, onChange: (authorizationNumber) => setDraft((current) => ({ ...current, authorizationNumber })) })
250
536
  ] })
251
537
  ] }),
252
538
  /* @__PURE__ */ jsxs("section", { className: sectionClass, children: [
@@ -260,11 +546,11 @@ function BillReviewForm({
260
546
  /* @__PURE__ */ jsxs("div", { className: "mb-native-grid three", children: [
261
547
  /* @__PURE__ */ jsx(Field, { label: "Practice name", required: true, value: draft.billingProvider.name, onChange: (value) => updateBillingProvider("name", value) }),
262
548
  /* @__PURE__ */ jsx(Field, { label: "Tax ID", required: true, value: draft.billingProvider.taxId, onChange: (value) => updateBillingProvider("taxId", value) }),
263
- /* @__PURE__ */ jsx(Field, { label: "Group NPI", required: true, value: draft.billingProvider.npi, onChange: (value) => updateBillingProvider("npi", value) }),
549
+ /* @__PURE__ */ jsx(Field, { label: "Billing NPI", required: true, value: draft.billingProvider.npi, onChange: (value) => updateBillingProvider("npi", value) }),
264
550
  /* @__PURE__ */ jsx(Field, { label: "Phone", optional: true, value: draft.billingProvider.phone || "", onChange: (value) => updateBillingProvider("phone", value) }),
265
551
  /* @__PURE__ */ jsx(Field, { label: "Billing street", required: true, value: draft.billingProvider.billingStreet || "", onChange: (value) => updateBillingProvider("billingStreet", value) }),
266
552
  /* @__PURE__ */ jsx(Field, { label: "City", required: true, value: draft.billingProvider.billingCity || "", onChange: (value) => updateBillingProvider("billingCity", value) }),
267
- /* @__PURE__ */ jsx(Field, { label: "State", required: true, value: draft.billingProvider.billingState || "", onChange: (value) => updateBillingProvider("billingState", value) }),
553
+ /* @__PURE__ */ jsx(StateCombobox, { label: "State", required: true, disabled: !editable, value: draft.billingProvider.billingState || "", onChange: (value) => updateBillingProvider("billingState", value) }),
268
554
  /* @__PURE__ */ jsx(Field, { label: "ZIP", required: true, value: draft.billingProvider.billingZip || "", onChange: (value) => updateBillingProvider("billingZip", value) })
269
555
  ] })
270
556
  ] }),
@@ -282,7 +568,7 @@ function BillReviewForm({
282
568
  /* @__PURE__ */ jsx(Field, { label: "NPI", required: true, value: draft.clinician.npi, onChange: (value) => updateClinician("npi", value) }),
283
569
  /* @__PURE__ */ jsx(Field, { label: "Taxonomy", optional: true, value: draft.clinician.taxonomy || "", onChange: (value) => updateClinician("taxonomy", value) }),
284
570
  /* @__PURE__ */ jsx(Field, { label: "License number", optional: true, value: draft.clinician.licenseNumber || "", onChange: (value) => updateClinician("licenseNumber", value) }),
285
- /* @__PURE__ */ jsx(Field, { label: "License state", optional: true, value: draft.clinician.licenseState || "", onChange: (value) => updateClinician("licenseState", value) })
571
+ /* @__PURE__ */ jsx(StateCombobox, { label: "License state (optional)", disabled: !editable, value: draft.clinician.licenseState || "", onChange: (value) => updateClinician("licenseState", value) })
286
572
  ] })
287
573
  ] }),
288
574
  /* @__PURE__ */ jsxs("section", { className: sectionClass, children: [
@@ -297,7 +583,7 @@ function BillReviewForm({
297
583
  /* @__PURE__ */ jsx(Field, { label: "Location name", required: true, value: draft.location.name, onChange: (value) => updateLocation("name", value) }),
298
584
  /* @__PURE__ */ jsx(Field, { label: "Street", required: true, value: draft.location.street, onChange: (value) => updateLocation("street", value) }),
299
585
  /* @__PURE__ */ jsx(Field, { label: "City", required: true, value: draft.location.city, onChange: (value) => updateLocation("city", value) }),
300
- /* @__PURE__ */ jsx(Field, { label: "State", required: true, value: draft.location.state, onChange: (value) => updateLocation("state", value) }),
586
+ /* @__PURE__ */ jsx(StateCombobox, { label: "State", required: true, disabled: !editable, value: draft.location.state, onChange: (value) => updateLocation("state", value) }),
301
587
  /* @__PURE__ */ jsx(Field, { label: "ZIP", required: true, value: draft.location.zip, onChange: (value) => updateLocation("zip", value) }),
302
588
  /* @__PURE__ */ jsx(Field, { label: "Place of service code", required: true, value: draft.location.posCode || "11", onChange: (value) => updateLocation("posCode", value) })
303
589
  ] })
@@ -306,16 +592,75 @@ function BillReviewForm({
306
592
  /* @__PURE__ */ jsxs("div", { className: "mb-native-section-head", children: [
307
593
  /* @__PURE__ */ jsxs("div", { children: [
308
594
  /* @__PURE__ */ jsx("h3", { children: "Procedure lines" }),
309
- /* @__PURE__ */ jsx("p", { children: "MindBill recalculates the allowed amount when changes are saved." })
595
+ /* @__PURE__ */ jsx("p", { children: "Choose a billing profile, then review the codes and modifiers. Allowed amounts recalculate on save." })
310
596
  ] }),
311
- /* @__PURE__ */ jsx("button", { type: "button", className: "mb-native-button quiet", disabled: !editable, onClick: () => setDraft((current) => ({ ...current, lineItems: [...current.lineItems, { code: "", modifiers: [], units: 1, charge: 0 }] })), children: "+ Add line" })
597
+ /* @__PURE__ */ jsx("button", { type: "button", className: "mb-native-button quiet", disabled: !editable || draft.lineItems.length >= 50, onClick: () => setDraft((current) => ({ ...current, lineItems: [...current.lineItems, { code: "", modifiers: [], units: 1, charge: 0 }] })), children: "+ Add line" })
598
+ ] }),
599
+ features?.codingPresets === false ? null : /* @__PURE__ */ jsxs("div", { className: "mb-native-presets", role: "group", "aria-label": "Evaluation billing profile", children: [
600
+ [["qme", "QME"], ["ame", "AME"], ["psych_qme", "Psych QME"]].map(([value, label]) => /* @__PURE__ */ jsx("button", { type: "button", className: inferPreset(draft.lineItems) === value ? "active" : "", disabled: !editable, onClick: () => setDraft((current) => ({ ...current, lineItems: applyPreset(current.lineItems, value) })), children: label }, value)),
601
+ /* @__PURE__ */ jsx("span", { children: "Sets evaluator modifiers across med-legal lines. You can still edit each line." })
312
602
  ] }),
313
603
  /* @__PURE__ */ jsx("div", { className: "mb-native-lines", children: draft.lineItems.map((line, index) => /* @__PURE__ */ jsxs("div", { className: "mb-native-line", children: [
314
- /* @__PURE__ */ jsx(Field, { label: "Procedure", required: true, value: line.code, onChange: (value) => setDraft((current) => ({ ...current, lineItems: current.lineItems.map((item, itemIndex) => itemIndex === index ? { ...item, code: value } : item) })) }),
315
- /* @__PURE__ */ jsx(Field, { label: "Modifiers", value: line.modifiers.join(", "), onChange: (value) => setDraft((current) => ({ ...current, lineItems: current.lineItems.map((item, itemIndex) => itemIndex === index ? { ...item, modifiers: value.split(",").map((part) => part.trim()).filter(Boolean) } : item) })) }),
604
+ /* @__PURE__ */ jsxs("label", { className: "mb-native-field", children: [
605
+ /* @__PURE__ */ jsx("span", { children: "Procedure" }),
606
+ /* @__PURE__ */ jsxs("select", { disabled: !editable, value: line.code, onChange: (event) => {
607
+ const code = event.target.value;
608
+ setDraft((current) => {
609
+ const lineItems = current.lineItems.map((item, itemIndex) => {
610
+ if (itemIndex !== index) return item;
611
+ const presetLine = applyPreset(
612
+ [{ ...item, code }],
613
+ inferPreset(current.lineItems)
614
+ )[0];
615
+ return { ...item, code, modifiers: presetLine?.modifiers || [] };
616
+ });
617
+ if (code && index === lineItems.length - 1 && lineItems.length < 50) {
618
+ lineItems.push({
619
+ code: "",
620
+ modifiers: [],
621
+ units: 1,
622
+ charge: 0
623
+ });
624
+ }
625
+ return { ...current, lineItems };
626
+ });
627
+ }, children: [
628
+ line.code && !PROCEDURES.some(([code]) => code === line.code) ? /* @__PURE__ */ jsx("option", { value: line.code, children: line.code }) : null,
629
+ /* @__PURE__ */ jsx("option", { value: "", children: "Select code\u2026" }),
630
+ PROCEDURES.map(([code, label]) => /* @__PURE__ */ jsxs("option", { value: code, children: [
631
+ code,
632
+ " \u2014 ",
633
+ label
634
+ ] }, code))
635
+ ] }),
636
+ line.code ? /* @__PURE__ */ jsx("small", { children: PROCEDURES.find(([code]) => code === line.code)?.[1] }) : null
637
+ ] }),
638
+ /* @__PURE__ */ jsxs("div", { className: "mb-native-modifiers", children: [
639
+ /* @__PURE__ */ jsxs("label", { className: "mb-native-field", children: [
640
+ /* @__PURE__ */ jsx("span", { children: "Modifiers" }),
641
+ /* @__PURE__ */ jsxs("select", { disabled: !editable, value: "", onChange: (event) => {
642
+ const modifier = event.target.value;
643
+ if (!modifier) return;
644
+ setDraft((current) => ({ ...current, lineItems: current.lineItems.map((item, itemIndex) => itemIndex === index ? { ...item, modifiers: [.../* @__PURE__ */ new Set([...item.modifiers, modifier])] } : item) }));
645
+ }, children: [
646
+ /* @__PURE__ */ jsx("option", { value: "", children: "Add modifier\u2026" }),
647
+ MODIFIERS.filter(([value]) => !line.modifiers.includes(value) && modifierAppliesToCode(value, line.code)).map(([value, label]) => /* @__PURE__ */ jsxs("option", { value, children: [
648
+ "-",
649
+ value,
650
+ " \u2014 ",
651
+ label
652
+ ] }, value))
653
+ ] })
654
+ ] }),
655
+ /* @__PURE__ */ jsx("div", { className: "mb-native-chips", children: line.modifiers.map((modifier) => /* @__PURE__ */ jsxs("button", { type: "button", disabled: !editable, onClick: () => setDraft((current) => ({ ...current, lineItems: current.lineItems.map((item, itemIndex) => itemIndex === index ? { ...item, modifiers: item.modifiers.filter((value) => value !== modifier) } : item) })), children: [
656
+ "-",
657
+ modifier,
658
+ " \xD7"
659
+ ] }, modifier)) })
660
+ ] }),
316
661
  /* @__PURE__ */ jsxs("label", { className: "mb-native-field", children: [
317
662
  /* @__PURE__ */ jsx("span", { children: "Units" }),
318
- /* @__PURE__ */ jsx("input", { type: "number", min: "1", required: true, value: line.units, onChange: (event) => setDraft((current) => ({ ...current, lineItems: current.lineItems.map((item, itemIndex) => itemIndex === index ? { ...item, units: Number(event.target.value) } : item) })) })
663
+ /* @__PURE__ */ jsx("input", { type: "number", min: "1", required: true, disabled: !editable, value: line.units, onChange: (event) => setDraft((current) => ({ ...current, lineItems: current.lineItems.map((item, itemIndex) => itemIndex === index ? { ...item, units: Number(event.target.value) } : item) })) })
319
664
  ] }),
320
665
  /* @__PURE__ */ jsxs("div", { className: "mb-native-allowed", children: [
321
666
  /* @__PURE__ */ jsx("span", { children: "Allowed" }),
@@ -362,7 +707,7 @@ function BillReviewForm({
362
707
  /* @__PURE__ */ jsxs("div", { children: [
363
708
  /* @__PURE__ */ jsx("span", { className: "mb-native-eyebrow", children: "Delivery" }),
364
709
  /* @__PURE__ */ jsx("h3", { children: "Submit this bill" }),
365
- /* @__PURE__ */ jsx("p", { children: "MindBill will send the claim and own status, payment, denial, and resubmission." })
710
+ /* @__PURE__ */ jsx("p", { children: "After submission, status, payments, denials, and resubmissions stay available here." })
366
711
  ] }),
367
712
  /* @__PURE__ */ jsxs("fieldset", { children: [
368
713
  /* @__PURE__ */ jsx("legend", { children: "Send via" }),
@@ -373,6 +718,10 @@ function BillReviewForm({
373
718
  ] }),
374
719
  error ? /* @__PURE__ */ jsx("div", { className: "mb-native-message error", role: "alert", children: error }) : null,
375
720
  notice ? /* @__PURE__ */ jsx("div", { className: "mb-native-message success", role: "status", children: notice }) : null,
721
+ !canSubmit ? /* @__PURE__ */ jsxs("div", { className: "mb-native-blockers", role: "status", children: [
722
+ /* @__PURE__ */ jsx("strong", { children: "Before you can submit:" }),
723
+ /* @__PURE__ */ jsx("span", { children: blockers.join(" \xB7 ") })
724
+ ] }) : null,
376
725
  /* @__PURE__ */ jsxs("div", { className: "mb-native-actions", children: [
377
726
  /* @__PURE__ */ jsx("button", { className: "mb-native-button secondary", type: "submit", disabled: !editable || busy !== "", children: busy === "save" ? "Saving\u2026" : "Save changes" }),
378
727
  /* @__PURE__ */ jsx("button", { className: "mb-native-button primary", type: "button", disabled: !editable || !canSubmit || busy !== "", onClick: () => void handleSubmit(), children: busy === "submit" ? "Submitting\u2026" : "Submit bill" })
@@ -415,6 +764,28 @@ var NATIVE_BILL_REVIEW_STYLES = `
415
764
  .mb-native-review,.mb-native-status{font-family:var(--mb-font,Inter,ui-sans-serif,system-ui,sans-serif)}
416
765
  .mb-native-review,.mb-native-status{--mb-accent:#238dbd;--mb-accent-dark:#176f98;--mb-text:#203743;--mb-muted:#657982;--mb-border:#dbe6ea;--mb-soft:#f3f8fa;--mb-surface:#fff;color:var(--mb-text);font:14px/1.45 Inter,ui-sans-serif,system-ui,sans-serif}.mb-native-review *,.mb-native-status *{box-sizing:border-box}.mb-native-review{display:grid;gap:16px}.mb-native-heading{display:flex;align-items:flex-end;justify-content:space-between;gap:24px;padding:6px 2px}.mb-native-heading h2,.mb-native-section h3,.mb-native-submit h3,.mb-native-status h3{margin:3px 0 2px;line-height:1.2}.mb-native-heading h2{font-size:25px}.mb-native-heading p,.mb-native-section p,.mb-native-submit p,.mb-native-status p{margin:0;color:var(--mb-muted)}.mb-native-eyebrow{color:#59727d;font-size:11px;font-weight:800;letter-spacing:.14em;text-transform:uppercase}.mb-native-total{display:flex;align-items:center;gap:18px}.mb-native-total span,.mb-native-section-head>span{border-radius:999px;background:var(--mb-soft);color:#58717c;font-size:11px;font-weight:800;padding:6px 10px;text-transform:capitalize}.mb-native-total strong{font-size:24px}.mb-native-summary{display:grid;grid-template-columns:repeat(4,1fr);margin:0;border:1px solid var(--mb-border);border-radius:12px;background:var(--mb-surface);overflow:hidden}.mb-native-summary div{padding:17px 20px;border-right:1px solid var(--mb-border)}.mb-native-summary div:last-child{border:0}.mb-native-summary dt,.mb-native-allowed span{color:#647982;font-size:10px;font-weight:800;letter-spacing:.12em;text-transform:uppercase}.mb-native-summary dd{margin:5px 0 0;font-weight:750}.mb-native-section{padding:20px;border:1px solid var(--mb-border);border-radius:14px;background:var(--mb-surface);box-shadow:0 8px 24px rgba(28,58,72,.04)}.mb-native-section-head{display:flex;align-items:start;justify-content:space-between;gap:16px;margin-bottom:17px}.mb-native-section h3,.mb-native-submit h3,.mb-native-status h3{font-size:19px}.mb-native-grid{display:grid;gap:14px}.mb-native-grid.three{grid-template-columns:repeat(3,minmax(0,1fr))}.mb-native-field{display:grid;gap:6px;min-width:0;color:var(--mb-text);font-size:12px;font-weight:750}.mb-native-field small{color:var(--mb-muted);font-size:inherit;font-weight:500}.mb-native-field input,.mb-native-attach select,.mb-native-attach input{width:100%;min-height:43px;border:1px solid var(--mb-border);border-radius:8px;background:#fff;color:var(--mb-text);font:inherit;padding:10px 12px}.mb-native-field input:focus,.mb-native-attach select:focus,.mb-native-attach input:focus{border-color:var(--mb-accent);box-shadow:0 0 0 3px color-mix(in srgb,var(--mb-accent) 14%,transparent);outline:0}.mb-native-lines{display:grid;gap:10px}.mb-native-line{display:grid;grid-template-columns:1.1fr 1.1fr 110px 120px 28px;align-items:end;gap:12px;padding:13px;background:var(--mb-soft);border:1px solid #e3edf0;border-radius:10px}.mb-native-allowed{display:grid;gap:5px;padding:0 8px 11px;text-align:right}.mb-native-allowed strong{font-size:16px}.mb-native-remove{border:0;background:transparent;color:#667d86;cursor:pointer;font-size:20px;padding:7px}.mb-native-note{padding:13px 15px;border:1px solid #bdd9e4;border-radius:9px;background:#f2f9fc;color:#526d78}.mb-native-note strong{color:var(--mb-text);margin-right:12px}.mb-native-documents{list-style:none;margin:14px 0;padding:0}.mb-native-documents li{display:grid;grid-template-columns:42px 1fr auto 28px;align-items:center;gap:12px;padding:12px 4px;border-bottom:1px solid var(--mb-border)}.mb-native-documents li>div{display:grid}.mb-native-documents li span{color:var(--mb-muted);font-size:12px}.mb-native-file{display:grid;place-items:center;width:40px;height:40px;border-radius:8px;background:#eaf5f9;color:var(--mb-accent)!important;font-size:11px!important;font-weight:850}.mb-native-attach{display:grid;grid-template-columns:1fr 230px minmax(220px,1fr) auto;align-items:end;gap:12px;padding:15px;border-radius:10px;background:var(--mb-soft)}.mb-native-attach>div{display:grid;gap:3px}.mb-native-attach span{color:var(--mb-muted);font-size:12px}.mb-native-button{min-height:40px;border:1px solid var(--mb-border);border-radius:8px;background:#fff;color:var(--mb-text);cursor:pointer;font:inherit;font-weight:750;padding:9px 14px}.mb-native-button.primary{border-color:var(--mb-accent);background:var(--mb-accent);color:#fff}.mb-native-button.primary:hover{background:var(--mb-accent-dark)}.mb-native-button.secondary{background:#fff}.mb-native-button.quiet{min-height:auto;background:var(--mb-soft);padding:7px 11px}.mb-native-button:disabled,.mb-native-remove:disabled{cursor:not-allowed;opacity:.5}.mb-native-submit{display:grid;grid-template-columns:1fr auto;align-items:end;gap:18px;padding:22px;border:1px solid #bcd8e2;border-radius:14px;background:linear-gradient(135deg,#f3fafc,#eaf6fa)}.mb-native-submit fieldset{display:flex;gap:6px;margin:0;padding:0;border:0}.mb-native-submit legend{position:absolute;width:1px;height:1px;overflow:hidden}.mb-native-submit fieldset label{display:flex;align-items:center;gap:6px;padding:9px 11px;border:1px solid #c9dce3;border-radius:8px;background:#fff;font-weight:700}.mb-native-actions{display:flex;justify-content:flex-end;gap:10px;grid-column:1/-1}.mb-native-message{grid-column:1/-1;padding:10px 12px;border-radius:8px}.mb-native-message.error{background:#fff0ef;color:#9d3029}.mb-native-message.success{background:#edf9f2;color:#217449}.mb-native-status{display:flex;align-items:center;justify-content:space-between;gap:20px;padding:20px;border:1px solid var(--mb-border);border-radius:12px;background:#fff}.mb-native-status h3{text-transform:capitalize}.mb-native-status dl{display:flex;margin:0}.mb-native-status dl div{min-width:110px;padding:0 18px;border-left:1px solid var(--mb-border)}.mb-native-status dt{color:var(--mb-muted);font-size:11px}.mb-native-status dd{margin:4px 0 0;font-size:17px;font-weight:800}@media(max-width:900px){.mb-native-grid.three{grid-template-columns:repeat(2,minmax(0,1fr))}.mb-native-summary{grid-template-columns:repeat(2,1fr)}.mb-native-summary div:nth-child(2){border-right:0}.mb-native-summary div:nth-child(-n+2){border-bottom:1px solid var(--mb-border)}.mb-native-line{grid-template-columns:1fr 1fr 90px}.mb-native-allowed{align-self:center}.mb-native-attach{grid-template-columns:1fr 1fr}.mb-native-submit{grid-template-columns:1fr}.mb-native-submit fieldset,.mb-native-actions{grid-column:1}.mb-native-actions{justify-content:start}}@media(max-width:620px){.mb-native-heading,.mb-native-total,.mb-native-status{align-items:start;flex-direction:column}.mb-native-grid.three,.mb-native-summary,.mb-native-line,.mb-native-attach{grid-template-columns:1fr}.mb-native-summary div,.mb-native-summary div:nth-child(2){border-right:0;border-bottom:1px solid var(--mb-border)}.mb-native-line{align-items:stretch}.mb-native-allowed{text-align:left}.mb-native-submit fieldset{display:grid;grid-template-columns:1fr 1fr}.mb-native-status dl{width:100%}.mb-native-status dl div{min-width:0;flex:1;padding:0 10px}.mb-native-status dl div:first-child{padding-left:0;border-left:0}}
417
766
  .mb-native-status-actions{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:8px}.mb-native-status-copy{min-width:150px}.mb-native-review,.mb-native-status{font-family:var(--mb-font,Inter,ui-sans-serif,system-ui,sans-serif)}
767
+ .mb-native-review{padding:clamp(16px,2vw,24px)}
768
+ .mb-native-grid.two{grid-template-columns:repeat(2,minmax(0,1fr))}
769
+ .mb-native-payer-picker{position:relative;max-width:760px}
770
+ .mb-native-payer-help{display:block;margin-top:7px;color:var(--mb-muted);font-size:12px}
771
+ .mb-native-payer-results{position:absolute;z-index:5;top:calc(100% + 6px);right:0;left:0;max-height:280px;overflow:auto;list-style:none;margin:0;padding:6px;border:1px solid var(--mb-border);border-radius:10px;background:var(--mb-surface);box-shadow:0 16px 40px rgba(28,58,72,.16)}
772
+ .mb-native-payer-results li{margin:0;padding:0}
773
+ .mb-native-payer-results button{display:grid;width:100%;gap:2px;padding:11px 12px;border:0;border-radius:7px;background:transparent;color:var(--mb-text);font:inherit;text-align:left;cursor:pointer}
774
+ .mb-native-payer-results button:hover,.mb-native-payer-results button:focus{background:var(--mb-soft);outline:0}
775
+ .mb-native-payer-results span{color:var(--mb-muted);font-size:12px}
776
+ .mb-native-grid.one{grid-template-columns:minmax(0,1fr)}
777
+ .mb-native-field select{width:100%;min-height:43px;border:1px solid var(--mb-border);border-radius:8px;background:#fff;color:var(--mb-text);font:inherit;padding:10px 36px 10px 12px}
778
+ .mb-native-field select:focus{border-color:var(--mb-accent);box-shadow:0 0 0 3px color-mix(in srgb,var(--mb-accent) 14%,transparent);outline:0}
779
+ .mb-native-field input:disabled,.mb-native-field select:disabled{cursor:not-allowed;background:#f6f8f9;color:#667982}
780
+ .mb-native-hint{color:var(--mb-muted);font-size:12px;font-weight:500}
781
+ .mb-native-combo{position:relative;min-width:0}
782
+ .mb-native-combo-list{position:absolute;z-index:20;top:calc(100% + 6px);right:0;left:0;max-height:300px;overflow:auto;list-style:none;margin:0;padding:6px;border:1px solid var(--mb-border);border-radius:10px;background:var(--mb-surface);box-shadow:0 18px 42px rgba(28,58,72,.18)}
783
+ .mb-native-combo-list li{margin:0;padding:0}.mb-native-combo-list button{display:grid;width:100%;gap:2px;padding:11px 12px;border:0;border-radius:7px;background:transparent;color:var(--mb-text);font:inherit;text-align:left;cursor:pointer}.mb-native-combo-list button:hover,.mb-native-combo-list button.active{background:var(--mb-soft);outline:0}.mb-native-combo-list span{color:var(--mb-muted);font-size:12px;font-weight:500}
784
+ .mb-native-presets{display:flex;align-items:center;flex-wrap:wrap;gap:7px;margin:-2px 0 14px}.mb-native-presets button{min-height:36px;border:1px solid var(--mb-border);border-radius:8px;background:#fff;color:var(--mb-text);cursor:pointer;font:inherit;font-weight:750;padding:7px 13px}.mb-native-presets button.active{border-color:var(--mb-accent);background:var(--mb-accent);color:#fff}.mb-native-presets span{margin-left:5px;color:var(--mb-muted);font-size:12px}
785
+ .mb-native-modifiers{display:grid;gap:7px}.mb-native-chips{display:flex;flex-wrap:wrap;gap:5px}.mb-native-chips button{border:1px solid #c9dce3;border-radius:999px;background:#fff;color:var(--mb-text);cursor:pointer;font:inherit;font-size:11px;font-weight:750;padding:4px 8px}
786
+ .mb-native-blockers{grid-column:1/-1;display:grid;gap:2px;padding:11px 13px;border:1px solid #e8cf9a;border-radius:8px;background:#fff9ea;color:#74531b}.mb-native-blockers span{font-size:12px}
787
+ .mb-native-eams{margin-top:13px!important;font-size:12px}.mb-native-eams a{color:var(--mb-accent);font-weight:750}
788
+ @media(max-width:620px){.mb-native-review{padding:12px}.mb-native-grid.two{grid-template-columns:1fr}}
418
789
  `;
419
790
 
420
791
  // src/connected-bill-status.tsx
@@ -422,7 +793,7 @@ import {
422
793
  useCallback,
423
794
  useEffect as useEffect2,
424
795
  useMemo as useMemo2,
425
- useRef,
796
+ useRef as useRef2,
426
797
  useState as useState2
427
798
  } from "react";
428
799
  import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
@@ -571,11 +942,11 @@ function useBillStatus({
571
942
  const [error, setError] = useState2(null);
572
943
  const [isLoading, setIsLoading] = useState2(enabled && !initialData);
573
944
  const [isRefreshing, setIsRefreshing] = useState2(false);
574
- const dataRef = useRef(initialData);
575
- const initialDataRef = useRef(initialData);
945
+ const dataRef = useRef2(initialData);
946
+ const initialDataRef = useRef2(initialData);
576
947
  initialDataRef.current = initialData;
577
- const activeControllerRef = useRef(null);
578
- const requestSequence = useRef(0);
948
+ const activeControllerRef = useRef2(null);
949
+ const requestSequence = useRef2(0);
579
950
  useEffect2(() => {
580
951
  const seed = initialDataRef.current;
581
952
  dataRef.current = seed;
@@ -681,7 +1052,7 @@ import {
681
1052
  useCallback as useCallback2,
682
1053
  useEffect as useEffect3,
683
1054
  useMemo as useMemo3,
684
- useRef as useRef2,
1055
+ useRef as useRef3,
685
1056
  useState as useState3
686
1057
  } from "react";
687
1058
  import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
@@ -701,14 +1072,14 @@ function isSessionFresh2(session) {
701
1072
  }
702
1073
  function normalizeSession2(value) {
703
1074
  if (!value || typeof value !== "object") {
704
- throw new Error("The MindBill session endpoint returned an invalid response.");
1075
+ throw new Error("The billing session endpoint returned an invalid response.");
705
1076
  }
706
1077
  const candidate = value;
707
1078
  const nested = candidate.session ?? candidate.data;
708
1079
  const session = nested && typeof nested === "object" ? nested : candidate;
709
1080
  if (typeof session.token !== "string" || session.token.length < 8) {
710
1081
  throw new Error(
711
- "The MindBill session endpoint did not return a browser session token."
1082
+ "The billing session endpoint did not return a browser session token."
712
1083
  );
713
1084
  }
714
1085
  return {
@@ -719,11 +1090,11 @@ function normalizeSession2(value) {
719
1090
  }
720
1091
  function normalizeLifecycle(value) {
721
1092
  if (!value || typeof value !== "object") {
722
- throw new Error("MindBill returned an invalid bill lifecycle.");
1093
+ throw new Error("The billing service returned an invalid bill lifecycle.");
723
1094
  }
724
1095
  const data = value;
725
1096
  if (!data.bill || !data.patient || !data.injury || !data.lifecycle || !Array.isArray(data.lifecycle.actions) || !Array.isArray(data.eors)) {
726
- throw new Error("MindBill returned an invalid bill lifecycle.");
1097
+ throw new Error("The billing service returned an invalid bill lifecycle.");
727
1098
  }
728
1099
  return data;
729
1100
  }
@@ -759,7 +1130,7 @@ function createBillLifecycleClient({
759
1130
  if (!response.ok) {
760
1131
  throw await responseError2(
761
1132
  response,
762
- "MindBill browser session could not be created."
1133
+ "The billing session could not be created."
763
1134
  );
764
1135
  }
765
1136
  return response.json();
@@ -800,6 +1171,34 @@ function createBillLifecycleClient({
800
1171
  const body = await response.json();
801
1172
  return normalizeLifecycle(body.data);
802
1173
  };
1174
+ const searchClaimsAdministrators = async (query) => {
1175
+ const response = await request(
1176
+ `/embed/api/bill-review/payers?q=${encodeURIComponent(query)}`
1177
+ );
1178
+ if (!response.ok) {
1179
+ throw await responseError2(
1180
+ response,
1181
+ "Claims administrator search is unavailable."
1182
+ );
1183
+ }
1184
+ const body = await response.json();
1185
+ if (!Array.isArray(body.results)) {
1186
+ throw new Error("Claims administrator search returned an invalid response.");
1187
+ }
1188
+ return body.results.flatMap((value) => {
1189
+ if (!value || typeof value !== "object") return [];
1190
+ const payer = value;
1191
+ if (typeof payer.id !== "string" || typeof payer.name !== "string") {
1192
+ return [];
1193
+ }
1194
+ return [{
1195
+ id: payer.id,
1196
+ name: payer.name,
1197
+ ...typeof payer.hasElectronic === "boolean" ? { hasElectronic: payer.hasElectronic } : {},
1198
+ ...Array.isArray(payer.states) ? { states: payer.states.filter((state) => typeof state === "string") } : {}
1199
+ }];
1200
+ });
1201
+ };
803
1202
  const mutation = async (path, init, fallback) => {
804
1203
  const headers = new Headers(init.headers);
805
1204
  headers.set("idempotency-key", idempotencyKey());
@@ -838,6 +1237,7 @@ function createBillLifecycleClient({
838
1237
  sessionRequest = null;
839
1238
  },
840
1239
  getLifecycle: loadLifecycle,
1240
+ searchClaimsAdministrators,
841
1241
  saveReview,
842
1242
  async submitBill(input, route) {
843
1243
  await saveReview(input);
@@ -915,7 +1315,7 @@ function createBillLifecycleClient({
915
1315
  );
916
1316
  const body = await response.json();
917
1317
  if (typeof body.replacementBillId !== "string") {
918
- throw new Error("MindBill did not return the correction bill ID.");
1318
+ throw new Error("The billing service did not return the correction bill ID.");
919
1319
  }
920
1320
  return {
921
1321
  replacementBillId: body.replacementBillId,
@@ -951,7 +1351,7 @@ function useBillLifecycle({
951
1351
  const [isLoading, setIsLoading] = useState3(enabled && !initialData);
952
1352
  const [isRefreshing, setIsRefreshing] = useState3(false);
953
1353
  const [isMutating, setIsMutating] = useState3(false);
954
- const mounted = useRef2(true);
1354
+ const mounted = useRef3(true);
955
1355
  useEffect3(() => {
956
1356
  setBillId(providedBillId);
957
1357
  setData(initialData);
@@ -1008,7 +1408,7 @@ function useBillLifecycle({
1008
1408
  if (mounted.current) setData(next);
1009
1409
  return next;
1010
1410
  } catch (cause) {
1011
- const nextError = cause instanceof Error ? cause : new Error("MindBill could not complete this request.");
1411
+ const nextError = cause instanceof Error ? cause : new Error("The billing service could not complete this request.");
1012
1412
  if (mounted.current) setError(nextError);
1013
1413
  throw nextError;
1014
1414
  } finally {
@@ -1019,6 +1419,10 @@ function useBillLifecycle({
1019
1419
  (input) => mutate(() => client.saveReview(input)),
1020
1420
  [client, mutate]
1021
1421
  );
1422
+ const searchClaimsAdministrators = useCallback2(
1423
+ (query) => client.searchClaimsAdministrators(query),
1424
+ [client]
1425
+ );
1022
1426
  const submitBill = useCallback2(
1023
1427
  (input, route) => mutate(() => client.submitBill(input, route)),
1024
1428
  [client, mutate]
@@ -1075,6 +1479,7 @@ function useBillLifecycle({
1075
1479
  isRefreshing,
1076
1480
  isMutating,
1077
1481
  refresh,
1482
+ searchClaimsAdministrators,
1078
1483
  saveReview,
1079
1484
  submitBill,
1080
1485
  addAttachment,
@@ -1131,6 +1536,7 @@ function SupportingDocumentControl({
1131
1536
  }
1132
1537
  function ConnectedBillLifecycle({
1133
1538
  appearance,
1539
+ features,
1134
1540
  className,
1135
1541
  style,
1136
1542
  loadingFallback,
@@ -1157,7 +1563,7 @@ function ConnectedBillLifecycle({
1157
1563
  attachmentIds: [],
1158
1564
  route: "ebill"
1159
1565
  });
1160
- const lastData = useRef2(null);
1566
+ const lastData = useRef3(null);
1161
1567
  useEffect3(() => {
1162
1568
  if (!data || data === lastData.current) return;
1163
1569
  lastData.current = data;
@@ -1217,7 +1623,9 @@ function ConnectedBillLifecycle({
1217
1623
  {
1218
1624
  data,
1219
1625
  ...appearance ? { appearance } : {},
1626
+ ...features ? { features } : {},
1220
1627
  disabled: lifecycle.isMutating,
1628
+ onSearchClaimsAdministrators: lifecycle.searchClaimsAdministrators,
1221
1629
  onSave: lifecycle.saveReview,
1222
1630
  onSubmit: async (input, route) => {
1223
1631
  await complete("Bill submitted.", () => lifecycle.submitBill(input, route));
@@ -1250,7 +1658,7 @@ function ConnectedBillLifecycle({
1250
1658
  "Bill #",
1251
1659
  data.bill.billNumber
1252
1660
  ] }),
1253
- /* @__PURE__ */ jsx3("span", { children: lifecycle.isRefreshing ? "Refreshing\u2026" : "MindBill manages this lifecycle." })
1661
+ /* @__PURE__ */ jsx3("span", { children: lifecycle.isRefreshing ? "Refreshing\u2026" : "Status and actions update automatically." })
1254
1662
  ] }),
1255
1663
  /* @__PURE__ */ jsxs3("div", { className: "mb-lifecycle-toolbar-actions", children: [
1256
1664
  has("view_eor") ? /* @__PURE__ */ jsx3("button", { type: "button", className: "mb-lifecycle-button secondary", onClick: () => document.getElementById(`mb-eors-${data.bill.id}`)?.scrollIntoView({ behavior: "smooth", block: "center" }), children: "View EOR" }) : null,
@@ -1284,7 +1692,7 @@ function ConnectedBillLifecycle({
1284
1692
  panel === "correction" ? /* @__PURE__ */ jsxs3("section", { className: "mb-lifecycle-panel", children: [
1285
1693
  /* @__PURE__ */ jsxs3("div", { children: [
1286
1694
  /* @__PURE__ */ jsx3("h3", { children: "Correct and resubmit" }),
1287
- /* @__PURE__ */ jsx3("p", { children: "MindBill will create a new correction draft and preserve this rejected bill in history. Review the copied values before submitting." })
1695
+ /* @__PURE__ */ jsx3("p", { children: "A new correction draft will preserve this rejected bill in history. Review the copied values before submitting." })
1288
1696
  ] }),
1289
1697
  /* @__PURE__ */ jsxs3("div", { className: "mb-lifecycle-panel-actions", children: [
1290
1698
  /* @__PURE__ */ jsx3("button", { type: "button", className: "mb-lifecycle-button secondary", onClick: () => setPanel(""), children: "Cancel" }),
@@ -1294,7 +1702,7 @@ function ConnectedBillLifecycle({
1294
1702
  panel === "second_review" ? /* @__PURE__ */ jsxs3("section", { className: "mb-lifecycle-panel wide", children: [
1295
1703
  /* @__PURE__ */ jsxs3("div", { children: [
1296
1704
  /* @__PURE__ */ jsx3("h3", { children: "Submit Second Review" }),
1297
- /* @__PURE__ */ jsx3("p", { children: "State why payment is disputed, confirm the payer control number, and choose the supporting documents MindBill should send." })
1705
+ /* @__PURE__ */ jsx3("p", { children: "State why payment is disputed, confirm the payer control number, and choose the supporting documents to send." })
1298
1706
  ] }),
1299
1707
  /* @__PURE__ */ jsxs3("div", { className: "mb-lifecycle-fields two", children: [
1300
1708
  /* @__PURE__ */ jsxs3("label", { children: [
@@ -1351,7 +1759,7 @@ function ConnectedBillLifecycle({
1351
1759
  panel === "payment" ? /* @__PURE__ */ jsxs3("section", { className: "mb-lifecycle-panel", children: [
1352
1760
  /* @__PURE__ */ jsxs3("div", { children: [
1353
1761
  /* @__PURE__ */ jsx3("h3", { children: "Post payment" }),
1354
- /* @__PURE__ */ jsx3("p", { children: "Record funds shown on the EOR. MindBill updates the balance and closes the bill automatically when configured." })
1762
+ /* @__PURE__ */ jsx3("p", { children: "Record funds shown on the EOR. The balance updates and the bill closes automatically when configured." })
1355
1763
  ] }),
1356
1764
  /* @__PURE__ */ jsxs3("div", { className: "mb-lifecycle-fields two", children: [
1357
1765
  /* @__PURE__ */ jsxs3("label", { children: [
@@ -1410,7 +1818,7 @@ var CONNECTED_LIFECYCLE_STYLES = `
1410
1818
 
1411
1819
  // src/index.tsx
1412
1820
  function widget(tagName, props) {
1413
- const ref = useRef3(null);
1821
+ const ref = useRef4(null);
1414
1822
  const { onMindBill, onMindBillError } = props;
1415
1823
  useEffect4(() => {
1416
1824
  const element = ref.current;