feat: rename MH Status to MH Eligibility&Appointment, add MH Eligibility&Claims/PreAuth button
This commit is contained in:
@@ -42,7 +42,7 @@ export default function InsuranceStatusPage() {
|
||||
(state) => state.seleniumTasks.eligibilityCheck,
|
||||
);
|
||||
const [selectedPatient, setSelectedPatient] = useState<Patient | null>(null);
|
||||
const [location] = useLocation();
|
||||
const [location, setLocation] = useLocation();
|
||||
|
||||
// Insurance eligibility and claim check form fields
|
||||
const [memberId, setMemberId] = useState("");
|
||||
@@ -52,7 +52,10 @@ export default function InsuranceStatusPage() {
|
||||
const isFormIncomplete = !memberId || !dateOfBirth;
|
||||
const [isCheckingEligibilityStatus, setIsCheckingEligibilityStatus] =
|
||||
useState(false);
|
||||
const [isCheckingClaimStatus, setIsCheckingClaimStatus] = useState(false);
|
||||
const [isCheckingEligibilityAppointment, setIsCheckingEligibilityAppointment] =
|
||||
useState(false);
|
||||
const [isCheckingEligibilityClaimsPreAuth, setIsCheckingEligibilityClaimsPreAuth] =
|
||||
useState(false);
|
||||
|
||||
// PDF preview modal state
|
||||
const [previewOpen, setPreviewOpen] = useState(false);
|
||||
@@ -114,8 +117,8 @@ export default function InsuranceStatusPage() {
|
||||
},
|
||||
});
|
||||
|
||||
// handle eligibility selenium
|
||||
const handleEligibilityCheckSelenium = async () => {
|
||||
// Shared: run MH eligibility selenium job, return jobResult or throw
|
||||
const runMHEligibilitySelenium = async (): Promise<any> => {
|
||||
const formattedDob = dateOfBirth ? formatLocalDate(dateOfBirth) : "";
|
||||
|
||||
const data = {
|
||||
@@ -125,7 +128,7 @@ export default function InsuranceStatusPage() {
|
||||
firstName: firstName || undefined,
|
||||
lastName: lastName || undefined,
|
||||
};
|
||||
try {
|
||||
|
||||
dispatch(
|
||||
setTaskStatus({
|
||||
key: "eligibilityCheck",
|
||||
@@ -133,6 +136,7 @@ export default function InsuranceStatusPage() {
|
||||
message: "Sending Data to Selenium...",
|
||||
}),
|
||||
);
|
||||
|
||||
const response = await apiRequest(
|
||||
"POST",
|
||||
"/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
|
||||
const jobResult = await new Promise<any>((resolve, reject) => {
|
||||
return new Promise<any>((resolve, reject) => {
|
||||
const handler = (payload: any) => {
|
||||
if (String(payload.jobId) !== String(jobId)) return;
|
||||
if (payload.status === "active") {
|
||||
@@ -174,148 +177,6 @@ export default function InsuranceStatusPage() {
|
||||
};
|
||||
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 () => {
|
||||
@@ -331,56 +192,125 @@ export default function InsuranceStatusPage() {
|
||||
await addPatientMutation.mutateAsync(newPatient);
|
||||
};
|
||||
|
||||
// Handle insurance provider eligibility button clicks
|
||||
// MH Eligibility — check eligibility, save to DB, open PDF preview
|
||||
const handleMHEligibilityButton = async () => {
|
||||
// Form Fields check
|
||||
if (!memberId || !dateOfBirth) {
|
||||
toast({
|
||||
title: "Missing Fields",
|
||||
description:
|
||||
"Please fill in all the required fields: Member ID, Date of Birth.",
|
||||
description: "Please fill in all the required fields: Member ID, Date of Birth.",
|
||||
variant: "destructive",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
setIsCheckingEligibilityStatus(true);
|
||||
|
||||
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 });
|
||||
|
||||
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 {
|
||||
setIsCheckingEligibilityStatus(false);
|
||||
}
|
||||
};
|
||||
|
||||
// Handle insurance provider Status Check button clicks
|
||||
const handleMHStatusButton = async () => {
|
||||
// Form Fields check
|
||||
if (!memberId || !dateOfBirth || !firstName) {
|
||||
// MH Eligibility & Appointment — check eligibility, save to DB, navigate to appointments
|
||||
const handleMHEligibilityAppointmentButton = async () => {
|
||||
if (!memberId || !dateOfBirth) {
|
||||
toast({
|
||||
title: "Missing Fields",
|
||||
description:
|
||||
"Please fill in all the required fields: Member ID, Date of Birth, First Name.",
|
||||
description: "Please fill in all the required fields: Member ID, Date of Birth.",
|
||||
variant: "destructive",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
setIsCheckingClaimStatus(true);
|
||||
|
||||
// Adding patient if same patient exists then it will skip.
|
||||
setIsCheckingEligibilityAppointment(true);
|
||||
try {
|
||||
if (!selectedPatient) {
|
||||
await handleAddPatient();
|
||||
await runMHEligibilitySelenium();
|
||||
|
||||
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 });
|
||||
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 {
|
||||
setIsCheckingClaimStatus(false);
|
||||
setIsCheckingEligibilityClaimsPreAuth(false);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -585,11 +515,11 @@ export default function InsuranceStatusPage() {
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
onClick={() => handleMHStatusButton()}
|
||||
onClick={() => handleMHEligibilityAppointmentButton()}
|
||||
className="w-full"
|
||||
disabled={isCheckingClaimStatus}
|
||||
disabled={isCheckingEligibilityAppointment}
|
||||
>
|
||||
{isCheckingClaimStatus ? (
|
||||
{isCheckingEligibilityAppointment ? (
|
||||
<>
|
||||
<LoaderCircleIcon className="h-4 w-4 mr-2 animate-spin" />
|
||||
Processing...
|
||||
@@ -597,7 +527,25 @@ export default function InsuranceStatusPage() {
|
||||
) : (
|
||||
<>
|
||||
<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>
|
||||
|
||||
Reference in New Issue
Block a user