checkpoint claimpage
This commit is contained in:
@@ -108,7 +108,6 @@ interface ClaimFormData {
|
|||||||
|
|
||||||
interface ClaimFormProps {
|
interface ClaimFormProps {
|
||||||
patientId: number;
|
patientId: number;
|
||||||
extractedData?: Partial<Patient>;
|
|
||||||
onSubmit: (data: ClaimFormData) => Promise<Claim>;
|
onSubmit: (data: ClaimFormData) => Promise<Claim>;
|
||||||
onHandleAppointmentSubmit: (
|
onHandleAppointmentSubmit: (
|
||||||
appointmentData: InsertAppointment | UpdateAppointment
|
appointmentData: InsertAppointment | UpdateAppointment
|
||||||
@@ -123,7 +122,6 @@ type Staff = z.infer<typeof StaffUncheckedCreateInputObjectSchema>;
|
|||||||
|
|
||||||
export function ClaimForm({
|
export function ClaimForm({
|
||||||
patientId,
|
patientId,
|
||||||
extractedData,
|
|
||||||
onHandleAppointmentSubmit,
|
onHandleAppointmentSubmit,
|
||||||
onHandleUpdatePatient,
|
onHandleUpdatePatient,
|
||||||
onHandleForMHSelenium,
|
onHandleForMHSelenium,
|
||||||
@@ -133,10 +131,7 @@ export function ClaimForm({
|
|||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
const { user } = useAuth();
|
const { user } = useAuth();
|
||||||
|
|
||||||
// Patient state - initialize from extractedData (if given ) or null (new patient)
|
const [patient, setPatient] = useState<Patient | null>(null);
|
||||||
const [patient, setPatient] = useState<Patient | null>(
|
|
||||||
extractedData ? ({ ...extractedData } as Patient) : null
|
|
||||||
);
|
|
||||||
|
|
||||||
// Query patient based on given patient id
|
// Query patient based on given patient id
|
||||||
const {
|
const {
|
||||||
@@ -185,14 +180,6 @@ export function ClaimForm({
|
|||||||
const [serviceDate, setServiceDate] = useState<string>(
|
const [serviceDate, setServiceDate] = useState<string>(
|
||||||
formatLocalDate(new Date())
|
formatLocalDate(new Date())
|
||||||
);
|
);
|
||||||
useEffect(() => {
|
|
||||||
if (extractedData?.serviceDate) {
|
|
||||||
const parsed = parseLocalDate(extractedData.serviceDate);
|
|
||||||
const isoFormatted = formatLocalDate(parsed);
|
|
||||||
setServiceDateValue(parsed);
|
|
||||||
setServiceDate(isoFormatted);
|
|
||||||
}
|
|
||||||
}, [extractedData]);
|
|
||||||
|
|
||||||
// Update service date when calendar date changes
|
// Update service date when calendar date changes
|
||||||
const onServiceDateChange = (date: Date | undefined) => {
|
const onServiceDateChange = (date: Date | undefined) => {
|
||||||
@@ -219,7 +206,7 @@ export function ClaimForm({
|
|||||||
});
|
});
|
||||||
}, [serviceDate]);
|
}, [serviceDate]);
|
||||||
|
|
||||||
// Determine patient date of birth format
|
// Determine patient date of birth format - required as date extracted from pdfs has different format.
|
||||||
const formatDOB = (dob: string | undefined) => {
|
const formatDOB = (dob: string | undefined) => {
|
||||||
if (!dob) return "";
|
if (!dob) return "";
|
||||||
if (/^\d{2}\/\d{2}\/\d{4}$/.test(dob)) return dob; // already MM/DD/YYYY
|
if (/^\d{2}\/\d{2}\/\d{4}$/.test(dob)) return dob; // already MM/DD/YYYY
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import { CalendarIcon } from "lucide-react";
|
|||||||
import { format } from "date-fns";
|
import { format } from "date-fns";
|
||||||
import { Button } from "../ui/button";
|
import { Button } from "../ui/button";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
|
import { formatLocalDate, parseLocalDate } from "@/utils/dateUtils";
|
||||||
|
|
||||||
const PatientSchema = (
|
const PatientSchema = (
|
||||||
PatientUncheckedCreateInputObjectSchema as unknown as z.ZodObject<any>
|
PatientUncheckedCreateInputObjectSchema as unknown as z.ZodObject<any>
|
||||||
@@ -94,7 +95,7 @@ export const PatientForm = forwardRef<PatientFormRef, PatientFormProps>(
|
|||||||
return {
|
return {
|
||||||
...sanitizedPatient,
|
...sanitizedPatient,
|
||||||
dateOfBirth: patient.dateOfBirth
|
dateOfBirth: patient.dateOfBirth
|
||||||
? new Date(patient.dateOfBirth).toISOString().split("T")[0]
|
? formatLocalDate(new Date(patient.dateOfBirth))
|
||||||
: "",
|
: "",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -146,7 +147,7 @@ export const PatientForm = forwardRef<PatientFormRef, PatientFormProps>(
|
|||||||
const resetValues: Partial<Patient> = {
|
const resetValues: Partial<Patient> = {
|
||||||
...sanitizedPatient,
|
...sanitizedPatient,
|
||||||
dateOfBirth: patient.dateOfBirth
|
dateOfBirth: patient.dateOfBirth
|
||||||
? new Date(patient.dateOfBirth).toISOString().split("T")[0]
|
? formatLocalDate(new Date(patient.dateOfBirth))
|
||||||
: "",
|
: "",
|
||||||
};
|
};
|
||||||
form.reset(resetValues);
|
form.reset(resetValues);
|
||||||
@@ -218,7 +219,7 @@ export const PatientForm = forwardRef<PatientFormRef, PatientFormProps>(
|
|||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{field.value ? (
|
{field.value ? (
|
||||||
format(field.value, "PPP")
|
format(parseLocalDate(field.value), "PPP")
|
||||||
) : (
|
) : (
|
||||||
<span>Pick a date</span>
|
<span>Pick a date</span>
|
||||||
)}
|
)}
|
||||||
@@ -229,10 +230,14 @@ export const PatientForm = forwardRef<PatientFormRef, PatientFormProps>(
|
|||||||
<PopoverContent className="w-auto p-4">
|
<PopoverContent className="w-auto p-4">
|
||||||
<Calendar
|
<Calendar
|
||||||
mode="single"
|
mode="single"
|
||||||
selected={field.value}
|
selected={
|
||||||
|
field.value
|
||||||
|
? parseLocalDate(field.value)
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
onSelect={(date) => {
|
onSelect={(date) => {
|
||||||
if (date) {
|
if (date) {
|
||||||
const localDate = format(date, "yyyy-MM-dd");
|
const localDate = formatLocalDate(date); // keep yyyy-MM-dd
|
||||||
field.onChange(localDate);
|
field.onChange(localDate);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -91,13 +91,11 @@ export default function ClaimsPage() {
|
|||||||
const { status, message, show } = useAppSelector(
|
const { status, message, show } = useAppSelector(
|
||||||
(state) => state.seleniumClaimSubmitTask
|
(state) => state.seleniumClaimSubmitTask
|
||||||
);
|
);
|
||||||
|
|
||||||
const { toast } = useToast();
|
const { toast } = useToast();
|
||||||
const { user } = useAuth();
|
const { user } = useAuth();
|
||||||
const [claimFormData, setClaimFormData] = useState<any>({
|
const toggleMobileMenu = () => {
|
||||||
patientId: null,
|
setIsMobileMenuOpen(!isMobileMenuOpen);
|
||||||
serviceDate: "",
|
};
|
||||||
});
|
|
||||||
|
|
||||||
// Fetch patients
|
// Fetch patients
|
||||||
const { data: patients = [], isLoading: isLoadingPatients } = useQuery<
|
const { data: patients = [], isLoading: isLoadingPatients } = useQuery<
|
||||||
@@ -204,51 +202,95 @@ export default function ClaimsPage() {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// Update appointment mutation
|
// create claim mutation
|
||||||
const updateAppointmentMutation = useMutation({
|
const createClaimMutation = useMutation({
|
||||||
mutationFn: async ({
|
mutationFn: async (claimData: any) => {
|
||||||
id,
|
const res = await apiRequest("POST", "/api/claims/", claimData);
|
||||||
appointment,
|
return res.json();
|
||||||
}: {
|
|
||||||
id: number;
|
|
||||||
appointment: UpdateAppointment;
|
|
||||||
}) => {
|
|
||||||
const res = await apiRequest(
|
|
||||||
"PUT",
|
|
||||||
`/api/appointments/${id}`,
|
|
||||||
appointment
|
|
||||||
);
|
|
||||||
return await res.json();
|
|
||||||
},
|
},
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
toast({
|
toast({
|
||||||
title: "Success",
|
title: "Claim created successfully",
|
||||||
description: "Appointment updated successfully.",
|
variant: "default",
|
||||||
});
|
});
|
||||||
queryClient.invalidateQueries({ queryKey: ["/api/appointments/all"] });
|
|
||||||
queryClient.invalidateQueries({ queryKey: ["/api/patients/"] });
|
|
||||||
},
|
},
|
||||||
onError: (error: Error) => {
|
onError: (error: any) => {
|
||||||
toast({
|
toast({
|
||||||
title: "Error",
|
title: "Error submitting claim",
|
||||||
description: `Failed to update appointment: ${error.message}`,
|
description: error.message,
|
||||||
variant: "destructive",
|
variant: "destructive",
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// workflow starts from there - this params are set by pdf extraction/patient page.
|
||||||
|
// the fields are either send by pdfExtraction or by selecting patients.
|
||||||
|
const [location] = useLocation();
|
||||||
|
const { name, memberId, dob } = useMemo(() => {
|
||||||
|
const search = window.location.search;
|
||||||
|
const params = new URLSearchParams(search);
|
||||||
|
return {
|
||||||
|
name: params.get("name") || "",
|
||||||
|
memberId: params.get("memberId") || "",
|
||||||
|
dob: params.get("dob") || "",
|
||||||
|
};
|
||||||
|
}, [location]);
|
||||||
|
|
||||||
|
const handleNewClaim = (patientId: number) => {
|
||||||
|
setSelectedPatientId(patientId);
|
||||||
|
setIsClaimFormOpen(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (memberId && dob) {
|
||||||
|
// if matching patient found then simply send its id to claim form,
|
||||||
|
// if not then create new patient then send its id to claim form.
|
||||||
|
const fetchMatchingPatient = async () => {
|
||||||
|
try {
|
||||||
|
const matchingPatient = await getPatientByInsuranceId(memberId);
|
||||||
|
|
||||||
|
if (matchingPatient) {
|
||||||
|
handleNewClaim(matchingPatient.id);
|
||||||
|
} else {
|
||||||
|
const [firstName, ...rest] = name.trim().split(" ");
|
||||||
|
const lastName = rest.join(" ") || "";
|
||||||
|
const parsedDob = parse(dob, "M/d/yyyy", new Date()); // robust for "4/17/1964", "12/1/1975", etc.
|
||||||
|
|
||||||
|
const newPatient: InsertPatient = {
|
||||||
|
firstName,
|
||||||
|
lastName,
|
||||||
|
dateOfBirth: formatLocalDate(parsedDob),
|
||||||
|
gender: "",
|
||||||
|
phone: "",
|
||||||
|
userId: user?.id ?? 1,
|
||||||
|
status: "active",
|
||||||
|
insuranceId: memberId,
|
||||||
|
};
|
||||||
|
|
||||||
|
addPatientMutation.mutate(newPatient, {
|
||||||
|
onSuccess: (created) => {
|
||||||
|
handleNewClaim(created.id);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Error checking/creating patient:", err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
fetchMatchingPatient();
|
||||||
|
}
|
||||||
|
}, [memberId, dob]);
|
||||||
|
|
||||||
|
// 1. upsert appointment.
|
||||||
const handleAppointmentSubmit = async (
|
const handleAppointmentSubmit = async (
|
||||||
appointmentData: InsertAppointment | UpdateAppointment
|
appointmentData: InsertAppointment | UpdateAppointment
|
||||||
): Promise<number> => {
|
): Promise<number> => {
|
||||||
return new Promise<number>((resolve, reject) => {
|
return new Promise<number>((resolve, reject) => {
|
||||||
console.log("Constructed appointmentData:", appointmentData);
|
|
||||||
|
|
||||||
console.log(appointmentData.date);
|
|
||||||
createAppointmentMutation.mutate(
|
createAppointmentMutation.mutate(
|
||||||
{
|
{
|
||||||
date: appointmentData.date,
|
date: appointmentData.date,
|
||||||
startTime: appointmentData.startTime || "09:00",
|
startTime: "09:00",
|
||||||
endTime: appointmentData.endTime || "09:30",
|
endTime: "09:30",
|
||||||
staffId: appointmentData.staffId,
|
staffId: appointmentData.staffId,
|
||||||
patientId: appointmentData.patientId,
|
patientId: appointmentData.patientId,
|
||||||
userId: user?.id,
|
userId: user?.id,
|
||||||
@@ -272,192 +314,15 @@ export default function ClaimsPage() {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const createClaimMutation = useMutation({
|
// 2. Update Patient ( for insuranceId and Insurance Provider)
|
||||||
mutationFn: async (claimData: any) => {
|
|
||||||
const res = await apiRequest("POST", "/api/claims/", claimData);
|
|
||||||
return res.json();
|
|
||||||
},
|
|
||||||
onSuccess: () => {
|
|
||||||
toast({
|
|
||||||
title: "Claim created successfully",
|
|
||||||
variant: "default",
|
|
||||||
});
|
|
||||||
},
|
|
||||||
onError: (error: any) => {
|
|
||||||
toast({
|
|
||||||
title: "Error submitting claim",
|
|
||||||
description: error.message,
|
|
||||||
variant: "destructive",
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
function handleClaimSubmit(claimData: any): Promise<Claim> {
|
|
||||||
return createClaimMutation.mutateAsync(claimData).then((data) => {
|
|
||||||
return data;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const [location] = useLocation(); // gets path, e.g. "/claims"
|
|
||||||
|
|
||||||
const { name, memberId, dob } = useMemo(() => {
|
|
||||||
const search = window.location.search; // this gets the real query string
|
|
||||||
const params = new URLSearchParams(search);
|
|
||||||
return {
|
|
||||||
name: params.get("name") || "",
|
|
||||||
memberId: params.get("memberId") || "",
|
|
||||||
dob: params.get("dob") || "",
|
|
||||||
};
|
|
||||||
}, [location]);
|
|
||||||
|
|
||||||
const toggleMobileMenu = () => {
|
|
||||||
setIsMobileMenuOpen(!isMobileMenuOpen);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleNewClaim = (patientId: number) => {
|
|
||||||
setSelectedPatientId(patientId);
|
|
||||||
setIsClaimFormOpen(true);
|
|
||||||
|
|
||||||
const patient = patients.find((p) => p.id === patientId);
|
|
||||||
if (!patient) return;
|
|
||||||
|
|
||||||
prefillClaimForm(patient);
|
|
||||||
};
|
|
||||||
|
|
||||||
const closeClaim = () => {
|
|
||||||
setSelectedPatientId(null);
|
|
||||||
setIsClaimFormOpen(false);
|
|
||||||
setClaimFormData({
|
|
||||||
patientId: null,
|
|
||||||
serviceDate: "",
|
|
||||||
});
|
|
||||||
|
|
||||||
// Remove query parameters without reload
|
|
||||||
const url = new URL(window.location.href);
|
|
||||||
url.searchParams.delete("memberId");
|
|
||||||
url.searchParams.delete("dob");
|
|
||||||
url.searchParams.delete("name");
|
|
||||||
|
|
||||||
// Use history.replaceState to update the URL without reloading
|
|
||||||
window.history.replaceState({}, document.title, url.toString());
|
|
||||||
};
|
|
||||||
|
|
||||||
const prefillClaimForm = (patient: Patient) => {
|
|
||||||
const patientAppointments = appointments
|
|
||||||
.filter((a) => a.patientId === patient.id)
|
|
||||||
.sort(
|
|
||||||
(a, b) =>
|
|
||||||
parseLocalDate(b.date).getTime() - parseLocalDate(a.date).getTime()
|
|
||||||
);
|
|
||||||
|
|
||||||
const lastAppointment = patientAppointments[0]; // most recent
|
|
||||||
|
|
||||||
const dateToUse = lastAppointment
|
|
||||||
? parseLocalDate(lastAppointment.date)
|
|
||||||
: parseLocalDate(new Date());
|
|
||||||
|
|
||||||
setClaimFormData((prev: any) => ({
|
|
||||||
...prev,
|
|
||||||
patientId: patient.id,
|
|
||||||
serviceDate: formatLocalDate(dateToUse),
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (memberId && dob) {
|
|
||||||
const matchingPatient = patients.find(
|
|
||||||
(p) =>
|
|
||||||
p.insuranceId?.toLowerCase().trim() === memberId.toLowerCase().trim()
|
|
||||||
);
|
|
||||||
|
|
||||||
if (matchingPatient) {
|
|
||||||
setSelectedPatientId(matchingPatient.id);
|
|
||||||
prefillClaimForm(matchingPatient);
|
|
||||||
setIsClaimFormOpen(true);
|
|
||||||
} else {
|
|
||||||
const [firstName, ...rest] = name.trim().split(" ");
|
|
||||||
const lastName = rest.join(" ") || "";
|
|
||||||
|
|
||||||
const parsedDob = parse(dob, "M/d/yyyy", new Date()); // robust for "4/17/1964", "12/1/1975", etc.
|
|
||||||
|
|
||||||
const newPatient: InsertPatient = {
|
|
||||||
firstName,
|
|
||||||
lastName,
|
|
||||||
dateOfBirth: formatLocalDate(parsedDob),
|
|
||||||
gender: "",
|
|
||||||
phone: "",
|
|
||||||
userId: user?.id ?? 1,
|
|
||||||
status: "active",
|
|
||||||
insuranceId: memberId,
|
|
||||||
};
|
|
||||||
|
|
||||||
addPatientMutation.mutate(newPatient, {
|
|
||||||
onSuccess: (created) => {
|
|
||||||
setSelectedPatientId(created.id);
|
|
||||||
prefillClaimForm(created);
|
|
||||||
setIsClaimFormOpen(true);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, [memberId, dob]);
|
|
||||||
|
|
||||||
const getDisplayProvider = (provider: string) => {
|
|
||||||
const insuranceMap: Record<string, string> = {
|
|
||||||
delta: "Delta Dental",
|
|
||||||
metlife: "MetLife",
|
|
||||||
cigna: "Cigna",
|
|
||||||
aetna: "Aetna",
|
|
||||||
};
|
|
||||||
return insuranceMap[provider?.toLowerCase()] || provider;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Get unique patients with appointments
|
|
||||||
const patientsWithAppointments = patients.reduce(
|
|
||||||
(acc, patient) => {
|
|
||||||
const patientAppointments = appointments
|
|
||||||
.filter((appt) => appt.patientId === patient.id)
|
|
||||||
.sort(
|
|
||||||
(a, b) =>
|
|
||||||
parseLocalDate(b.date).getTime() - parseLocalDate(a.date).getTime()
|
|
||||||
); // Sort descending by date
|
|
||||||
|
|
||||||
if (patientAppointments.length > 0) {
|
|
||||||
const latestAppointment = patientAppointments[0];
|
|
||||||
acc.push({
|
|
||||||
patientId: patient.id,
|
|
||||||
patientName: `${patient.firstName} ${patient.lastName}`,
|
|
||||||
appointmentId: latestAppointment!.id,
|
|
||||||
insuranceProvider: patient.insuranceProvider || "N/A",
|
|
||||||
insuranceId: patient.insuranceId || "N/A",
|
|
||||||
lastAppointment: formatLocalDate(
|
|
||||||
parseLocalDate(latestAppointment!.date)
|
|
||||||
),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return acc;
|
|
||||||
},
|
|
||||||
[] as Array<{
|
|
||||||
patientId: number;
|
|
||||||
patientName: string;
|
|
||||||
appointmentId: number;
|
|
||||||
insuranceProvider: string;
|
|
||||||
insuranceId: string;
|
|
||||||
lastAppointment: string;
|
|
||||||
}>
|
|
||||||
);
|
|
||||||
|
|
||||||
// Update Patient ( for insuranceId and Insurance Provider)
|
|
||||||
const handleUpdatePatient = (patient: UpdatePatient & { id?: number }) => {
|
const handleUpdatePatient = (patient: UpdatePatient & { id?: number }) => {
|
||||||
if (patient && user) {
|
if (patient) {
|
||||||
const { id, ...sanitizedPatient } = patient;
|
const { id, ...sanitizedPatient } = patient;
|
||||||
updatePatientMutation.mutate({
|
updatePatientMutation.mutate({
|
||||||
id: Number(patient.id),
|
id: Number(patient.id),
|
||||||
patient: sanitizedPatient,
|
patient: sanitizedPatient,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
console.error("No current patient or user found for update");
|
|
||||||
toast({
|
toast({
|
||||||
title: "Error",
|
title: "Error",
|
||||||
description: "Cannot update patient: No patient or user found",
|
description: "Cannot update patient: No patient or user found",
|
||||||
@@ -466,7 +331,14 @@ export default function ClaimsPage() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// handle selenium sybmiting Mass Health claim
|
// 3. create claim.
|
||||||
|
const handleClaimSubmit = (claimData: any): Promise<Claim> => {
|
||||||
|
return createClaimMutation.mutateAsync(claimData).then((data) => {
|
||||||
|
return data;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 4. handle selenium sybmiting Mass Health claim
|
||||||
const handleMHClaimSubmitSelenium = async (data: any) => {
|
const handleMHClaimSubmitSelenium = async (data: any) => {
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append("data", JSON.stringify(data));
|
formData.append("data", JSON.stringify(data));
|
||||||
@@ -509,7 +381,10 @@ export default function ClaimsPage() {
|
|||||||
variant: "default",
|
variant: "default",
|
||||||
});
|
});
|
||||||
|
|
||||||
const result2 = await handleMHSeleniumPdfDownload(result1);
|
const result2 = await handleMHSeleniumPdfDownload(
|
||||||
|
result1,
|
||||||
|
selectedPatientId
|
||||||
|
);
|
||||||
return result2;
|
return result2;
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
dispatch(
|
dispatch(
|
||||||
@@ -526,8 +401,11 @@ export default function ClaimsPage() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// selenium pdf download handler
|
// 5. selenium pdf download handler
|
||||||
const handleMHSeleniumPdfDownload = async (data: any) => {
|
const handleMHSeleniumPdfDownload = async (
|
||||||
|
data: any,
|
||||||
|
selectedPatientId: number | null
|
||||||
|
) => {
|
||||||
try {
|
try {
|
||||||
if (!selectedPatientId) {
|
if (!selectedPatientId) {
|
||||||
throw new Error("Missing patientId");
|
throw new Error("Missing patientId");
|
||||||
@@ -575,6 +453,68 @@ export default function ClaimsPage() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 6. close claim
|
||||||
|
const closeClaim = () => {
|
||||||
|
setSelectedPatientId(null);
|
||||||
|
setIsClaimFormOpen(false);
|
||||||
|
|
||||||
|
// Remove query parameters without reload
|
||||||
|
const url = new URL(window.location.href);
|
||||||
|
url.searchParams.delete("memberId");
|
||||||
|
url.searchParams.delete("dob");
|
||||||
|
url.searchParams.delete("name");
|
||||||
|
|
||||||
|
// Use history.replaceState to update the URL without reloading
|
||||||
|
window.history.replaceState({}, document.title, url.toString());
|
||||||
|
};
|
||||||
|
|
||||||
|
// helper func for frontend
|
||||||
|
const getDisplayProvider = (provider: string) => {
|
||||||
|
const insuranceMap: Record<string, string> = {
|
||||||
|
delta: "Delta Dental",
|
||||||
|
metlife: "MetLife",
|
||||||
|
cigna: "Cigna",
|
||||||
|
aetna: "Aetna",
|
||||||
|
};
|
||||||
|
return insuranceMap[provider?.toLowerCase()] || provider;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Get unique patients with appointments - might not needed now, can shift this to the recent patients table
|
||||||
|
const patientsWithAppointments = patients.reduce(
|
||||||
|
(acc, patient) => {
|
||||||
|
const patientAppointments = appointments
|
||||||
|
.filter((appt) => appt.patientId === patient.id)
|
||||||
|
.sort(
|
||||||
|
(a, b) =>
|
||||||
|
parseLocalDate(b.date).getTime() - parseLocalDate(a.date).getTime()
|
||||||
|
); // Sort descending by date
|
||||||
|
|
||||||
|
if (patientAppointments.length > 0) {
|
||||||
|
const latestAppointment = patientAppointments[0];
|
||||||
|
acc.push({
|
||||||
|
patientId: patient.id,
|
||||||
|
patientName: `${patient.firstName} ${patient.lastName}`,
|
||||||
|
appointmentId: latestAppointment!.id,
|
||||||
|
insuranceProvider: patient.insuranceProvider || "N/A",
|
||||||
|
insuranceId: patient.insuranceId || "N/A",
|
||||||
|
lastAppointment: formatLocalDate(
|
||||||
|
parseLocalDate(latestAppointment!.date)
|
||||||
|
),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return acc;
|
||||||
|
},
|
||||||
|
[] as Array<{
|
||||||
|
patientId: number;
|
||||||
|
patientName: string;
|
||||||
|
appointmentId: number;
|
||||||
|
insuranceProvider: string;
|
||||||
|
insuranceId: string;
|
||||||
|
lastAppointment: string;
|
||||||
|
}>
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex h-screen overflow-hidden bg-gray-100">
|
<div className="flex h-screen overflow-hidden bg-gray-100">
|
||||||
<Sidebar
|
<Sidebar
|
||||||
@@ -720,7 +660,6 @@ export default function ClaimsPage() {
|
|||||||
<ClaimForm
|
<ClaimForm
|
||||||
patientId={selectedPatientId}
|
patientId={selectedPatientId}
|
||||||
onClose={closeClaim}
|
onClose={closeClaim}
|
||||||
extractedData={claimFormData}
|
|
||||||
onSubmit={handleClaimSubmit}
|
onSubmit={handleClaimSubmit}
|
||||||
onHandleAppointmentSubmit={handleAppointmentSubmit}
|
onHandleAppointmentSubmit={handleAppointmentSubmit}
|
||||||
onHandleUpdatePatient={handleUpdatePatient}
|
onHandleUpdatePatient={handleUpdatePatient}
|
||||||
|
|||||||
Reference in New Issue
Block a user