feat(frontend): refactor Upload page to use useParse hook

This commit is contained in:
Tyler
2026-06-19 19:46:12 -06:00
parent 7333f0f50e
commit 5c26d296be
+15 -10
View File
@@ -28,6 +28,7 @@ import {
import { api, type ParseProgress } from "@/lib/api"; import { api, type ParseProgress } from "@/lib/api";
import { fmt, toNum } from "@/lib/format"; import { fmt, toNum } from "@/lib/format";
import { useAppStore } from "@/store"; import { useAppStore } from "@/store";
import { useParse } from "@/hooks/useParse";
import type { import type {
ClaimOutput, ClaimOutput,
ClaimPayment, ClaimPayment,
@@ -465,7 +466,6 @@ export function Upload() {
const [file, setFile] = useState<File | null>(null); const [file, setFile] = useState<File | null>(null);
const [kind, setKind] = useState<ParsedBatchKind>("837p"); const [kind, setKind] = useState<ParsedBatchKind>("837p");
const [payer, setPayer] = useState<string>(PAYERS_837[0]!.value); const [payer, setPayer] = useState<string>(PAYERS_837[0]!.value);
const [running, setRunning] = useState(false);
const [stream, setStream] = useState<StreamState>({ const [stream, setStream] = useState<StreamState>({
items: [], items: [],
expectedTotal: null, expectedTotal: null,
@@ -474,11 +474,16 @@ export function Upload() {
}); });
const addParsedBatch = useAppStore((s) => s.addParsedBatch); const addParsedBatch = useAppStore((s) => s.addParsedBatch);
const parsedBatches = useAppStore((s) => s.parsedBatches); const parsedBatches = useAppStore((s) => s.parsedBatches);
// useParse wires the mutation; on success it invalidates every list query
// (batches, claims, remittances, providers, activity) so the other pages
// see the new data without manual refetching.
const parseMutation = useParse(kind);
const payerOptions = kind === "837p" ? PAYERS_837 : PAYERS_835; const payerOptions = kind === "837p" ? PAYERS_837 : PAYERS_835;
const expectedTotal = stream.expectedTotal; const expectedTotal = stream.expectedTotal;
const totalSoFar = stream.items.length; const totalSoFar = stream.items.length;
const running = parseMutation.isPending;
const progressPct = useMemo(() => { const progressPct = useMemo(() => {
if (!expectedTotal || expectedTotal <= 0) return 0; if (!expectedTotal || expectedTotal <= 0) return 0;
return Math.min(100, Math.round((totalSoFar / expectedTotal) * 100)); return Math.min(100, Math.round((totalSoFar / expectedTotal) * 100));
@@ -497,11 +502,8 @@ export function Upload() {
); );
return; return;
} }
setRunning(true);
setStream({ items: [], expectedTotal: null, passed: 0, failed: 0 }); setStream({ items: [], expectedTotal: null, passed: 0, failed: 0 });
const startedAt = new Date().toISOString();
const items: StreamedClaim[] = []; const items: StreamedClaim[] = [];
try {
const onProgress: ParseProgress = (event) => { const onProgress: ParseProgress = (event) => {
if (event.type === "claim") { if (event.type === "claim") {
items.push({ kind: "837p", data: event.data }); items.push({ kind: "837p", data: event.data });
@@ -527,9 +529,14 @@ export function Upload() {
// the page summary at the end reports the real pass/fail counts. // the page summary at the end reports the real pass/fail counts.
}; };
const summary = await (kind === "837p" try {
? api.parse837(file, { payer, onProgress }) // mutateAsync triggers the mutation; the streaming callbacks above
: api.parse835(file, { payer, onProgress })); // populate `stream` as claims arrive, and the resolver returns the
// final BatchSummary from the "summary" NDJSON line.
const summary = await parseMutation.mutateAsync({
file,
options: { payer, onProgress },
});
// The final return value is a BatchSummary in the streaming case. // The final return value is a BatchSummary in the streaming case.
const finalSummary = const finalSummary =
@@ -548,7 +555,7 @@ export function Upload() {
id, id,
kind, kind,
inputFilename: file.name, inputFilename: file.name,
parsedAt: startedAt, parsedAt: new Date().toISOString(),
claimCount: finalSummary.total_claims, claimCount: finalSummary.total_claims,
passed: finalSummary.passed, passed: finalSummary.passed,
failed: finalSummary.failed, failed: finalSummary.failed,
@@ -567,8 +574,6 @@ export function Upload() {
toast.error( toast.error(
err instanceof Error ? err.message : "Failed to parse file" err instanceof Error ? err.message : "Failed to parse file"
); );
} finally {
setRunning(false);
} }
} }