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:
@@ -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"
|
||||
|
||||
@@ -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 (
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user