feat: add insurance provider dropdown to eligibility page, save to patient record after eligibility check
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
a3d2960c98
commit
34e9c83a63
@@ -43,6 +43,26 @@ import { CCAEligibilityButton } from "@/components/insurance-status/cca-button-m
|
||||
import { BcbsMaEligibilityButton } from "@/components/insurance-status/bcbs-ma-button-modal";
|
||||
import { useLicense } from "@/hooks/use-license";
|
||||
|
||||
const INSURANCE_PROVIDERS = [
|
||||
"Aetna",
|
||||
"BMC HealthNet Plan",
|
||||
"CIGNA",
|
||||
"Cenpatico Massachusetts",
|
||||
"Commonwealth Care Alliance",
|
||||
"Harvard Pilgrim Health Care",
|
||||
"Humana",
|
||||
"MA BCBS",
|
||||
"MA Medicaid-MassHealth",
|
||||
"Mass Advantage",
|
||||
"Mass General Brigham Health Plan",
|
||||
"Senior Whole Health of Massachusetts",
|
||||
"Tricare East",
|
||||
"Tufts Health Plan",
|
||||
"UMR - Wausau",
|
||||
"United Health Care",
|
||||
"Wellcare",
|
||||
];
|
||||
|
||||
/**
|
||||
* Waits for a Selenium job to complete by racing socket.io events against
|
||||
* HTTP polling every 3 seconds. This ensures the result is received even
|
||||
@@ -109,6 +129,7 @@ export default function InsuranceStatusPage() {
|
||||
const [dateOfBirth, setDateOfBirth] = useState<Date | null>(null);
|
||||
const [firstName, setFirstName] = useState("");
|
||||
const [lastName, setLastName] = useState("");
|
||||
const [insuranceProvider, setInsuranceProvider] = useState("");
|
||||
const isFormIncomplete = !memberId || !dateOfBirth;
|
||||
|
||||
// AI Call Insurance section
|
||||
@@ -176,6 +197,11 @@ export default function InsuranceStatusPage() {
|
||||
setMemberId(selectedPatient.insuranceId ?? "");
|
||||
setFirstName(selectedPatient.firstName ?? "");
|
||||
setLastName(selectedPatient.lastName ?? "");
|
||||
setInsuranceProvider(
|
||||
INSURANCE_PROVIDERS.includes(selectedPatient.insuranceProvider ?? "")
|
||||
? selectedPatient.insuranceProvider!
|
||||
: "",
|
||||
);
|
||||
|
||||
const dob =
|
||||
typeof selectedPatient.dateOfBirth === "string"
|
||||
@@ -187,9 +213,34 @@ export default function InsuranceStatusPage() {
|
||||
setFirstName("");
|
||||
setLastName("");
|
||||
setDateOfBirth(null);
|
||||
setInsuranceProvider("");
|
||||
}
|
||||
}, [selectedPatient]);
|
||||
|
||||
// Save the chosen insurance provider on the patient record once an
|
||||
// eligibility check succeeds, so it shows in the patient table.
|
||||
const saveInsuranceProvider = async () => {
|
||||
if (!insuranceProvider) return;
|
||||
try {
|
||||
let patientId = selectedPatient?.id ?? null;
|
||||
if (!patientId && memberId) {
|
||||
const res = await apiRequest(
|
||||
"GET",
|
||||
`/api/patients/by-insurance-id?insuranceId=${encodeURIComponent(memberId)}`,
|
||||
);
|
||||
if (res.ok) patientId = (await res.json())?.id ?? null;
|
||||
}
|
||||
if (!patientId) return;
|
||||
const res = await apiRequest("PUT", `/api/patients/${patientId}`, {
|
||||
insuranceProvider,
|
||||
});
|
||||
if (!res.ok) return;
|
||||
queryClient.invalidateQueries({ queryKey: QK_PATIENTS_BASE });
|
||||
} catch {
|
||||
// non-critical: eligibility result is already available
|
||||
}
|
||||
};
|
||||
|
||||
// Auto-lookup patient by member ID when typed manually
|
||||
useEffect(() => {
|
||||
if (selectedPatient && memberId === (selectedPatient.insuranceId ?? "")) return;
|
||||
@@ -518,6 +569,27 @@ export default function InsuranceStatusPage() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-4 md:grid-cols-4 gap-4 mb-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="insuranceProvider">Insurance Provider</Label>
|
||||
<Select
|
||||
value={insuranceProvider}
|
||||
onValueChange={setInsuranceProvider}
|
||||
>
|
||||
<SelectTrigger id="insuranceProvider">
|
||||
<SelectValue placeholder="Select insurance provider" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{INSURANCE_PROVIDERS.map((name) => (
|
||||
<SelectItem key={name} value={name}>
|
||||
{name}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* TEMP PROVIDER BUTTONS */}
|
||||
<div id="eligibility-other-providers" className="space-y-4 mt-6">
|
||||
<h3 className="text-sm font-medium text-muted-foreground">
|
||||
@@ -536,6 +608,7 @@ export default function InsuranceStatusPage() {
|
||||
autoTrigger={triggerTarget === "ddma"}
|
||||
onAutoTriggered={() => setTriggerTarget(null)}
|
||||
onPdfReady={async (pdfId, fallbackFilename) => {
|
||||
void saveInsuranceProvider();
|
||||
const claimed = await tryClaimFromChatbot(selectedPatient?.id);
|
||||
void tryAppointmentFromChatbot();
|
||||
if (!claimed) {
|
||||
@@ -558,6 +631,7 @@ export default function InsuranceStatusPage() {
|
||||
autoTrigger={triggerTarget === "delta-ins"}
|
||||
onAutoTriggered={() => setTriggerTarget(null)}
|
||||
onPdfReady={async (pdfId, fallbackFilename) => {
|
||||
void saveInsuranceProvider();
|
||||
const claimed = await tryClaimFromChatbot(selectedPatient?.id);
|
||||
void tryAppointmentFromChatbot();
|
||||
if (!claimed) {
|
||||
@@ -578,6 +652,7 @@ export default function InsuranceStatusPage() {
|
||||
lastName={lastName}
|
||||
isFormIncomplete={isFormIncomplete}
|
||||
onPdfReady={async (pdfId, fallbackFilename) => {
|
||||
void saveInsuranceProvider();
|
||||
void tryAppointmentFromChatbot();
|
||||
setPreviewPdfId(pdfId);
|
||||
setPreviewFallbackFilename(
|
||||
@@ -602,6 +677,7 @@ export default function InsuranceStatusPage() {
|
||||
autoTrigger={triggerTarget === "tufts-sco"}
|
||||
onAutoTriggered={() => setTriggerTarget(null)}
|
||||
onPdfReady={async (pdfId, fallbackFilename) => {
|
||||
void saveInsuranceProvider();
|
||||
const claimed = await tryClaimFromChatbot(selectedPatient?.id);
|
||||
void tryAppointmentFromChatbot();
|
||||
if (!claimed) {
|
||||
@@ -624,6 +700,7 @@ export default function InsuranceStatusPage() {
|
||||
autoTrigger={triggerTarget === "united-sco"}
|
||||
onAutoTriggered={() => setTriggerTarget(null)}
|
||||
onPdfReady={async (pdfId, fallbackFilename) => {
|
||||
void saveInsuranceProvider();
|
||||
const claimed = await tryClaimFromChatbot(selectedPatient?.id);
|
||||
void tryAppointmentFromChatbot();
|
||||
if (!claimed) {
|
||||
@@ -646,6 +723,7 @@ export default function InsuranceStatusPage() {
|
||||
autoTrigger={triggerTarget === "cca"}
|
||||
onAutoTriggered={() => setTriggerTarget(null)}
|
||||
onPdfReady={async (pdfId, fallbackFilename) => {
|
||||
void saveInsuranceProvider();
|
||||
const claimed = await tryClaimFromChatbot(selectedPatient?.id);
|
||||
void tryAppointmentFromChatbot();
|
||||
if (!claimed) {
|
||||
|
||||
Reference in New Issue
Block a user