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 { BcbsMaEligibilityButton } from "@/components/insurance-status/bcbs-ma-button-modal";
|
||||||
import { useLicense } from "@/hooks/use-license";
|
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
|
* 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
|
* 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 [dateOfBirth, setDateOfBirth] = useState<Date | null>(null);
|
||||||
const [firstName, setFirstName] = useState("");
|
const [firstName, setFirstName] = useState("");
|
||||||
const [lastName, setLastName] = useState("");
|
const [lastName, setLastName] = useState("");
|
||||||
|
const [insuranceProvider, setInsuranceProvider] = useState("");
|
||||||
const isFormIncomplete = !memberId || !dateOfBirth;
|
const isFormIncomplete = !memberId || !dateOfBirth;
|
||||||
|
|
||||||
// AI Call Insurance section
|
// AI Call Insurance section
|
||||||
@@ -176,6 +197,11 @@ export default function InsuranceStatusPage() {
|
|||||||
setMemberId(selectedPatient.insuranceId ?? "");
|
setMemberId(selectedPatient.insuranceId ?? "");
|
||||||
setFirstName(selectedPatient.firstName ?? "");
|
setFirstName(selectedPatient.firstName ?? "");
|
||||||
setLastName(selectedPatient.lastName ?? "");
|
setLastName(selectedPatient.lastName ?? "");
|
||||||
|
setInsuranceProvider(
|
||||||
|
INSURANCE_PROVIDERS.includes(selectedPatient.insuranceProvider ?? "")
|
||||||
|
? selectedPatient.insuranceProvider!
|
||||||
|
: "",
|
||||||
|
);
|
||||||
|
|
||||||
const dob =
|
const dob =
|
||||||
typeof selectedPatient.dateOfBirth === "string"
|
typeof selectedPatient.dateOfBirth === "string"
|
||||||
@@ -187,9 +213,34 @@ export default function InsuranceStatusPage() {
|
|||||||
setFirstName("");
|
setFirstName("");
|
||||||
setLastName("");
|
setLastName("");
|
||||||
setDateOfBirth(null);
|
setDateOfBirth(null);
|
||||||
|
setInsuranceProvider("");
|
||||||
}
|
}
|
||||||
}, [selectedPatient]);
|
}, [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
|
// Auto-lookup patient by member ID when typed manually
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedPatient && memberId === (selectedPatient.insuranceId ?? "")) return;
|
if (selectedPatient && memberId === (selectedPatient.insuranceId ?? "")) return;
|
||||||
@@ -518,6 +569,27 @@ export default function InsuranceStatusPage() {
|
|||||||
</div>
|
</div>
|
||||||
</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 */}
|
{/* TEMP PROVIDER BUTTONS */}
|
||||||
<div id="eligibility-other-providers" className="space-y-4 mt-6">
|
<div id="eligibility-other-providers" className="space-y-4 mt-6">
|
||||||
<h3 className="text-sm font-medium text-muted-foreground">
|
<h3 className="text-sm font-medium text-muted-foreground">
|
||||||
@@ -536,6 +608,7 @@ export default function InsuranceStatusPage() {
|
|||||||
autoTrigger={triggerTarget === "ddma"}
|
autoTrigger={triggerTarget === "ddma"}
|
||||||
onAutoTriggered={() => setTriggerTarget(null)}
|
onAutoTriggered={() => setTriggerTarget(null)}
|
||||||
onPdfReady={async (pdfId, fallbackFilename) => {
|
onPdfReady={async (pdfId, fallbackFilename) => {
|
||||||
|
void saveInsuranceProvider();
|
||||||
const claimed = await tryClaimFromChatbot(selectedPatient?.id);
|
const claimed = await tryClaimFromChatbot(selectedPatient?.id);
|
||||||
void tryAppointmentFromChatbot();
|
void tryAppointmentFromChatbot();
|
||||||
if (!claimed) {
|
if (!claimed) {
|
||||||
@@ -558,6 +631,7 @@ export default function InsuranceStatusPage() {
|
|||||||
autoTrigger={triggerTarget === "delta-ins"}
|
autoTrigger={triggerTarget === "delta-ins"}
|
||||||
onAutoTriggered={() => setTriggerTarget(null)}
|
onAutoTriggered={() => setTriggerTarget(null)}
|
||||||
onPdfReady={async (pdfId, fallbackFilename) => {
|
onPdfReady={async (pdfId, fallbackFilename) => {
|
||||||
|
void saveInsuranceProvider();
|
||||||
const claimed = await tryClaimFromChatbot(selectedPatient?.id);
|
const claimed = await tryClaimFromChatbot(selectedPatient?.id);
|
||||||
void tryAppointmentFromChatbot();
|
void tryAppointmentFromChatbot();
|
||||||
if (!claimed) {
|
if (!claimed) {
|
||||||
@@ -578,6 +652,7 @@ export default function InsuranceStatusPage() {
|
|||||||
lastName={lastName}
|
lastName={lastName}
|
||||||
isFormIncomplete={isFormIncomplete}
|
isFormIncomplete={isFormIncomplete}
|
||||||
onPdfReady={async (pdfId, fallbackFilename) => {
|
onPdfReady={async (pdfId, fallbackFilename) => {
|
||||||
|
void saveInsuranceProvider();
|
||||||
void tryAppointmentFromChatbot();
|
void tryAppointmentFromChatbot();
|
||||||
setPreviewPdfId(pdfId);
|
setPreviewPdfId(pdfId);
|
||||||
setPreviewFallbackFilename(
|
setPreviewFallbackFilename(
|
||||||
@@ -602,6 +677,7 @@ export default function InsuranceStatusPage() {
|
|||||||
autoTrigger={triggerTarget === "tufts-sco"}
|
autoTrigger={triggerTarget === "tufts-sco"}
|
||||||
onAutoTriggered={() => setTriggerTarget(null)}
|
onAutoTriggered={() => setTriggerTarget(null)}
|
||||||
onPdfReady={async (pdfId, fallbackFilename) => {
|
onPdfReady={async (pdfId, fallbackFilename) => {
|
||||||
|
void saveInsuranceProvider();
|
||||||
const claimed = await tryClaimFromChatbot(selectedPatient?.id);
|
const claimed = await tryClaimFromChatbot(selectedPatient?.id);
|
||||||
void tryAppointmentFromChatbot();
|
void tryAppointmentFromChatbot();
|
||||||
if (!claimed) {
|
if (!claimed) {
|
||||||
@@ -624,6 +700,7 @@ export default function InsuranceStatusPage() {
|
|||||||
autoTrigger={triggerTarget === "united-sco"}
|
autoTrigger={triggerTarget === "united-sco"}
|
||||||
onAutoTriggered={() => setTriggerTarget(null)}
|
onAutoTriggered={() => setTriggerTarget(null)}
|
||||||
onPdfReady={async (pdfId, fallbackFilename) => {
|
onPdfReady={async (pdfId, fallbackFilename) => {
|
||||||
|
void saveInsuranceProvider();
|
||||||
const claimed = await tryClaimFromChatbot(selectedPatient?.id);
|
const claimed = await tryClaimFromChatbot(selectedPatient?.id);
|
||||||
void tryAppointmentFromChatbot();
|
void tryAppointmentFromChatbot();
|
||||||
if (!claimed) {
|
if (!claimed) {
|
||||||
@@ -646,6 +723,7 @@ export default function InsuranceStatusPage() {
|
|||||||
autoTrigger={triggerTarget === "cca"}
|
autoTrigger={triggerTarget === "cca"}
|
||||||
onAutoTriggered={() => setTriggerTarget(null)}
|
onAutoTriggered={() => setTriggerTarget(null)}
|
||||||
onPdfReady={async (pdfId, fallbackFilename) => {
|
onPdfReady={async (pdfId, fallbackFilename) => {
|
||||||
|
void saveInsuranceProvider();
|
||||||
const claimed = await tryClaimFromChatbot(selectedPatient?.id);
|
const claimed = await tryClaimFromChatbot(selectedPatient?.id);
|
||||||
void tryAppointmentFromChatbot();
|
void tryAppointmentFromChatbot();
|
||||||
if (!claimed) {
|
if (!claimed) {
|
||||||
|
|||||||
Reference in New Issue
Block a user