feat: United/DentalHub + Tufts SCO pre-auth, cloud storage search & file thumbnails

- Add United/DentalHub pre-authorization Selenium worker, helpers, backend route/processor/client, and frontend OTP modal + wired button
- Add Tufts SCO pre-authorization Selenium worker, helpers, backend route/processor/client, and frontend OTP modal + wired button
- Fix btnSubmitAuthorization selector for UnitedDH preauth step2
- Fix Tufts SCO preauth step3 to target <span>pre-authorization</span> button
- Cloud storage search: default to "both" mode so patient folder names match on first search
- Cloud storage folder panel: auto-scroll to panel when opened from search results
- Cloud storage files: show inline image thumbnails and PDF badge in file grid

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
ff
2026-06-13 00:03:58 -04:00
co-authored by Claude Sonnet 4.6
parent fd4feb3e76
commit 3978b16d7d
20 changed files with 4044 additions and 19 deletions
@@ -93,6 +93,8 @@ interface ClaimFormProps {
onHandleForMHSeleniumClaimPreAuth: (data: ClaimPreAuthData) => void;
onHandleForCCASeleniumClaim: (data: ClaimFormData) => void;
onHandleForCCASeleniumPreAuth: (data: ClaimPreAuthData) => void;
onHandleForUnitedDHSeleniumPreAuth: (data: ClaimPreAuthData) => void;
onHandleForTuftsSCOSeleniumPreAuth: (data: ClaimPreAuthData) => void;
onHandleForDDMASeleniumClaim: (data: ClaimFormData) => void;
onHandleForUnitedDHSeleniumClaim: (data: ClaimFormData) => void;
onHandleForTuftsSCOSeleniumClaim: (data: ClaimFormData) => void;
@@ -112,6 +114,8 @@ export function ClaimForm({
onHandleForMHSeleniumClaimPreAuth,
onHandleForCCASeleniumClaim,
onHandleForCCASeleniumPreAuth,
onHandleForUnitedDHSeleniumPreAuth,
onHandleForTuftsSCOSeleniumPreAuth,
onHandleForDDMASeleniumClaim,
onHandleForUnitedDHSeleniumClaim,
onHandleForTuftsSCOSeleniumClaim,
@@ -1433,6 +1437,82 @@ export function ClaimForm({
onClose();
};
const handleUnitedDHPreAuth = async () => {
const missingFields: string[] = [];
if (!form.memberId?.trim()) missingFields.push("Member ID");
if (!form.dateOfBirth?.trim()) missingFields.push("Date of Birth");
if (!patient?.firstName?.trim()) missingFields.push("First Name");
if (missingFields.length > 0) {
toast({
title: "Missing Required Fields",
description: `Please fill out the following field(s): ${missingFields.join(", ")}`,
variant: "destructive",
});
return;
}
const filteredServiceLines = (form.serviceLines || []).filter(
(line) => (line.procedureCode ?? "").trim() !== "",
);
if (filteredServiceLines.length === 0) {
toast({
title: "No procedure codes",
description: "Please add at least one procedure code before submitting the pre-authorization.",
variant: "destructive",
});
return;
}
onHandleForUnitedDHSeleniumPreAuth({
...form,
serviceLines: filteredServiceLines,
staffId: appointmentStaffId ?? Number(staff?.id),
patientId,
insuranceProvider: "United/DentalHub",
insuranceSiteKey: "UNITED_SCO",
});
onClose();
};
const handleTuftsSCOPreAuth = async () => {
const missingFields: string[] = [];
if (!form.memberId?.trim()) missingFields.push("Member ID");
if (!form.dateOfBirth?.trim()) missingFields.push("Date of Birth");
if (!patient?.firstName?.trim()) missingFields.push("First Name");
if (missingFields.length > 0) {
toast({
title: "Missing Required Fields",
description: `Please fill out the following field(s): ${missingFields.join(", ")}`,
variant: "destructive",
});
return;
}
const filteredServiceLines = (form.serviceLines || []).filter(
(line) => (line.procedureCode ?? "").trim() !== "",
);
if (filteredServiceLines.length === 0) {
toast({
title: "No procedure codes",
description: "Please add at least one procedure code before submitting the pre-authorization.",
variant: "destructive",
});
return;
}
onHandleForTuftsSCOSeleniumPreAuth({
...form,
serviceLines: filteredServiceLines,
staffId: appointmentStaffId ?? Number(staff?.id),
patientId,
insuranceProvider: "Tufts SCO",
insuranceSiteKey: "TUFTS_SCO",
});
onClose();
};
/** Check prices against the fee schedule. If mismatches exist, show dialog and
* store the action to run after the user responds. Otherwise run immediately. */
const runWithPriceCheck = (action: () => void) => {
@@ -2931,16 +3011,16 @@ export function ClaimForm({
CCA PreAuth
</Button>
<Button
className="w-44"
variant="secondary"
className="w-44 bg-blue-600 hover:bg-blue-700 text-white"
onClick={handleUnitedDHPreAuth}
disabled={!isLicensed}
title={!isLicensed ? "License required" : undefined}
>
United/DentalHub PreAuth
</Button>
<Button
className="w-32"
variant="secondary"
className="w-32 bg-blue-600 hover:bg-blue-700 text-white"
onClick={handleTuftsSCOPreAuth}
disabled={!isLicensed}
title={!isLicensed ? "License required" : undefined}
>