@mindbill/react 0.42.4 → 0.44.0
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/README.md +12 -3
- package/dist/index.d.ts +252 -29
- package/dist/index.js +1383 -325
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
// src/index.tsx
|
|
4
4
|
import "@mindbill/embed";
|
|
5
|
-
import { createElement, useEffect as
|
|
5
|
+
import { createElement, useEffect as useEffect12, useRef as useRef7 } from "react";
|
|
6
6
|
|
|
7
7
|
// src/appearance.ts
|
|
8
8
|
var mindBillThemePresets = {
|
|
@@ -39,6 +39,23 @@ var mindBillThemePresets = {
|
|
|
39
39
|
warningColor: "#9a6418",
|
|
40
40
|
fontFamily: "Inter, ui-sans-serif, system-ui, sans-serif"
|
|
41
41
|
},
|
|
42
|
+
"calm-clinical": {
|
|
43
|
+
accentColor: "#52b4d7",
|
|
44
|
+
accentTextColor: "#173542",
|
|
45
|
+
backgroundColor: "#f2f8fb",
|
|
46
|
+
surfaceColor: "#ffffff",
|
|
47
|
+
inputBackgroundColor: "#ffffff",
|
|
48
|
+
textColor: "#20323c",
|
|
49
|
+
mutedColor: "#687b84",
|
|
50
|
+
borderColor: "#d8e4e9",
|
|
51
|
+
borderRadius: "12px",
|
|
52
|
+
controlRadius: "8px",
|
|
53
|
+
shadow: "0 1px 2px rgba(32,50,60,.05)",
|
|
54
|
+
dangerColor: "#b83f3a",
|
|
55
|
+
successColor: "#21835d",
|
|
56
|
+
warningColor: "#9a6418",
|
|
57
|
+
fontFamily: "Inter, ui-sans-serif, system-ui, sans-serif"
|
|
58
|
+
},
|
|
42
59
|
"orange-bright": {
|
|
43
60
|
accentColor: "#f4510b",
|
|
44
61
|
accentTextColor: "#ffffff",
|
|
@@ -2560,6 +2577,7 @@ function BillSubmissionForm({
|
|
|
2560
2577
|
modifierOptions,
|
|
2561
2578
|
taxonomyOptions,
|
|
2562
2579
|
deliveryRoutePicker = "auto",
|
|
2580
|
+
deliveryRouteDialogTitle = "Send bill",
|
|
2563
2581
|
attachmentReportTypeMode = "auto",
|
|
2564
2582
|
attachmentReportTypes = BILL_SUBMISSION_REPORT_TYPES,
|
|
2565
2583
|
defaultAttachmentReportType,
|
|
@@ -2854,37 +2872,42 @@ function BillSubmissionForm({
|
|
|
2854
2872
|
...administrator2 ? { claimsAdministrator: submittedClaimsAdministrator(administrator2) } : {}
|
|
2855
2873
|
}
|
|
2856
2874
|
};
|
|
2857
|
-
|
|
2858
|
-
setSubmitting(true);
|
|
2859
|
-
try {
|
|
2860
|
-
await onSubmit({ bill: complete, sourceAttachmentIds: selectedIds, sourceAttachmentReportTypes, uploads });
|
|
2861
|
-
} catch (caught) {
|
|
2862
|
-
setFormError(caught instanceof Error ? caught.message : "Unable to submit the bill.");
|
|
2863
|
-
} finally {
|
|
2864
|
-
setSubmitting(false);
|
|
2865
|
-
}
|
|
2866
|
-
return;
|
|
2867
|
-
}
|
|
2875
|
+
const value = { bill: complete, sourceAttachmentIds: selectedIds, sourceAttachmentReportTypes, uploads };
|
|
2868
2876
|
if (deliveryRoutePicker !== "off" && referenceClient) {
|
|
2869
2877
|
setSubmitting(true);
|
|
2870
2878
|
try {
|
|
2871
2879
|
const delivery = await referenceClient.getDeliveryPreview({
|
|
2872
2880
|
claimsAdministratorId: complete.claim.claimsAdministrator.id,
|
|
2881
|
+
...complete.claim.claimsAdministrator.payerId ? { payerId: complete.claim.claimsAdministrator.payerId } : {},
|
|
2873
2882
|
...complete.claim.injuryState ? { injuryState: complete.claim.injuryState } : {}
|
|
2874
2883
|
});
|
|
2875
2884
|
setSubmitting(false);
|
|
2876
2885
|
setRouteError(null);
|
|
2877
|
-
setRouteDialog({ delivery,
|
|
2886
|
+
setRouteDialog({ delivery, value });
|
|
2878
2887
|
return;
|
|
2879
|
-
} catch {
|
|
2888
|
+
} catch (caught) {
|
|
2880
2889
|
setSubmitting(false);
|
|
2890
|
+
if (deliveryRoutePicker === "required") {
|
|
2891
|
+
setFormError(caught instanceof Error ? caught.message : "Delivery routes could not be loaded. Nothing was sent.");
|
|
2892
|
+
return;
|
|
2893
|
+
}
|
|
2881
2894
|
}
|
|
2882
2895
|
}
|
|
2883
|
-
|
|
2896
|
+
if (deliveryRoutePicker === "required") {
|
|
2897
|
+
setFormError("Delivery confirmation is unavailable. Nothing was sent.");
|
|
2898
|
+
return;
|
|
2899
|
+
}
|
|
2900
|
+
await performSubmit(value);
|
|
2884
2901
|
}
|
|
2885
|
-
async function
|
|
2902
|
+
async function performSubmit(value) {
|
|
2886
2903
|
setSubmitting(true);
|
|
2887
2904
|
try {
|
|
2905
|
+
if (onSubmit) {
|
|
2906
|
+
await onSubmit(value);
|
|
2907
|
+
setRouteDialog(null);
|
|
2908
|
+
setRouteError(null);
|
|
2909
|
+
return;
|
|
2910
|
+
}
|
|
2888
2911
|
if (!submissionClient) throw new Error("The connected billing client is unavailable.");
|
|
2889
2912
|
const documents = await prepareBillSubmissionDocuments({
|
|
2890
2913
|
attachments,
|
|
@@ -2895,8 +2918,8 @@ function BillSubmissionForm({
|
|
|
2895
2918
|
...fetchOverride ? { fetch: fetchOverride } : {}
|
|
2896
2919
|
});
|
|
2897
2920
|
const result = await submissionClient.submitBill({
|
|
2898
|
-
bill:
|
|
2899
|
-
...submission ? { submission } : {},
|
|
2921
|
+
bill: value.bill,
|
|
2922
|
+
...value.submission ? { submission: value.submission } : {},
|
|
2900
2923
|
documents
|
|
2901
2924
|
});
|
|
2902
2925
|
setRouteDialog(null);
|
|
@@ -2904,7 +2927,7 @@ function BillSubmissionForm({
|
|
|
2904
2927
|
await onSubmitted?.(result);
|
|
2905
2928
|
} catch (caught) {
|
|
2906
2929
|
const message = caught instanceof Error ? caught.message : "Unable to submit the bill.";
|
|
2907
|
-
if (submission) setRouteError(message);
|
|
2930
|
+
if (value.submission) setRouteError(message);
|
|
2908
2931
|
else setFormError(message);
|
|
2909
2932
|
} finally {
|
|
2910
2933
|
setSubmitting(false);
|
|
@@ -3237,7 +3260,7 @@ function BillSubmissionForm({
|
|
|
3237
3260
|
routeDialog ? /* @__PURE__ */ jsx5(
|
|
3238
3261
|
SendRouteDialog,
|
|
3239
3262
|
{
|
|
3240
|
-
title:
|
|
3263
|
+
title: deliveryRouteDialogTitle,
|
|
3241
3264
|
delivery: routeDialog.delivery,
|
|
3242
3265
|
submitting,
|
|
3243
3266
|
error: routeError,
|
|
@@ -3248,7 +3271,7 @@ function BillSubmissionForm({
|
|
|
3248
3271
|
}
|
|
3249
3272
|
},
|
|
3250
3273
|
onConfirm: (submission) => {
|
|
3251
|
-
void
|
|
3274
|
+
void performSubmit({ ...routeDialog.value, submission });
|
|
3252
3275
|
}
|
|
3253
3276
|
}
|
|
3254
3277
|
) : null
|
|
@@ -3861,15 +3884,90 @@ function ribbonDate(iso) {
|
|
|
3861
3884
|
if (Number.isNaN(parsed.getTime())) return iso;
|
|
3862
3885
|
return new Intl.DateTimeFormat("en-US", { month: "2-digit", day: "2-digit", year: "numeric" }).format(parsed);
|
|
3863
3886
|
}
|
|
3864
|
-
function
|
|
3865
|
-
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
]
|
|
3872
|
-
}
|
|
3887
|
+
function attemptStatus(entries, attempt) {
|
|
3888
|
+
const rejected = [...entries].reverse().find(
|
|
3889
|
+
(entry) => entry.kind === "ack" && (/reject|deni|error/i.test(entry.action) || entry.tone === "problem")
|
|
3890
|
+
);
|
|
3891
|
+
if (rejected) return {
|
|
3892
|
+
badge: rejected.action,
|
|
3893
|
+
badgeTone: "danger",
|
|
3894
|
+
meta: [{ label: "Rejected", value: ribbonDate(rejected.date) }]
|
|
3895
|
+
};
|
|
3896
|
+
const complianceDueDate = entries.flatMap((entry) => entry.details?.complianceDueDates ?? []).find((due) => /payment|working day/i.test(due.text));
|
|
3897
|
+
if (complianceDueDate) return {
|
|
3898
|
+
badge: complianceDueDate.text,
|
|
3899
|
+
badgeTone: "warning",
|
|
3900
|
+
meta: [{ label: "Effective date", value: ribbonDate(complianceDueDate.date) }]
|
|
3901
|
+
};
|
|
3902
|
+
const processed = [...entries].reverse().find((entry) => entry.kind === "eor" || entry.kind === "payment");
|
|
3903
|
+
if (processed) return {
|
|
3904
|
+
badge: "Processed",
|
|
3905
|
+
badgeTone: "success",
|
|
3906
|
+
meta: [{ label: "Processed", value: ribbonDate(processed.date) }]
|
|
3907
|
+
};
|
|
3908
|
+
const accepted = [...entries].reverse().find(
|
|
3909
|
+
(entry) => entry.kind === "ack" && (/accept/i.test(entry.action) || entry.tone === "success")
|
|
3910
|
+
);
|
|
3911
|
+
if (accepted) return {
|
|
3912
|
+
badge: accepted.action,
|
|
3913
|
+
badgeTone: "success",
|
|
3914
|
+
meta: [{ label: "Accepted", value: ribbonDate(accepted.date) }]
|
|
3915
|
+
};
|
|
3916
|
+
const closed = [...entries].reverse().find((entry) => entry.kind === "close");
|
|
3917
|
+
if (closed) return {
|
|
3918
|
+
badge: "Closed",
|
|
3919
|
+
badgeTone: "neutral",
|
|
3920
|
+
meta: [{ label: "Closed", value: ribbonDate(closed.date) }]
|
|
3921
|
+
};
|
|
3922
|
+
if (attempt?.ackLabel) return {
|
|
3923
|
+
badge: attempt.ackLabel,
|
|
3924
|
+
badgeTone: /reject|deni|error/i.test(attempt.ackLabel) ? "danger" : /accept/i.test(attempt.ackLabel) ? "success" : "neutral",
|
|
3925
|
+
...attempt.ackAt ? { meta: [{ label: /reject|deni|error/i.test(attempt.ackLabel) ? "Rejected" : "Acknowledged", value: ribbonDate(attempt.ackAt) }] } : {}
|
|
3926
|
+
};
|
|
3927
|
+
if (attempt?.status) return {
|
|
3928
|
+
badge: attempt.status.replaceAll("_", " "),
|
|
3929
|
+
badgeTone: "neutral"
|
|
3930
|
+
};
|
|
3931
|
+
return {};
|
|
3932
|
+
}
|
|
3933
|
+
function billSubmissionsRibbonFromHistory(history, attempts = []) {
|
|
3934
|
+
if (attempts.length) {
|
|
3935
|
+
return attempts.map((attempt) => {
|
|
3936
|
+
const attemptEntries = history.filter((entry) => entry.attemptId === attempt.id);
|
|
3937
|
+
const submission = attemptEntries.find((entry) => entry.kind === "submission");
|
|
3938
|
+
const status = attemptStatus(attemptEntries, attempt);
|
|
3939
|
+
return {
|
|
3940
|
+
id: attempt.id,
|
|
3941
|
+
...submission ? { historyEntryId: submission.id } : {},
|
|
3942
|
+
label: attempt.label,
|
|
3943
|
+
...status.badge ? { badge: status.badge } : {},
|
|
3944
|
+
...status.badgeTone ? { badgeTone: status.badgeTone } : {},
|
|
3945
|
+
meta: [
|
|
3946
|
+
{ label: "Delivery", value: attempt.deliveryLabel ?? (submission ? billSubmissionsRibbonDeliveryLabel(submission.summary) : "\u2014") },
|
|
3947
|
+
{ label: "Sent", value: attempt.sentAt ? ribbonDate(attempt.sentAt) : submission ? ribbonDate(submission.date) : "\u2014" },
|
|
3948
|
+
...status.meta ?? []
|
|
3949
|
+
],
|
|
3950
|
+
active: attempt.isCurrent
|
|
3951
|
+
};
|
|
3952
|
+
});
|
|
3953
|
+
}
|
|
3954
|
+
const submissions = history.map((entry, index) => ({ entry, index })).filter(({ entry }) => entry.kind === "submission");
|
|
3955
|
+
return submissions.map(({ entry, index }, submissionIndex) => {
|
|
3956
|
+
const nextSubmissionIndex = submissions[submissionIndex + 1]?.index ?? history.length;
|
|
3957
|
+
const status = attemptStatus(history.slice(index, nextSubmissionIndex));
|
|
3958
|
+
return {
|
|
3959
|
+
id: entry.id,
|
|
3960
|
+
historyEntryId: entry.id,
|
|
3961
|
+
label: entry.action,
|
|
3962
|
+
...status.badge ? { badge: status.badge } : {},
|
|
3963
|
+
...status.badgeTone ? { badgeTone: status.badgeTone } : {},
|
|
3964
|
+
meta: [
|
|
3965
|
+
{ label: "Delivery", value: billSubmissionsRibbonDeliveryLabel(entry.summary) },
|
|
3966
|
+
{ label: "Sent", value: ribbonDate(entry.date) },
|
|
3967
|
+
...status.meta ?? []
|
|
3968
|
+
]
|
|
3969
|
+
};
|
|
3970
|
+
});
|
|
3873
3971
|
}
|
|
3874
3972
|
var css7 = `
|
|
3875
3973
|
.mbsr{display:flex;gap:10px;overflow-x:auto;padding-bottom:4px;color:var(--mb-text);font-family:var(--mb-font);font-size:13px}
|
|
@@ -3879,7 +3977,10 @@ var css7 = `
|
|
|
3879
3977
|
.mbsr-chip[data-active=true]{border-color:var(--mb-accent);background:color-mix(in srgb,var(--mb-accent) 7%,var(--mb-surface));box-shadow:0 0 0 1px var(--mb-accent) inset}
|
|
3880
3978
|
.mbsr-top{display:flex;align-items:center;gap:8px;min-width:0}
|
|
3881
3979
|
.mbsr-label{font-size:13.5px;font-weight:760;line-height:1.3;overflow-wrap:anywhere}
|
|
3882
|
-
.mbsr-badge{flex:0 0 auto;padding:2px 8px;border:1px solid color-mix(in srgb,var(--mb-
|
|
3980
|
+
.mbsr-badge{flex:0 0 auto;padding:2px 8px;border:1px solid color-mix(in srgb,var(--mb-muted) 45%,var(--mb-border));border-radius:999px;background:var(--mb-soft);font-size:11px;font-weight:700;white-space:nowrap}
|
|
3981
|
+
.mbsr-badge[data-tone=success]{border-color:color-mix(in srgb,#23876f 52%,var(--mb-border));background:color-mix(in srgb,#23876f 11%,var(--mb-surface));color:#176452}
|
|
3982
|
+
.mbsr-badge[data-tone=warning]{border-color:color-mix(in srgb,var(--mb-warning) 55%,var(--mb-border));background:color-mix(in srgb,var(--mb-warning) 12%,var(--mb-surface))}
|
|
3983
|
+
.mbsr-badge[data-tone=danger]{border-color:color-mix(in srgb,var(--mb-danger) 45%,var(--mb-border));background:color-mix(in srgb,var(--mb-danger) 9%,var(--mb-surface));color:var(--mb-danger)}
|
|
3883
3984
|
.mbsr-meta{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(0,auto);gap:2px 14px;justify-content:start}
|
|
3884
3985
|
.mbsr-meta>span{display:grid;gap:1px;min-width:0}
|
|
3885
3986
|
.mbsr-meta i{color:var(--mb-muted);font-size:10.5px;font-style:normal;font-weight:800;letter-spacing:.05em;text-transform:uppercase;white-space:nowrap}
|
|
@@ -3905,7 +4006,7 @@ function BillSubmissionsRibbon({
|
|
|
3905
4006
|
const content = /* @__PURE__ */ jsxs9(Fragment7, { children: [
|
|
3906
4007
|
/* @__PURE__ */ jsxs9("span", { className: "mbsr-top", children: [
|
|
3907
4008
|
/* @__PURE__ */ jsx9("span", { className: "mbsr-label", children: item.label }),
|
|
3908
|
-
item.badge ? /* @__PURE__ */ jsx9("span", { className: "mbsr-badge", children: item.badge }) : null
|
|
4009
|
+
item.badge ? /* @__PURE__ */ jsx9("span", { className: "mbsr-badge", "data-tone": item.badgeTone ?? "neutral", children: item.badge }) : null
|
|
3909
4010
|
] }),
|
|
3910
4011
|
item.meta?.length ? /* @__PURE__ */ jsx9("span", { className: "mbsr-meta", children: item.meta.slice(0, 3).map((pair) => /* @__PURE__ */ jsxs9("span", { children: [
|
|
3911
4012
|
/* @__PURE__ */ jsx9("i", { children: pair.label }),
|
|
@@ -3917,6 +4018,7 @@ function BillSubmissionsRibbon({
|
|
|
3917
4018
|
{
|
|
3918
4019
|
className: "mbsr-chip",
|
|
3919
4020
|
"data-active": Boolean(item.active),
|
|
4021
|
+
"aria-current": item.active ? "true" : void 0,
|
|
3920
4022
|
href: item.href,
|
|
3921
4023
|
role: "listitem",
|
|
3922
4024
|
onClick: () => onSelect?.(item),
|
|
@@ -3929,6 +4031,7 @@ function BillSubmissionsRibbon({
|
|
|
3929
4031
|
type: "button",
|
|
3930
4032
|
className: "mbsr-chip",
|
|
3931
4033
|
"data-active": Boolean(item.active),
|
|
4034
|
+
"aria-pressed": Boolean(item.active),
|
|
3932
4035
|
role: "listitem",
|
|
3933
4036
|
onClick: () => onSelect?.(item),
|
|
3934
4037
|
children: content
|
|
@@ -3947,7 +4050,7 @@ import {
|
|
|
3947
4050
|
REPORT_BILL_STATUS_OPTIONS
|
|
3948
4051
|
} from "@mindbill/browser";
|
|
3949
4052
|
import { REPORT_BILL_STATUS_OPTIONS as REPORT_BILL_STATUS_OPTIONS2 } from "@mindbill/browser";
|
|
3950
|
-
import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
4053
|
+
import { Fragment as Fragment8, jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
3951
4054
|
var css8 = `
|
|
3952
4055
|
.mbbs-overlay{position:fixed;inset:0;z-index:1000;display:grid;place-items:center;padding:20px;background:rgba(15,30,40,.45)}
|
|
3953
4056
|
.mbbs{display:grid;gap:18px;width:min(860px,100%);max-height:min(90vh,960px);overflow:auto;overscroll-behavior:contain;padding:24px;border:1px solid var(--mb-border);border-radius:var(--mb-radius);background:var(--mb-surface);color:var(--mb-text);font-family:var(--mb-font);font-size:14px;box-shadow:0 24px 60px rgba(17,38,49,.28)}
|
|
@@ -3964,6 +4067,20 @@ var css8 = `
|
|
|
3964
4067
|
.mbbs-contact dl>div{display:grid;grid-template-columns:130px minmax(0,1fr);gap:10px}
|
|
3965
4068
|
.mbbs-contact dt{color:var(--mb-muted);font-size:12.5px}
|
|
3966
4069
|
.mbbs-contact dd{margin:0;font-weight:700;overflow-wrap:anywhere}
|
|
4070
|
+
.mbbs-contact a,.mbbs-directory a{color:var(--mb-accent);text-decoration-thickness:1px;text-underline-offset:2px}
|
|
4071
|
+
.mbbs-directory{display:grid;gap:10px}
|
|
4072
|
+
.mbbs-directory-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
|
|
4073
|
+
.mbbs-directory-card{min-width:0;padding:12px 14px;border:1px solid var(--mb-border);border-radius:var(--mb-control-radius);background:color-mix(in srgb,var(--mb-accent) 3%,var(--mb-surface))}
|
|
4074
|
+
.mbbs-directory-card.wide{grid-column:1/-1}
|
|
4075
|
+
.mbbs-directory-card h5{margin:0 0 8px;color:var(--mb-muted);font-size:11px;font-weight:800;letter-spacing:.07em;text-transform:uppercase}
|
|
4076
|
+
.mbbs-directory-card dl{display:grid;gap:7px;margin:0}
|
|
4077
|
+
.mbbs-directory-card dl>div{display:grid;grid-template-columns:120px minmax(0,1fr);gap:10px}
|
|
4078
|
+
.mbbs-directory-card dt{color:var(--mb-muted);font-size:12px}
|
|
4079
|
+
.mbbs-directory-card dd{min-width:0;margin:0;font-weight:650;overflow-wrap:anywhere}
|
|
4080
|
+
.mbbs-directory-list{display:grid;gap:8px;margin:0;padding:0;list-style:none}
|
|
4081
|
+
.mbbs-directory-list li{display:grid;gap:2px;padding-top:8px;border-top:1px solid var(--mb-border)}
|
|
4082
|
+
.mbbs-directory-list li:first-child{padding-top:0;border-top:0}
|
|
4083
|
+
.mbbs-directory-list small{color:var(--mb-muted);line-height:1.4}
|
|
3967
4084
|
.mbbs-receipt{border:1px solid var(--mb-border);border-radius:var(--mb-control-radius);padding:10px}
|
|
3968
4085
|
.mbbs-report{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);gap:18px}
|
|
3969
4086
|
.mbbs-options{display:grid;gap:8px;align-content:start}
|
|
@@ -3983,12 +4100,156 @@ var css8 = `
|
|
|
3983
4100
|
.mbbs-cancel{min-height:42px;padding:9px 16px;border:1px solid var(--mb-border);border-radius:var(--mb-control-radius);background:var(--mb-surface);color:var(--mb-text);font:inherit;font-weight:680;cursor:pointer}
|
|
3984
4101
|
.mbbs-save{min-height:42px;min-width:130px;padding:9px 18px;border:0;border-radius:var(--mb-control-radius);background:var(--mb-accent);color:var(--mb-accent-contrast);font:inherit;font-weight:760;cursor:pointer}
|
|
3985
4102
|
.mbbs-save:disabled,.mbbs-cancel:disabled{opacity:.6;cursor:not-allowed}
|
|
3986
|
-
@media(max-width:700px){.mbbs-contacts,.mbbs-report{grid-template-columns:1fr}}
|
|
4103
|
+
@media(max-width:700px){.mbbs-contacts,.mbbs-directory-grid,.mbbs-report{grid-template-columns:1fr}.mbbs-directory-card.wide{grid-column:auto}.mbbs-directory-card dl>div{grid-template-columns:1fr;gap:2px}}
|
|
3987
4104
|
`;
|
|
4105
|
+
function externalHref(value) {
|
|
4106
|
+
return /^https?:\/\//i.test(value) ? value : `https://${value}`;
|
|
4107
|
+
}
|
|
4108
|
+
function contactLine(contact, key) {
|
|
4109
|
+
return /* @__PURE__ */ jsxs10("li", { children: [
|
|
4110
|
+
/* @__PURE__ */ jsx10("strong", { children: contact.name || "Contact" }),
|
|
4111
|
+
/* @__PURE__ */ jsxs10("span", { children: [
|
|
4112
|
+
contact.phone ? /* @__PURE__ */ jsxs10(Fragment8, { children: [
|
|
4113
|
+
/* @__PURE__ */ jsx10("a", { href: `tel:${contact.phone}`, children: contact.phone }),
|
|
4114
|
+
" "
|
|
4115
|
+
] }) : null,
|
|
4116
|
+
contact.email ? /* @__PURE__ */ jsxs10(Fragment8, { children: [
|
|
4117
|
+
/* @__PURE__ */ jsx10("a", { href: `mailto:${contact.email}`, children: contact.email }),
|
|
4118
|
+
" "
|
|
4119
|
+
] }) : null,
|
|
4120
|
+
contact.portalUrl ? /* @__PURE__ */ jsxs10(Fragment8, { children: [
|
|
4121
|
+
/* @__PURE__ */ jsx10("a", { href: externalHref(contact.portalUrl), target: "_blank", rel: "noreferrer", children: "Open portal" }),
|
|
4122
|
+
" "
|
|
4123
|
+
] }) : null,
|
|
4124
|
+
contact.fax ? /* @__PURE__ */ jsxs10(Fragment8, { children: [
|
|
4125
|
+
"Fax ",
|
|
4126
|
+
contact.fax,
|
|
4127
|
+
" "
|
|
4128
|
+
] }) : null,
|
|
4129
|
+
contact.address || null
|
|
4130
|
+
] }),
|
|
4131
|
+
contact.note ? /* @__PURE__ */ jsx10("small", { children: contact.note }) : null
|
|
4132
|
+
] }, key);
|
|
4133
|
+
}
|
|
4134
|
+
function DirectoryDetails({ directory }) {
|
|
4135
|
+
const aliases = directory.aliases?.filter(Boolean).join(", ");
|
|
4136
|
+
const affiliates = directory.affiliatedEntities?.filter(Boolean).join(", ");
|
|
4137
|
+
return /* @__PURE__ */ jsxs10("div", { className: "mbbs-directory-grid", children: [
|
|
4138
|
+
/* @__PURE__ */ jsxs10("section", { className: "mbbs-directory-card wide", children: [
|
|
4139
|
+
/* @__PURE__ */ jsx10("h5", { children: "Claims administrator" }),
|
|
4140
|
+
/* @__PURE__ */ jsxs10("dl", { children: [
|
|
4141
|
+
directory.name ? /* @__PURE__ */ jsxs10("div", { children: [
|
|
4142
|
+
/* @__PURE__ */ jsx10("dt", { children: "Name" }),
|
|
4143
|
+
/* @__PURE__ */ jsx10("dd", { children: directory.name })
|
|
4144
|
+
] }) : null,
|
|
4145
|
+
directory.type ? /* @__PURE__ */ jsxs10("div", { children: [
|
|
4146
|
+
/* @__PURE__ */ jsx10("dt", { children: "Type" }),
|
|
4147
|
+
/* @__PURE__ */ jsx10("dd", { children: directory.type })
|
|
4148
|
+
] }) : null,
|
|
4149
|
+
directory.description ? /* @__PURE__ */ jsxs10("div", { children: [
|
|
4150
|
+
/* @__PURE__ */ jsx10("dt", { children: "Description" }),
|
|
4151
|
+
/* @__PURE__ */ jsx10("dd", { children: directory.description })
|
|
4152
|
+
] }) : null,
|
|
4153
|
+
directory.website ? /* @__PURE__ */ jsxs10("div", { children: [
|
|
4154
|
+
/* @__PURE__ */ jsx10("dt", { children: "Website" }),
|
|
4155
|
+
/* @__PURE__ */ jsx10("dd", { children: /* @__PURE__ */ jsx10("a", { href: externalHref(directory.website), target: "_blank", rel: "noreferrer", children: directory.website }) })
|
|
4156
|
+
] }) : null,
|
|
4157
|
+
directory.hours ? /* @__PURE__ */ jsxs10("div", { children: [
|
|
4158
|
+
/* @__PURE__ */ jsx10("dt", { children: "Hours" }),
|
|
4159
|
+
/* @__PURE__ */ jsx10("dd", { children: directory.hours })
|
|
4160
|
+
] }) : null,
|
|
4161
|
+
directory.telephoneNumbers?.length ? /* @__PURE__ */ jsxs10("div", { children: [
|
|
4162
|
+
/* @__PURE__ */ jsx10("dt", { children: "Phone" }),
|
|
4163
|
+
/* @__PURE__ */ jsx10("dd", { children: directory.telephoneNumbers.map((value, index) => /* @__PURE__ */ jsxs10("span", { children: [
|
|
4164
|
+
index ? ", " : "",
|
|
4165
|
+
/* @__PURE__ */ jsx10("a", { href: `tel:${value}`, children: value })
|
|
4166
|
+
] }, value)) })
|
|
4167
|
+
] }) : null,
|
|
4168
|
+
directory.emailAddresses?.length ? /* @__PURE__ */ jsxs10("div", { children: [
|
|
4169
|
+
/* @__PURE__ */ jsx10("dt", { children: "Email" }),
|
|
4170
|
+
/* @__PURE__ */ jsx10("dd", { children: directory.emailAddresses.map((value, index) => /* @__PURE__ */ jsxs10("span", { children: [
|
|
4171
|
+
index ? ", " : "",
|
|
4172
|
+
/* @__PURE__ */ jsx10("a", { href: `mailto:${value}`, children: value })
|
|
4173
|
+
] }, value)) })
|
|
4174
|
+
] }) : null,
|
|
4175
|
+
directory.webPortals?.length ? /* @__PURE__ */ jsxs10("div", { children: [
|
|
4176
|
+
/* @__PURE__ */ jsx10("dt", { children: "Portals" }),
|
|
4177
|
+
/* @__PURE__ */ jsx10("dd", { children: directory.webPortals.map((value, index) => /* @__PURE__ */ jsxs10("span", { children: [
|
|
4178
|
+
index ? ", " : "",
|
|
4179
|
+
/* @__PURE__ */ jsxs10("a", { href: externalHref(value), target: "_blank", rel: "noreferrer", children: [
|
|
4180
|
+
"Open portal ",
|
|
4181
|
+
index + 1
|
|
4182
|
+
] })
|
|
4183
|
+
] }, value)) })
|
|
4184
|
+
] }) : null,
|
|
4185
|
+
aliases ? /* @__PURE__ */ jsxs10("div", { children: [
|
|
4186
|
+
/* @__PURE__ */ jsx10("dt", { children: "Also known as" }),
|
|
4187
|
+
/* @__PURE__ */ jsx10("dd", { children: aliases })
|
|
4188
|
+
] }) : null,
|
|
4189
|
+
affiliates ? /* @__PURE__ */ jsxs10("div", { children: [
|
|
4190
|
+
/* @__PURE__ */ jsx10("dt", { children: "Affiliates" }),
|
|
4191
|
+
/* @__PURE__ */ jsx10("dd", { children: affiliates })
|
|
4192
|
+
] }) : null,
|
|
4193
|
+
directory.claimNumberHint ? /* @__PURE__ */ jsxs10("div", { children: [
|
|
4194
|
+
/* @__PURE__ */ jsx10("dt", { children: "Claim number" }),
|
|
4195
|
+
/* @__PURE__ */ jsx10("dd", { children: directory.claimNumberHint })
|
|
4196
|
+
] }) : null,
|
|
4197
|
+
directory.billProcessingWorkflow ? /* @__PURE__ */ jsxs10("div", { children: [
|
|
4198
|
+
/* @__PURE__ */ jsx10("dt", { children: "Workflow" }),
|
|
4199
|
+
/* @__PURE__ */ jsx10("dd", { children: directory.billProcessingWorkflow })
|
|
4200
|
+
] }) : null,
|
|
4201
|
+
directory.billProcessingWorkflowNotes ? /* @__PURE__ */ jsxs10("div", { children: [
|
|
4202
|
+
/* @__PURE__ */ jsx10("dt", { children: "Workflow notes" }),
|
|
4203
|
+
/* @__PURE__ */ jsx10("dd", { children: directory.billProcessingWorkflowNotes })
|
|
4204
|
+
] }) : null
|
|
4205
|
+
] })
|
|
4206
|
+
] }),
|
|
4207
|
+
directory.billReview?.length ? /* @__PURE__ */ jsxs10("section", { className: "mbbs-directory-card", children: [
|
|
4208
|
+
/* @__PURE__ */ jsx10("h5", { children: "Bill review" }),
|
|
4209
|
+
/* @__PURE__ */ jsx10("ul", { className: "mbbs-directory-list", children: directory.billReview.map(contactLine) })
|
|
4210
|
+
] }) : null,
|
|
4211
|
+
directory.authorization?.length || directory.authorizationNotice ? /* @__PURE__ */ jsxs10("section", { className: "mbbs-directory-card", children: [
|
|
4212
|
+
/* @__PURE__ */ jsx10("h5", { children: "Authorization" }),
|
|
4213
|
+
directory.authorizationNotice ? /* @__PURE__ */ jsx10("p", { className: "mbbs-copy", children: directory.authorizationNotice }) : null,
|
|
4214
|
+
/* @__PURE__ */ jsx10("ul", { className: "mbbs-directory-list", children: (directory.authorization ?? []).map(contactLine) })
|
|
4215
|
+
] }) : null,
|
|
4216
|
+
directory.mailingAddresses?.length ? /* @__PURE__ */ jsxs10("section", { className: "mbbs-directory-card", children: [
|
|
4217
|
+
/* @__PURE__ */ jsx10("h5", { children: "Mailing addresses" }),
|
|
4218
|
+
/* @__PURE__ */ jsx10("ul", { className: "mbbs-directory-list", children: directory.mailingAddresses.map((entry, index) => /* @__PURE__ */ jsxs10("li", { children: [
|
|
4219
|
+
/* @__PURE__ */ jsx10("strong", { children: entry.company || "Mailing address" }),
|
|
4220
|
+
/* @__PURE__ */ jsx10("span", { children: entry.address }),
|
|
4221
|
+
entry.notes ? /* @__PURE__ */ jsx10("small", { children: entry.notes }) : null,
|
|
4222
|
+
entry.submissionTypes?.length ? /* @__PURE__ */ jsxs10("small", { children: [
|
|
4223
|
+
"Submission types: ",
|
|
4224
|
+
entry.submissionTypes.join(", ")
|
|
4225
|
+
] }) : null
|
|
4226
|
+
] }, index)) })
|
|
4227
|
+
] }) : null,
|
|
4228
|
+
directory.claimNumberPatterns?.length ? /* @__PURE__ */ jsxs10("section", { className: "mbbs-directory-card", children: [
|
|
4229
|
+
/* @__PURE__ */ jsx10("h5", { children: "Claim number patterns" }),
|
|
4230
|
+
/* @__PURE__ */ jsx10("ul", { className: "mbbs-directory-list", children: directory.claimNumberPatterns.map((entry, index) => /* @__PURE__ */ jsxs10("li", { children: [
|
|
4231
|
+
/* @__PURE__ */ jsx10("strong", { children: entry.pattern }),
|
|
4232
|
+
/* @__PURE__ */ jsxs10("span", { children: [
|
|
4233
|
+
entry.length ? `Length ${entry.length}` : "",
|
|
4234
|
+
entry.example ? `${entry.length ? " \xB7 " : ""}Example ${entry.example}` : ""
|
|
4235
|
+
] })
|
|
4236
|
+
] }, index)) })
|
|
4237
|
+
] }) : null,
|
|
4238
|
+
directory.payers?.length ? /* @__PURE__ */ jsxs10("section", { className: "mbbs-directory-card wide", children: [
|
|
4239
|
+
/* @__PURE__ */ jsx10("h5", { children: "Electronic billing routes" }),
|
|
4240
|
+
/* @__PURE__ */ jsx10("ul", { className: "mbbs-directory-list", children: directory.payers.map((payer, index) => /* @__PURE__ */ jsxs10("li", { children: [
|
|
4241
|
+
/* @__PURE__ */ jsx10("strong", { children: payer.name }),
|
|
4242
|
+
/* @__PURE__ */ jsx10("span", { children: [payer.deliveryType || payer.route, payer.clearinghouse, payer.payerId ? `Payer ID ${payer.payerId}` : null].filter(Boolean).join(" \xB7 ") }),
|
|
4243
|
+
payer.hint ? /* @__PURE__ */ jsx10("small", { children: payer.hint }) : null
|
|
4244
|
+
] }, `${payer.name}-${payer.payerId ?? index}`)) })
|
|
4245
|
+
] }) : null
|
|
4246
|
+
] });
|
|
4247
|
+
}
|
|
3988
4248
|
function ReportBillStatusDialog({
|
|
3989
4249
|
title = "Report Bill Status",
|
|
3990
4250
|
claimsAdmin,
|
|
3991
4251
|
billReview,
|
|
4252
|
+
directory,
|
|
3992
4253
|
receipt,
|
|
3993
4254
|
submitting = false,
|
|
3994
4255
|
error = null,
|
|
@@ -4051,10 +4312,10 @@ function ReportBillStatusDialog({
|
|
|
4051
4312
|
/* @__PURE__ */ jsx10("h3", { className: "mbbs-title", children: title }),
|
|
4052
4313
|
/* @__PURE__ */ jsx10("button", { className: "mbbs-close", type: "button", "aria-label": "Close", disabled: submitting, onClick: onCancel, children: "\xD7" })
|
|
4053
4314
|
] }),
|
|
4054
|
-
claimsAdmin || billReview ? /* @__PURE__ */ jsxs10("div", { className: "mbbs-section", children: [
|
|
4315
|
+
directory || claimsAdmin || billReview ? /* @__PURE__ */ jsxs10("div", { className: "mbbs-section", children: [
|
|
4055
4316
|
/* @__PURE__ */ jsx10("h4", { children: "1. Call Claims Administrator or Bill Review" }),
|
|
4056
4317
|
/* @__PURE__ */ jsx10("p", { className: "mbbs-copy", children: "Contact the payer to request the payment status of this bill." }),
|
|
4057
|
-
/* @__PURE__ */ jsxs10("div", { className: "mbbs-contacts", children: [
|
|
4318
|
+
directory ? /* @__PURE__ */ jsx10(DirectoryDetails, { directory }) : /* @__PURE__ */ jsxs10("div", { className: "mbbs-contacts", children: [
|
|
4058
4319
|
claimsAdmin ? /* @__PURE__ */ jsxs10("div", { className: "mbbs-contact", children: [
|
|
4059
4320
|
/* @__PURE__ */ jsx10("h5", { children: "Claims Admin" }),
|
|
4060
4321
|
/* @__PURE__ */ jsxs10("dl", { children: [
|
|
@@ -4144,7 +4405,7 @@ import { useCallback as useCallback2, useEffect as useEffect7, useMemo as useMem
|
|
|
4144
4405
|
import {
|
|
4145
4406
|
createOrganizationClient
|
|
4146
4407
|
} from "@mindbill/browser";
|
|
4147
|
-
import { Fragment as
|
|
4408
|
+
import { Fragment as Fragment9, jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
4148
4409
|
var STEPS = [
|
|
4149
4410
|
{ id: "practice", label: "Practice & billing" },
|
|
4150
4411
|
{ id: "locations", label: "Locations" },
|
|
@@ -4379,13 +4640,13 @@ function OrganizationOnboarding({
|
|
|
4379
4640
|
/* @__PURE__ */ jsx11("p", { className: "mbob-copy", children: description })
|
|
4380
4641
|
] }) }),
|
|
4381
4642
|
loadError ? /* @__PURE__ */ jsx11("div", { className: "mbob-error", role: "alert", children: loadError }) : null,
|
|
4382
|
-
variant === "onboarding" ? /* @__PURE__ */ jsxs11(
|
|
4643
|
+
variant === "onboarding" ? /* @__PURE__ */ jsxs11(Fragment9, { children: [
|
|
4383
4644
|
/* @__PURE__ */ jsx11("div", { className: "mbob-steps", children: STEPS.map((item) => /* @__PURE__ */ jsxs11("button", { className: "mbob-step", type: "button", "data-active": step === item.id, "data-done": Boolean(savedStep[item.id]), onClick: () => setStep(item.id), children: [
|
|
4384
4645
|
/* @__PURE__ */ jsx11("i", { children: savedStep[item.id] ? "\u2713" : "" }),
|
|
4385
4646
|
item.label
|
|
4386
4647
|
] }, item.id)) }),
|
|
4387
4648
|
sections[step]
|
|
4388
|
-
] }) : /* @__PURE__ */ jsxs11(
|
|
4649
|
+
] }) : /* @__PURE__ */ jsxs11(Fragment9, { children: [
|
|
4389
4650
|
practiceSection,
|
|
4390
4651
|
/* @__PURE__ */ jsx11("h3", { className: "mbob-subhead", children: "Locations" }),
|
|
4391
4652
|
locationsSection,
|
|
@@ -4422,7 +4683,7 @@ import {
|
|
|
4422
4683
|
DEFAULT_API_BASE_URL,
|
|
4423
4684
|
DEFAULT_SESSION_ENDPOINT
|
|
4424
4685
|
} from "@mindbill/browser";
|
|
4425
|
-
import { Fragment as
|
|
4686
|
+
import { Fragment as Fragment10, jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
4426
4687
|
var DEFAULT_REFRESH_INTERVAL = 6e4;
|
|
4427
4688
|
async function responseError(response, fallback) {
|
|
4428
4689
|
const body = await response.json().catch(() => null);
|
|
@@ -4643,10 +4904,10 @@ function ConnectedBillStatus({
|
|
|
4643
4904
|
}) {
|
|
4644
4905
|
const status = useBillStatus(options);
|
|
4645
4906
|
if (status.isLoading && !status.data) {
|
|
4646
|
-
return /* @__PURE__ */ jsx12(
|
|
4907
|
+
return /* @__PURE__ */ jsx12(Fragment10, { children: loadingFallback ?? /* @__PURE__ */ jsx12("div", { role: "status", children: "Loading bill status\u2026" }) });
|
|
4647
4908
|
}
|
|
4648
4909
|
if (status.error && !status.data) {
|
|
4649
|
-
return /* @__PURE__ */ jsx12(
|
|
4910
|
+
return /* @__PURE__ */ jsx12(Fragment10, { children: errorFallback?.(status.error, status.refresh) ?? /* @__PURE__ */ jsxs12("div", { role: "alert", children: [
|
|
4650
4911
|
status.error.message,
|
|
4651
4912
|
" ",
|
|
4652
4913
|
/* @__PURE__ */ jsx12("button", { type: "button", onClick: () => void status.refresh(), children: "Retry" })
|
|
@@ -4672,8 +4933,8 @@ function ConnectedBillStatus({
|
|
|
4672
4933
|
}
|
|
4673
4934
|
|
|
4674
4935
|
// src/bill-lifecycle-surfaces.tsx
|
|
4675
|
-
import { useState as useState10 } from "react";
|
|
4676
|
-
import { Fragment as
|
|
4936
|
+
import { useEffect as useEffect9, useRef as useRef5, useState as useState10 } from "react";
|
|
4937
|
+
import { Fragment as Fragment11, jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
4677
4938
|
function visibleBillLifecycleActions(actions, showUnavailable = false) {
|
|
4678
4939
|
return actions.filter((action) => action.enabled || showUnavailable);
|
|
4679
4940
|
}
|
|
@@ -4746,8 +5007,15 @@ function historyDate(iso) {
|
|
|
4746
5007
|
if (Number.isNaN(parsed.getTime())) return iso;
|
|
4747
5008
|
return new Intl.DateTimeFormat("en-US", { month: "2-digit", day: "2-digit", year: "numeric" }).format(parsed);
|
|
4748
5009
|
}
|
|
4749
|
-
function BillHistoryTable({ entries, emptyLabel = "No bill history yet.", appearance, className, style, formatDate = historyDate, documentHref, onOpenDocument }) {
|
|
5010
|
+
function BillHistoryTable({ entries, selectedEntryId, emptyLabel = "No bill history yet.", appearance, className, style, formatDate = historyDate, documentHref, onOpenDocument }) {
|
|
4750
5011
|
const [expanded, setExpanded] = useState10({});
|
|
5012
|
+
const selectedRowRef = useRef5(null);
|
|
5013
|
+
useEffect9(() => {
|
|
5014
|
+
if (!selectedEntryId) return;
|
|
5015
|
+
const selected = entries.find((entry) => entry.id === selectedEntryId);
|
|
5016
|
+
if (selected?.details) setExpanded((current) => current[selectedEntryId] ? current : { ...current, [selectedEntryId]: true });
|
|
5017
|
+
selectedRowRef.current?.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
5018
|
+
}, [entries, selectedEntryId]);
|
|
4751
5019
|
return /* @__PURE__ */ jsxs13("section", { className: classes("mb-surface mb-history", className), style: mindBillAppearanceStyle(appearance, style), "aria-label": "Bill history", children: [
|
|
4752
5020
|
/* @__PURE__ */ jsx13("style", { children: lifecycleSurfaceStyles }),
|
|
4753
5021
|
/* @__PURE__ */ jsx13("header", { className: "mb-surface-heading", children: /* @__PURE__ */ jsxs13("div", { children: [
|
|
@@ -4762,10 +5030,11 @@ function BillHistoryTable({ entries, emptyLabel = "No bill history yet.", appear
|
|
|
4762
5030
|
/* @__PURE__ */ jsx13("span", { children: "Details" })
|
|
4763
5031
|
] }),
|
|
4764
5032
|
/* @__PURE__ */ jsx13("ul", { className: "mb-history-rows", children: entries.map((entry) => {
|
|
5033
|
+
const isSelected = entry.id === selectedEntryId;
|
|
4765
5034
|
const expandable = Boolean(entry.details);
|
|
4766
5035
|
const isOpen = expandable && Boolean(expanded[entry.id]);
|
|
4767
5036
|
const details = entry.details;
|
|
4768
|
-
const lineContents = /* @__PURE__ */ jsxs13(
|
|
5037
|
+
const lineContents = /* @__PURE__ */ jsxs13(Fragment11, { children: [
|
|
4769
5038
|
/* @__PURE__ */ jsx13("span", { className: "mb-history-date", children: formatDate(entry.date) }),
|
|
4770
5039
|
/* @__PURE__ */ jsx13("span", { className: "mb-history-action", children: entry.action }),
|
|
4771
5040
|
/* @__PURE__ */ jsx13("span", { className: "mb-history-actor", children: entry.actor ?? "\u2014" }),
|
|
@@ -4774,43 +5043,52 @@ function BillHistoryTable({ entries, emptyLabel = "No bill history yet.", appear
|
|
|
4774
5043
|
entry.summary
|
|
4775
5044
|
] })
|
|
4776
5045
|
] });
|
|
4777
|
-
return /* @__PURE__ */ jsxs13(
|
|
4778
|
-
|
|
4779
|
-
|
|
4780
|
-
|
|
4781
|
-
|
|
4782
|
-
|
|
4783
|
-
|
|
4784
|
-
|
|
4785
|
-
|
|
4786
|
-
|
|
4787
|
-
|
|
4788
|
-
|
|
4789
|
-
|
|
4790
|
-
|
|
4791
|
-
|
|
4792
|
-
|
|
4793
|
-
|
|
4794
|
-
/* @__PURE__ */
|
|
4795
|
-
|
|
4796
|
-
|
|
4797
|
-
|
|
4798
|
-
|
|
4799
|
-
|
|
4800
|
-
|
|
4801
|
-
|
|
4802
|
-
|
|
4803
|
-
|
|
4804
|
-
|
|
4805
|
-
|
|
4806
|
-
|
|
4807
|
-
|
|
4808
|
-
|
|
4809
|
-
|
|
4810
|
-
|
|
4811
|
-
|
|
4812
|
-
|
|
4813
|
-
|
|
5046
|
+
return /* @__PURE__ */ jsxs13(
|
|
5047
|
+
"li",
|
|
5048
|
+
{
|
|
5049
|
+
ref: isSelected ? selectedRowRef : void 0,
|
|
5050
|
+
className: `mb-history-row is-${entry.tone}${isSelected ? " is-selected" : ""}`,
|
|
5051
|
+
"aria-current": isSelected ? "true" : void 0,
|
|
5052
|
+
children: [
|
|
5053
|
+
expandable ? /* @__PURE__ */ jsx13(
|
|
5054
|
+
"button",
|
|
5055
|
+
{
|
|
5056
|
+
type: "button",
|
|
5057
|
+
className: "mb-history-line is-expandable",
|
|
5058
|
+
"aria-expanded": isOpen,
|
|
5059
|
+
onClick: () => setExpanded((current) => ({ ...current, [entry.id]: !current[entry.id] })),
|
|
5060
|
+
children: lineContents
|
|
5061
|
+
}
|
|
5062
|
+
) : /* @__PURE__ */ jsx13("div", { className: "mb-history-line", children: lineContents }),
|
|
5063
|
+
isOpen && details ? /* @__PURE__ */ jsxs13("div", { className: "mb-history-details", children: [
|
|
5064
|
+
details.rows?.length ? /* @__PURE__ */ jsx13("dl", { className: "mb-history-kv", children: details.rows.map((row) => /* @__PURE__ */ jsxs13("div", { children: [
|
|
5065
|
+
/* @__PURE__ */ jsx13("dt", { children: row.label }),
|
|
5066
|
+
/* @__PURE__ */ jsx13("dd", { children: row.value })
|
|
5067
|
+
] }, `${row.label}-${row.value}`)) }) : null,
|
|
5068
|
+
details.documents?.length ? /* @__PURE__ */ jsx13("div", { className: "mb-history-kv", children: /* @__PURE__ */ jsxs13("div", { children: [
|
|
5069
|
+
/* @__PURE__ */ jsx13("dt", { children: "Documents" }),
|
|
5070
|
+
/* @__PURE__ */ jsx13("dd", { children: details.documents.map((doc) => {
|
|
5071
|
+
const href = documentHref?.(doc) ?? null;
|
|
5072
|
+
return href ? /* @__PURE__ */ jsx13("a", { className: "mb-history-doc", href, target: "_blank", rel: "noreferrer", children: doc.filename }, doc.id) : onOpenDocument ? /* @__PURE__ */ jsx13("button", { type: "button", className: "mb-history-doc", onClick: () => void onOpenDocument(doc), children: doc.filename }, doc.id) : /* @__PURE__ */ jsx13("span", { className: "mb-history-doc", children: doc.filename }, doc.id);
|
|
5073
|
+
}) })
|
|
5074
|
+
] }) }) : null,
|
|
5075
|
+
details.codes?.length ? /* @__PURE__ */ jsx13("dl", { className: "mb-history-codes", children: details.codes.map((code) => /* @__PURE__ */ jsxs13("div", { children: [
|
|
5076
|
+
/* @__PURE__ */ jsx13("dt", { children: code.code }),
|
|
5077
|
+
/* @__PURE__ */ jsx13("dd", { children: code.text })
|
|
5078
|
+
] }, code.code)) }) : null,
|
|
5079
|
+
details.complianceDueDates?.length ? /* @__PURE__ */ jsxs13("div", { className: "mb-history-due", children: [
|
|
5080
|
+
/* @__PURE__ */ jsx13("em", { children: "Compliance Due Dates" }),
|
|
5081
|
+
/* @__PURE__ */ jsx13("dl", { children: details.complianceDueDates.map((due) => /* @__PURE__ */ jsxs13("div", { children: [
|
|
5082
|
+
/* @__PURE__ */ jsx13("dt", { children: formatDate(due.date) }),
|
|
5083
|
+
/* @__PURE__ */ jsx13("dd", { children: due.text })
|
|
5084
|
+
] }, `${due.date}-${due.text}`)) })
|
|
5085
|
+
] }) : null,
|
|
5086
|
+
details.text ? /* @__PURE__ */ jsx13("p", { className: "mb-history-text", children: details.text }) : null
|
|
5087
|
+
] }) : null
|
|
5088
|
+
]
|
|
5089
|
+
},
|
|
5090
|
+
entry.id
|
|
5091
|
+
);
|
|
4814
5092
|
}) })
|
|
4815
5093
|
] })
|
|
4816
5094
|
] });
|
|
@@ -5214,6 +5492,7 @@ var lifecycleSurfaceStyles = `
|
|
|
5214
5492
|
.mb-history-rows{list-style:none;margin:0;padding:0}.mb-history-row{border-top:1px solid var(--mb-border)}
|
|
5215
5493
|
.mb-history-row.is-submission{background:color-mix(in srgb,var(--mb-accent) 9%,var(--mb-surface))}
|
|
5216
5494
|
.mb-history-row.is-note{background:color-mix(in srgb,#f2c344 13%,var(--mb-surface))}
|
|
5495
|
+
.mb-history-row.is-selected{position:relative;background:color-mix(in srgb,var(--mb-accent) 15%,var(--mb-surface));box-shadow:inset 4px 0 0 var(--mb-accent),inset 0 0 0 1px color-mix(in srgb,var(--mb-accent) 44%,transparent)}
|
|
5217
5496
|
.mb-history-line{display:grid;grid-template-columns:96px 160px 140px minmax(0,1fr);gap:12px;width:100%;padding:10px 14px;border:0;background:transparent;color:inherit;font:inherit;text-align:left}
|
|
5218
5497
|
.mb-history-line.is-expandable{cursor:pointer}.mb-history-line.is-expandable:hover .mb-history-summary{text-decoration:underline}
|
|
5219
5498
|
.mb-history-date{color:var(--mb-muted);font-size:13px}.mb-history-action{font-size:13.5px;font-weight:750}
|
|
@@ -5238,27 +5517,274 @@ var lifecycleSurfaceStyles = `
|
|
|
5238
5517
|
// src/connected-bill-lifecycle.tsx
|
|
5239
5518
|
import {
|
|
5240
5519
|
useCallback as useCallback4,
|
|
5241
|
-
useEffect as
|
|
5242
|
-
useMemo as
|
|
5243
|
-
useRef as
|
|
5244
|
-
useState as
|
|
5520
|
+
useEffect as useEffect10,
|
|
5521
|
+
useMemo as useMemo9,
|
|
5522
|
+
useRef as useRef6,
|
|
5523
|
+
useState as useState12
|
|
5245
5524
|
} from "react";
|
|
5246
5525
|
import {
|
|
5247
5526
|
DEFAULT_API_BASE_URL as DEFAULT_API_BASE_URL2,
|
|
5248
5527
|
DEFAULT_SESSION_ENDPOINT as DEFAULT_SESSION_ENDPOINT2,
|
|
5249
|
-
SECOND_REVIEW_REASON_TEMPLATE,
|
|
5250
5528
|
createBillLifecycleClient,
|
|
5251
5529
|
reportBillStatusContacts,
|
|
5252
5530
|
secondReviewDeadline
|
|
5253
5531
|
} from "@mindbill/browser";
|
|
5532
|
+
|
|
5533
|
+
// src/second-review-form.tsx
|
|
5534
|
+
import { useMemo as useMemo8, useState as useState11 } from "react";
|
|
5535
|
+
import { Fragment as Fragment12, jsx as jsx14, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
5536
|
+
var SECOND_REVIEW_REASON_TEMPLATES = [
|
|
5537
|
+
{
|
|
5538
|
+
label: "Med-legal report denied",
|
|
5539
|
+
value: "The attached medical-legal report satisfies the applicable requirements for a compensable medical-legal evaluation. Please reprocess this service and issue payment under the Medical-Legal Fee Schedule."
|
|
5540
|
+
},
|
|
5541
|
+
{
|
|
5542
|
+
label: "Supporting documentation was provided",
|
|
5543
|
+
value: "The EOR incorrectly states that supporting documentation was not received. The original electronic submission included the required documentation and was acknowledged as accepted. Please reprocess this service."
|
|
5544
|
+
},
|
|
5545
|
+
{
|
|
5546
|
+
label: "Payment missing or not received",
|
|
5547
|
+
value: "The EOR reports payment, but the funds have not been received or deposited by the provider. Please issue or reissue payment and pay the remaining fee-schedule balance, including applicable penalty and interest."
|
|
5548
|
+
},
|
|
5549
|
+
{
|
|
5550
|
+
label: "PPO or network reduction unsupported",
|
|
5551
|
+
value: "The EOR applies a PPO or network discount, but the provider has no agreement authorizing this reduction. Please demonstrate entitlement to the contracted rate or reprocess this service under the applicable fee schedule."
|
|
5552
|
+
},
|
|
5553
|
+
{
|
|
5554
|
+
label: "Service was authorized",
|
|
5555
|
+
value: "The billed service was authorized. Please reprocess this service and issue payment; the supporting authorization is included with this request."
|
|
5556
|
+
},
|
|
5557
|
+
{
|
|
5558
|
+
label: "Correct units or modifiers",
|
|
5559
|
+
value: "The units or modifiers on this service have been corrected on the accompanying modified bill. Please reprocess the service using the corrected billing information."
|
|
5560
|
+
},
|
|
5561
|
+
{
|
|
5562
|
+
label: "Fee schedule incorrectly applied",
|
|
5563
|
+
value: "The applicable fee schedule was incorrectly applied to this service. Please recalculate the allowed amount under the governing fee schedule and issue the additional payment due."
|
|
5564
|
+
},
|
|
5565
|
+
{
|
|
5566
|
+
label: "Treatment before liability decision",
|
|
5567
|
+
value: "This service was provided before the claims administrator accepted or denied liability and was authorized under California Labor Code section 5402(c). Please reprocess this service and issue payment."
|
|
5568
|
+
}
|
|
5569
|
+
];
|
|
5570
|
+
var css10 = `
|
|
5571
|
+
.mbsr{display:grid;gap:18px;color:var(--mb-text);font-family:var(--mb-font)}
|
|
5572
|
+
.mbsr *{box-sizing:border-box}.mbsr h3{margin:0;font-size:22px}.mbsr p{margin:4px 0 0;color:var(--mb-muted)}
|
|
5573
|
+
.mbsr-deadline{padding:12px 14px;border-radius:var(--mb-control-radius);background:color-mix(in srgb,var(--mb-warning) 10%,var(--mb-surface));color:var(--mb-text)!important}
|
|
5574
|
+
.mbsr-template,.mbsr-field{display:grid;gap:6px}.mbsr-label{font-size:13px;font-weight:720}.mbsr-select,.mbsr-textarea{width:100%;padding:10px 12px;border:1px solid var(--mb-border);border-radius:var(--mb-control-radius);background:var(--mb-input);color:var(--mb-text);font:inherit}.mbsr-textarea{min-height:86px;resize:vertical}.mbsr-select:focus,.mbsr-textarea:focus{outline:3px solid color-mix(in srgb,var(--mb-accent) 20%,transparent);border-color:var(--mb-accent)}
|
|
5575
|
+
.mbsr-lines{display:grid;gap:10px}.mbsr-line{display:grid;gap:12px;padding:14px;border:1px solid var(--mb-border);border-radius:var(--mb-control-radius);background:var(--mb-surface)}.mbsr-line[data-selected=true]{border-color:color-mix(in srgb,var(--mb-accent) 65%,var(--mb-border));background:color-mix(in srgb,var(--mb-accent) 4%,var(--mb-surface))}.mbsr-line-head{display:flex;align-items:center;justify-content:space-between;gap:12px}.mbsr-check{display:flex;align-items:center;gap:9px;font-weight:750}.mbsr-check input{width:18px;height:18px;accent-color:var(--mb-accent)}.mbsr-metrics{display:flex;gap:14px;color:var(--mb-muted);font-size:12px}.mbsr-auth{display:flex;align-items:center;flex-wrap:wrap;gap:8px;font-size:13px}.mbsr-auth strong{margin-right:4px}.mbsr-auth label{display:flex;align-items:center;gap:5px}.mbsr-auth input{accent-color:var(--mb-accent)}
|
|
5576
|
+
.mbsr-packet{display:grid;gap:10px;padding:0;border:0}.mbsr-packet legend{margin-bottom:8px;font-weight:750}.mbsr-document{display:flex;align-items:center;gap:10px;padding:10px 0;border-top:1px solid var(--mb-border)}.mbsr-document input{width:18px;height:18px;accent-color:var(--mb-accent)}.mbsr-document span{display:grid;min-width:0;flex:1}.mbsr-document small{color:var(--mb-muted)}.mbsr-link{border:0;background:transparent;color:var(--mb-accent);font:inherit;font-weight:700;cursor:pointer}
|
|
5577
|
+
.mbsr-upload{display:grid;place-items:center;min-height:82px;padding:16px;border:1px dashed color-mix(in srgb,var(--mb-accent) 55%,var(--mb-border));border-radius:var(--mb-control-radius);background:color-mix(in srgb,var(--mb-accent) 3%,var(--mb-surface));cursor:pointer}.mbsr-upload input{position:absolute;width:1px;height:1px;opacity:0}.mbsr-upload strong{color:var(--mb-accent)}
|
|
5578
|
+
.mbsr-uploaded{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:9px 11px;border:1px solid var(--mb-border);border-radius:var(--mb-control-radius)}
|
|
5579
|
+
.mbsr-error{padding:10px 12px;border-radius:var(--mb-control-radius);background:color-mix(in srgb,var(--mb-danger) 10%,transparent);color:var(--mb-danger);font-size:13px}.mbsr-actions{display:flex;justify-content:flex-end;gap:10px}.mbsr-button{min-height:42px;padding:9px 16px;border-radius:var(--mb-control-radius);font:inherit;font-weight:740;cursor:pointer}.mbsr-button.secondary{border:1px solid var(--mb-border);background:var(--mb-surface);color:var(--mb-text)}.mbsr-button.primary{border:0;background:var(--mb-accent);color:var(--mb-accent-contrast)}.mbsr-button:disabled{opacity:.55;cursor:not-allowed}
|
|
5580
|
+
@media(max-width:680px){.mbsr-line-head{align-items:flex-start;flex-direction:column}.mbsr-metrics{flex-wrap:wrap}}
|
|
5581
|
+
`;
|
|
5582
|
+
function money5(value) {
|
|
5583
|
+
return new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" }).format(value);
|
|
5584
|
+
}
|
|
5585
|
+
function initialLineDrafts(data) {
|
|
5586
|
+
return Object.fromEntries(data.bill.lineItems.flatMap((line) => line.id ? [[line.id, {
|
|
5587
|
+
selected: true,
|
|
5588
|
+
reason: "",
|
|
5589
|
+
serviceAuthorized: ""
|
|
5590
|
+
}]] : []));
|
|
5591
|
+
}
|
|
5592
|
+
function SecondReviewForm({
|
|
5593
|
+
data,
|
|
5594
|
+
submitting = false,
|
|
5595
|
+
error,
|
|
5596
|
+
fetch: fetchOverride,
|
|
5597
|
+
getDeliveryOptions,
|
|
5598
|
+
openAttachment,
|
|
5599
|
+
onCancel,
|
|
5600
|
+
onSubmit
|
|
5601
|
+
}) {
|
|
5602
|
+
const [lines, setLines] = useState11(() => initialLineDrafts(data));
|
|
5603
|
+
const [attachmentIds, setAttachmentIds] = useState11(() => data.bill.attachments.map((attachment) => attachment.id));
|
|
5604
|
+
const [uploads, setUploads] = useState11([]);
|
|
5605
|
+
const [formError, setFormError] = useState11("");
|
|
5606
|
+
const [preparing, setPreparing] = useState11(false);
|
|
5607
|
+
const [delivery, setDelivery] = useState11(null);
|
|
5608
|
+
const selectableLines = useMemo8(() => data.bill.lineItems.filter((line) => Boolean(line.id)), [data.bill.lineItems]);
|
|
5609
|
+
const selected = selectableLines.filter((line) => lines[line.id]?.selected);
|
|
5610
|
+
const invalidReason = selected.some((line) => !lines[line.id]?.reason.trim());
|
|
5611
|
+
const disputedAmount = selected.reduce((sum, line) => sum + Math.max(0, line.charge), 0);
|
|
5612
|
+
const patchLine = (id, patch) => setLines((current) => {
|
|
5613
|
+
const line = current[id];
|
|
5614
|
+
if (!line) return current;
|
|
5615
|
+
return { ...current, [id]: { ...line, ...patch } };
|
|
5616
|
+
});
|
|
5617
|
+
const applyTemplate = (value) => {
|
|
5618
|
+
if (!value) return;
|
|
5619
|
+
setLines((current) => Object.fromEntries(Object.entries(current).map(([id, line]) => [
|
|
5620
|
+
id,
|
|
5621
|
+
line.selected ? { ...line, reason: value } : line
|
|
5622
|
+
])));
|
|
5623
|
+
};
|
|
5624
|
+
const addUploads = (event) => {
|
|
5625
|
+
const files = Array.from(event.target.files || []);
|
|
5626
|
+
event.target.value = "";
|
|
5627
|
+
if (!files.length) return;
|
|
5628
|
+
const invalid = files.find((file) => file.type !== "application/pdf" && !file.name.toLowerCase().endsWith(".pdf"));
|
|
5629
|
+
if (invalid) {
|
|
5630
|
+
setFormError(`${invalid.name} is not a PDF.`);
|
|
5631
|
+
return;
|
|
5632
|
+
}
|
|
5633
|
+
const oversized = files.find((file) => file.size > 25 * 1024 * 1024);
|
|
5634
|
+
if (oversized) {
|
|
5635
|
+
setFormError(`${oversized.name} is larger than 25 MB.`);
|
|
5636
|
+
return;
|
|
5637
|
+
}
|
|
5638
|
+
setFormError("");
|
|
5639
|
+
setUploads((current) => [...current, ...files.map((file) => ({ file, documentType: "appeal" }))]);
|
|
5640
|
+
};
|
|
5641
|
+
const continueToDelivery = async () => {
|
|
5642
|
+
if (!selected.length) {
|
|
5643
|
+
setFormError("Select at least one service line.");
|
|
5644
|
+
return;
|
|
5645
|
+
}
|
|
5646
|
+
if (invalidReason) {
|
|
5647
|
+
setFormError("Enter a dispute reason for every selected service line.");
|
|
5648
|
+
return;
|
|
5649
|
+
}
|
|
5650
|
+
setPreparing(true);
|
|
5651
|
+
setFormError("");
|
|
5652
|
+
try {
|
|
5653
|
+
setDelivery(await getDeliveryOptions());
|
|
5654
|
+
} catch (cause) {
|
|
5655
|
+
setFormError(cause instanceof Error ? cause.message : "Delivery methods could not be loaded.");
|
|
5656
|
+
} finally {
|
|
5657
|
+
setPreparing(false);
|
|
5658
|
+
}
|
|
5659
|
+
};
|
|
5660
|
+
const submit = async (route) => {
|
|
5661
|
+
setPreparing(true);
|
|
5662
|
+
setFormError("");
|
|
5663
|
+
try {
|
|
5664
|
+
const documents = await prepareBillSubmissionDocuments({
|
|
5665
|
+
attachments: [],
|
|
5666
|
+
selectedIds: [],
|
|
5667
|
+
uploads,
|
|
5668
|
+
...fetchOverride ? { fetch: fetchOverride } : {}
|
|
5669
|
+
});
|
|
5670
|
+
const lineItems = selected.map((line) => {
|
|
5671
|
+
const draft = lines[line.id];
|
|
5672
|
+
return {
|
|
5673
|
+
lineItemId: line.id,
|
|
5674
|
+
reason: draft.reason.trim(),
|
|
5675
|
+
...draft.serviceAuthorized === "" ? {} : { serviceAuthorized: draft.serviceAuthorized === "yes" }
|
|
5676
|
+
};
|
|
5677
|
+
});
|
|
5678
|
+
await onSubmit({
|
|
5679
|
+
attachmentIds,
|
|
5680
|
+
documents,
|
|
5681
|
+
disputedAmount,
|
|
5682
|
+
lineItems,
|
|
5683
|
+
...lineItems[0] ? { reason: lineItems[0].reason } : {},
|
|
5684
|
+
...route
|
|
5685
|
+
});
|
|
5686
|
+
} catch (cause) {
|
|
5687
|
+
setFormError(cause instanceof Error ? cause.message : "The Second Review could not be submitted.");
|
|
5688
|
+
} finally {
|
|
5689
|
+
setPreparing(false);
|
|
5690
|
+
}
|
|
5691
|
+
};
|
|
5692
|
+
return /* @__PURE__ */ jsxs14(Fragment12, { children: [
|
|
5693
|
+
/* @__PURE__ */ jsx14("style", { children: css10 }),
|
|
5694
|
+
/* @__PURE__ */ jsxs14("section", { className: "mbsr", children: [
|
|
5695
|
+
/* @__PURE__ */ jsxs14("div", { children: [
|
|
5696
|
+
/* @__PURE__ */ jsx14("h3", { children: "Submit Second Review" }),
|
|
5697
|
+
/* @__PURE__ */ jsx14("p", { children: "Select each disputed service and explain why it should be reconsidered." })
|
|
5698
|
+
] }),
|
|
5699
|
+
/* @__PURE__ */ jsxs14("label", { className: "mbsr-template", children: [
|
|
5700
|
+
/* @__PURE__ */ jsx14("span", { className: "mbsr-label", children: "Apply a saved reason to selected lines" }),
|
|
5701
|
+
/* @__PURE__ */ jsxs14("select", { className: "mbsr-select", defaultValue: "", onChange: (event) => {
|
|
5702
|
+
applyTemplate(event.target.value);
|
|
5703
|
+
event.target.value = "";
|
|
5704
|
+
}, children: [
|
|
5705
|
+
/* @__PURE__ */ jsx14("option", { value: "", children: "Choose a reason template (optional)" }),
|
|
5706
|
+
SECOND_REVIEW_REASON_TEMPLATES.map((template) => /* @__PURE__ */ jsx14("option", { value: template.value, children: template.label }, template.label))
|
|
5707
|
+
] })
|
|
5708
|
+
] }),
|
|
5709
|
+
/* @__PURE__ */ jsxs14("section", { className: "mbsr-lines", "aria-label": "Service lines in dispute", children: [
|
|
5710
|
+
selectableLines.map((line) => {
|
|
5711
|
+
const draft = lines[line.id];
|
|
5712
|
+
return /* @__PURE__ */ jsxs14("article", { className: "mbsr-line", "data-selected": draft?.selected, children: [
|
|
5713
|
+
/* @__PURE__ */ jsxs14("div", { className: "mbsr-line-head", children: [
|
|
5714
|
+
/* @__PURE__ */ jsxs14("label", { className: "mbsr-check", children: [
|
|
5715
|
+
/* @__PURE__ */ jsx14("input", { type: "checkbox", checked: Boolean(draft?.selected), onChange: (event) => patchLine(line.id, { selected: event.target.checked }) }),
|
|
5716
|
+
/* @__PURE__ */ jsxs14("span", { children: [
|
|
5717
|
+
line.code,
|
|
5718
|
+
line.modifiers.length ? `-${line.modifiers.join("-")}` : ""
|
|
5719
|
+
] })
|
|
5720
|
+
] }),
|
|
5721
|
+
/* @__PURE__ */ jsxs14("span", { className: "mbsr-metrics", children: [
|
|
5722
|
+
/* @__PURE__ */ jsxs14("span", { children: [
|
|
5723
|
+
line.units,
|
|
5724
|
+
" unit",
|
|
5725
|
+
line.units === 1 ? "" : "s"
|
|
5726
|
+
] }),
|
|
5727
|
+
/* @__PURE__ */ jsx14("span", { children: money5(line.charge) })
|
|
5728
|
+
] })
|
|
5729
|
+
] }),
|
|
5730
|
+
draft?.selected ? /* @__PURE__ */ jsxs14(Fragment12, { children: [
|
|
5731
|
+
/* @__PURE__ */ jsxs14("label", { className: "mbsr-field", children: [
|
|
5732
|
+
/* @__PURE__ */ jsx14("span", { className: "mbsr-label", children: "Reason for requesting Second Review" }),
|
|
5733
|
+
/* @__PURE__ */ jsx14("textarea", { className: "mbsr-textarea", required: true, value: draft.reason, onChange: (event) => patchLine(line.id, { reason: event.target.value }) })
|
|
5734
|
+
] }),
|
|
5735
|
+
/* @__PURE__ */ jsxs14("div", { className: "mbsr-auth", role: "radiogroup", "aria-label": `Service or good ${line.code} authorized`, children: [
|
|
5736
|
+
/* @__PURE__ */ jsx14("strong", { children: "Service/Good Authorized?" }),
|
|
5737
|
+
[["yes", "Yes"], ["no", "No"], ["", "Not specified"]].map(([value, label]) => /* @__PURE__ */ jsxs14("label", { children: [
|
|
5738
|
+
/* @__PURE__ */ jsx14("input", { type: "radio", name: `authorized-${line.id}`, checked: draft.serviceAuthorized === value, onChange: () => patchLine(line.id, { serviceAuthorized: value }) }),
|
|
5739
|
+
label
|
|
5740
|
+
] }, label))
|
|
5741
|
+
] })
|
|
5742
|
+
] }) : null
|
|
5743
|
+
] }, line.id);
|
|
5744
|
+
}),
|
|
5745
|
+
!selectableLines.length ? /* @__PURE__ */ jsx14("div", { className: "mbsr-error", children: "This bill has no stable service-line identifiers. Refresh the bill before submitting a Second Review." }) : null
|
|
5746
|
+
] }),
|
|
5747
|
+
/* @__PURE__ */ jsxs14("fieldset", { className: "mbsr-packet", children: [
|
|
5748
|
+
/* @__PURE__ */ jsx14("legend", { children: "Supporting packet" }),
|
|
5749
|
+
data.bill.attachments.map((attachment) => /* @__PURE__ */ jsxs14("label", { className: "mbsr-document", children: [
|
|
5750
|
+
/* @__PURE__ */ jsx14("input", { type: "checkbox", checked: attachmentIds.includes(attachment.id), onChange: (event) => setAttachmentIds((current) => event.target.checked ? [...current, attachment.id] : current.filter((id) => id !== attachment.id)) }),
|
|
5751
|
+
/* @__PURE__ */ jsxs14("span", { children: [
|
|
5752
|
+
/* @__PURE__ */ jsx14("strong", { children: attachment.filename }),
|
|
5753
|
+
/* @__PURE__ */ jsx14("small", { children: attachment.description || attachment.documentType })
|
|
5754
|
+
] }),
|
|
5755
|
+
/* @__PURE__ */ jsx14("button", { className: "mbsr-link", type: "button", onClick: () => void openAttachment(attachment).catch(() => void 0), children: "View" })
|
|
5756
|
+
] }, attachment.id)),
|
|
5757
|
+
/* @__PURE__ */ jsxs14("label", { className: "mbsr-upload", children: [
|
|
5758
|
+
/* @__PURE__ */ jsx14("input", { type: "file", accept: "application/pdf,.pdf", multiple: true, onChange: addUploads }),
|
|
5759
|
+
/* @__PURE__ */ jsxs14("span", { children: [
|
|
5760
|
+
/* @__PURE__ */ jsx14("strong", { children: "Choose one or more PDF files" }),
|
|
5761
|
+
" to attach"
|
|
5762
|
+
] })
|
|
5763
|
+
] }),
|
|
5764
|
+
uploads.map((upload, index) => /* @__PURE__ */ jsxs14("div", { className: "mbsr-uploaded", children: [
|
|
5765
|
+
/* @__PURE__ */ jsx14("span", { children: upload.file.name }),
|
|
5766
|
+
/* @__PURE__ */ jsx14("button", { className: "mbsr-link", type: "button", onClick: () => setUploads((current) => current.filter((_, itemIndex) => itemIndex !== index)), children: "Remove" })
|
|
5767
|
+
] }, `${upload.file.name}-${index}`))
|
|
5768
|
+
] }),
|
|
5769
|
+
formError || error?.message ? /* @__PURE__ */ jsx14("div", { className: "mbsr-error", role: "alert", children: formError || error?.message }) : null,
|
|
5770
|
+
/* @__PURE__ */ jsxs14("div", { className: "mbsr-actions", children: [
|
|
5771
|
+
/* @__PURE__ */ jsx14("button", { className: "mbsr-button secondary", type: "button", disabled: submitting || preparing, onClick: onCancel, children: "Cancel" }),
|
|
5772
|
+
/* @__PURE__ */ jsx14("button", { className: "mbsr-button primary", type: "button", disabled: submitting || preparing || !selected.length || invalidReason, onClick: () => void continueToDelivery(), children: preparing ? "Preparing\u2026" : "Continue to delivery" })
|
|
5773
|
+
] })
|
|
5774
|
+
] }),
|
|
5775
|
+
delivery ? /* @__PURE__ */ jsx14(SendRouteDialog, { title: "Confirm Second Review delivery", delivery, submitting: submitting || preparing, error: formError || error?.message || null, onCancel: () => setDelivery(null), onConfirm: (route) => void submit(route) }) : null
|
|
5776
|
+
] });
|
|
5777
|
+
}
|
|
5778
|
+
|
|
5779
|
+
// src/connected-bill-lifecycle.tsx
|
|
5254
5780
|
import {
|
|
5255
|
-
SECOND_REVIEW_REASON_TEMPLATE
|
|
5781
|
+
SECOND_REVIEW_REASON_TEMPLATE,
|
|
5256
5782
|
SECOND_REVIEW_WINDOW_DAYS,
|
|
5257
5783
|
createBillLifecycleClient as createBillLifecycleClient2,
|
|
5258
5784
|
reportBillStatusContacts as reportBillStatusContacts2,
|
|
5259
5785
|
secondReviewDeadline as secondReviewDeadline2
|
|
5260
5786
|
} from "@mindbill/browser";
|
|
5261
|
-
import { Fragment as
|
|
5787
|
+
import { Fragment as Fragment13, jsx as jsx15, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
5262
5788
|
var DEFAULT_REFRESH_INTERVAL2 = 6e4;
|
|
5263
5789
|
function reservePreviewWindow() {
|
|
5264
5790
|
const preview = window.open("about:blank", "_blank");
|
|
@@ -5300,25 +5826,25 @@ function useBillLifecycle({
|
|
|
5300
5826
|
enabled = true,
|
|
5301
5827
|
fetch: fetchOverride
|
|
5302
5828
|
}) {
|
|
5303
|
-
const [data, setData] =
|
|
5304
|
-
const [error, setError] =
|
|
5305
|
-
const [isLoading, setIsLoading] =
|
|
5306
|
-
const [isRefreshing, setIsRefreshing] =
|
|
5307
|
-
const [isMutating, setIsMutating] =
|
|
5308
|
-
const mounted =
|
|
5309
|
-
const client =
|
|
5829
|
+
const [data, setData] = useState12(null);
|
|
5830
|
+
const [error, setError] = useState12(null);
|
|
5831
|
+
const [isLoading, setIsLoading] = useState12(enabled);
|
|
5832
|
+
const [isRefreshing, setIsRefreshing] = useState12(false);
|
|
5833
|
+
const [isMutating, setIsMutating] = useState12(false);
|
|
5834
|
+
const mounted = useRef6(true);
|
|
5835
|
+
const client = useMemo9(() => createBillLifecycleClient({
|
|
5310
5836
|
billId: providedBillId,
|
|
5311
5837
|
sessionEndpoint,
|
|
5312
5838
|
getSession,
|
|
5313
5839
|
apiBaseUrl,
|
|
5314
5840
|
fetch: fetchOverride
|
|
5315
5841
|
}), [apiBaseUrl, fetchOverride, getSession, providedBillId, sessionEndpoint]);
|
|
5316
|
-
|
|
5842
|
+
useEffect10(() => {
|
|
5317
5843
|
setData(null);
|
|
5318
5844
|
setError(null);
|
|
5319
5845
|
setIsLoading(enabled);
|
|
5320
5846
|
}, [enabled, providedBillId]);
|
|
5321
|
-
|
|
5847
|
+
useEffect10(() => {
|
|
5322
5848
|
mounted.current = true;
|
|
5323
5849
|
return () => {
|
|
5324
5850
|
mounted.current = false;
|
|
@@ -5342,7 +5868,7 @@ function useBillLifecycle({
|
|
|
5342
5868
|
}
|
|
5343
5869
|
}
|
|
5344
5870
|
}, [client, enabled]);
|
|
5345
|
-
|
|
5871
|
+
useEffect10(() => {
|
|
5346
5872
|
if (!enabled) return;
|
|
5347
5873
|
void refresh();
|
|
5348
5874
|
const interval = refreshInterval > 0 ? window.setInterval(() => void refresh(), refreshInterval) : null;
|
|
@@ -5411,10 +5937,10 @@ function useBillLifecycle({
|
|
|
5411
5937
|
};
|
|
5412
5938
|
}
|
|
5413
5939
|
function LifecycleDialog({ children, title, wide = false, onClose }) {
|
|
5414
|
-
const dialog =
|
|
5415
|
-
const onCloseRef =
|
|
5940
|
+
const dialog = useRef6(null);
|
|
5941
|
+
const onCloseRef = useRef6(onClose);
|
|
5416
5942
|
onCloseRef.current = onClose;
|
|
5417
|
-
|
|
5943
|
+
useEffect10(() => {
|
|
5418
5944
|
const previous = document.activeElement;
|
|
5419
5945
|
dialog.current?.focus();
|
|
5420
5946
|
const onKeyDown = (event) => event.key === "Escape" && onCloseRef.current();
|
|
@@ -5424,8 +5950,8 @@ function LifecycleDialog({ children, title, wide = false, onClose }) {
|
|
|
5424
5950
|
previous?.focus();
|
|
5425
5951
|
};
|
|
5426
5952
|
}, []);
|
|
5427
|
-
return /* @__PURE__ */
|
|
5428
|
-
/* @__PURE__ */
|
|
5953
|
+
return /* @__PURE__ */ jsx15("div", { className: "mb-lifecycle-dialog-backdrop", onMouseDown: (event) => event.currentTarget === event.target && onClose(), children: /* @__PURE__ */ jsxs15("div", { ref: dialog, className: ["mb-lifecycle-dialog", wide ? "wide" : ""].filter(Boolean).join(" "), role: "dialog", "aria-modal": "true", "aria-label": title, tabIndex: -1, children: [
|
|
5954
|
+
/* @__PURE__ */ jsx15("button", { type: "button", className: "mb-lifecycle-dialog-close", "aria-label": "Close", onClick: onClose, children: "\xD7" }),
|
|
5429
5955
|
children
|
|
5430
5956
|
] }) });
|
|
5431
5957
|
}
|
|
@@ -5464,22 +5990,22 @@ function correctionRejectionSummary(rejection) {
|
|
|
5464
5990
|
function CorrectionRejectionReason({ rejection }) {
|
|
5465
5991
|
const summary = correctionRejectionSummary(rejection);
|
|
5466
5992
|
const details = rejection.issues?.filter((issue) => issue.description.trim() !== summary.description || Boolean(issue.code?.trim() && issue.code.trim() !== summary.code)) ?? [];
|
|
5467
|
-
return /* @__PURE__ */
|
|
5468
|
-
summary.code ? /* @__PURE__ */
|
|
5469
|
-
/* @__PURE__ */
|
|
5470
|
-
/* @__PURE__ */
|
|
5471
|
-
summary.clearinghouseDetail ? /* @__PURE__ */
|
|
5472
|
-
/* @__PURE__ */
|
|
5993
|
+
return /* @__PURE__ */ jsxs15("div", { className: "mb-lifecycle-correction-reason", role: "alert", children: [
|
|
5994
|
+
summary.code ? /* @__PURE__ */ jsxs15("div", { className: "mb-lifecycle-correction-reason-code", children: [
|
|
5995
|
+
/* @__PURE__ */ jsx15("span", { children: "Rejection code" }),
|
|
5996
|
+
/* @__PURE__ */ jsx15("code", { children: summary.code }),
|
|
5997
|
+
summary.clearinghouseDetail ? /* @__PURE__ */ jsxs15("small", { children: [
|
|
5998
|
+
/* @__PURE__ */ jsx15("span", { children: "Clearinghouse detail" }),
|
|
5473
5999
|
summary.clearinghouseDetail
|
|
5474
6000
|
] }) : null
|
|
5475
6001
|
] }) : null,
|
|
5476
|
-
/* @__PURE__ */
|
|
5477
|
-
/* @__PURE__ */
|
|
5478
|
-
/* @__PURE__ */
|
|
6002
|
+
/* @__PURE__ */ jsxs15("div", { className: "mb-lifecycle-correction-reason-description", children: [
|
|
6003
|
+
/* @__PURE__ */ jsx15("span", { children: "Reason" }),
|
|
6004
|
+
/* @__PURE__ */ jsx15("strong", { children: summary.description })
|
|
5479
6005
|
] }),
|
|
5480
|
-
details.length ? /* @__PURE__ */
|
|
5481
|
-
issue.code ? /* @__PURE__ */
|
|
5482
|
-
/* @__PURE__ */
|
|
6006
|
+
details.length ? /* @__PURE__ */ jsx15("ul", { "aria-label": "Additional rejection details", children: details.map((issue, index) => /* @__PURE__ */ jsxs15("li", { children: [
|
|
6007
|
+
issue.code ? /* @__PURE__ */ jsx15("code", { children: issue.code }) : null,
|
|
6008
|
+
/* @__PURE__ */ jsx15("span", { children: issue.description })
|
|
5483
6009
|
] }, `${issue.code || "issue"}-${index}`)) }) : null
|
|
5484
6010
|
] });
|
|
5485
6011
|
}
|
|
@@ -5520,16 +6046,16 @@ function CorrectionVerificationContact({ delivery }) {
|
|
|
5520
6046
|
{ label: "Mail", values: mailingAddresses }
|
|
5521
6047
|
].filter((method) => method.values.length);
|
|
5522
6048
|
if (!methods.length) return null;
|
|
5523
|
-
return /* @__PURE__ */
|
|
5524
|
-
/* @__PURE__ */
|
|
5525
|
-
/* @__PURE__ */
|
|
6049
|
+
return /* @__PURE__ */ jsxs15("aside", { className: "mb-lifecycle-correction-contact", children: [
|
|
6050
|
+
/* @__PURE__ */ jsx15("strong", { children: "Need to verify the rejected information?" }),
|
|
6051
|
+
/* @__PURE__ */ jsxs15("span", { children: [
|
|
5526
6052
|
"Contact ",
|
|
5527
6053
|
delivery.payerName,
|
|
5528
6054
|
" using any available method:"
|
|
5529
6055
|
] }),
|
|
5530
|
-
/* @__PURE__ */
|
|
5531
|
-
/* @__PURE__ */
|
|
5532
|
-
/* @__PURE__ */
|
|
6056
|
+
/* @__PURE__ */ jsx15("dl", { children: methods.map((method) => /* @__PURE__ */ jsxs15("div", { children: [
|
|
6057
|
+
/* @__PURE__ */ jsx15("dt", { children: method.label }),
|
|
6058
|
+
/* @__PURE__ */ jsx15("dd", { children: /* @__PURE__ */ jsx15("ul", { children: method.values.map((value) => /* @__PURE__ */ jsx15("li", { children: method.href ? /* @__PURE__ */ jsx15("a", { href: method.href(value), ...method.label === "Portal" ? { target: "_blank", rel: "noreferrer" } : {}, children: value }) : value }, value)) }) })
|
|
5533
6059
|
] }, method.label)) })
|
|
5534
6060
|
] });
|
|
5535
6061
|
}
|
|
@@ -5645,20 +6171,19 @@ function shouldShowSandboxControls(environment, enabled = false) {
|
|
|
5645
6171
|
function ConnectedBillLifecycle({ appearance, actorName, claimsAdministratorHint, claimsAdministratorSources, sandboxControls = false, className, style, loadingFallback, errorFallback, onChanged, ...options }) {
|
|
5646
6172
|
const lifecycle = useBillLifecycle(options);
|
|
5647
6173
|
const { data } = lifecycle;
|
|
5648
|
-
const [tab, setTab] =
|
|
5649
|
-
const [
|
|
5650
|
-
const [
|
|
5651
|
-
const [
|
|
5652
|
-
const [
|
|
5653
|
-
const [
|
|
5654
|
-
const [
|
|
5655
|
-
const [
|
|
5656
|
-
const [
|
|
5657
|
-
const [duplicateDeliveryError, setDuplicateDeliveryError] = useState11("");
|
|
6174
|
+
const [tab, setTab] = useState12("details");
|
|
6175
|
+
const [selectedSubmissionId, setSelectedSubmissionId] = useState12();
|
|
6176
|
+
const [panel, setPanel] = useState12("");
|
|
6177
|
+
const [notice, setNotice] = useState12("");
|
|
6178
|
+
const [reason, setReason] = useState12("");
|
|
6179
|
+
const [correctionError, setCorrectionError] = useState12("");
|
|
6180
|
+
const [newBillError, setNewBillError] = useState12("");
|
|
6181
|
+
const [payment, setPayment] = useState12({ amount: 0, penaltyAmount: 0, interestAmount: 0, method: "check", checkNumber: "", depositDate: today(), note: "" });
|
|
6182
|
+
const [duplicateError, setDuplicateError] = useState12("");
|
|
5658
6183
|
const actor = actorName?.trim() ? { actorName: actorName.trim() } : {};
|
|
5659
|
-
const lastData =
|
|
5660
|
-
const correctionInitialBill =
|
|
5661
|
-
const correctionAttachments =
|
|
6184
|
+
const lastData = useRef6(null);
|
|
6185
|
+
const correctionInitialBill = useMemo9(() => data ? correctionBill(data) : null, [data]);
|
|
6186
|
+
const correctionAttachments = useMemo9(() => data ? data.bill.attachments.map((attachment) => {
|
|
5662
6187
|
const documentType = correctionDocumentType(attachment.documentType);
|
|
5663
6188
|
const isW9 = documentType === "w9";
|
|
5664
6189
|
return {
|
|
@@ -5671,8 +6196,8 @@ function ConnectedBillLifecycle({ appearance, actorName, claimsAdministratorHint
|
|
|
5671
6196
|
...isW9 ? { autoAttached: true, removable: false } : { removable: true }
|
|
5672
6197
|
};
|
|
5673
6198
|
}) : [], [data, lifecycle]);
|
|
5674
|
-
const correctionAttentionFields =
|
|
5675
|
-
|
|
6199
|
+
const correctionAttentionFields = useMemo9(() => data?.rejection?.issues?.flatMap((issue) => issue.fieldPaths || []).filter((path, index, fields) => fields.indexOf(path) === index) || [], [data]);
|
|
6200
|
+
useEffect10(() => {
|
|
5676
6201
|
if (!data || data === lastData.current) return;
|
|
5677
6202
|
lastData.current = data;
|
|
5678
6203
|
onChanged?.(data);
|
|
@@ -5683,19 +6208,14 @@ function ConnectedBillLifecycle({ appearance, actorName, claimsAdministratorHint
|
|
|
5683
6208
|
penaltyAmount: 0,
|
|
5684
6209
|
interestAmount: 0
|
|
5685
6210
|
}));
|
|
5686
|
-
setReview((current) => ({
|
|
5687
|
-
...current,
|
|
5688
|
-
disputedAmount: current.disputedAmount ?? data.bill.balanceDue,
|
|
5689
|
-
attachmentIds: current.attachmentIds.length ? current.attachmentIds.filter((id) => data.bill.attachments.some((document2) => document2.id === id)) : data.bill.attachments.map((document2) => document2.id)
|
|
5690
|
-
}));
|
|
5691
6211
|
}, [data, onChanged]);
|
|
5692
|
-
if (lifecycle.isLoading && !data) return /* @__PURE__ */
|
|
6212
|
+
if (lifecycle.isLoading && !data) return /* @__PURE__ */ jsx15(Fragment13, { children: loadingFallback ?? /* @__PURE__ */ jsx15("div", { className: "mb-lifecycle-loading", children: "Loading bill\u2026" }) });
|
|
5693
6213
|
if (!data) {
|
|
5694
6214
|
const error = lifecycle.error ?? new Error("Bill could not be loaded.");
|
|
5695
|
-
return /* @__PURE__ */
|
|
5696
|
-
/* @__PURE__ */
|
|
5697
|
-
/* @__PURE__ */
|
|
5698
|
-
/* @__PURE__ */
|
|
6215
|
+
return /* @__PURE__ */ jsx15(Fragment13, { children: errorFallback?.(error, lifecycle.refresh) ?? /* @__PURE__ */ jsxs15("div", { className: "mb-lifecycle-error", role: "alert", children: [
|
|
6216
|
+
/* @__PURE__ */ jsx15("strong", { children: "Billing is unavailable." }),
|
|
6217
|
+
/* @__PURE__ */ jsx15("span", { children: error.message }),
|
|
6218
|
+
/* @__PURE__ */ jsx15("button", { type: "button", onClick: () => void lifecycle.refresh(), children: "Try again" })
|
|
5699
6219
|
] }) });
|
|
5700
6220
|
}
|
|
5701
6221
|
const complete = async (message, task) => {
|
|
@@ -5721,6 +6241,7 @@ function ConnectedBillLifecycle({ appearance, actorName, claimsAdministratorHint
|
|
|
5721
6241
|
});
|
|
5722
6242
|
await lifecycle.resubmitBill({
|
|
5723
6243
|
bill: value.bill,
|
|
6244
|
+
...value.submission ? { submission: value.submission } : {},
|
|
5724
6245
|
...documents.length ? { documents } : {},
|
|
5725
6246
|
...reason.trim() ? { reason: reason.trim() } : {},
|
|
5726
6247
|
...actor
|
|
@@ -5729,7 +6250,7 @@ function ConnectedBillLifecycle({ appearance, actorName, claimsAdministratorHint
|
|
|
5729
6250
|
setCorrectionError(
|
|
5730
6251
|
cause instanceof Error && cause.message ? cause.message : "The corrected bill could not be resubmitted."
|
|
5731
6252
|
);
|
|
5732
|
-
|
|
6253
|
+
throw cause;
|
|
5733
6254
|
}
|
|
5734
6255
|
setPanel("");
|
|
5735
6256
|
setReason("");
|
|
@@ -5748,6 +6269,7 @@ function ConnectedBillLifecycle({ appearance, actorName, claimsAdministratorHint
|
|
|
5748
6269
|
});
|
|
5749
6270
|
await lifecycle.submitNewBill({
|
|
5750
6271
|
bill: value.bill,
|
|
6272
|
+
...value.submission ? { submission: value.submission } : {},
|
|
5751
6273
|
...documents.length ? { documents } : {},
|
|
5752
6274
|
...reason.trim() ? { reason: reason.trim() } : {},
|
|
5753
6275
|
...actor
|
|
@@ -5756,91 +6278,117 @@ function ConnectedBillLifecycle({ appearance, actorName, claimsAdministratorHint
|
|
|
5756
6278
|
setNewBillError(
|
|
5757
6279
|
cause instanceof Error && cause.message ? cause.message : "The new bill could not be submitted."
|
|
5758
6280
|
);
|
|
5759
|
-
|
|
6281
|
+
throw cause;
|
|
5760
6282
|
}
|
|
5761
6283
|
setPanel("");
|
|
5762
6284
|
setReason("");
|
|
5763
6285
|
setNotice("New bill submitted.");
|
|
5764
6286
|
};
|
|
5765
|
-
const
|
|
5766
|
-
|
|
5767
|
-
|
|
5768
|
-
|
|
6287
|
+
const submitDuplicateFromForm = async (value) => {
|
|
6288
|
+
setNotice("");
|
|
6289
|
+
setDuplicateError("");
|
|
6290
|
+
try {
|
|
6291
|
+
const documents = await prepareBillSubmissionDocuments({
|
|
6292
|
+
attachments: correctionAttachments,
|
|
6293
|
+
selectedIds: value.sourceAttachmentIds,
|
|
6294
|
+
reportTypeCodeByAttachmentId: value.sourceAttachmentReportTypes,
|
|
6295
|
+
uploads: value.uploads,
|
|
6296
|
+
...options.fetch ? { fetch: options.fetch } : {}
|
|
6297
|
+
});
|
|
6298
|
+
await lifecycle.sendDuplicateBill({
|
|
6299
|
+
bill: value.bill,
|
|
6300
|
+
...value.submission ? { submission: value.submission } : {},
|
|
6301
|
+
...documents.length ? { documents } : {},
|
|
6302
|
+
...actor
|
|
6303
|
+
});
|
|
6304
|
+
} catch (cause) {
|
|
6305
|
+
setDuplicateError(
|
|
6306
|
+
cause instanceof Error && cause.message ? cause.message : "The duplicate bill could not be submitted."
|
|
6307
|
+
);
|
|
6308
|
+
throw cause;
|
|
6309
|
+
}
|
|
6310
|
+
setPanel("");
|
|
6311
|
+
setNotice("Duplicate bill sent.");
|
|
5769
6312
|
};
|
|
5770
6313
|
const viewEor = data.lifecycle.actions.find((action) => action.id === "view_eor" && action.enabled);
|
|
5771
6314
|
const supportedActions = /* @__PURE__ */ new Set(["resubmit", "submit_new_bill", "second_review", "post_payment", "close", "reopen", "send_duplicate", "report_bill_status"]);
|
|
5772
6315
|
const actions = data.lifecycle.actions.filter((action) => action.enabled && supportedActions.has(action.id));
|
|
5773
6316
|
const showSandboxControls = shouldShowSandboxControls(data.environment, sandboxControls);
|
|
5774
6317
|
const simulations = showSandboxControls ? sandboxScenarios(data.lifecycle.state) : [];
|
|
5775
|
-
const
|
|
6318
|
+
const mappedRibbonItems = data.history ? billSubmissionsRibbonFromHistory(data.history, data.attempts) : [];
|
|
6319
|
+
const activeSubmissionId = selectedSubmissionId ?? mappedRibbonItems.find((item) => item.active)?.id ?? mappedRibbonItems[mappedRibbonItems.length - 1]?.id;
|
|
6320
|
+
const ribbonItems = mappedRibbonItems.map((item) => ({ ...item, active: item.id === activeSubmissionId }));
|
|
6321
|
+
const selectedHistoryEntryId = ribbonItems.find((item) => item.id === activeSubmissionId)?.historyEntryId;
|
|
5776
6322
|
const statusContacts = reportBillStatusContacts(data.delivery);
|
|
5777
6323
|
const receiptEntries = (data.history ?? []).filter((entry) => entry.kind === "submission" || entry.kind === "ack");
|
|
5778
6324
|
const reviewDeadline = secondReviewDeadline(data.eors);
|
|
5779
|
-
return /* @__PURE__ */
|
|
5780
|
-
/* @__PURE__ */
|
|
5781
|
-
ribbonItems.length >= 2 ? /* @__PURE__ */
|
|
5782
|
-
|
|
5783
|
-
|
|
5784
|
-
|
|
5785
|
-
|
|
6325
|
+
return /* @__PURE__ */ jsxs15("section", { className: ["mb-connected-lifecycle", className].filter(Boolean).join(" "), style: mindBillAppearanceStyle(appearance, style), children: [
|
|
6326
|
+
/* @__PURE__ */ jsx15("style", { children: CONNECTED_LIFECYCLE_STYLES }),
|
|
6327
|
+
ribbonItems.length >= 2 ? /* @__PURE__ */ jsx15(BillSubmissionsRibbon, { items: ribbonItems, onSelect: (item) => {
|
|
6328
|
+
setSelectedSubmissionId(item.id);
|
|
6329
|
+
setTab("history");
|
|
6330
|
+
}, ...appearance ? { appearance } : {} }) : null,
|
|
6331
|
+
data.lifecycle.state.toLowerCase() === "rejected" && data.rejection ? /* @__PURE__ */ jsx15(BillRejectionNotice, { rejection: data.rejection, submittedAt: data.lifecycle.submittedAt ?? null, ...appearance ? { appearance } : {} }) : /* @__PURE__ */ jsx15(BillLifecycleProgress, { state: data.lifecycle.state, nativeStatus: data.lifecycle.nativeStatus, submittedAt: data.lifecycle.submittedAt ?? null, agingDays: data.lifecycle.agingDays ?? null, ...appearance ? { appearance } : {} }),
|
|
6332
|
+
/* @__PURE__ */ jsxs15("header", { className: "mb-lifecycle-head", children: [
|
|
6333
|
+
/* @__PURE__ */ jsxs15("div", { children: [
|
|
6334
|
+
/* @__PURE__ */ jsx15("div", { className: "mb-lifecycle-title", children: /* @__PURE__ */ jsxs15("h2", { children: [
|
|
5786
6335
|
"Bill #",
|
|
5787
6336
|
data.bill.billNumber
|
|
5788
6337
|
] }) }),
|
|
5789
|
-
/* @__PURE__ */
|
|
6338
|
+
/* @__PURE__ */ jsxs15("p", { children: [
|
|
5790
6339
|
"Claim ",
|
|
5791
6340
|
data.injury.claimNumber || "\u2014",
|
|
5792
6341
|
lifecycle.isRefreshing ? " \xB7 Refreshing\u2026" : ""
|
|
5793
6342
|
] })
|
|
5794
6343
|
] }),
|
|
5795
|
-
/* @__PURE__ */
|
|
6344
|
+
/* @__PURE__ */ jsx15("button", { type: "button", className: "mb-lifecycle-button primary", disabled: lifecycle.isMutating, onClick: () => void lifecycle.downloadPacket().catch(() => void 0), children: "Download packet" })
|
|
5796
6345
|
] }),
|
|
5797
|
-
/* @__PURE__ */
|
|
5798
|
-
/* @__PURE__ */
|
|
5799
|
-
/* @__PURE__ */
|
|
6346
|
+
/* @__PURE__ */ jsxs15("div", { className: "mb-lifecycle-tabs", role: "tablist", "aria-label": "Bill view", children: [
|
|
6347
|
+
/* @__PURE__ */ jsx15("button", { type: "button", role: "tab", "aria-selected": tab === "details", onClick: () => setTab("details"), children: "Bill details" }),
|
|
6348
|
+
/* @__PURE__ */ jsx15("button", { type: "button", role: "tab", "aria-selected": tab === "history", onClick: () => setTab("history"), children: "Bill history" })
|
|
5800
6349
|
] }),
|
|
5801
|
-
tab === "details" ? /* @__PURE__ */
|
|
5802
|
-
data.eors.length || data.payments.length || ["processed", "denied", "partially_paid"].includes(data.lifecycle.state) ? /* @__PURE__ */
|
|
5803
|
-
showSandboxControls ? /* @__PURE__ */
|
|
5804
|
-
/* @__PURE__ */
|
|
5805
|
-
/* @__PURE__ */
|
|
5806
|
-
/* @__PURE__ */
|
|
5807
|
-
/* @__PURE__ */
|
|
6350
|
+
tab === "details" ? /* @__PURE__ */ jsxs15("div", { className: "mb-lifecycle-tabpanel", role: "tabpanel", children: [
|
|
6351
|
+
data.eors.length || data.payments.length || ["processed", "denied", "partially_paid"].includes(data.lifecycle.state) ? /* @__PURE__ */ jsx15(BillExplanationOfReview, { remittance: data.remittance, eors: data.eors, payments: data.payments, submittedAt: data.lifecycle.submittedAt ?? null, onOpenEor: lifecycle.openEor, ...appearance ? { appearance } : {} }) : null,
|
|
6352
|
+
showSandboxControls ? /* @__PURE__ */ jsxs15("section", { className: "mb-lifecycle-simulator", "aria-label": "Sandbox lifecycle simulator", children: [
|
|
6353
|
+
/* @__PURE__ */ jsxs15("div", { children: [
|
|
6354
|
+
/* @__PURE__ */ jsx15("span", { children: "Sandbox demo controls" }),
|
|
6355
|
+
/* @__PURE__ */ jsx15("h3", { children: "Simulate the next payer response" }),
|
|
6356
|
+
/* @__PURE__ */ jsx15("p", { children: "This changes sandbox data only. The host receives the result through the same lifecycle API and components partners use." })
|
|
5808
6357
|
] }),
|
|
5809
|
-
simulations.length ? /* @__PURE__ */
|
|
5810
|
-
/* @__PURE__ */
|
|
5811
|
-
/* @__PURE__ */
|
|
5812
|
-
] }, scenario.id)) }) : /* @__PURE__ */
|
|
6358
|
+
simulations.length ? /* @__PURE__ */ jsx15("div", { className: "mb-lifecycle-simulator-actions", children: simulations.map((scenario) => /* @__PURE__ */ jsxs15("button", { type: "button", disabled: lifecycle.isMutating, onClick: () => void complete(`${scenario.label} simulated.`, () => lifecycle.simulateSandbox({ scenario: scenario.id })), children: [
|
|
6359
|
+
/* @__PURE__ */ jsx15("strong", { children: scenario.label }),
|
|
6360
|
+
/* @__PURE__ */ jsx15("span", { children: scenario.detail })
|
|
6361
|
+
] }, scenario.id)) }) : /* @__PURE__ */ jsx15("p", { className: "mb-lifecycle-simulator-idle", children: "No simulated payer transition is needed at this stage. Use the bill action below to continue." })
|
|
5813
6362
|
] }) : null,
|
|
5814
|
-
/* @__PURE__ */
|
|
5815
|
-
] }) : /* @__PURE__ */
|
|
5816
|
-
viewEor || actions.length ? /* @__PURE__ */
|
|
5817
|
-
viewEor && data.eors[0] ? /* @__PURE__ */
|
|
5818
|
-
actions.map((action) => /* @__PURE__ */
|
|
6363
|
+
/* @__PURE__ */ jsx15(BillReadOnlyForm, { data, onOpenAttachment: lifecycle.openAttachment, ...appearance ? { appearance } : {} })
|
|
6364
|
+
] }) : /* @__PURE__ */ jsx15("div", { className: "mb-lifecycle-tabpanel", role: "tabpanel", children: data.history?.length ? /* @__PURE__ */ jsx15(BillHistoryTable, { entries: data.history, ...selectedHistoryEntryId ? { selectedEntryId: selectedHistoryEntryId } : {}, onOpenDocument: lifecycle.openAttachment, ...appearance ? { appearance } : {} }) : /* @__PURE__ */ jsx15(BillActivityTimeline, { events: data.activity, ...appearance ? { appearance } : {} }) }),
|
|
6365
|
+
viewEor || actions.length ? /* @__PURE__ */ jsxs15("aside", { className: "mb-lifecycle-actions-sheet", "aria-label": "Bill actions", children: [
|
|
6366
|
+
viewEor && data.eors[0] ? /* @__PURE__ */ jsx15("button", { type: "button", className: "mb-lifecycle-button secondary", onClick: () => void lifecycle.openEor(data.eors[0]).catch(() => void 0), children: viewEor.label }) : null,
|
|
6367
|
+
actions.map((action) => /* @__PURE__ */ jsx15("button", { type: "button", className: action.primary ? "mb-lifecycle-button primary" : "mb-lifecycle-button secondary", onClick: () => {
|
|
5819
6368
|
const next = actionPanel(action);
|
|
5820
6369
|
if (!next) return;
|
|
5821
6370
|
if (next === "resubmit") setCorrectionError("");
|
|
5822
6371
|
if (next === "submit_new_bill") setNewBillError("");
|
|
5823
|
-
if (next === "send_duplicate")
|
|
5824
|
-
if (next === "second_review") setReview((current) => current.reason.trim() ? current : { ...current, reason: SECOND_REVIEW_REASON_TEMPLATE });
|
|
6372
|
+
if (next === "send_duplicate") setDuplicateError("");
|
|
5825
6373
|
setPanel(next);
|
|
5826
6374
|
}, children: action.label }, action.id))
|
|
5827
6375
|
] }) : null,
|
|
5828
|
-
panel === "resubmit" && correctionInitialBill ? /* @__PURE__ */
|
|
5829
|
-
/* @__PURE__ */
|
|
5830
|
-
/* @__PURE__ */
|
|
5831
|
-
/* @__PURE__ */
|
|
6376
|
+
panel === "resubmit" && correctionInitialBill ? /* @__PURE__ */ jsx15(LifecycleDialog, { title: "Correct and resubmit", wide: true, onClose: () => setPanel(""), children: /* @__PURE__ */ jsxs15("section", { className: "mb-lifecycle-correction", children: [
|
|
6377
|
+
/* @__PURE__ */ jsx15("header", { children: /* @__PURE__ */ jsxs15("div", { children: [
|
|
6378
|
+
/* @__PURE__ */ jsx15("h3", { children: "Correct and resubmit" }),
|
|
6379
|
+
/* @__PURE__ */ jsx15("p", { children: "Review the rejected snapshot, correct the highlighted information, and submit a new immutable attempt under this bill." })
|
|
5832
6380
|
] }) }),
|
|
5833
|
-
data.environment === "live" ? /* @__PURE__ */
|
|
5834
|
-
/* @__PURE__ */
|
|
5835
|
-
/* @__PURE__ */
|
|
6381
|
+
data.environment === "live" ? /* @__PURE__ */ jsxs15("div", { className: "mb-lifecycle-live-warning", children: [
|
|
6382
|
+
/* @__PURE__ */ jsx15("strong", { children: "Live clearinghouse submission" }),
|
|
6383
|
+
/* @__PURE__ */ jsx15("span", { children: "Resubmitting sends a real bill. Confirm the corrected information before continuing." })
|
|
5836
6384
|
] }) : null,
|
|
5837
|
-
data.rejection ? /* @__PURE__ */
|
|
5838
|
-
/* @__PURE__ */
|
|
5839
|
-
/* @__PURE__ */
|
|
5840
|
-
/* @__PURE__ */
|
|
5841
|
-
/* @__PURE__ */
|
|
6385
|
+
data.rejection ? /* @__PURE__ */ jsx15(CorrectionRejectionReason, { rejection: data.rejection }) : null,
|
|
6386
|
+
/* @__PURE__ */ jsx15(CorrectionVerificationContact, { delivery: data.delivery }),
|
|
6387
|
+
/* @__PURE__ */ jsxs15("label", { className: "mb-lifecycle-correction-note", children: [
|
|
6388
|
+
/* @__PURE__ */ jsx15("span", { children: "Correction note (optional)" }),
|
|
6389
|
+
/* @__PURE__ */ jsx15("textarea", { value: reason, placeholder: "What changed before resubmission?", onChange: (event) => setReason(event.target.value) })
|
|
5842
6390
|
] }),
|
|
5843
|
-
/* @__PURE__ */
|
|
6391
|
+
/* @__PURE__ */ jsx15(
|
|
5844
6392
|
BillSubmissionForm,
|
|
5845
6393
|
{
|
|
5846
6394
|
className: "mbsf-lifecycle-correction",
|
|
@@ -5854,6 +6402,8 @@ function ConnectedBillLifecycle({ appearance, actorName, claimsAdministratorHint
|
|
|
5854
6402
|
attentionFields: correctionAttentionFields,
|
|
5855
6403
|
attentionMessage: correctionAttentionFields.length ? "The rejected response points to the highlighted fields. Confirm every required value before resubmitting." : "Confirm the bill information below before resubmitting.",
|
|
5856
6404
|
submitLabel: lifecycle.isMutating ? "Resubmitting\u2026" : "Resubmit bill",
|
|
6405
|
+
deliveryRoutePicker: "required",
|
|
6406
|
+
deliveryRouteDialogTitle: "Confirm corrected bill delivery",
|
|
5857
6407
|
heading: "Corrected bill information",
|
|
5858
6408
|
description: "The original submission stays unchanged. This form creates the next submission attempt.",
|
|
5859
6409
|
disabled: lifecycle.isMutating,
|
|
@@ -5864,18 +6414,18 @@ function ConnectedBillLifecycle({ appearance, actorName, claimsAdministratorHint
|
|
|
5864
6414
|
...appearance ? { appearance } : {}
|
|
5865
6415
|
}
|
|
5866
6416
|
),
|
|
5867
|
-
correctionError ? /* @__PURE__ */
|
|
6417
|
+
correctionError ? /* @__PURE__ */ jsx15("div", { className: "mb-lifecycle-message error", role: "alert", children: correctionError }) : null
|
|
5868
6418
|
] }) }) : null,
|
|
5869
|
-
panel === "submit_new_bill" && correctionInitialBill ? /* @__PURE__ */
|
|
5870
|
-
/* @__PURE__ */
|
|
5871
|
-
/* @__PURE__ */
|
|
5872
|
-
/* @__PURE__ */
|
|
6419
|
+
panel === "submit_new_bill" && correctionInitialBill ? /* @__PURE__ */ jsx15(LifecycleDialog, { title: "Submit New Bill", wide: true, onClose: () => setPanel(""), children: /* @__PURE__ */ jsxs15("section", { className: "mb-lifecycle-correction", children: [
|
|
6420
|
+
/* @__PURE__ */ jsx15("header", { children: /* @__PURE__ */ jsxs15("div", { children: [
|
|
6421
|
+
/* @__PURE__ */ jsx15("h3", { children: "Submit New Bill" }),
|
|
6422
|
+
/* @__PURE__ */ jsx15("p", { children: "This closed bill stays closed and keeps its record. Review the carried-over snapshot below and submit a fresh bill \u2014 both bills stay linked in the submissions timeline." })
|
|
5873
6423
|
] }) }),
|
|
5874
|
-
/* @__PURE__ */
|
|
5875
|
-
/* @__PURE__ */
|
|
5876
|
-
/* @__PURE__ */
|
|
6424
|
+
/* @__PURE__ */ jsxs15("label", { className: "mb-lifecycle-correction-note", children: [
|
|
6425
|
+
/* @__PURE__ */ jsx15("span", { children: "Submission note (optional)" }),
|
|
6426
|
+
/* @__PURE__ */ jsx15("textarea", { value: reason, placeholder: "Why is a new bill being submitted?", onChange: (event) => setReason(event.target.value) })
|
|
5877
6427
|
] }),
|
|
5878
|
-
/* @__PURE__ */
|
|
6428
|
+
/* @__PURE__ */ jsx15(
|
|
5879
6429
|
BillSubmissionForm,
|
|
5880
6430
|
{
|
|
5881
6431
|
className: "mbsf-lifecycle-correction",
|
|
@@ -5888,6 +6438,8 @@ function ConnectedBillLifecycle({ appearance, actorName, claimsAdministratorHint
|
|
|
5888
6438
|
...claimsAdministratorSources ? { claimsAdministratorSources } : {},
|
|
5889
6439
|
attentionMessage: "Confirm every value carried over from the closed bill before submitting the new bill.",
|
|
5890
6440
|
submitLabel: lifecycle.isMutating ? "Submitting\u2026" : "Submit New Bill",
|
|
6441
|
+
deliveryRoutePicker: "required",
|
|
6442
|
+
deliveryRouteDialogTitle: "Confirm new bill delivery",
|
|
5891
6443
|
heading: "New bill information",
|
|
5892
6444
|
description: "The closed bill stays unchanged. This form submits a fresh bill linked to it.",
|
|
5893
6445
|
disabled: lifecycle.isMutating,
|
|
@@ -5898,146 +6450,135 @@ function ConnectedBillLifecycle({ appearance, actorName, claimsAdministratorHint
|
|
|
5898
6450
|
...appearance ? { appearance } : {}
|
|
5899
6451
|
}
|
|
5900
6452
|
),
|
|
5901
|
-
newBillError ? /* @__PURE__ */
|
|
6453
|
+
newBillError ? /* @__PURE__ */ jsx15("div", { className: "mb-lifecycle-message error", role: "alert", children: newBillError }) : null
|
|
5902
6454
|
] }) }) : null,
|
|
5903
|
-
panel === "second_review" ? /* @__PURE__ */
|
|
5904
|
-
/* @__PURE__ */
|
|
5905
|
-
|
|
5906
|
-
|
|
5907
|
-
|
|
5908
|
-
|
|
6455
|
+
panel === "second_review" ? /* @__PURE__ */ jsxs15(LifecycleDialog, { title: "Submit Second Review", wide: true, onClose: () => setPanel(""), children: [
|
|
6456
|
+
/* @__PURE__ */ jsx15(
|
|
6457
|
+
SecondReviewForm,
|
|
6458
|
+
{
|
|
6459
|
+
data,
|
|
6460
|
+
submitting: lifecycle.isMutating,
|
|
6461
|
+
error: lifecycle.error,
|
|
6462
|
+
...options.fetch ? { fetch: options.fetch } : {},
|
|
6463
|
+
getDeliveryOptions: lifecycle.getDeliveryOptions,
|
|
6464
|
+
openAttachment: lifecycle.openAttachment,
|
|
6465
|
+
onCancel: () => setPanel(""),
|
|
6466
|
+
onSubmit: (input) => complete("Second Review submitted.", () => lifecycle.submitSecondReview({ ...input, ...actor }))
|
|
6467
|
+
}
|
|
6468
|
+
),
|
|
6469
|
+
reviewDeadline ? /* @__PURE__ */ jsxs15("p", { className: "mb-lifecycle-deadline-hint", children: [
|
|
5909
6470
|
"Second Review must be requested within 90 days of the denial EOR (dated ",
|
|
5910
6471
|
usDate(reviewDeadline.eorDate),
|
|
5911
6472
|
") \u2014 file by ",
|
|
5912
|
-
/* @__PURE__ */
|
|
6473
|
+
/* @__PURE__ */ jsx15("strong", { children: usDate(reviewDeadline.deadline) }),
|
|
5913
6474
|
"."
|
|
5914
|
-
] }) : null
|
|
5915
|
-
|
|
5916
|
-
|
|
5917
|
-
|
|
5918
|
-
|
|
5919
|
-
|
|
5920
|
-
/* @__PURE__ */ jsxs14("label", { children: [
|
|
5921
|
-
/* @__PURE__ */ jsx14("span", { children: "Payer claim control number" }),
|
|
5922
|
-
/* @__PURE__ */ jsx14("input", { required: true, value: review.payerClaimControlNumber, onChange: (event) => setReview((current) => ({ ...current, payerClaimControlNumber: event.target.value })) })
|
|
5923
|
-
] }),
|
|
5924
|
-
/* @__PURE__ */ jsxs14("label", { children: [
|
|
5925
|
-
/* @__PURE__ */ jsx14("span", { children: "Disputed amount" }),
|
|
5926
|
-
/* @__PURE__ */ jsx14("input", { type: "number", min: "0.01", step: "0.01", value: review.disputedAmount ?? "", onChange: (event) => setReview((current) => ({ ...current, disputedAmount: event.target.value ? Number(event.target.value) : void 0 })) })
|
|
5927
|
-
] }),
|
|
5928
|
-
/* @__PURE__ */ jsxs14("label", { children: [
|
|
5929
|
-
/* @__PURE__ */ jsx14("span", { children: "Send via" }),
|
|
5930
|
-
/* @__PURE__ */ jsxs14("select", { value: review.route, onChange: (event) => setReview((current) => ({ ...current, route: event.target.value })), children: [
|
|
5931
|
-
/* @__PURE__ */ jsx14("option", { value: "ebill", children: "E-bill" }),
|
|
5932
|
-
/* @__PURE__ */ jsx14("option", { value: "fax", children: "Fax" }),
|
|
5933
|
-
/* @__PURE__ */ jsx14("option", { value: "mail", children: "Mail" }),
|
|
5934
|
-
/* @__PURE__ */ jsx14("option", { value: "email", children: "Email" })
|
|
5935
|
-
] })
|
|
5936
|
-
] })
|
|
5937
|
-
] }),
|
|
5938
|
-
/* @__PURE__ */ jsxs14("fieldset", { className: "mb-lifecycle-packet", children: [
|
|
5939
|
-
/* @__PURE__ */ jsx14("legend", { children: "Supporting packet" }),
|
|
5940
|
-
data.bill.attachments.map((attachment) => /* @__PURE__ */ jsxs14("label", { children: [
|
|
5941
|
-
/* @__PURE__ */ jsx14("input", { type: "checkbox", checked: review.attachmentIds.includes(attachment.id), onChange: (event) => setReview((current) => ({ ...current, attachmentIds: event.target.checked ? [...current.attachmentIds, attachment.id] : current.attachmentIds.filter((id) => id !== attachment.id) })) }),
|
|
5942
|
-
/* @__PURE__ */ jsxs14("span", { children: [
|
|
5943
|
-
/* @__PURE__ */ jsx14("strong", { children: attachment.filename }),
|
|
5944
|
-
/* @__PURE__ */ jsx14("small", { children: attachment.description || attachment.documentType })
|
|
5945
|
-
] }),
|
|
5946
|
-
/* @__PURE__ */ jsx14("button", { type: "button", onClick: () => void lifecycle.openAttachment(attachment).catch(() => void 0), children: "View" })
|
|
5947
|
-
] }, attachment.id))
|
|
5948
|
-
] }),
|
|
5949
|
-
/* @__PURE__ */ jsxs14("div", { className: "mb-lifecycle-panel-actions", children: [
|
|
5950
|
-
/* @__PURE__ */ jsx14("button", { type: "button", className: "mb-lifecycle-button secondary", onClick: () => setPanel(""), children: "Cancel" }),
|
|
5951
|
-
/* @__PURE__ */ jsx14("button", { type: "button", className: "mb-lifecycle-button primary", disabled: lifecycle.isMutating || !review.reason.trim() || !review.payerClaimControlNumber.trim(), onClick: () => void complete("Second Review submitted.", () => lifecycle.submitSecondReview({ ...review, ...actor })), children: lifecycle.isMutating ? "Submitting\u2026" : "Submit Second Review" })
|
|
5952
|
-
] })
|
|
5953
|
-
] }) }) : null,
|
|
5954
|
-
panel === "payment" ? /* @__PURE__ */ jsx14(LifecycleDialog, { title: "Post payment", onClose: () => setPanel(""), children: /* @__PURE__ */ jsxs14("section", { className: "mb-lifecycle-panel", children: [
|
|
5955
|
-
/* @__PURE__ */ jsxs14("div", { children: [
|
|
5956
|
-
/* @__PURE__ */ jsx14("h3", { children: "Post payment" }),
|
|
5957
|
-
/* @__PURE__ */ jsx14("p", { children: "Record a full or partial payment, plus any penalty and interest received." })
|
|
6475
|
+
] }) : null
|
|
6476
|
+
] }) : null,
|
|
6477
|
+
panel === "payment" ? /* @__PURE__ */ jsx15(LifecycleDialog, { title: "Post payment", onClose: () => setPanel(""), children: /* @__PURE__ */ jsxs15("section", { className: "mb-lifecycle-panel", children: [
|
|
6478
|
+
/* @__PURE__ */ jsxs15("div", { children: [
|
|
6479
|
+
/* @__PURE__ */ jsx15("h3", { children: "Post payment" }),
|
|
6480
|
+
/* @__PURE__ */ jsx15("p", { children: "Record a full or partial payment, plus any penalty and interest received." })
|
|
5958
6481
|
] }),
|
|
5959
|
-
/* @__PURE__ */
|
|
5960
|
-
/* @__PURE__ */
|
|
5961
|
-
/* @__PURE__ */
|
|
5962
|
-
/* @__PURE__ */
|
|
6482
|
+
/* @__PURE__ */ jsxs15("div", { className: "mb-lifecycle-fields two", children: [
|
|
6483
|
+
/* @__PURE__ */ jsxs15("label", { children: [
|
|
6484
|
+
/* @__PURE__ */ jsx15("span", { children: "Amount applied to bill" }),
|
|
6485
|
+
/* @__PURE__ */ jsx15("input", { type: "number", min: "0.01", max: data.bill.balanceDue, step: "0.01", value: payment.amount || "", onChange: (event) => setPayment((current) => ({ ...current, amount: Number(event.target.value) })) })
|
|
5963
6486
|
] }),
|
|
5964
|
-
/* @__PURE__ */
|
|
5965
|
-
/* @__PURE__ */
|
|
5966
|
-
/* @__PURE__ */
|
|
6487
|
+
/* @__PURE__ */ jsxs15("label", { children: [
|
|
6488
|
+
/* @__PURE__ */ jsx15("span", { children: "Penalty" }),
|
|
6489
|
+
/* @__PURE__ */ jsx15("input", { type: "number", min: "0", step: "0.01", value: payment.penaltyAmount || "", placeholder: "0.00", onChange: (event) => setPayment((current) => ({ ...current, penaltyAmount: Number(event.target.value) })) })
|
|
5967
6490
|
] }),
|
|
5968
|
-
/* @__PURE__ */
|
|
5969
|
-
/* @__PURE__ */
|
|
5970
|
-
/* @__PURE__ */
|
|
6491
|
+
/* @__PURE__ */ jsxs15("label", { children: [
|
|
6492
|
+
/* @__PURE__ */ jsx15("span", { children: "Interest" }),
|
|
6493
|
+
/* @__PURE__ */ jsx15("input", { type: "number", min: "0", step: "0.01", value: payment.interestAmount || "", placeholder: "0.00", onChange: (event) => setPayment((current) => ({ ...current, interestAmount: Number(event.target.value) })) })
|
|
5971
6494
|
] }),
|
|
5972
|
-
/* @__PURE__ */
|
|
5973
|
-
/* @__PURE__ */
|
|
5974
|
-
/* @__PURE__ */
|
|
5975
|
-
/* @__PURE__ */
|
|
5976
|
-
/* @__PURE__ */
|
|
6495
|
+
/* @__PURE__ */ jsxs15("label", { children: [
|
|
6496
|
+
/* @__PURE__ */ jsx15("span", { children: "Method" }),
|
|
6497
|
+
/* @__PURE__ */ jsxs15("select", { value: payment.method, onChange: (event) => setPayment((current) => ({ ...current, method: event.target.value })), children: [
|
|
6498
|
+
/* @__PURE__ */ jsx15("option", { value: "check", children: "Check" }),
|
|
6499
|
+
/* @__PURE__ */ jsx15("option", { value: "eft", children: "EFT" })
|
|
5977
6500
|
] })
|
|
5978
6501
|
] }),
|
|
5979
|
-
/* @__PURE__ */
|
|
5980
|
-
/* @__PURE__ */
|
|
5981
|
-
/* @__PURE__ */
|
|
6502
|
+
/* @__PURE__ */ jsxs15("label", { children: [
|
|
6503
|
+
/* @__PURE__ */ jsx15("span", { children: payment.method === "check" ? "Check number" : "EFT reference" }),
|
|
6504
|
+
/* @__PURE__ */ jsx15("input", { value: payment.checkNumber, onChange: (event) => setPayment((current) => ({ ...current, checkNumber: event.target.value })) })
|
|
5982
6505
|
] }),
|
|
5983
|
-
/* @__PURE__ */
|
|
5984
|
-
/* @__PURE__ */
|
|
5985
|
-
/* @__PURE__ */
|
|
6506
|
+
/* @__PURE__ */ jsxs15("label", { children: [
|
|
6507
|
+
/* @__PURE__ */ jsx15("span", { children: "Deposit date" }),
|
|
6508
|
+
/* @__PURE__ */ jsx15("input", { required: true, value: payment.depositDate, placeholder: "MM/DD/YYYY", onChange: (event) => setPayment((current) => ({ ...current, depositDate: event.target.value })) })
|
|
5986
6509
|
] }),
|
|
5987
|
-
/* @__PURE__ */
|
|
5988
|
-
/* @__PURE__ */
|
|
5989
|
-
/* @__PURE__ */
|
|
6510
|
+
/* @__PURE__ */ jsxs15("label", { className: "full", children: [
|
|
6511
|
+
/* @__PURE__ */ jsx15("span", { children: "Note (optional)" }),
|
|
6512
|
+
/* @__PURE__ */ jsx15("input", { value: payment.note, onChange: (event) => setPayment((current) => ({ ...current, note: event.target.value })) })
|
|
5990
6513
|
] })
|
|
5991
6514
|
] }),
|
|
5992
|
-
/* @__PURE__ */
|
|
5993
|
-
/* @__PURE__ */
|
|
5994
|
-
/* @__PURE__ */
|
|
6515
|
+
/* @__PURE__ */ jsxs15("div", { className: "mb-payment-total", children: [
|
|
6516
|
+
/* @__PURE__ */ jsx15("span", { children: "Total received" }),
|
|
6517
|
+
/* @__PURE__ */ jsx15("strong", { children: new Intl.NumberFormat(void 0, { style: "currency", currency: "USD" }).format(payment.amount + (payment.penaltyAmount ?? 0) + (payment.interestAmount ?? 0)) })
|
|
5995
6518
|
] }),
|
|
5996
|
-
/* @__PURE__ */
|
|
5997
|
-
/* @__PURE__ */
|
|
5998
|
-
/* @__PURE__ */
|
|
6519
|
+
/* @__PURE__ */ jsxs15("div", { className: "mb-lifecycle-panel-actions", children: [
|
|
6520
|
+
/* @__PURE__ */ jsx15("button", { type: "button", className: "mb-lifecycle-button secondary", onClick: () => setPanel(""), children: "Cancel" }),
|
|
6521
|
+
/* @__PURE__ */ jsx15("button", { type: "button", className: "mb-lifecycle-button primary", disabled: lifecycle.isMutating || payment.amount <= 0 || payment.amount > data.bill.balanceDue || (payment.penaltyAmount ?? 0) < 0 || (payment.interestAmount ?? 0) < 0 || !payment.depositDate, onClick: () => void complete("Payment posted.", () => lifecycle.postPayment({ ...payment, ...actor })), children: lifecycle.isMutating ? "Posting\u2026" : "Post payment" })
|
|
5999
6522
|
] })
|
|
6000
6523
|
] }) }) : null,
|
|
6001
|
-
panel === "close" || panel === "reopen" ? /* @__PURE__ */
|
|
6002
|
-
/* @__PURE__ */
|
|
6003
|
-
/* @__PURE__ */
|
|
6004
|
-
/* @__PURE__ */
|
|
6524
|
+
panel === "close" || panel === "reopen" ? /* @__PURE__ */ jsx15(LifecycleDialog, { title: panel === "close" ? "Close bill" : "Reopen bill", onClose: () => setPanel(""), children: /* @__PURE__ */ jsxs15("section", { className: "mb-lifecycle-panel", children: [
|
|
6525
|
+
/* @__PURE__ */ jsxs15("div", { children: [
|
|
6526
|
+
/* @__PURE__ */ jsx15("h3", { children: panel === "close" ? "Close bill" : "Reopen bill" }),
|
|
6527
|
+
/* @__PURE__ */ jsx15("p", { children: panel === "close" ? "The immutable submission and history remain available." : "Return this bill to active follow-up without changing the submitted snapshot." })
|
|
6005
6528
|
] }),
|
|
6006
|
-
/* @__PURE__ */
|
|
6007
|
-
/* @__PURE__ */
|
|
6008
|
-
/* @__PURE__ */
|
|
6529
|
+
/* @__PURE__ */ jsxs15("label", { children: [
|
|
6530
|
+
/* @__PURE__ */ jsx15("span", { children: "Reason" }),
|
|
6531
|
+
/* @__PURE__ */ jsx15("textarea", { required: true, value: reason, onChange: (event) => setReason(event.target.value) })
|
|
6009
6532
|
] }),
|
|
6010
|
-
/* @__PURE__ */
|
|
6011
|
-
/* @__PURE__ */
|
|
6012
|
-
/* @__PURE__ */
|
|
6533
|
+
/* @__PURE__ */ jsxs15("div", { className: "mb-lifecycle-panel-actions", children: [
|
|
6534
|
+
/* @__PURE__ */ jsx15("button", { type: "button", className: "mb-lifecycle-button secondary", onClick: () => setPanel(""), children: "Cancel" }),
|
|
6535
|
+
/* @__PURE__ */ jsx15("button", { type: "button", className: "mb-lifecycle-button primary", disabled: lifecycle.isMutating || !reason.trim(), onClick: () => void complete(panel === "close" ? "Bill closed." : "Bill reopened.", () => panel === "close" ? lifecycle.closeBill({ reason, ...actor }) : lifecycle.reopenBill({ reason, ...actor })), children: lifecycle.isMutating ? "Saving\u2026" : panel === "close" ? "Close bill" : "Reopen bill" })
|
|
6013
6536
|
] })
|
|
6014
6537
|
] }) }) : null,
|
|
6015
|
-
panel === "send_duplicate"
|
|
6016
|
-
|
|
6017
|
-
|
|
6018
|
-
|
|
6019
|
-
|
|
6020
|
-
|
|
6021
|
-
|
|
6022
|
-
|
|
6023
|
-
|
|
6024
|
-
}
|
|
6025
|
-
|
|
6026
|
-
|
|
6027
|
-
|
|
6028
|
-
|
|
6029
|
-
|
|
6030
|
-
|
|
6031
|
-
|
|
6032
|
-
|
|
6033
|
-
|
|
6538
|
+
panel === "send_duplicate" && correctionInitialBill ? /* @__PURE__ */ jsx15(LifecycleDialog, { title: "Send duplicate bill", wide: true, onClose: () => setPanel(""), children: /* @__PURE__ */ jsxs15("section", { className: "mb-lifecycle-correction", children: [
|
|
6539
|
+
/* @__PURE__ */ jsx15("header", { children: /* @__PURE__ */ jsxs15("div", { children: [
|
|
6540
|
+
/* @__PURE__ */ jsx15("h3", { children: "Send duplicate bill" }),
|
|
6541
|
+
/* @__PURE__ */ jsx15("p", { children: "Review and edit any bill field before creating a duplicate submission. The original bill and its history stay unchanged." })
|
|
6542
|
+
] }) }),
|
|
6543
|
+
data.environment === "live" ? /* @__PURE__ */ jsxs15("div", { className: "mb-lifecycle-live-warning", children: [
|
|
6544
|
+
/* @__PURE__ */ jsx15("strong", { children: "Live clearinghouse submission" }),
|
|
6545
|
+
/* @__PURE__ */ jsx15("span", { children: "The duplicate will be sent only after you confirm its delivery route in the next dialog." })
|
|
6546
|
+
] }) : null,
|
|
6547
|
+
/* @__PURE__ */ jsx15(CorrectionVerificationContact, { delivery: data.delivery }),
|
|
6548
|
+
/* @__PURE__ */ jsx15(
|
|
6549
|
+
BillSubmissionForm,
|
|
6550
|
+
{
|
|
6551
|
+
className: "mbsf-lifecycle-correction",
|
|
6552
|
+
initialBill: correctionInitialBill,
|
|
6553
|
+
attachments: correctionAttachments,
|
|
6554
|
+
onSubmit: submitDuplicateFromForm,
|
|
6555
|
+
onSearchClaimsAdministrators: lifecycle.searchClaimsAdministrators,
|
|
6556
|
+
onGetClaimsAdministratorDirectory: lifecycle.getClaimsAdministratorDirectory,
|
|
6557
|
+
claimsAdministratorHint,
|
|
6558
|
+
...claimsAdministratorSources ? { claimsAdministratorSources } : {},
|
|
6559
|
+
attentionMessage: "Confirm every carried-over value. You may edit any field before sending this duplicate.",
|
|
6560
|
+
submitLabel: lifecycle.isMutating ? "Sending\u2026" : "Send duplicate",
|
|
6561
|
+
deliveryRoutePicker: "required",
|
|
6562
|
+
deliveryRouteDialogTitle: "Confirm duplicate bill delivery",
|
|
6563
|
+
heading: "Duplicate bill information",
|
|
6564
|
+
description: "The submitted original remains immutable. This form creates and sends a linked duplicate.",
|
|
6565
|
+
disabled: lifecycle.isMutating,
|
|
6566
|
+
...options.getSession ? { getSession: options.getSession } : {},
|
|
6567
|
+
...options.sessionEndpoint ? { sessionEndpoint: options.sessionEndpoint } : {},
|
|
6568
|
+
...options.apiBaseUrl ? { apiBaseUrl: options.apiBaseUrl } : {},
|
|
6569
|
+
...options.fetch ? { fetch: options.fetch } : {},
|
|
6570
|
+
...appearance ? { appearance } : {}
|
|
6571
|
+
}
|
|
6572
|
+
),
|
|
6573
|
+
duplicateError ? /* @__PURE__ */ jsx15("div", { className: "mb-lifecycle-message error", role: "alert", children: duplicateError }) : null
|
|
6034
6574
|
] }) }) : null,
|
|
6035
|
-
panel === "report_status" ? /* @__PURE__ */
|
|
6575
|
+
panel === "report_status" ? /* @__PURE__ */ jsx15(
|
|
6036
6576
|
ReportBillStatusDialog,
|
|
6037
6577
|
{
|
|
6578
|
+
...data.delivery.directory ? { directory: data.delivery.directory } : {},
|
|
6038
6579
|
...statusContacts.claimsAdmin ? { claimsAdmin: statusContacts.claimsAdmin } : {},
|
|
6039
6580
|
...statusContacts.billReview ? { billReview: statusContacts.billReview } : {},
|
|
6040
|
-
...receiptEntries.length ? { receipt: /* @__PURE__ */
|
|
6581
|
+
...receiptEntries.length ? { receipt: /* @__PURE__ */ jsx15(BillHistoryTable, { entries: receiptEntries, onOpenDocument: lifecycle.openAttachment, ...appearance ? { appearance } : {} }) } : {},
|
|
6041
6582
|
submitting: lifecycle.isMutating,
|
|
6042
6583
|
error: lifecycle.error?.message ?? null,
|
|
6043
6584
|
onCancel: () => setPanel(""),
|
|
@@ -6045,8 +6586,8 @@ function ConnectedBillLifecycle({ appearance, actorName, claimsAdministratorHint
|
|
|
6045
6586
|
...appearance ? { appearance } : {}
|
|
6046
6587
|
}
|
|
6047
6588
|
) : null,
|
|
6048
|
-
notice ? /* @__PURE__ */
|
|
6049
|
-
lifecycle.error ? /* @__PURE__ */
|
|
6589
|
+
notice ? /* @__PURE__ */ jsx15("div", { className: "mb-lifecycle-message success", role: "status", children: notice }) : null,
|
|
6590
|
+
lifecycle.error ? /* @__PURE__ */ jsx15("div", { className: "mb-lifecycle-message error", role: "alert", children: lifecycle.error.message }) : null
|
|
6050
6591
|
] });
|
|
6051
6592
|
}
|
|
6052
6593
|
var CONNECTED_LIFECYCLE_STYLES = `
|
|
@@ -6058,11 +6599,520 @@ var CONNECTED_LIFECYCLE_STYLES = `
|
|
|
6058
6599
|
@media(max-width:700px){.mb-lifecycle-head,.mb-lifecycle-card header{align-items:stretch;flex-direction:column}.mb-lifecycle-head>.mb-lifecycle-button{width:100%}.mb-lifecycle-actions-sheet{bottom:calc(var(--mb-host-bottom-offset,72px) + env(safe-area-inset-bottom) + 8px);grid-template-columns:repeat(2,minmax(0,1fr))}.mb-lifecycle-actions-sheet .mb-lifecycle-button:last-child:nth-child(odd){grid-column:1/-1}.mb-lifecycle-fields.two{grid-template-columns:1fr}.mb-lifecycle-fields .full{grid-column:auto}.mb-lifecycle-dialog-backdrop{align-items:end;padding:0}.mb-lifecycle-dialog{max-height:calc(100dvh - 12px)}.mb-lifecycle-dialog .mb-lifecycle-panel,.mb-lifecycle-correction{border-radius:18px 18px 0 0}.mb-lifecycle-correction{padding:18px 12px calc(18px + env(safe-area-inset-bottom))}.mb-lifecycle-correction>header{align-items:stretch;flex-direction:column;padding-right:56px}.mb-lifecycle-correction-reason{grid-template-columns:1fr}.mb-lifecycle-correction-reason>ul{grid-column:auto}.mb-lifecycle-correction-contact dl>div{grid-template-columns:1fr;gap:2px}.mb-lifecycle-tabs button{font-size:.9rem}.mb-lifecycle-title h2{font-size:1.4rem}}
|
|
6059
6600
|
`;
|
|
6060
6601
|
|
|
6602
|
+
// src/connected-billing-workspace.tsx
|
|
6603
|
+
import {
|
|
6604
|
+
useCallback as useCallback5,
|
|
6605
|
+
useEffect as useEffect11,
|
|
6606
|
+
useMemo as useMemo10,
|
|
6607
|
+
useState as useState13
|
|
6608
|
+
} from "react";
|
|
6609
|
+
|
|
6610
|
+
// src/billing-operations-client.ts
|
|
6611
|
+
import {
|
|
6612
|
+
DEFAULT_API_BASE_URL as DEFAULT_API_BASE_URL3,
|
|
6613
|
+
DEFAULT_SESSION_ENDPOINT as DEFAULT_SESSION_ENDPOINT3
|
|
6614
|
+
} from "@mindbill/browser";
|
|
6615
|
+
async function responseError2(response, fallback) {
|
|
6616
|
+
const body = await response.json().catch(() => null);
|
|
6617
|
+
const detail = body && typeof body === "object" ? body.detail ?? body.error : null;
|
|
6618
|
+
return new Error(typeof detail === "string" ? detail : fallback);
|
|
6619
|
+
}
|
|
6620
|
+
function normalizeSession2(value) {
|
|
6621
|
+
if (!value || typeof value !== "object") throw new Error("The MindBill session endpoint returned an invalid response.");
|
|
6622
|
+
const candidate = value;
|
|
6623
|
+
const nested = candidate.session ?? candidate.data;
|
|
6624
|
+
const session = nested && typeof nested === "object" ? nested : candidate;
|
|
6625
|
+
if (typeof session.token !== "string" || session.token.length < 8) {
|
|
6626
|
+
throw new Error("The MindBill session endpoint did not return a browser session token.");
|
|
6627
|
+
}
|
|
6628
|
+
return {
|
|
6629
|
+
token: session.token,
|
|
6630
|
+
...typeof session.expiresAt === "string" ? { expiresAt: session.expiresAt } : {},
|
|
6631
|
+
...typeof session.apiBaseUrl === "string" ? { apiBaseUrl: session.apiBaseUrl } : {}
|
|
6632
|
+
};
|
|
6633
|
+
}
|
|
6634
|
+
function isFresh(session) {
|
|
6635
|
+
if (!session) return false;
|
|
6636
|
+
if (!session.expiresAt) return true;
|
|
6637
|
+
const expiresAt = Date.parse(session.expiresAt);
|
|
6638
|
+
return Number.isFinite(expiresAt) && expiresAt > Date.now() + 3e4;
|
|
6639
|
+
}
|
|
6640
|
+
function queryString(values) {
|
|
6641
|
+
const params = new URLSearchParams();
|
|
6642
|
+
for (const [key, value] of Object.entries(values)) {
|
|
6643
|
+
if (value !== void 0 && value !== "") params.set(key, String(value));
|
|
6644
|
+
}
|
|
6645
|
+
const text = params.toString();
|
|
6646
|
+
return text ? `?${text}` : "";
|
|
6647
|
+
}
|
|
6648
|
+
function createBillingOperationsClient({
|
|
6649
|
+
sessionEndpoint = DEFAULT_SESSION_ENDPOINT3,
|
|
6650
|
+
getSession,
|
|
6651
|
+
apiBaseUrl = DEFAULT_API_BASE_URL3,
|
|
6652
|
+
fetch: fetchOverride
|
|
6653
|
+
} = {}) {
|
|
6654
|
+
const fetcher = fetchOverride ?? globalThis.fetch;
|
|
6655
|
+
if (typeof fetcher !== "function") throw new Error("A Fetch API implementation is required.");
|
|
6656
|
+
let session = null;
|
|
6657
|
+
let pendingSession = null;
|
|
6658
|
+
const mintSession = async (signal, force = false) => {
|
|
6659
|
+
if (!force && isFresh(session)) return session;
|
|
6660
|
+
if (!force && pendingSession) return pendingSession;
|
|
6661
|
+
const pending = getSession ? getSession({ signal }) : fetcher(sessionEndpoint, {
|
|
6662
|
+
method: "POST",
|
|
6663
|
+
credentials: "same-origin",
|
|
6664
|
+
headers: { "content-type": "application/json" },
|
|
6665
|
+
body: JSON.stringify({}),
|
|
6666
|
+
signal
|
|
6667
|
+
}).then(async (response) => {
|
|
6668
|
+
if (!response.ok) throw await responseError2(response, "MindBill browser session could not be created.");
|
|
6669
|
+
return response.json();
|
|
6670
|
+
});
|
|
6671
|
+
const request = Promise.resolve(pending).then(normalizeSession2).then((next) => {
|
|
6672
|
+
session = next;
|
|
6673
|
+
return next;
|
|
6674
|
+
}).finally(() => {
|
|
6675
|
+
if (pendingSession === request) pendingSession = null;
|
|
6676
|
+
});
|
|
6677
|
+
pendingSession = request;
|
|
6678
|
+
return request;
|
|
6679
|
+
};
|
|
6680
|
+
const get = async (path, signal) => {
|
|
6681
|
+
const controller = signal ? null : new AbortController();
|
|
6682
|
+
const requestSignal = signal ?? controller?.signal;
|
|
6683
|
+
if (!requestSignal) throw new Error("An AbortSignal could not be created.");
|
|
6684
|
+
let browserSession = await mintSession(requestSignal);
|
|
6685
|
+
const request = (active) => {
|
|
6686
|
+
const base = (active.apiBaseUrl ?? apiBaseUrl).replace(/\/$/, "");
|
|
6687
|
+
return fetcher(`${base}${path}`, {
|
|
6688
|
+
headers: { authorization: `Bearer ${active.token}` },
|
|
6689
|
+
signal: requestSignal
|
|
6690
|
+
});
|
|
6691
|
+
};
|
|
6692
|
+
let response = await request(browserSession);
|
|
6693
|
+
if (response.status === 401) {
|
|
6694
|
+
session = null;
|
|
6695
|
+
browserSession = await mintSession(requestSignal, true);
|
|
6696
|
+
response = await request(browserSession);
|
|
6697
|
+
}
|
|
6698
|
+
if (!response.ok) throw await responseError2(response, "MindBill data could not be loaded.");
|
|
6699
|
+
const body = await response.json();
|
|
6700
|
+
return body.data ?? body;
|
|
6701
|
+
};
|
|
6702
|
+
return {
|
|
6703
|
+
clearSession() {
|
|
6704
|
+
session = null;
|
|
6705
|
+
pendingSession = null;
|
|
6706
|
+
},
|
|
6707
|
+
getBills(query = {}, signal) {
|
|
6708
|
+
return get(`/partner/v2/browser/bills${queryString(query)}`, signal);
|
|
6709
|
+
},
|
|
6710
|
+
getBillTasks(claimsAdministrator, signal) {
|
|
6711
|
+
return get(
|
|
6712
|
+
`/partner/v2/browser/bill-tasks${queryString({ claimsAdminId: claimsAdministrator })}`,
|
|
6713
|
+
signal
|
|
6714
|
+
);
|
|
6715
|
+
},
|
|
6716
|
+
getServiceLineItems(range, signal) {
|
|
6717
|
+
return get(
|
|
6718
|
+
`/partner/v2/browser/reports/service-line-items${queryString(range)}`,
|
|
6719
|
+
signal
|
|
6720
|
+
);
|
|
6721
|
+
},
|
|
6722
|
+
getProductivity(range, signal) {
|
|
6723
|
+
return get(`/partner/v2/browser/reports/productivity${queryString(range)}`, signal);
|
|
6724
|
+
}
|
|
6725
|
+
};
|
|
6726
|
+
}
|
|
6727
|
+
|
|
6728
|
+
// src/connected-billing-workspace.tsx
|
|
6729
|
+
import { Fragment as Fragment14, jsx as jsx16, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
6730
|
+
var css11 = `
|
|
6731
|
+
.mbow{color:var(--mb-text);font:14px/1.45 var(--mb-font);background:var(--mb-soft);border-radius:var(--mb-radius);padding:20px}.mbow *{box-sizing:border-box}.mbow h2,.mbow h3,.mbow p{margin:0}.mbow a{color:var(--mb-accent)}
|
|
6732
|
+
.mbow-head{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;margin-bottom:18px}.mbow-head h2{font-size:24px;line-height:1.2}.mbow-sub{color:var(--mb-muted);margin-top:4px!important}.mbow-actions{display:flex;gap:8px;flex-wrap:wrap}
|
|
6733
|
+
.mbow-button,.mbow-input,.mbow-select{min-height:38px;border:1px solid var(--mb-border);border-radius:var(--mb-control-radius);background:var(--mb-input);color:var(--mb-text);font:inherit}.mbow-button{padding:7px 12px;cursor:pointer;font-weight:650}.mbow-button:hover{border-color:var(--mb-accent)}.mbow-button.primary{background:var(--mb-accent);border-color:var(--mb-accent);color:var(--mb-accent-contrast)}.mbow-button:disabled{opacity:.55;cursor:not-allowed}.mbow-input,.mbow-select{padding:7px 10px}.mbow-input{min-width:260px;flex:1}
|
|
6734
|
+
.mbow-tabs{display:flex;gap:4px;border-bottom:1px solid var(--mb-border);margin-bottom:18px;overflow:auto}.mbow-tab{border:0;border-bottom:3px solid transparent;background:transparent;color:var(--mb-muted);padding:10px 13px;font:inherit;font-weight:700;white-space:nowrap;cursor:pointer}.mbow-tab.active{color:var(--mb-text);border-bottom-color:var(--mb-accent)}
|
|
6735
|
+
.mbow-toolbar{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-bottom:14px}.mbow-card{background:var(--mb-surface);border:1px solid var(--mb-border);border-radius:var(--mb-radius);box-shadow:var(--mb-shadow);overflow:hidden}.mbow-scroll{overflow:auto}.mbow-table{width:100%;border-collapse:collapse;min-width:820px}.mbow-table th,.mbow-table td{padding:11px 12px;border-bottom:1px solid var(--mb-border);text-align:left;vertical-align:middle}.mbow-table th{color:var(--mb-muted);font-size:11px;letter-spacing:.045em;text-transform:uppercase;font-weight:800;background:color-mix(in srgb,var(--mb-soft) 60%,var(--mb-surface))}.mbow-table tr:last-child td{border-bottom:0}.mbow-table tbody tr.clickable{cursor:pointer}.mbow-table tbody tr.clickable:hover{background:color-mix(in srgb,var(--mb-accent) 6%,var(--mb-surface))}.mbow-money{text-align:right!important;font-variant-numeric:tabular-nums}.mbow-strong{font-weight:760}.mbow-muted{color:var(--mb-muted);font-size:12px}.mbow-badge{display:inline-flex;border:1px solid var(--mb-border);border-radius:999px;padding:2px 8px;font-size:12px;background:var(--mb-soft);white-space:nowrap}.mbow-badge.success{color:var(--mb-success);border-color:color-mix(in srgb,var(--mb-success) 35%,var(--mb-border));background:color-mix(in srgb,var(--mb-success) 8%,var(--mb-surface))}.mbow-badge.danger{color:var(--mb-danger)}.mbow-badge.warning{color:var(--mb-warning)}
|
|
6736
|
+
.mbow-state{padding:28px;text-align:center;color:var(--mb-muted)}.mbow-error{color:var(--mb-danger)}.mbow-pager{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:12px;color:var(--mb-muted)}
|
|
6737
|
+
.mbow-metrics{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;margin:14px 0 18px}.mbow-metric{padding:16px;background:var(--mb-surface);border:1px solid var(--mb-border);border-radius:var(--mb-radius);box-shadow:var(--mb-shadow)}.mbow-metric span{display:block;color:var(--mb-muted);font-size:11px;text-transform:uppercase;letter-spacing:.05em}.mbow-metric strong{display:block;font-size:24px;margin-top:5px}.mbow-section-head{display:flex;justify-content:space-between;align-items:center;gap:12px;padding:14px 16px;border-bottom:1px solid var(--mb-border)}
|
|
6738
|
+
.mbow-back{margin-bottom:12px}.mbow-task-note{color:var(--mb-muted);font-size:13px;margin-bottom:14px!important}.mbow-bar{height:7px;min-width:70px;background:var(--mb-soft);border-radius:99px;overflow:hidden}.mbow-bar i{display:block;height:100%;background:var(--mb-accent);border-radius:inherit}
|
|
6739
|
+
@media(max-width:760px){.mbow{padding:14px}.mbow-head{display:block}.mbow-actions{margin-top:12px}.mbow-metrics{grid-template-columns:repeat(2,minmax(0,1fr))}.mbow-input{min-width:100%}}
|
|
6740
|
+
`;
|
|
6741
|
+
function money6(value) {
|
|
6742
|
+
return new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" }).format(value);
|
|
6743
|
+
}
|
|
6744
|
+
function shortDate(value) {
|
|
6745
|
+
if (!value) return "\u2014";
|
|
6746
|
+
const date2 = /* @__PURE__ */ new Date(`${value.slice(0, 10)}T12:00:00`);
|
|
6747
|
+
return Number.isNaN(date2.getTime()) ? value : date2.toLocaleDateString("en-US");
|
|
6748
|
+
}
|
|
6749
|
+
function defaultRange(days = 29) {
|
|
6750
|
+
const to = /* @__PURE__ */ new Date();
|
|
6751
|
+
const from = new Date(to);
|
|
6752
|
+
from.setDate(to.getDate() - days);
|
|
6753
|
+
const iso = (date2) => date2.toISOString().slice(0, 10);
|
|
6754
|
+
return { from: iso(from), to: iso(to) };
|
|
6755
|
+
}
|
|
6756
|
+
function Surface({ appearance, className = "", style, children }) {
|
|
6757
|
+
return /* @__PURE__ */ jsxs16("div", { className: `mbow ${className}`.trim(), style: mindBillAppearanceStyle(appearance, style), children: [
|
|
6758
|
+
/* @__PURE__ */ jsx16("style", { children: css11 }),
|
|
6759
|
+
children
|
|
6760
|
+
] });
|
|
6761
|
+
}
|
|
6762
|
+
function useClient(options) {
|
|
6763
|
+
return useMemo10(() => createBillingOperationsClient(options), [options.apiBaseUrl, options.fetch, options.getSession, options.sessionEndpoint]);
|
|
6764
|
+
}
|
|
6765
|
+
function BillSearchContent({
|
|
6766
|
+
client,
|
|
6767
|
+
initialQuery,
|
|
6768
|
+
onSelectBill,
|
|
6769
|
+
heading
|
|
6770
|
+
}) {
|
|
6771
|
+
const [query, setQuery] = useState13({ status: "all", age: "all", page: 1, pageSize: 25, sort: "submitted_desc", ...initialQuery });
|
|
6772
|
+
const [draft, setDraft] = useState13(initialQuery?.q ?? "");
|
|
6773
|
+
const [result, setResult] = useState13(null);
|
|
6774
|
+
const [error, setError] = useState13(null);
|
|
6775
|
+
const [loading, setLoading] = useState13(true);
|
|
6776
|
+
const load = useCallback5(async (signal) => {
|
|
6777
|
+
setLoading(true);
|
|
6778
|
+
setError(null);
|
|
6779
|
+
try {
|
|
6780
|
+
setResult(await client.getBills(query, signal));
|
|
6781
|
+
} catch (cause) {
|
|
6782
|
+
if (!signal?.aborted) setError(cause instanceof Error ? cause : new Error("Bills could not be loaded."));
|
|
6783
|
+
} finally {
|
|
6784
|
+
if (!signal?.aborted) setLoading(false);
|
|
6785
|
+
}
|
|
6786
|
+
}, [client, query]);
|
|
6787
|
+
useEffect11(() => {
|
|
6788
|
+
const controller = new AbortController();
|
|
6789
|
+
void load(controller.signal);
|
|
6790
|
+
return () => controller.abort();
|
|
6791
|
+
}, [load]);
|
|
6792
|
+
const update = (next) => setQuery((current) => ({ ...current, ...next, page: next.page ?? 1 }));
|
|
6793
|
+
const pageCount = Math.max(1, Math.ceil((result?.total ?? 0) / (result?.pageSize ?? 25)));
|
|
6794
|
+
return /* @__PURE__ */ jsxs16(Fragment14, { children: [
|
|
6795
|
+
heading ? /* @__PURE__ */ jsx16("div", { className: "mbow-head", children: /* @__PURE__ */ jsx16("div", { children: typeof heading === "string" ? /* @__PURE__ */ jsx16("h2", { children: heading }) : heading }) }) : null,
|
|
6796
|
+
/* @__PURE__ */ jsxs16("form", { className: "mbow-toolbar", onSubmit: (event) => {
|
|
6797
|
+
event.preventDefault();
|
|
6798
|
+
update({ q: draft.trim() });
|
|
6799
|
+
}, children: [
|
|
6800
|
+
/* @__PURE__ */ jsx16("input", { className: "mbow-input", value: draft, onChange: (event) => setDraft(event.target.value), placeholder: "Search patient, bill ID, claim, or external ID\u2026", "aria-label": "Search bills" }),
|
|
6801
|
+
/* @__PURE__ */ jsxs16("select", { className: "mbow-select", value: query.status ?? "all", onChange: (event) => update({ status: event.target.value }), "aria-label": "Bill status", children: [
|
|
6802
|
+
/* @__PURE__ */ jsx16("option", { value: "all", children: "All statuses" }),
|
|
6803
|
+
/* @__PURE__ */ jsx16("option", { value: "incomplete", children: "Incomplete" }),
|
|
6804
|
+
/* @__PURE__ */ jsx16("option", { value: "submitted", children: "Submitted" }),
|
|
6805
|
+
/* @__PURE__ */ jsx16("option", { value: "accepted", children: "Accepted" }),
|
|
6806
|
+
/* @__PURE__ */ jsx16("option", { value: "rejected", children: "Rejected" }),
|
|
6807
|
+
/* @__PURE__ */ jsx16("option", { value: "processed", children: "Processed" }),
|
|
6808
|
+
/* @__PURE__ */ jsx16("option", { value: "paid", children: "Paid" }),
|
|
6809
|
+
/* @__PURE__ */ jsx16("option", { value: "closed", children: "Closed" })
|
|
6810
|
+
] }),
|
|
6811
|
+
/* @__PURE__ */ jsxs16("select", { className: "mbow-select", value: query.age ?? "all", onChange: (event) => update({ age: event.target.value }), "aria-label": "A/R age", children: [
|
|
6812
|
+
/* @__PURE__ */ jsx16("option", { value: "all", children: "All A/R ages" }),
|
|
6813
|
+
/* @__PURE__ */ jsx16("option", { value: "0-30", children: "0\u201330 days" }),
|
|
6814
|
+
/* @__PURE__ */ jsx16("option", { value: "31-60", children: "31\u201360 days" }),
|
|
6815
|
+
/* @__PURE__ */ jsx16("option", { value: "61-90", children: "61\u201390 days" }),
|
|
6816
|
+
/* @__PURE__ */ jsx16("option", { value: "91+", children: "91+ days" }),
|
|
6817
|
+
/* @__PURE__ */ jsx16("option", { value: "91-180", children: "91\u2013180 days" }),
|
|
6818
|
+
/* @__PURE__ */ jsx16("option", { value: "181+", children: "181+ days" })
|
|
6819
|
+
] }),
|
|
6820
|
+
/* @__PURE__ */ jsx16("button", { className: "mbow-button", type: "submit", children: "Search" })
|
|
6821
|
+
] }),
|
|
6822
|
+
/* @__PURE__ */ jsxs16("div", { className: "mbow-card mbow-scroll", children: [
|
|
6823
|
+
loading && !result ? /* @__PURE__ */ jsx16("div", { className: "mbow-state", role: "status", children: "Loading bills\u2026" }) : error && !result ? /* @__PURE__ */ jsxs16("div", { className: "mbow-state mbow-error", role: "alert", children: [
|
|
6824
|
+
error.message,
|
|
6825
|
+
" ",
|
|
6826
|
+
/* @__PURE__ */ jsx16("button", { className: "mbow-button", type: "button", onClick: () => void load(), children: "Retry" })
|
|
6827
|
+
] }) : result?.items.length === 0 ? /* @__PURE__ */ jsx16("div", { className: "mbow-state", children: "No bills match these filters." }) : /* @__PURE__ */ jsxs16("table", { className: "mbow-table", children: [
|
|
6828
|
+
/* @__PURE__ */ jsx16("thead", { children: /* @__PURE__ */ jsxs16("tr", { children: [
|
|
6829
|
+
/* @__PURE__ */ jsx16("th", { children: "Bill" }),
|
|
6830
|
+
/* @__PURE__ */ jsx16("th", { children: "Patient" }),
|
|
6831
|
+
/* @__PURE__ */ jsx16("th", { children: "DOS" }),
|
|
6832
|
+
/* @__PURE__ */ jsx16("th", { children: "Codes" }),
|
|
6833
|
+
/* @__PURE__ */ jsx16("th", { children: "Claims administrator" }),
|
|
6834
|
+
/* @__PURE__ */ jsx16("th", { children: "Status" }),
|
|
6835
|
+
/* @__PURE__ */ jsx16("th", { children: "Submitted / A/R age" }),
|
|
6836
|
+
/* @__PURE__ */ jsx16("th", { className: "mbow-money", children: "Balance due" })
|
|
6837
|
+
] }) }),
|
|
6838
|
+
/* @__PURE__ */ jsx16("tbody", { children: result?.items.map((bill) => /* @__PURE__ */ jsxs16("tr", { className: onSelectBill ? "clickable" : "", onClick: () => onSelectBill?.(bill), children: [
|
|
6839
|
+
/* @__PURE__ */ jsxs16("td", { className: "mbow-strong", children: [
|
|
6840
|
+
"#",
|
|
6841
|
+
bill.billNumber
|
|
6842
|
+
] }),
|
|
6843
|
+
/* @__PURE__ */ jsx16("td", { children: bill.patientName }),
|
|
6844
|
+
/* @__PURE__ */ jsx16("td", { children: shortDate(bill.dateOfService) }),
|
|
6845
|
+
/* @__PURE__ */ jsx16("td", { children: bill.procedureCodes.join(", ") || "\u2014" }),
|
|
6846
|
+
/* @__PURE__ */ jsx16("td", { children: bill.claimsAdministrator || "\u2014" }),
|
|
6847
|
+
/* @__PURE__ */ jsx16("td", { children: /* @__PURE__ */ jsx16("span", { className: `mbow-badge ${bill.status.tone ?? ""}`, children: bill.status.label }) }),
|
|
6848
|
+
/* @__PURE__ */ jsxs16("td", { children: [
|
|
6849
|
+
shortDate(bill.submittedAt),
|
|
6850
|
+
/* @__PURE__ */ jsx16("div", { className: "mbow-muted", children: bill.arAgeDays == null ? "\u2014" : `${bill.arAgeDays} days` })
|
|
6851
|
+
] }),
|
|
6852
|
+
/* @__PURE__ */ jsx16("td", { className: "mbow-money mbow-strong", children: money6(bill.balanceDue) })
|
|
6853
|
+
] }, bill.id)) })
|
|
6854
|
+
] }),
|
|
6855
|
+
result ? /* @__PURE__ */ jsxs16("div", { className: "mbow-pager", children: [
|
|
6856
|
+
/* @__PURE__ */ jsxs16("span", { children: [
|
|
6857
|
+
"Showing ",
|
|
6858
|
+
result.total === 0 ? 0 : (result.page - 1) * result.pageSize + 1,
|
|
6859
|
+
"\u2013",
|
|
6860
|
+
Math.min(result.page * result.pageSize, result.total),
|
|
6861
|
+
" of ",
|
|
6862
|
+
result.total
|
|
6863
|
+
] }),
|
|
6864
|
+
/* @__PURE__ */ jsxs16("span", { children: [
|
|
6865
|
+
/* @__PURE__ */ jsx16("button", { className: "mbow-button", type: "button", disabled: result.page <= 1, onClick: () => update({ page: result.page - 1 }), children: "Previous" }),
|
|
6866
|
+
" ",
|
|
6867
|
+
result.page,
|
|
6868
|
+
" / ",
|
|
6869
|
+
pageCount,
|
|
6870
|
+
" ",
|
|
6871
|
+
/* @__PURE__ */ jsx16("button", { className: "mbow-button", type: "button", disabled: result.page >= pageCount, onClick: () => update({ page: result.page + 1 }), children: "Next" })
|
|
6872
|
+
] })
|
|
6873
|
+
] }) : null
|
|
6874
|
+
] })
|
|
6875
|
+
] });
|
|
6876
|
+
}
|
|
6877
|
+
function ConnectedBillSearch({ appearance, className, style, initialQuery, onSelectBill, heading = "All bills", ...options }) {
|
|
6878
|
+
const client = useClient(options);
|
|
6879
|
+
return /* @__PURE__ */ jsx16(Surface, { appearance, className, style, children: /* @__PURE__ */ jsx16(BillSearchContent, { client, initialQuery, onSelectBill, heading }) });
|
|
6880
|
+
}
|
|
6881
|
+
function taskQuery(cell) {
|
|
6882
|
+
const [taskType, taskLabel] = cell.rowId.split("::", 2);
|
|
6883
|
+
const age = cell.bucketId === "1-30" ? "0-30" : cell.bucketId;
|
|
6884
|
+
return { status: "all", taskSection: cell.sectionId, ...taskType ? { taskType } : {}, ...taskLabel ? { taskLabel } : {}, ...age ? { age } : {} };
|
|
6885
|
+
}
|
|
6886
|
+
function BillTasksContent({ client, onDrillDown, appearance }) {
|
|
6887
|
+
const [claimsAdminId, setClaimsAdminId] = useState13("");
|
|
6888
|
+
const [result, setResult] = useState13(null);
|
|
6889
|
+
const [error, setError] = useState13(null);
|
|
6890
|
+
const [loading, setLoading] = useState13(true);
|
|
6891
|
+
const load = useCallback5(async (signal) => {
|
|
6892
|
+
setLoading(true);
|
|
6893
|
+
setError(null);
|
|
6894
|
+
try {
|
|
6895
|
+
setResult(await client.getBillTasks(claimsAdminId || void 0, signal));
|
|
6896
|
+
} catch (cause) {
|
|
6897
|
+
if (!signal?.aborted) setError(cause instanceof Error ? cause : new Error("Bill tasks could not be loaded."));
|
|
6898
|
+
} finally {
|
|
6899
|
+
if (!signal?.aborted) setLoading(false);
|
|
6900
|
+
}
|
|
6901
|
+
}, [claimsAdminId, client]);
|
|
6902
|
+
useEffect11(() => {
|
|
6903
|
+
const controller = new AbortController();
|
|
6904
|
+
void load(controller.signal);
|
|
6905
|
+
return () => controller.abort();
|
|
6906
|
+
}, [load]);
|
|
6907
|
+
if (loading && !result) return /* @__PURE__ */ jsx16("div", { className: "mbow-state", children: "Loading bill tasks\u2026" });
|
|
6908
|
+
if (error && !result) return /* @__PURE__ */ jsx16("div", { className: "mbow-state mbow-error", children: error.message });
|
|
6909
|
+
if (!result) return /* @__PURE__ */ jsx16(Fragment14, {});
|
|
6910
|
+
return /* @__PURE__ */ jsxs16(Fragment14, { children: [
|
|
6911
|
+
/* @__PURE__ */ jsxs16("p", { className: "mbow-task-note", children: [
|
|
6912
|
+
"Open follow-up work only. Sent bills waiting on a payer stay available in ",
|
|
6913
|
+
/* @__PURE__ */ jsx16("strong", { children: "All bills" }),
|
|
6914
|
+
"."
|
|
6915
|
+
] }),
|
|
6916
|
+
/* @__PURE__ */ jsx16(BillTasksDashboard, { data: result.dashboard, appearance: appearance ?? { preset: "mindbill" }, toolbar: /* @__PURE__ */ jsxs16("select", { className: "mbow-select", value: claimsAdminId, onChange: (event) => setClaimsAdminId(event.target.value), children: [
|
|
6917
|
+
/* @__PURE__ */ jsx16("option", { value: "", children: "All claims administrators" }),
|
|
6918
|
+
result.filters.claimsAdministrators.map((item) => /* @__PURE__ */ jsx16("option", { value: item.id, children: item.name }, item.id))
|
|
6919
|
+
] }), onSelectCell: (cell) => onDrillDown?.(taskQuery(cell)) })
|
|
6920
|
+
] });
|
|
6921
|
+
}
|
|
6922
|
+
function ConnectedBillTasksDashboard({ appearance, className, style, onDrillDown, ...options }) {
|
|
6923
|
+
const client = useClient(options);
|
|
6924
|
+
return /* @__PURE__ */ jsx16(Surface, { appearance, className, style, children: /* @__PURE__ */ jsx16(BillTasksContent, { client, onDrillDown, appearance }) });
|
|
6925
|
+
}
|
|
6926
|
+
function RangeToolbar({ from, to, setFrom, setTo }) {
|
|
6927
|
+
return /* @__PURE__ */ jsxs16("div", { className: "mbow-toolbar", children: [
|
|
6928
|
+
/* @__PURE__ */ jsxs16("label", { children: [
|
|
6929
|
+
"From ",
|
|
6930
|
+
/* @__PURE__ */ jsx16("input", { className: "mbow-input", type: "date", value: from, onChange: (event) => setFrom(event.target.value) })
|
|
6931
|
+
] }),
|
|
6932
|
+
/* @__PURE__ */ jsxs16("label", { children: [
|
|
6933
|
+
"To ",
|
|
6934
|
+
/* @__PURE__ */ jsx16("input", { className: "mbow-input", type: "date", value: to, onChange: (event) => setTo(event.target.value) })
|
|
6935
|
+
] })
|
|
6936
|
+
] });
|
|
6937
|
+
}
|
|
6938
|
+
function ConnectedServiceLineItemsReport({ appearance, className, style, initialFrom, initialTo, onSelectBill, ...options }) {
|
|
6939
|
+
const defaults = useMemo10(() => defaultRange(), []);
|
|
6940
|
+
const client = useClient(options);
|
|
6941
|
+
const [from, setFrom] = useState13(initialFrom ?? defaults.from);
|
|
6942
|
+
const [to, setTo] = useState13(initialTo ?? defaults.to);
|
|
6943
|
+
const [data, setData] = useState13(null);
|
|
6944
|
+
const [error, setError] = useState13(null);
|
|
6945
|
+
useEffect11(() => {
|
|
6946
|
+
const controller = new AbortController();
|
|
6947
|
+
setError(null);
|
|
6948
|
+
void client.getServiceLineItems({ from, to }, controller.signal).then(setData).catch((cause) => {
|
|
6949
|
+
if (!controller.signal.aborted) setError(cause instanceof Error ? cause : new Error("Report could not be loaded."));
|
|
6950
|
+
});
|
|
6951
|
+
return () => controller.abort();
|
|
6952
|
+
}, [client, from, to]);
|
|
6953
|
+
return /* @__PURE__ */ jsxs16(Surface, { appearance, className, style, children: [
|
|
6954
|
+
/* @__PURE__ */ jsx16("div", { className: "mbow-head", children: /* @__PURE__ */ jsxs16("div", { children: [
|
|
6955
|
+
/* @__PURE__ */ jsx16("h2", { children: "Original submissions by procedure" }),
|
|
6956
|
+
/* @__PURE__ */ jsx16("p", { className: "mbow-sub", children: "First payer submission for each patient and date of service." })
|
|
6957
|
+
] }) }),
|
|
6958
|
+
/* @__PURE__ */ jsx16(RangeToolbar, { from, to, setFrom, setTo }),
|
|
6959
|
+
error ? /* @__PURE__ */ jsx16("div", { className: "mbow-state mbow-error", children: error.message }) : !data ? /* @__PURE__ */ jsx16("div", { className: "mbow-state", children: "Loading report\u2026" }) : /* @__PURE__ */ jsxs16(Fragment14, { children: [
|
|
6960
|
+
/* @__PURE__ */ jsxs16("div", { className: "mbow-metrics", children: [
|
|
6961
|
+
/* @__PURE__ */ jsx16(Metric, { label: "Original bills", value: String(data.totalBills) }),
|
|
6962
|
+
/* @__PURE__ */ jsx16(Metric, { label: "Service lines", value: String(data.totalLines) }),
|
|
6963
|
+
/* @__PURE__ */ jsx16(Metric, { label: "Total billed", value: money6(data.totalBilled) }),
|
|
6964
|
+
/* @__PURE__ */ jsx16(Metric, { label: "Report window", value: data.windowLabel })
|
|
6965
|
+
] }),
|
|
6966
|
+
/* @__PURE__ */ jsxs16("div", { className: "mbow-card mbow-scroll", children: [
|
|
6967
|
+
/* @__PURE__ */ jsx16("div", { className: "mbow-section-head", children: /* @__PURE__ */ jsx16("h3", { children: "Procedure summary" }) }),
|
|
6968
|
+
/* @__PURE__ */ jsxs16("table", { className: "mbow-table", children: [
|
|
6969
|
+
/* @__PURE__ */ jsx16("thead", { children: /* @__PURE__ */ jsxs16("tr", { children: [
|
|
6970
|
+
/* @__PURE__ */ jsx16("th", { children: "Procedure code" }),
|
|
6971
|
+
/* @__PURE__ */ jsx16("th", { children: "Bills" }),
|
|
6972
|
+
/* @__PURE__ */ jsx16("th", { children: "Service lines" }),
|
|
6973
|
+
/* @__PURE__ */ jsx16("th", { className: "mbow-money", children: "Total billed" })
|
|
6974
|
+
] }) }),
|
|
6975
|
+
/* @__PURE__ */ jsx16("tbody", { children: data.cptRows.map((row) => /* @__PURE__ */ jsxs16("tr", { children: [
|
|
6976
|
+
/* @__PURE__ */ jsx16("td", { className: "mbow-strong", children: row.code }),
|
|
6977
|
+
/* @__PURE__ */ jsx16("td", { children: row.bills }),
|
|
6978
|
+
/* @__PURE__ */ jsx16("td", { children: row.lines }),
|
|
6979
|
+
/* @__PURE__ */ jsx16("td", { className: "mbow-money", children: money6(row.billed) })
|
|
6980
|
+
] }, row.code)) })
|
|
6981
|
+
] })
|
|
6982
|
+
] }),
|
|
6983
|
+
/* @__PURE__ */ jsxs16("div", { className: "mbow-card mbow-scroll", style: { marginTop: 16 }, children: [
|
|
6984
|
+
/* @__PURE__ */ jsx16("div", { className: "mbow-section-head", children: /* @__PURE__ */ jsx16("h3", { children: "All original bills" }) }),
|
|
6985
|
+
/* @__PURE__ */ jsxs16("table", { className: "mbow-table", children: [
|
|
6986
|
+
/* @__PURE__ */ jsx16("thead", { children: /* @__PURE__ */ jsxs16("tr", { children: [
|
|
6987
|
+
/* @__PURE__ */ jsx16("th", { children: "Bill" }),
|
|
6988
|
+
/* @__PURE__ */ jsx16("th", { children: "First submitted" }),
|
|
6989
|
+
/* @__PURE__ */ jsx16("th", { children: "Patient \xB7 Claim" }),
|
|
6990
|
+
/* @__PURE__ */ jsx16("th", { children: "DOS" }),
|
|
6991
|
+
/* @__PURE__ */ jsx16("th", { children: "Claims administrator" }),
|
|
6992
|
+
/* @__PURE__ */ jsx16("th", { children: "Codes" }),
|
|
6993
|
+
/* @__PURE__ */ jsx16("th", { className: "mbow-money", children: "Billed" }),
|
|
6994
|
+
/* @__PURE__ */ jsx16("th", { children: "Status" })
|
|
6995
|
+
] }) }),
|
|
6996
|
+
/* @__PURE__ */ jsx16("tbody", { children: data.billRows.map((row) => /* @__PURE__ */ jsxs16("tr", { className: onSelectBill ? "clickable" : "", onClick: () => onSelectBill?.(row.billId), children: [
|
|
6997
|
+
/* @__PURE__ */ jsxs16("td", { className: "mbow-strong", children: [
|
|
6998
|
+
"#",
|
|
6999
|
+
row.billNumber
|
|
7000
|
+
] }),
|
|
7001
|
+
/* @__PURE__ */ jsx16("td", { children: shortDate(row.submittedDate) }),
|
|
7002
|
+
/* @__PURE__ */ jsxs16("td", { children: [
|
|
7003
|
+
row.patient,
|
|
7004
|
+
/* @__PURE__ */ jsx16("div", { className: "mbow-muted", children: row.claim })
|
|
7005
|
+
] }),
|
|
7006
|
+
/* @__PURE__ */ jsx16("td", { children: shortDate(row.dos) }),
|
|
7007
|
+
/* @__PURE__ */ jsx16("td", { children: row.claimsAdmin }),
|
|
7008
|
+
/* @__PURE__ */ jsx16("td", { children: row.codes.join(", ") }),
|
|
7009
|
+
/* @__PURE__ */ jsx16("td", { className: "mbow-money", children: money6(row.billed) }),
|
|
7010
|
+
/* @__PURE__ */ jsx16("td", { children: row.status })
|
|
7011
|
+
] }, row.billId)) })
|
|
7012
|
+
] })
|
|
7013
|
+
] })
|
|
7014
|
+
] })
|
|
7015
|
+
] });
|
|
7016
|
+
}
|
|
7017
|
+
function Metric({ label, value }) {
|
|
7018
|
+
return /* @__PURE__ */ jsxs16("div", { className: "mbow-metric", children: [
|
|
7019
|
+
/* @__PURE__ */ jsx16("span", { children: label }),
|
|
7020
|
+
/* @__PURE__ */ jsx16("strong", { children: value })
|
|
7021
|
+
] });
|
|
7022
|
+
}
|
|
7023
|
+
function ConnectedProductivityReport({ appearance, className, style, initialFrom, initialTo, ...options }) {
|
|
7024
|
+
const defaults = useMemo10(() => defaultRange(13), []);
|
|
7025
|
+
const client = useClient(options);
|
|
7026
|
+
const [from, setFrom] = useState13(initialFrom ?? defaults.from);
|
|
7027
|
+
const [to, setTo] = useState13(initialTo ?? defaults.to);
|
|
7028
|
+
const [data, setData] = useState13(null);
|
|
7029
|
+
const [error, setError] = useState13(null);
|
|
7030
|
+
useEffect11(() => {
|
|
7031
|
+
const controller = new AbortController();
|
|
7032
|
+
setError(null);
|
|
7033
|
+
void client.getProductivity({ from, to }, controller.signal).then(setData).catch((cause) => {
|
|
7034
|
+
if (!controller.signal.aborted) setError(cause instanceof Error ? cause : new Error("Report could not be loaded."));
|
|
7035
|
+
});
|
|
7036
|
+
return () => controller.abort();
|
|
7037
|
+
}, [client, from, to]);
|
|
7038
|
+
const maxSent = data ? Math.max(1, ...Object.values(data.sentTotal)) : 1;
|
|
7039
|
+
return /* @__PURE__ */ jsxs16(Surface, { appearance, className, style, children: [
|
|
7040
|
+
/* @__PURE__ */ jsx16("div", { className: "mbow-head", children: /* @__PURE__ */ jsxs16("div", { children: [
|
|
7041
|
+
/* @__PURE__ */ jsx16("h2", { children: "Productivity" }),
|
|
7042
|
+
/* @__PURE__ */ jsx16("p", { className: "mbow-sub", children: "Bills created and sent per biller, plus accepted-first-try rate." })
|
|
7043
|
+
] }) }),
|
|
7044
|
+
/* @__PURE__ */ jsx16(RangeToolbar, { from, to, setFrom, setTo }),
|
|
7045
|
+
error ? /* @__PURE__ */ jsx16("div", { className: "mbow-state mbow-error", children: error.message }) : !data ? /* @__PURE__ */ jsx16("div", { className: "mbow-state", children: "Loading report\u2026" }) : /* @__PURE__ */ jsxs16(Fragment14, { children: [
|
|
7046
|
+
/* @__PURE__ */ jsxs16("div", { className: "mbow-metrics", children: [
|
|
7047
|
+
/* @__PURE__ */ jsx16(Metric, { label: "Bills created", value: String(data.totalCreated) }),
|
|
7048
|
+
/* @__PURE__ */ jsx16(Metric, { label: "Transmissions", value: String(data.totalSent) }),
|
|
7049
|
+
/* @__PURE__ */ jsx16(Metric, { label: "Bills submitted", value: String(data.totalSubmitted) }),
|
|
7050
|
+
/* @__PURE__ */ jsx16(Metric, { label: "Accepted first try", value: data.totalSubmitted ? `${Math.round(data.totalClean / data.totalSubmitted * 100)}%` : "\u2014" })
|
|
7051
|
+
] }),
|
|
7052
|
+
/* @__PURE__ */ jsxs16("div", { className: "mbow-card mbow-scroll", children: [
|
|
7053
|
+
/* @__PURE__ */ jsx16("div", { className: "mbow-section-head", children: /* @__PURE__ */ jsx16("h3", { children: "Per-biller summary" }) }),
|
|
7054
|
+
/* @__PURE__ */ jsxs16("table", { className: "mbow-table", children: [
|
|
7055
|
+
/* @__PURE__ */ jsx16("thead", { children: /* @__PURE__ */ jsxs16("tr", { children: [
|
|
7056
|
+
/* @__PURE__ */ jsx16("th", { children: "Biller" }),
|
|
7057
|
+
/* @__PURE__ */ jsx16("th", { children: "Created" }),
|
|
7058
|
+
/* @__PURE__ */ jsx16("th", { children: "Transmissions" }),
|
|
7059
|
+
/* @__PURE__ */ jsx16("th", { children: "Submitted" }),
|
|
7060
|
+
/* @__PURE__ */ jsx16("th", { children: "Accepted first try" }),
|
|
7061
|
+
/* @__PURE__ */ jsx16("th", { children: "Volume" })
|
|
7062
|
+
] }) }),
|
|
7063
|
+
/* @__PURE__ */ jsx16("tbody", { children: data.billers.map((biller) => {
|
|
7064
|
+
const sent = data.sentTotal[biller.name] ?? 0;
|
|
7065
|
+
const submitted = data.submittedTotal[biller.name] ?? 0;
|
|
7066
|
+
const clean = data.cleanTotal[biller.name] ?? 0;
|
|
7067
|
+
return /* @__PURE__ */ jsxs16("tr", { children: [
|
|
7068
|
+
/* @__PURE__ */ jsx16("td", { className: "mbow-strong", children: biller.name }),
|
|
7069
|
+
/* @__PURE__ */ jsx16("td", { children: data.createdTotal[biller.name] ?? 0 }),
|
|
7070
|
+
/* @__PURE__ */ jsx16("td", { children: sent }),
|
|
7071
|
+
/* @__PURE__ */ jsx16("td", { children: submitted }),
|
|
7072
|
+
/* @__PURE__ */ jsx16("td", { children: submitted ? `${Math.round(clean / submitted * 100)}%` : "\u2014" }),
|
|
7073
|
+
/* @__PURE__ */ jsx16("td", { children: /* @__PURE__ */ jsx16("div", { className: "mbow-bar", children: /* @__PURE__ */ jsx16("i", { style: { width: `${sent / maxSent * 100}%` } }) }) })
|
|
7074
|
+
] }, biller.name);
|
|
7075
|
+
}) })
|
|
7076
|
+
] })
|
|
7077
|
+
] })
|
|
7078
|
+
] })
|
|
7079
|
+
] });
|
|
7080
|
+
}
|
|
7081
|
+
function ConnectedBillingWorkspace({ appearance, className, style, initialView = "tasks", onCreateBill, ...options }) {
|
|
7082
|
+
const client = useClient(options);
|
|
7083
|
+
const [view, setView] = useState13(initialView);
|
|
7084
|
+
const [billQuery, setBillQuery] = useState13({ status: "all" });
|
|
7085
|
+
const [selectedBillId, setSelectedBillId] = useState13(null);
|
|
7086
|
+
if (selectedBillId) return /* @__PURE__ */ jsxs16(Surface, { appearance, className, style, children: [
|
|
7087
|
+
/* @__PURE__ */ jsx16("button", { className: "mbow-button mbow-back", type: "button", onClick: () => setSelectedBillId(null), children: "\u2190 Back to bills" }),
|
|
7088
|
+
/* @__PURE__ */ jsx16(ConnectedBillLifecycle, { billId: selectedBillId, ...options, ...appearance ? { appearance } : {} })
|
|
7089
|
+
] });
|
|
7090
|
+
const selectView = (next) => {
|
|
7091
|
+
setView(next);
|
|
7092
|
+
setSelectedBillId(null);
|
|
7093
|
+
};
|
|
7094
|
+
const appearanceProps = appearance ? { appearance } : {};
|
|
7095
|
+
return /* @__PURE__ */ jsxs16(Surface, { appearance, className, style, children: [
|
|
7096
|
+
/* @__PURE__ */ jsxs16("div", { className: "mbow-head", children: [
|
|
7097
|
+
/* @__PURE__ */ jsxs16("div", { children: [
|
|
7098
|
+
/* @__PURE__ */ jsx16("h2", { children: "Billing" }),
|
|
7099
|
+
/* @__PURE__ */ jsx16("p", { className: "mbow-sub", children: "Follow up on open work or find any bill and its current status." })
|
|
7100
|
+
] }),
|
|
7101
|
+
onCreateBill ? /* @__PURE__ */ jsx16("div", { className: "mbow-actions", children: /* @__PURE__ */ jsx16("button", { className: "mbow-button primary", type: "button", onClick: onCreateBill, children: "+ Add bill" }) }) : null
|
|
7102
|
+
] }),
|
|
7103
|
+
/* @__PURE__ */ jsx16("div", { className: "mbow-tabs", role: "tablist", children: [["tasks", "Bill tasks"], ["bills", "All bills"], ["procedures", "Procedures"], ["productivity", "Productivity"]].map(([id, label]) => /* @__PURE__ */ jsx16("button", { className: `mbow-tab ${view === id ? "active" : ""}`, type: "button", role: "tab", "aria-selected": view === id, onClick: () => selectView(id), children: label }, id)) }),
|
|
7104
|
+
view === "tasks" ? /* @__PURE__ */ jsx16(BillTasksContent, { client, onDrillDown: (query) => {
|
|
7105
|
+
setBillQuery(query);
|
|
7106
|
+
setView("bills");
|
|
7107
|
+
}, appearance }) : view === "bills" ? /* @__PURE__ */ jsx16(BillSearchContent, { client, initialQuery: billQuery, onSelectBill: (bill) => setSelectedBillId(bill.id) }) : view === "procedures" ? /* @__PURE__ */ jsx16(ConnectedServiceLineItemsReport, { ...options, ...appearanceProps, onSelectBill: setSelectedBillId }) : /* @__PURE__ */ jsx16(ConnectedProductivityReport, { ...options, ...appearanceProps })
|
|
7108
|
+
] });
|
|
7109
|
+
}
|
|
7110
|
+
|
|
6061
7111
|
// src/index.tsx
|
|
6062
7112
|
function widget(tagName, props) {
|
|
6063
|
-
const ref =
|
|
7113
|
+
const ref = useRef7(null);
|
|
6064
7114
|
const { onMindBill, onMindBillError } = props;
|
|
6065
|
-
|
|
7115
|
+
useEffect12(() => {
|
|
6066
7116
|
const element = ref.current;
|
|
6067
7117
|
if (!element) return;
|
|
6068
7118
|
const handleEvent = (event) => onMindBill?.(event);
|
|
@@ -6136,7 +7186,12 @@ export {
|
|
|
6136
7186
|
BillingSettings,
|
|
6137
7187
|
ClaimsAdministratorDirectoryDialog,
|
|
6138
7188
|
ConnectedBillLifecycle,
|
|
7189
|
+
ConnectedBillSearch,
|
|
6139
7190
|
ConnectedBillStatus,
|
|
7191
|
+
ConnectedBillTasksDashboard,
|
|
7192
|
+
ConnectedBillingWorkspace,
|
|
7193
|
+
ConnectedProductivityReport,
|
|
7194
|
+
ConnectedServiceLineItemsReport,
|
|
6140
7195
|
DEFAULT_BILL_SUBMISSION_MODIFIERS,
|
|
6141
7196
|
DEFAULT_BILL_SUBMISSION_PROCEDURES,
|
|
6142
7197
|
DEFAULT_BILL_SUBMISSION_TAXONOMIES,
|
|
@@ -6147,8 +7202,10 @@ export {
|
|
|
6147
7202
|
PSYCH_QME_DEFAULT_DIAGNOSIS,
|
|
6148
7203
|
REPORT_BILL_STATUS_OPTIONS2 as REPORT_BILL_STATUS_OPTIONS,
|
|
6149
7204
|
ReportBillStatusDialog,
|
|
6150
|
-
|
|
7205
|
+
SECOND_REVIEW_REASON_TEMPLATE,
|
|
7206
|
+
SECOND_REVIEW_REASON_TEMPLATES,
|
|
6151
7207
|
SECOND_REVIEW_WINDOW_DAYS,
|
|
7208
|
+
SecondReviewForm,
|
|
6152
7209
|
SendRouteDialog,
|
|
6153
7210
|
applyBillSubmissionEvaluationDiagnoses,
|
|
6154
7211
|
applyBillSubmissionEvaluationModifiers,
|
|
@@ -6171,6 +7228,7 @@ export {
|
|
|
6171
7228
|
claimsAdministratorRecommendations,
|
|
6172
7229
|
createBillLifecycleClient2 as createBillLifecycleClient,
|
|
6173
7230
|
createBillStatusClient,
|
|
7231
|
+
createBillingOperationsClient,
|
|
6174
7232
|
ensureTrailingBillSubmissionLine,
|
|
6175
7233
|
ensureTrailingProcedureLine,
|
|
6176
7234
|
exactClaimsAdministratorMatch,
|