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:
Summit Dental Care
2026-09-23 16:49:54 -04:00
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) {