feat: rename MH Status to MH Eligibility&Appointment, add MH Eligibility&Claims/PreAuth button

This commit is contained in:
Gitead
2026-04-27 19:44:18 -04:00
parent da7038e051
commit 2a49695125

View File

@@ -42,7 +42,7 @@ export default function InsuranceStatusPage() {
(state) => state.seleniumTasks.eligibilityCheck, (state) => state.seleniumTasks.eligibilityCheck,
); );
const [selectedPatient, setSelectedPatient] = useState<Patient | null>(null); const [selectedPatient, setSelectedPatient] = useState<Patient | null>(null);
const [location] = useLocation(); const [location, setLocation] = useLocation();
// Insurance eligibility and claim check form fields // Insurance eligibility and claim check form fields
const [memberId, setMemberId] = useState(""); const [memberId, setMemberId] = useState("");
@@ -52,7 +52,10 @@ export default function InsuranceStatusPage() {
const isFormIncomplete = !memberId || !dateOfBirth; const isFormIncomplete = !memberId || !dateOfBirth;
const [isCheckingEligibilityStatus, setIsCheckingEligibilityStatus] = const [isCheckingEligibilityStatus, setIsCheckingEligibilityStatus] =
useState(false); useState(false);
const [isCheckingClaimStatus, setIsCheckingClaimStatus] = useState(false); const [isCheckingEligibilityAppointment, setIsCheckingEligibilityAppointment] =
useState(false);
const [isCheckingEligibilityClaimsPreAuth, setIsCheckingEligibilityClaimsPreAuth] =
useState(false);
// PDF preview modal state // PDF preview modal state
const [previewOpen, setPreviewOpen] = useState(false); const [previewOpen, setPreviewOpen] = useState(false);
@@ -114,8 +117,8 @@ export default function InsuranceStatusPage() {
}, },
}); });
// handle eligibility selenium // Shared: run MH eligibility selenium job, return jobResult or throw
const handleEligibilityCheckSelenium = async () => { const runMHEligibilitySelenium = async (): Promise<any> => {
const formattedDob = dateOfBirth ? formatLocalDate(dateOfBirth) : ""; const formattedDob = dateOfBirth ? formatLocalDate(dateOfBirth) : "";
const data = { const data = {
@@ -125,7 +128,7 @@ export default function InsuranceStatusPage() {
firstName: firstName || undefined, firstName: firstName || undefined,
lastName: lastName || undefined, lastName: lastName || undefined,
}; };
try {
dispatch( dispatch(
setTaskStatus({ setTaskStatus({
key: "eligibilityCheck", key: "eligibilityCheck",
@@ -133,6 +136,7 @@ export default function InsuranceStatusPage() {
message: "Sending Data to Selenium...", message: "Sending Data to Selenium...",
}), }),
); );
const response = await apiRequest( const response = await apiRequest(
"POST", "POST",
"/api/insurance-status/eligibility-check", "/api/insurance-status/eligibility-check",
@@ -152,8 +156,7 @@ export default function InsuranceStatusPage() {
}), }),
); );
// Wait for the BullMQ worker to emit job:update on this socket return new Promise<any>((resolve, reject) => {
const jobResult = await new Promise<any>((resolve, reject) => {
const handler = (payload: any) => { const handler = (payload: any) => {
if (String(payload.jobId) !== String(jobId)) return; if (String(payload.jobId) !== String(jobId)) return;
if (payload.status === "active") { if (payload.status === "active") {
@@ -174,148 +177,6 @@ export default function InsuranceStatusPage() {
}; };
socket.on("job:update", handler); socket.on("job:update", handler);
}); });
dispatch(
setTaskStatus({
key: "eligibilityCheck",
status: "success",
message:
"Patient status is updated, and its eligibility pdf is uploaded at Document Page.",
}),
);
toast({
title: "Selenium service done.",
description:
"Your Patient Eligibility is fetched and updated, Kindly search through the patient.",
variant: "default",
});
setSelectedPatient(null);
// If worker returned pdfFileId: open preview modal
if (jobResult.pdfFileId) {
setPreviewPdfId(Number(jobResult.pdfFileId));
setPreviewFallbackFilename(
jobResult.pdfFilename ?? `eligibility_${memberId}.pdf`,
);
setPreviewOpen(true);
}
} catch (error: any) {
dispatch(
setTaskStatus({
key: "eligibilityCheck",
status: "error",
message: error.message || "Selenium submission failed",
}),
);
toast({
title: "Selenium service error",
description: error.message || "An error occurred.",
variant: "destructive",
});
}
};
// Claim Status Check Selenium
const handleStatusCheckSelenium = async () => {
const formattedDob = dateOfBirth ? formatLocalDate(dateOfBirth) : "";
const data = {
memberId,
dateOfBirth: formattedDob,
insuranceSiteKey: "MH",
};
try {
dispatch(
setTaskStatus({
key: "eligibilityCheck",
status: "pending",
message: "Sending Data to Selenium...",
}),
);
const response = await apiRequest(
"POST",
"/api/insurance-status/claim-status-check",
{ data: JSON.stringify(data), socketId: socket.id },
);
const enqueueResult = await response.json();
if (enqueueResult.error) throw new Error(enqueueResult.error);
const jobId = enqueueResult.jobId;
if (!jobId) throw new Error("No jobId returned from server");
dispatch(
setTaskStatus({
key: "eligibilityCheck",
status: "pending",
message: "Selenium browser starting...",
}),
);
// Wait for the BullMQ worker to emit job:update on this socket
const jobResult = await new Promise<any>((resolve, reject) => {
const handler = (payload: any) => {
if (String(payload.jobId) !== String(jobId)) return;
if (payload.status === "active") {
dispatch(
setTaskStatus({
key: "eligibilityCheck",
status: "pending",
message: payload.message ?? "Selenium running...",
}),
);
} else if (payload.status === "completed") {
socket.off("job:update", handler);
resolve(payload.result ?? {});
} else if (payload.status === "failed") {
socket.off("job:update", handler);
reject(new Error(payload.error ?? "Selenium job failed"));
}
};
socket.on("job:update", handler);
});
dispatch(
setTaskStatus({
key: "eligibilityCheck",
status: "success",
message:
"Claim status is updated, and its pdf is uploaded at Document Page.",
}),
);
toast({
title: "Selenium service done.",
description:
"Your Claim Status is fetched and updated, Kindly search through the patient.",
variant: "default",
});
setSelectedPatient(null);
// If worker returned pdfFileId: open preview modal
if (jobResult.pdfFileId) {
setPreviewPdfId(Number(jobResult.pdfFileId));
setPreviewFallbackFilename(
jobResult.pdfFilename ?? `eligibility_${memberId}.pdf`,
);
setPreviewOpen(true);
}
} catch (error: any) {
dispatch(
setTaskStatus({
key: "eligibilityCheck",
status: "error",
message: error.message || "Selenium submission failed",
}),
);
toast({
title: "Selenium service error",
description: error.message || "An error occurred.",
variant: "destructive",
});
}
}; };
const handleAddPatient = async () => { const handleAddPatient = async () => {
@@ -331,56 +192,125 @@ export default function InsuranceStatusPage() {
await addPatientMutation.mutateAsync(newPatient); await addPatientMutation.mutateAsync(newPatient);
}; };
// Handle insurance provider eligibility button clicks // MH Eligibility — check eligibility, save to DB, open PDF preview
const handleMHEligibilityButton = async () => { const handleMHEligibilityButton = async () => {
// Form Fields check
if (!memberId || !dateOfBirth) { if (!memberId || !dateOfBirth) {
toast({ toast({
title: "Missing Fields", title: "Missing Fields",
description: description: "Please fill in all the required fields: Member ID, Date of Birth.",
"Please fill in all the required fields: Member ID, Date of Birth.",
variant: "destructive", variant: "destructive",
}); });
return; return;
} }
setIsCheckingEligibilityStatus(true); setIsCheckingEligibilityStatus(true);
try { try {
await handleEligibilityCheckSelenium(); const jobResult = await runMHEligibilitySelenium();
dispatch(
setTaskStatus({
key: "eligibilityCheck",
status: "success",
message: "Patient status is updated, and its eligibility pdf is uploaded at Document Page.",
}),
);
toast({
title: "Selenium service done.",
description: "Your Patient Eligibility is fetched and updated, Kindly search through the patient.",
variant: "default",
});
setSelectedPatient(null);
await queryClient.invalidateQueries({ queryKey: QK_PATIENTS_BASE }); await queryClient.invalidateQueries({ queryKey: QK_PATIENTS_BASE });
if (jobResult.pdfFileId) {
setPreviewPdfId(Number(jobResult.pdfFileId));
setPreviewFallbackFilename(jobResult.pdfFilename ?? `eligibility_${memberId}.pdf`);
setPreviewOpen(true);
}
} catch (error: any) {
dispatch(setTaskStatus({ key: "eligibilityCheck", status: "error", message: error.message || "Selenium submission failed" }));
toast({ title: "Selenium service error", description: error.message || "An error occurred.", variant: "destructive" });
} finally { } finally {
setIsCheckingEligibilityStatus(false); setIsCheckingEligibilityStatus(false);
} }
}; };
// Handle insurance provider Status Check button clicks // MH Eligibility & Appointment — check eligibility, save to DB, navigate to appointments
const handleMHStatusButton = async () => { const handleMHEligibilityAppointmentButton = async () => {
// Form Fields check if (!memberId || !dateOfBirth) {
if (!memberId || !dateOfBirth || !firstName) {
toast({ toast({
title: "Missing Fields", title: "Missing Fields",
description: description: "Please fill in all the required fields: Member ID, Date of Birth.",
"Please fill in all the required fields: Member ID, Date of Birth, First Name.",
variant: "destructive", variant: "destructive",
}); });
return; return;
} }
setIsCheckingClaimStatus(true); setIsCheckingEligibilityAppointment(true);
// Adding patient if same patient exists then it will skip.
try { try {
if (!selectedPatient) { await runMHEligibilitySelenium();
await handleAddPatient();
dispatch(
setTaskStatus({
key: "eligibilityCheck",
status: "success",
message: "Eligibility checked and saved. Redirecting to Appointments...",
}),
);
toast({
title: "Eligibility checked.",
description: "Patient eligibility saved. Redirecting to Appointments.",
variant: "default",
});
setSelectedPatient(null);
await queryClient.invalidateQueries({ queryKey: QK_PATIENTS_BASE });
setLocation("/appointments");
} catch (error: any) {
dispatch(setTaskStatus({ key: "eligibilityCheck", status: "error", message: error.message || "Selenium submission failed" }));
toast({ title: "Selenium service error", description: error.message || "An error occurred.", variant: "destructive" });
} finally {
setIsCheckingEligibilityAppointment(false);
}
};
// MH Eligibility & Claims/PreAuth — check eligibility, save to DB, navigate to claims
const handleMHEligibilityClaimsPreAuthButton = async () => {
if (!memberId || !dateOfBirth) {
toast({
title: "Missing Fields",
description: "Please fill in all the required fields: Member ID, Date of Birth.",
variant: "destructive",
});
return;
} }
await handleStatusCheckSelenium(); setIsCheckingEligibilityClaimsPreAuth(true);
try {
await runMHEligibilitySelenium();
dispatch(
setTaskStatus({
key: "eligibilityCheck",
status: "success",
message: "Eligibility checked and saved. Redirecting to Claims/PreAuth...",
}),
);
toast({
title: "Eligibility checked.",
description: "Patient eligibility saved. Redirecting to Claims/PreAuth.",
variant: "default",
});
setSelectedPatient(null);
await queryClient.invalidateQueries({ queryKey: QK_PATIENTS_BASE }); await queryClient.invalidateQueries({ queryKey: QK_PATIENTS_BASE });
setLocation("/claims");
} catch (error: any) {
dispatch(setTaskStatus({ key: "eligibilityCheck", status: "error", message: error.message || "Selenium submission failed" }));
toast({ title: "Selenium service error", description: error.message || "An error occurred.", variant: "destructive" });
} finally { } finally {
setIsCheckingClaimStatus(false); setIsCheckingEligibilityClaimsPreAuth(false);
} }
}; };
@@ -585,11 +515,11 @@ export default function InsuranceStatusPage() {
</Button> </Button>
<Button <Button
onClick={() => handleMHStatusButton()} onClick={() => handleMHEligibilityAppointmentButton()}
className="w-full" className="w-full"
disabled={isCheckingClaimStatus} disabled={isCheckingEligibilityAppointment}
> >
{isCheckingClaimStatus ? ( {isCheckingEligibilityAppointment ? (
<> <>
<LoaderCircleIcon className="h-4 w-4 mr-2 animate-spin" /> <LoaderCircleIcon className="h-4 w-4 mr-2 animate-spin" />
Processing... Processing...
@@ -597,7 +527,25 @@ export default function InsuranceStatusPage() {
) : ( ) : (
<> <>
<CheckCircle className="h-4 w-4 mr-2" /> <CheckCircle className="h-4 w-4 mr-2" />
MH Status MH Eligibility&Appointment
</>
)}
</Button>
<Button
onClick={() => handleMHEligibilityClaimsPreAuthButton()}
className="w-full"
disabled={isCheckingEligibilityClaimsPreAuth}
>
{isCheckingEligibilityClaimsPreAuth ? (
<>
<LoaderCircleIcon className="h-4 w-4 mr-2 animate-spin" />
Processing...
</>
) : (
<>
<CheckCircle className="h-4 w-4 mr-2" />
MH Eligibility&Claims/PreAuth
</> </>
)} )}
</Button> </Button>