base claim page, claim form working, appoitmentLogic and pdfUpload in form is remaining

This commit is contained in:
2025-05-27 20:01:21 +05:30
parent 564a9927c9
commit 91b46126bf
2 changed files with 95 additions and 48 deletions

View File

@@ -56,7 +56,11 @@ export function ClaimForm({
const { toast } = useToast();
// Query patient if patientId provided
const { data: fetchedPatient, isLoading, error } = useQuery<Patient>({
const {
data: fetchedPatient,
isLoading,
error,
} = useQuery<Patient>({
queryKey: ["/api/patients/", patientId],
queryFn: async () => {
const res = await apiRequest("GET", `/api/patients/${patientId}`);
@@ -78,10 +82,22 @@ export function ClaimForm({
}
}, [fetchedPatient]);
// Service date state
// Service date state
const [serviceDateValue, setServiceDateValue] = useState<Date>(new Date());
const [serviceDate, setServiceDate] = useState<string>(format(new Date(), "MM/dd/yy"));
const [serviceDate, setServiceDate] = useState<string>(
format(new Date(), "MM/dd/yy")
);
useEffect(() => {
console.log("🚨 extractedData in effect:", extractedData);
if (extractedData?.serviceDate) {
const parsed = new Date(extractedData.serviceDate);
console.log("✅ Parsed serviceDate from extractedData:", parsed);
setServiceDateValue(parsed);
setServiceDate(format(parsed, "MM/dd/yy"));
}
}, [extractedData]);
// Clinical notes state
const [clinicalNotes, setClinicalNotes] = useState<string>("");
@@ -121,7 +137,6 @@ export function ClaimForm({
setPatient((prev) => (prev ? { ...prev, [field]: value } : null));
};
// Update service date when calendar date changes
const onServiceDateChange = (date: Date | undefined) => {
if (date) {
@@ -132,19 +147,19 @@ export function ClaimForm({
// Determine patient date of birth format
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
if (/^\d{4}-\d{2}-\d{2}/.test(dob)) {
const datePart = dob?.split("T")[0]; // safe optional chaining
if (!datePart) return "";
const [year, month, day] = datePart.split("-");
return `${month}/${day}/${year}`;
}
if (/^\d{4}-\d{2}-\d{2}/.test(dob)) {
const datePart = dob?.split("T")[0]; // safe optional chaining
if (!datePart) return "";
const [year, month, day] = datePart.split("-");
return `${month}/${day}/${year}`;
}
return dob;
};
return dob;
};
return (
<div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4 overflow-y-auto">
@@ -166,7 +181,9 @@ export function ClaimForm({
<Input
id="memberId"
value={patient?.insuranceId || ""}
onChange={(e) => updatePatientField("insuranceId", e.target.value)}
onChange={(e) =>
updatePatientField("insuranceId", e.target.value)
}
disabled={isLoading}
/>
</div>
@@ -175,7 +192,9 @@ export function ClaimForm({
<Input
id="dateOfBirth"
value={formatDOB(patient?.dateOfBirth)}
onChange={(e) => updatePatientField("dateOfBirth", e.target.value)}
onChange={(e) =>
updatePatientField("dateOfBirth", e.target.value)
}
disabled={isLoading}
/>
</div>
@@ -184,7 +203,9 @@ export function ClaimForm({
<Input
id="firstName"
value={patient?.firstName || ""}
onChange={(e) => updatePatientField("firstName", e.target.value)}
onChange={(e) =>
updatePatientField("firstName", e.target.value)
}
disabled={isLoading}
/>
</div>
@@ -193,7 +214,9 @@ export function ClaimForm({
<Input
id="lastName"
value={patient?.lastName || ""}
onChange={(e) => updatePatientField("lastName", e.target.value)}
onChange={(e) =>
updatePatientField("lastName", e.target.value)
}
disabled={isLoading}
/>
</div>

View File

@@ -1,4 +1,4 @@
import { useState, useEffect } from "react";
import { useState, useEffect, useMemo } from "react";
import { useMutation, useQuery } from "@tanstack/react-query";
import { TopAppBar } from "@/components/layout/top-app-bar";
import { Sidebar } from "@/components/layout/sidebar";
@@ -64,16 +64,6 @@ const updatePatientSchema = (
type UpdatePatient = z.infer<typeof updatePatientSchema>;
function getQueryParams() {
const search = window.location.search;
const params = new URLSearchParams(search);
return {
name: params.get("name") || "",
memberId: params.get("memberId") || "",
dob: params.get("dob") || "",
};
}
export default function ClaimsPage() {
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
const [isClaimFormOpen, setIsClaimFormOpen] = useState(false);
@@ -186,6 +176,18 @@ export default function ClaimsPage() {
},
});
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]); // <== re-run when route changes
const toggleMobileMenu = () => {
setIsMobileMenuOpen(!isMobileMenuOpen);
};
@@ -194,28 +196,45 @@ export default function ClaimsPage() {
setSelectedPatient(patientId);
setSelectedAppointment(appointmentId);
setIsClaimFormOpen(true);
const patient = patients.find((p) => p.id === patientId);
if (!patient) return;
prefillClaimForm(patient);
};
const closeClaim = () => {
setIsClaimFormOpen(false);
setSelectedPatient(null);
setSelectedAppointment(null);
setClaimFormData({
patientId: null,
carrier: "",
doctorName: "",
serviceDate: "",
clinicalNotes: "",
serviceLines: [],
});
};
const { name, memberId, dob } = getQueryParams();
const prefillClaimForm = (patient: Patient) => {
const lastAppointment = appointments.find(
(a) => a.patientId === patient.id
);
setClaimFormData((prev: any) => ({
...prev,
patientId: patient.id,
carrier: patient.insuranceProvider || "",
doctorName: user?.username || "",
serviceDate: new Date().toISOString().slice(0, 10),
serviceDate: lastAppointment
? new Date(lastAppointment.date).toISOString().slice(0, 10)
: new Date().toISOString().slice(0, 10),
clinicalNotes: "",
serviceLines: [],
}));
};
useEffect(() => {
if (memberId && dob) {
const matchingPatient = patients.find(
@@ -231,13 +250,17 @@ export default function ClaimsPage() {
const [firstName, ...rest] = name.trim().split(" ");
const lastName = rest.join(" ") || "";
const parsedDob = new Date(dob);
const isValidDob = !isNaN(parsedDob.getTime());
const newPatient: InsertPatient = {
firstName,
lastName,
dateOfBirth: new Date(dob),
gender: "unknown",
phone: "000-000-0000",
dateOfBirth: isValidDob ? parsedDob : new Date(),
gender: "",
phone: "",
userId: user?.id ?? 1,
status: "active",
insuranceId: memberId,
};
@@ -256,6 +279,17 @@ export default function ClaimsPage() {
createClaimMutation.mutate(claimData);
}
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 = appointments.reduce(
(acc, appointment) => {
@@ -357,18 +391,8 @@ export default function ClaimsPage() {
<div>
<h3 className="font-medium">{item.patientName}</h3>
<div className="text-sm text-gray-500">
<span>
Insurance:{" "}
{item.insuranceProvider === "delta"
? "Delta Dental"
: item.insuranceProvider === "metlife"
? "MetLife"
: item.insuranceProvider === "cigna"
? "Cigna"
: item.insuranceProvider === "aetna"
? "Aetna"
: item.insuranceProvider}
</span>
<span>Insurance: {getDisplayProvider(item.insuranceProvider)}</span>
<span className="mx-2"></span>
<span>ID: {item.insuranceId}</span>
<span className="mx-2"></span>