feat(upload): streamed claim cards offer drill to persisted entity
This commit is contained in:
+75
-2
@@ -1,4 +1,5 @@
|
||||
import { useMemo, useRef, useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import {
|
||||
AlertTriangle,
|
||||
ArrowRight,
|
||||
@@ -138,10 +139,22 @@ function StatPill({
|
||||
);
|
||||
}
|
||||
|
||||
function ClaimCard837({ claim }: { claim: ClaimOutput }) {
|
||||
export function ClaimCard837({ claim }: { claim: ClaimOutput }) {
|
||||
const [open, setOpen] = useState(false);
|
||||
const passed = claim.validation.passed;
|
||||
const hasWarnings = claim.validation.warnings.length > 0;
|
||||
// SP21 Phase 5 Task 5.7: a "See claim in detail →" link drills to
|
||||
// /claims?claim=ID — but ONLY when this streamed claim_id has
|
||||
// actually been persisted to a parsed batch. The Upload page
|
||||
// streams claims as the parser emits them; until the user clicks
|
||||
// "Save batch" the claim isn't visible to ClaimDrawer.
|
||||
const parsedBatches = useAppStore((s) => s.parsedBatches);
|
||||
const persistedClaimIds = useMemo(
|
||||
() => new Set(parsedBatches.flatMap((b) => b.claimIds)),
|
||||
[parsedBatches],
|
||||
);
|
||||
const canDrill = persistedClaimIds.has(claim.claim_id);
|
||||
const navigate = useNavigate();
|
||||
return (
|
||||
<div
|
||||
className="rounded-lg overflow-hidden border"
|
||||
@@ -331,6 +344,31 @@ function ClaimCard837({ claim }: { claim: ClaimOutput }) {
|
||||
</ul>
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{/* SP21 Phase 5 Task 5.7: drill to the persisted claim. Only
|
||||
renders when this streamed claim_id has been saved into
|
||||
a parsed batch (so ClaimDrawer can find it). Before
|
||||
"Save batch" the claim is streaming-only and the link
|
||||
would 404. */}
|
||||
{canDrill ? (
|
||||
<div className="pt-1">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() =>
|
||||
navigate(
|
||||
`/claims?claim=${encodeURIComponent(claim.claim_id)}`,
|
||||
)
|
||||
}
|
||||
data-testid="upload-claim-drill"
|
||||
aria-label={`See claim ${claim.claim_id} in detail`}
|
||||
className="inline-flex items-center gap-1.5 text-[12px] mono font-semibold cursor-pointer rounded-sm px-1 -mx-1 hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1"
|
||||
style={{ color: "hsl(var(--surface-ink))" }}
|
||||
>
|
||||
See claim in detail
|
||||
<ArrowRight className="h-3 w-3" strokeWidth={2} />
|
||||
</button>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
@@ -385,9 +423,19 @@ function ServiceLine837Row({ line }: { line: ServiceLine }) {
|
||||
);
|
||||
}
|
||||
|
||||
function ClaimCard835({ claim }: { claim: ClaimPayment }) {
|
||||
export function ClaimCard835({ claim }: { claim: ClaimPayment }) {
|
||||
const [open, setOpen] = useState(false);
|
||||
const passed = claim.service_payments.length > 0;
|
||||
// SP21 Phase 5 Task 5.7: same drill gate as ClaimCard837. Only show
|
||||
// "See claim in detail" once the claim_id is in the persisted
|
||||
// batches (otherwise ClaimDrawer would 404).
|
||||
const parsedBatches = useAppStore((s) => s.parsedBatches);
|
||||
const persistedClaimIds = useMemo(
|
||||
() => new Set(parsedBatches.flatMap((b) => b.claimIds)),
|
||||
[parsedBatches],
|
||||
);
|
||||
const canDrill = persistedClaimIds.has(claim.payer_claim_control_number);
|
||||
const navigate = useNavigate();
|
||||
return (
|
||||
<div
|
||||
className="rounded-lg overflow-hidden border"
|
||||
@@ -518,6 +566,31 @@ function ClaimCard835({ claim }: { claim: ClaimPayment }) {
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{/* SP21 Phase 5 Task 5.7: drill to the persisted remit. The
|
||||
835 cards have no separate "claim" (they're the payment
|
||||
side), so the link goes to /remittances?remit=PCN which
|
||||
opens the RemitDrawer for this payment. Same persisted-
|
||||
gate: only show when the PCN is in a saved batch. */}
|
||||
{canDrill ? (
|
||||
<div className="pt-1">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() =>
|
||||
navigate(
|
||||
`/remittances?remit=${encodeURIComponent(claim.payer_claim_control_number)}`,
|
||||
)
|
||||
}
|
||||
data-testid="upload-remit-drill"
|
||||
aria-label={`See remittance ${claim.payer_claim_control_number} in detail`}
|
||||
className="inline-flex items-center gap-1.5 text-[12px] mono font-semibold cursor-pointer rounded-sm px-1 -mx-1 hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1"
|
||||
style={{ color: "hsl(var(--surface-ink))" }}
|
||||
>
|
||||
See claim in detail
|
||||
<ArrowRight className="h-3 w-3" strokeWidth={2} />
|
||||
</button>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user