From e8151ce43096a6438533e3856af1bd32479c3307 Mon Sep 17 00:00:00 2001 From: Potenz Date: Sun, 21 Sep 2025 03:47:17 +0530 Subject: [PATCH] feat(eligibility-check) - appointment page redirecting to eligibility page --- apps/Backend/src/routes/appointments.ts | 34 +++++++++++ apps/Backend/src/storage/index.ts | 13 +++++ apps/Frontend/src/pages/appointments-page.tsx | 6 +- .../src/pages/insurance-status-page.tsx | 58 ++++++++++++++++++- 4 files changed, 107 insertions(+), 4 deletions(-) diff --git a/apps/Backend/src/routes/appointments.ts b/apps/Backend/src/routes/appointments.ts index adc8c5d..9f1568c 100644 --- a/apps/Backend/src/routes/appointments.ts +++ b/apps/Backend/src/routes/appointments.ts @@ -131,6 +131,40 @@ router.get( } ); +/** + * GET /api/appointments/:id/patient + */ +router.get( + "/:id/patient", + async (req: Request, res: Response): Promise => { + try { + const rawId = req.params.id; + if (!rawId) { + return res.status(400).json({ message: "Appointment ID is required" }); + } + + const apptId = parseInt(rawId, 10); + if (Number.isNaN(apptId) || apptId <= 0) { + return res.status(400).json({ message: "Invalid appointment ID" }); + } + + const patient = await storage.getPatientFromAppointmentId(apptId); + + if (!patient) { + return res + .status(404) + .json({ message: "Patient not found for the given appointment" }); + } + + return res.json(patient); + } catch (err) { + return res + .status(500) + .json({ message: "Failed to retrieve patient for appointment" }); + } + } +); + // Create a new appointment router.post( "/upsert", diff --git a/apps/Backend/src/storage/index.ts b/apps/Backend/src/storage/index.ts index 2c66068..4150b61 100644 --- a/apps/Backend/src/storage/index.ts +++ b/apps/Backend/src/storage/index.ts @@ -70,6 +70,9 @@ export interface IStorage { getAllAppointments(): Promise; getAppointmentsByUserId(userId: number): Promise; getAppointmentsByPatientId(patientId: number): Promise; + getPatientFromAppointmentId( + appointmentId: number + ): Promise; getRecentAppointments(limit: number, offset: number): Promise; getAppointmentsOnRange(start: Date, end: Date): Promise; createAppointment(appointment: InsertAppointment): Promise; @@ -393,6 +396,16 @@ export const storage: IStorage = { return await db.appointment.findMany({ where: { patientId } }); }, + async getPatientFromAppointmentId( + appointmentId: number + ): Promise { + const appointment = await db.appointment.findUnique({ + where: { id: appointmentId }, + include: { patient: true }, + }); + return appointment?.patient ?? undefined; + }, + async getAppointmentsOnRange(start: Date, end: Date): Promise { return db.appointment.findMany({ where: { diff --git a/apps/Frontend/src/pages/appointments-page.tsx b/apps/Frontend/src/pages/appointments-page.tsx index dba54f3..d322378 100644 --- a/apps/Frontend/src/pages/appointments-page.tsx +++ b/apps/Frontend/src/pages/appointments-page.tsx @@ -15,8 +15,6 @@ import { ChevronRight, Move, Trash2, - ShieldCheck, - FileText, CreditCard, ClipboardList, StickyNote, @@ -95,6 +93,8 @@ export default function AppointmentsPage() { appointmentId?: number; }>({ open: false }); + const [, setLocation] = useLocation(); + // Create context menu hook const { show } = useContextMenu({ id: APPOINTMENT_CONTEXT_MENU_ID, @@ -652,7 +652,7 @@ export default function AppointmentsPage() { // ------------------- const handleCheckEligibility = (appointmentId: number) => { - console.log(`Checking eligibility for appointment: ${appointmentId}`); + setLocation(`/insurance-status?appointmentId=${appointmentId}`); }; const handleClaimsPreAuth = (appointmentId: number) => { diff --git a/apps/Frontend/src/pages/insurance-status-page.tsx b/apps/Frontend/src/pages/insurance-status-page.tsx index db4334a..0b7c68d 100644 --- a/apps/Frontend/src/pages/insurance-status-page.tsx +++ b/apps/Frontend/src/pages/insurance-status-page.tsx @@ -26,8 +26,9 @@ import { InsertPatient, Patient } from "@repo/db/types"; import { DateInput } from "@/components/ui/dateInput"; import { QK_PATIENTS_BASE } from "@/components/patients/patient-table"; import { PdfPreviewModal } from "@/components/insurance-status/pdf-preview-modal"; +import { useLocation } from "wouter"; -export default function EligibilityClaimStatusPage() { +export default function InsuranceStatusPage() { const { user } = useAuth(); const { toast } = useToast(); const dispatch = useAppDispatch(); @@ -35,6 +36,7 @@ export default function EligibilityClaimStatusPage() { (state) => state.seleniumEligibilityCheckTask ); const [selectedPatient, setSelectedPatient] = useState(null); + const [location] = useLocation(); // Insurance eligibility and claim check form fields const [memberId, setMemberId] = useState(""); @@ -303,6 +305,60 @@ export default function EligibilityClaimStatusPage() { } }; + useEffect(() => { + const params = new URLSearchParams(window.location.search); + const appointmentId = params.get("appointmentId"); + if (!appointmentId) return; + + const id = Number(appointmentId); + if (Number.isNaN(id) || id <= 0) return; + + let cancelled = false; + + (async () => { + try { + const res = await apiRequest("GET", `/api/appointments/${id}/patient`); + if (!res.ok) { + // try to read body for a helpful error message, otherwise show generic + let body: any = null; + try { + body = await res.json(); + } catch {} + if (!cancelled) { + toast({ + title: "Failed to load patient", + description: + body?.message ?? + body?.error ?? + `Could not fetch patient for appointment ${id}.`, + variant: "destructive", + }); + } + return; + } + + const data = await res.json(); + // endpoint may return either { patient } or patient object directly + const patient = data?.patient ?? data; + if (!cancelled && patient) setSelectedPatient(patient as Patient); + } catch (err: any) { + if (!cancelled) { + console.error("Error fetching patient for appointment:", err); + toast({ + title: "Error", + description: + err?.message ?? "An error occurred while fetching patient.", + variant: "destructive", + }); + } + } + })(); + + return () => { + cancelled = true; + }; + }, [location]); // re-run when wouter location changes + return (