diff --git a/apps/Frontend/src/components/claims/claims-recent-table.tsx b/apps/Frontend/src/components/claims/claims-recent-table.tsx
index 637a10d..3fb6de7 100755
--- a/apps/Frontend/src/components/claims/claims-recent-table.tsx
+++ b/apps/Frontend/src/components/claims/claims-recent-table.tsx
@@ -20,7 +20,7 @@ import {
import { apiRequest, queryClient } from "@/lib/queryClient";
import { useToast } from "@/hooks/use-toast";
import { useAppDispatch } from "@/redux/hooks";
-import { setTaskStatus } from "@/redux/slices/seleniumClaimSubmitTaskSlice";
+import { setTaskStatus } from "@/redux/slices/seleniumTaskSlice";
import {
Pagination,
PaginationContent,
@@ -473,6 +473,7 @@ export default function ClaimsRecentTable({
try {
dispatch(
setTaskStatus({
+ key: "claimSubmit",
status: "pending",
message: "Sending Data to Selenium...",
})
@@ -499,6 +500,7 @@ export default function ClaimsRecentTable({
if (data?.status === "success") {
dispatch(
setTaskStatus({
+ key: "claimSubmit",
status: "success",
message: "Claims automation completed. Browser remains open.",
})
@@ -509,6 +511,7 @@ export default function ClaimsRecentTable({
} catch {
dispatch(
setTaskStatus({
+ key: "claimSubmit",
status: "error",
message: "Selenium submission failed",
})
diff --git a/apps/Frontend/src/components/insurance-status/ddma-buton-modal.tsx b/apps/Frontend/src/components/insurance-status/ddma-buton-modal.tsx
index 061f67d..9d39337 100755
--- a/apps/Frontend/src/components/insurance-status/ddma-buton-modal.tsx
+++ b/apps/Frontend/src/components/insurance-status/ddma-buton-modal.tsx
@@ -7,7 +7,7 @@ import { CheckCircle, LoaderCircleIcon, X } from "lucide-react";
import { useToast } from "@/hooks/use-toast";
import { apiRequest, queryClient } from "@/lib/queryClient";
import { useAppDispatch } from "@/redux/hooks";
-import { setTaskStatus } from "@/redux/slices/seleniumEligibilityCheckTaskSlice";
+import { setTaskStatus } from "@/redux/slices/seleniumTaskSlice";
import { formatLocalDate } from "@/utils/dateUtils";
import { QK_PATIENTS_BASE } from "@/components/patients/patient-table";
@@ -178,6 +178,7 @@ export function DdmaEligibilityButton({
socket.on("connect_error", (err: any) => {
dispatch(
setTaskStatus({
+ key: "eligibilityCheck",
status: "error",
message: "Connection failed",
})
@@ -195,6 +196,7 @@ export function DdmaEligibilityButton({
socket.on("reconnect_attempt", (attempt: number) => {
dispatch(
setTaskStatus({
+ key: "eligibilityCheck",
status: "pending",
message: `Realtime reconnect attempt #${attempt}`,
})
@@ -205,6 +207,7 @@ export function DdmaEligibilityButton({
socket.on("reconnect_failed", () => {
dispatch(
setTaskStatus({
+ key: "eligibilityCheck",
status: "error",
message: "Reconnect failed",
})
@@ -223,6 +226,7 @@ export function DdmaEligibilityButton({
socket.on("disconnect", (reason: any) => {
dispatch(
setTaskStatus({
+ key: "eligibilityCheck",
status: "error",
message: "Connection disconnected",
})
@@ -245,6 +249,7 @@ export function DdmaEligibilityButton({
setOtpModalOpen(true);
dispatch(
setTaskStatus({
+ key: "eligibilityCheck",
status: "pending",
message: "OTP required for DDMA eligibility. Please enter the OTP.",
})
@@ -256,6 +261,7 @@ export function DdmaEligibilityButton({
if (!payload?.session_id) return;
dispatch(
setTaskStatus({
+ key: "eligibilityCheck",
status: "pending",
message: "OTP submitted. Finishing DDMA eligibility check...",
})
@@ -270,6 +276,7 @@ export function DdmaEligibilityButton({
if (status === "completed") {
dispatch(
setTaskStatus({
+ key: "eligibilityCheck",
status: "success",
message:
"DDMA eligibility updated and PDF attached to patient documents.",
@@ -298,6 +305,7 @@ export function DdmaEligibilityButton({
"DDMA eligibility session failed.";
dispatch(
setTaskStatus({
+ key: "eligibilityCheck",
status: "error",
message: msg,
})
@@ -325,6 +333,7 @@ export function DdmaEligibilityButton({
dispatch(
setTaskStatus({
+ key: "eligibilityCheck",
status: "error",
message: msg,
})
@@ -396,6 +405,7 @@ export function DdmaEligibilityButton({
// 1) Ensure socket is connected (lazy)
dispatch(
setTaskStatus({
+ key: "eligibilityCheck",
status: "pending",
message: "Opening realtime channel for DDMA eligibility...",
})
@@ -412,6 +422,7 @@ export function DdmaEligibilityButton({
// 2) Start the selenium job via backend
dispatch(
setTaskStatus({
+ key: "eligibilityCheck",
status: "pending",
message: "Starting DDMA eligibility check via selenium...",
})
@@ -461,6 +472,7 @@ export function DdmaEligibilityButton({
setSessionId(result.session_id as string);
dispatch(
setTaskStatus({
+ key: "eligibilityCheck",
status: "pending",
message:
"DDMA eligibility job started. Waiting for OTP or final result...",
@@ -470,6 +482,7 @@ export function DdmaEligibilityButton({
// fallback if backend returns immediate result
dispatch(
setTaskStatus({
+ key: "eligibilityCheck",
status: "success",
message: "DDMA eligibility completed.",
})
@@ -479,6 +492,7 @@ export function DdmaEligibilityButton({
console.error("startDdmaEligibility error:", err);
dispatch(
setTaskStatus({
+ key: "eligibilityCheck",
status: "error",
message: err?.message || "Failed to start DDMA eligibility",
})
diff --git a/apps/Frontend/src/pages/appointments-page.tsx b/apps/Frontend/src/pages/appointments-page.tsx
index 94f57b3..b6815c9 100755
--- a/apps/Frontend/src/pages/appointments-page.tsx
+++ b/apps/Frontend/src/pages/appointments-page.tsx
@@ -50,7 +50,7 @@ import { useAppDispatch, useAppSelector } from "@/redux/hooks";
import {
clearTaskStatus,
setTaskStatus,
-} from "@/redux/slices/seleniumEligibilityBatchCheckTaskSlice";
+} from "@/redux/slices/seleniumTaskSlice";
import { SeleniumTaskBanner } from "@/components/ui/selenium-task-banner";
import { PatientStatusBadge } from "@/components/appointments/patient-status-badge";
import { AppointmentProceduresDialog } from "@/components/appointment-procedures/appointment-procedures-dialog";
@@ -117,7 +117,7 @@ export default function AppointmentsPage() {
}>({ open: false });
const dispatch = useAppDispatch();
const batchTask = useAppSelector(
- (state) => state.seleniumEligibilityBatchCheckTask
+ (state) => state.seleniumTasks.eligibilityBatchCheck
);
const [isCheckingAllElig, setIsCheckingAllElig] = useState(false);
const [processedAppointmentIds, setProcessedAppointmentIds] = useState<
@@ -743,6 +743,7 @@ export default function AppointmentsPage() {
// Start: set redux task status (visible globally)
dispatch(
setTaskStatus({
+ key: "eligibilityBatchCheck",
status: "pending",
message: `Checking eligibility for appointments on ${dateParam}...`,
})
@@ -771,6 +772,7 @@ export default function AppointmentsPage() {
// global error
dispatch(
setTaskStatus({
+ key: "eligibilityBatchCheck",
status: "error",
message: `Batch eligibility failed: ${errMsg}`,
})
@@ -849,6 +851,7 @@ export default function AppointmentsPage() {
// global success status (summary)
dispatch(
setTaskStatus({
+ key: "eligibilityBatchCheck",
status: skippedCount > 0 ? "error" : "success",
message: `Batch processed ${results.length} appointments — success: ${successCount}, warnings: ${warningCount}, skipped: ${skippedCount}.`,
})
@@ -864,6 +867,7 @@ export default function AppointmentsPage() {
console.error("[check-all-eligibilities] error", err);
dispatch(
setTaskStatus({
+ key: "eligibilityBatchCheck",
status: "error",
message: `Batch eligibility error: ${err?.message ?? String(err)}`,
})
@@ -912,7 +916,7 @@ export default function AppointmentsPage() {
status={batchTask.status}
message={batchTask.message}
show={batchTask.show}
- onClear={() => dispatch(clearTaskStatus())}
+ onClear={() => dispatch(clearTaskStatus("eligibilityBatchCheck"))}
/>
diff --git a/apps/Frontend/src/pages/claims-page.tsx b/apps/Frontend/src/pages/claims-page.tsx
index 758c892..f9db03a 100755
--- a/apps/Frontend/src/pages/claims-page.tsx
+++ b/apps/Frontend/src/pages/claims-page.tsx
@@ -16,7 +16,7 @@ import { useAppDispatch, useAppSelector } from "@/redux/hooks";
import {
setTaskStatus,
clearTaskStatus,
-} from "@/redux/slices/seleniumClaimSubmitTaskSlice";
+} from "@/redux/slices/seleniumTaskSlice";
import { SeleniumTaskBanner } from "@/components/ui/selenium-task-banner";
import ClaimsRecentTable, {
QK_CLAIMS_BASE,
@@ -47,7 +47,7 @@ export default function ClaimsPage() {
const [previewFallbackFilename, setPreviewFallbackFilename] = useState
(null);
const dispatch = useAppDispatch();
const { status, message, show } = useAppSelector(
- (state) => state.seleniumClaimSubmitTask
+ (state) => state.seleniumTasks.claimSubmit
);
const { toast } = useToast();
const { user } = useAuth();
@@ -318,6 +318,7 @@ export default function ClaimsPage() {
try {
dispatch(
setTaskStatus({
+ key: "claimSubmit",
status: "pending",
message: "Submitting claim to Selenium...",
})
@@ -336,6 +337,7 @@ export default function ClaimsPage() {
dispatch(
setTaskStatus({
+ key: "claimSubmit",
status: "pending",
message: "Submitted to Selenium. Awaiting PDF...",
})
@@ -357,6 +359,7 @@ export default function ClaimsPage() {
} catch (error: any) {
dispatch(
setTaskStatus({
+ key: "claimSubmit",
status: "error",
message: error.message || "Selenium submission failed",
})
@@ -382,6 +385,7 @@ export default function ClaimsPage() {
dispatch(
setTaskStatus({
+ key: "claimSubmit",
status: "pending",
message: "Downloading PDF from Selenium...",
})
@@ -402,6 +406,7 @@ export default function ClaimsPage() {
dispatch(
setTaskStatus({
+ key: "claimSubmit",
status: "success",
message: "Claim submitted & PDF downloaded successfully.",
})
@@ -418,6 +423,7 @@ export default function ClaimsPage() {
} catch (error: any) {
dispatch(
setTaskStatus({
+ key: "claimSubmit",
status: "error",
message: error.message || "Failed to download PDF",
})
@@ -456,6 +462,7 @@ export default function ClaimsPage() {
try {
dispatch(
setTaskStatus({
+ key: "claimSubmit",
status: "pending",
message: "Submitting claim pre auth to Selenium...",
})
@@ -470,6 +477,7 @@ export default function ClaimsPage() {
dispatch(
setTaskStatus({
+ key: "claimSubmit",
status: "pending",
message: "Submitted to Selenium. Awaiting PDF...",
})
@@ -491,6 +499,7 @@ export default function ClaimsPage() {
} catch (error: any) {
dispatch(
setTaskStatus({
+ key: "claimSubmit",
status: "error",
message: error.message || "Selenium submission failed",
})
@@ -508,7 +517,7 @@ export default function ClaimsPage() {
status={status}
message={message}
show={show}
- onClear={() => dispatch(clearTaskStatus())}
+ onClear={() => dispatch(clearTaskStatus("claimSubmit"))}
/>
diff --git a/apps/Frontend/src/pages/insurance-status-page.tsx b/apps/Frontend/src/pages/insurance-status-page.tsx
index 9de0174..1fa411c 100755
--- a/apps/Frontend/src/pages/insurance-status-page.tsx
+++ b/apps/Frontend/src/pages/insurance-status-page.tsx
@@ -19,7 +19,7 @@ import { useAppDispatch, useAppSelector } from "@/redux/hooks";
import {
setTaskStatus,
clearTaskStatus,
-} from "@/redux/slices/seleniumEligibilityCheckTaskSlice";
+} from "@/redux/slices/seleniumTaskSlice";
import { SeleniumTaskBanner } from "@/components/ui/selenium-task-banner";
import { formatLocalDate, parseLocalDate } from "@/utils/dateUtils";
import { InsertPatient, Patient } from "@repo/db/types";
@@ -34,7 +34,7 @@ export default function InsuranceStatusPage() {
const { toast } = useToast();
const dispatch = useAppDispatch();
const { status, message, show } = useAppSelector(
- (state) => state.seleniumEligibilityCheckTask,
+ (state) => state.seleniumTasks.eligibilityCheck,
);
const [selectedPatient, setSelectedPatient] = useState
(null);
const [location] = useLocation();
@@ -121,6 +121,7 @@ export default function InsuranceStatusPage() {
try {
dispatch(
setTaskStatus({
+ key: "eligibilityCheck",
status: "pending",
message: "Sending Data to Selenium...",
}),
@@ -136,6 +137,7 @@ export default function InsuranceStatusPage() {
dispatch(
setTaskStatus({
+ key: "eligibilityCheck",
status: "success",
message:
"Patient status is updated, and its eligibility pdf is uploaded at Document Page.",
@@ -163,6 +165,7 @@ export default function InsuranceStatusPage() {
} catch (error: any) {
dispatch(
setTaskStatus({
+ key: "eligibilityCheck",
status: "error",
message: error.message || "Selenium submission failed",
}),
@@ -187,6 +190,7 @@ export default function InsuranceStatusPage() {
try {
dispatch(
setTaskStatus({
+ key: "eligibilityCheck",
status: "pending",
message: "Sending Data to Selenium...",
}),
@@ -201,6 +205,7 @@ export default function InsuranceStatusPage() {
dispatch(
setTaskStatus({
+ key: "eligibilityCheck",
status: "success",
message:
"Claim status is updated, and its pdf is uploaded at Document Page.",
@@ -228,6 +233,7 @@ export default function InsuranceStatusPage() {
} catch (error: any) {
dispatch(
setTaskStatus({
+ key: "eligibilityCheck",
status: "error",
message: error.message || "Selenium submission failed",
}),
@@ -426,7 +432,7 @@ export default function InsuranceStatusPage() {
status={status}
message={message}
show={show}
- onClear={() => dispatch(clearTaskStatus())}
+ onClear={() => dispatch(clearTaskStatus("eligibilityCheck"))}
/>
diff --git a/apps/Frontend/src/redux/slices/seleniumClaimSubmitTaskSlice.ts b/apps/Frontend/src/redux/slices/seleniumClaimSubmitTaskSlice.ts
deleted file mode 100755
index b76e738..0000000
--- a/apps/Frontend/src/redux/slices/seleniumClaimSubmitTaskSlice.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import { createSlice, PayloadAction } from "@reduxjs/toolkit";
-
-export type TaskStatus = "idle" | "pending" | "success" | "error";
-
-export interface SeleniumTaskState {
- status: TaskStatus;
- message: string;
- show: boolean;
-}
-
-const initialState: SeleniumTaskState = {
- status: "idle",
- message: "",
- show: false,
-};
-
-const seleniumClaimSubmitTaskSlice = createSlice({
- name: "seleniumClaimSubmitTask",
- initialState,
- reducers: {
- setTaskStatus: (
- state: SeleniumTaskState,
- action: PayloadAction
>
- ) => {
- return { ...state, ...action.payload, show: true };
- },
- clearTaskStatus: () => initialState,
- },
-});
-
-export const { setTaskStatus, clearTaskStatus } = seleniumClaimSubmitTaskSlice.actions;
-export default seleniumClaimSubmitTaskSlice.reducer;
diff --git a/apps/Frontend/src/redux/slices/seleniumEligibilityBatchCheckTaskSlice.ts b/apps/Frontend/src/redux/slices/seleniumEligibilityBatchCheckTaskSlice.ts
deleted file mode 100755
index 1ed8747..0000000
--- a/apps/Frontend/src/redux/slices/seleniumEligibilityBatchCheckTaskSlice.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import { createSlice, PayloadAction } from "@reduxjs/toolkit";
-
-export type TaskStatus = "idle" | "pending" | "success" | "error";
-
-export interface SeleniumTaskState {
- status: TaskStatus;
- message: string;
- show: boolean;
-}
-
-const initialState: SeleniumTaskState = {
- status: "idle",
- message: "",
- show: false,
-};
-
-const seleniumEligibilityBatchCheckTaskSlice = createSlice({
- name: "seleniumEligibilityBatchCheckTask",
- initialState,
- reducers: {
- setTaskStatus: (
- state: SeleniumTaskState,
- action: PayloadAction>
- ) => {
- return { ...state, ...action.payload, show: true };
- },
- clearTaskStatus: () => initialState,
- },
-});
-
-export const { setTaskStatus, clearTaskStatus } = seleniumEligibilityBatchCheckTaskSlice.actions;
-export default seleniumEligibilityBatchCheckTaskSlice.reducer;
diff --git a/apps/Frontend/src/redux/slices/seleniumEligibilityCheckTaskSlice.ts b/apps/Frontend/src/redux/slices/seleniumEligibilityCheckTaskSlice.ts
deleted file mode 100755
index 7e77e32..0000000
--- a/apps/Frontend/src/redux/slices/seleniumEligibilityCheckTaskSlice.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-import { createSlice, PayloadAction } from "@reduxjs/toolkit";
-
-export type TaskStatus = "idle" | "pending" | "success" | "error";
-
-export interface SeleniumTaskState {
- status: TaskStatus;
- message: string;
- show: boolean;
-}
-
-const initialState: SeleniumTaskState = {
- status: "idle",
- message: "",
- show: false,
-};
-
-const seleniumEligibilityCheckTaskSlice = createSlice({
- name: "seleniumEligibilityCheckTask",
- initialState,
- reducers: {
- setTaskStatus: (
- state: SeleniumTaskState,
- action: PayloadAction>
- ) => {
- return { ...state, ...action.payload, show: true };
- },
- clearTaskStatus: () => initialState,
- },
-});
-
-export const { setTaskStatus, clearTaskStatus } = seleniumEligibilityCheckTaskSlice.actions;
-export default seleniumEligibilityCheckTaskSlice.reducer;
diff --git a/apps/Frontend/src/redux/slices/seleniumTaskSlice.ts b/apps/Frontend/src/redux/slices/seleniumTaskSlice.ts
new file mode 100644
index 0000000..07e401d
--- /dev/null
+++ b/apps/Frontend/src/redux/slices/seleniumTaskSlice.ts
@@ -0,0 +1,38 @@
+import { createSlice, PayloadAction } from "@reduxjs/toolkit";
+
+export type TaskStatus = "idle" | "pending" | "success" | "error";
+export type TaskKey = "claimSubmit" | "eligibilityCheck" | "eligibilityBatchCheck";
+
+export interface SeleniumTaskState {
+ status: TaskStatus;
+ message: string;
+ show: boolean;
+}
+
+const emptyTask: SeleniumTaskState = { status: "idle", message: "", show: false };
+
+const initialState: Record = {
+ claimSubmit: { ...emptyTask },
+ eligibilityCheck: { ...emptyTask },
+ eligibilityBatchCheck: { ...emptyTask },
+};
+
+const seleniumTaskSlice = createSlice({
+ name: "seleniumTasks",
+ initialState,
+ reducers: {
+ setTaskStatus: (
+ state,
+ action: PayloadAction<{ key: TaskKey } & Partial>
+ ) => {
+ const { key, ...partial } = action.payload;
+ state[key] = { ...state[key], ...partial, show: true };
+ },
+ clearTaskStatus: (state, action: PayloadAction) => {
+ state[action.payload] = { ...emptyTask };
+ },
+ },
+});
+
+export const { setTaskStatus, clearTaskStatus } = seleniumTaskSlice.actions;
+export default seleniumTaskSlice.reducer;
diff --git a/apps/Frontend/src/redux/store.ts b/apps/Frontend/src/redux/store.ts
index be26cd5..83812f9 100755
--- a/apps/Frontend/src/redux/store.ts
+++ b/apps/Frontend/src/redux/store.ts
@@ -1,13 +1,9 @@
import { configureStore } from "@reduxjs/toolkit";
-import seleniumClaimSubmitTaskReducer from "./slices/seleniumClaimSubmitTaskSlice";
-import seleniumEligibilityCheckTaskReducer from "./slices/seleniumEligibilityCheckTaskSlice";
-import seleniumEligibilityBatchCheckTaskReducer from "./slices/seleniumEligibilityBatchCheckTaskSlice";
+import seleniumTasksReducer from "./slices/seleniumTaskSlice";
export const store = configureStore({
reducer: {
- seleniumClaimSubmitTask: seleniumClaimSubmitTaskReducer,
- seleniumEligibilityCheckTask: seleniumEligibilityCheckTaskReducer,
- seleniumEligibilityBatchCheckTask: seleniumEligibilityBatchCheckTaskReducer,
+ seleniumTasks: seleniumTasksReducer,
},
});