feat: auto-trigger eligibility selenium from schedule right-click menu

- Remove "Claim Status" from appointment context menu
- Rename "Eligibility Status" → "Check Eligibility"
- Check Eligibility now navigates to insurance-status page and auto-starts
  the correct selenium flow based on the patient's stored insurance provider:
  MassHealth 21+ → MH Eligibility & History
  MassHealth <21  → CMSP Eligibility & History & Remaining
  Delta Dental MA → DDMA selenium
  Delta Dental Ins → Delta Ins selenium (OTP modal if needed)
  United Healthcare SCO → United SCO selenium
  DentaQuest/Tufts → Tufts SCO selenium
  Commonwealth Care Alliance → CCA selenium
  Unknown → scroll to Other provider checks section
- Add autoTrigger/onAutoTriggered props to all five button components

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Gitead
2026-05-17 00:12:09 -04:00
parent 4127861d06
commit edec03e893
7 changed files with 154 additions and 93 deletions

View File

@@ -1,4 +1,4 @@
import { useRef, useState } from "react";
import { useEffect, useRef, useState } from "react";
import { Button } from "@/components/ui/button";
import { CheckCircle, LoaderCircleIcon } from "lucide-react";
import { useToast } from "@/hooks/use-toast";
@@ -17,6 +17,8 @@ interface CCAEligibilityButtonProps {
firstName?: string;
lastName?: string;
isFormIncomplete: boolean;
autoTrigger?: boolean;
onAutoTriggered?: () => void;
onPdfReady: (pdfId: number, fallbackFilename: string | null) => void;
}
@@ -26,12 +28,15 @@ export function CCAEligibilityButton({
firstName,
lastName,
isFormIncomplete,
autoTrigger,
onAutoTriggered,
onPdfReady,
}: CCAEligibilityButtonProps) {
const { toast } = useToast();
const dispatch = useAppDispatch();
const sessionIdRef = useRef<string | null>(null);
const autoTriggeredRef = useRef(false);
const [isStarting, setIsStarting] = useState(false);
@@ -181,6 +186,14 @@ export function CCAEligibilityButton({
}
};
useEffect(() => {
if (!autoTrigger || autoTriggeredRef.current || isFormIncomplete) return;
autoTriggeredRef.current = true;
onAutoTriggered?.();
handleStart();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [autoTrigger, isFormIncomplete]);
return (
<Button
className="w-full"

View File

@@ -88,6 +88,8 @@ interface DdmaEligibilityButtonProps {
firstName?: string;
lastName?: string;
isFormIncomplete: boolean;
autoTrigger?: boolean;
onAutoTriggered?: () => void;
onPdfReady: (pdfId: number, fallbackFilename: string | null) => void;
}
@@ -97,15 +99,15 @@ export function DdmaEligibilityButton({
firstName,
lastName,
isFormIncomplete,
autoTrigger,
onAutoTriggered,
onPdfReady,
}: DdmaEligibilityButtonProps) {
const { toast } = useToast();
const dispatch = useAppDispatch();
// session_id is provided by the backend once the Python agent starts the
// browser session. We receive it via the selenium:ddma_session_started event
// and need it to forward the OTP back.
const sessionIdRef = useRef<string | null>(null);
const autoTriggeredRef = useRef(false);
const [otpModalOpen, setOtpModalOpen] = useState(false);
const [isStarting, setIsStarting] = useState(false);
@@ -390,6 +392,14 @@ export function DdmaEligibilityButton({
}
};
useEffect(() => {
if (!autoTrigger || autoTriggeredRef.current || isFormIncomplete) return;
autoTriggeredRef.current = true;
onAutoTriggered?.();
handleDdmaStart();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [autoTrigger, isFormIncomplete]);
// ── Render ────────────────────────────────────────────────────────────────
return (

View File

@@ -87,6 +87,8 @@ interface DeltaInsEligibilityButtonProps {
firstName?: string;
lastName?: string;
isFormIncomplete: boolean;
autoTrigger?: boolean;
onAutoTriggered?: () => void;
onPdfReady: (pdfId: number, fallbackFilename: string | null) => void;
}
@@ -96,12 +98,15 @@ export function DeltaInsEligibilityButton({
firstName,
lastName,
isFormIncomplete,
autoTrigger,
onAutoTriggered,
onPdfReady,
}: DeltaInsEligibilityButtonProps) {
const { toast } = useToast();
const dispatch = useAppDispatch();
const sessionIdRef = useRef<string | null>(null);
const autoTriggeredRef = useRef(false);
const [otpModalOpen, setOtpModalOpen] = useState(false);
const [isStarting, setIsStarting] = useState(false);
@@ -321,6 +326,14 @@ export function DeltaInsEligibilityButton({
}
};
useEffect(() => {
if (!autoTrigger || autoTriggeredRef.current || isFormIncomplete) return;
autoTriggeredRef.current = true;
onAutoTriggered?.();
handleStart();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [autoTrigger, isFormIncomplete]);
return (
<>
<Button

View File

@@ -87,6 +87,8 @@ interface TuftsSCOEligibilityButtonProps {
firstName?: string;
lastName?: string;
isFormIncomplete: boolean;
autoTrigger?: boolean;
onAutoTriggered?: () => void;
onPdfReady: (pdfId: number, fallbackFilename: string | null) => void;
}
@@ -96,12 +98,15 @@ export function TuftsSCOEligibilityButton({
firstName,
lastName,
isFormIncomplete,
autoTrigger,
onAutoTriggered,
onPdfReady,
}: TuftsSCOEligibilityButtonProps) {
const { toast } = useToast();
const dispatch = useAppDispatch();
const sessionIdRef = useRef<string | null>(null);
const autoTriggeredRef = useRef(false);
const [otpModalOpen, setOtpModalOpen] = useState(false);
const [isStarting, setIsStarting] = useState(false);
@@ -318,6 +323,14 @@ export function TuftsSCOEligibilityButton({
}
};
useEffect(() => {
if (!autoTrigger || autoTriggeredRef.current || isFormIncomplete) return;
autoTriggeredRef.current = true;
onAutoTriggered?.();
handleStart();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [autoTrigger, isFormIncomplete]);
return (
<>
<Button

View File

@@ -87,6 +87,8 @@ interface UnitedSCOEligibilityButtonProps {
firstName?: string;
lastName?: string;
isFormIncomplete: boolean;
autoTrigger?: boolean;
onAutoTriggered?: () => void;
onPdfReady: (pdfId: number, fallbackFilename: string | null) => void;
}
@@ -96,12 +98,15 @@ export function UnitedSCOEligibilityButton({
firstName,
lastName,
isFormIncomplete,
autoTrigger,
onAutoTriggered,
onPdfReady,
}: UnitedSCOEligibilityButtonProps) {
const { toast } = useToast();
const dispatch = useAppDispatch();
const sessionIdRef = useRef<string | null>(null);
const autoTriggeredRef = useRef(false);
const [otpModalOpen, setOtpModalOpen] = useState(false);
const [isStarting, setIsStarting] = useState(false);
@@ -318,6 +323,14 @@ export function UnitedSCOEligibilityButton({
}
};
useEffect(() => {
if (!autoTrigger || autoTriggeredRef.current || isFormIncomplete) return;
autoTriggeredRef.current = true;
onAutoTriggered?.();
handleStart();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [autoTrigger, isFormIncomplete]);
return (
<>
<Button