import { Dialog, DialogContent } from "@/components/ui/dialog"; import { Tabs } from "@/components/ui/tabs"; import { ApiError } from "@/lib/api"; import { DrillDrawerHeader } from "@/components/drill/DrillDrawerHeader"; import { Skeleton } from "@/components/ui/skeleton"; import { useProviderDetail } from "@/hooks/useProviderDetail"; import { ProviderOverview } from "./ProviderOverview"; import { ProviderRecentClaims } from "./ProviderRecentClaims"; import { ProviderRecentActivity } from "./ProviderRecentActivity"; import { ProviderDrawerError } from "./ProviderDrawerError"; interface Props { npi: string | null; onClose: () => void; } /** * Provider drill-down drawer (SP21 Task 2.2 + 3.1). * * Side-panel shell that consumes ``useProviderDetail(npi)`` and renders * a three-tab body: * * - Overview — base provider fields (identity + activity shape) * - Claims — top-10 claims joined to this provider * (extended `/api/config/providers/{npi}.recent_claims`, * populated by Task 1.6) * - Activity — top-10 events joined to this provider's claims * (extended `/api/config/providers/{npi}.recent_activity`) * * Layout mirrors the ClaimDrawer / RemitDrawer pattern: Radix Dialog * repositioned to the right edge as a fixed-height side panel, with * the shared ``DrillDrawerHeader`` on top and a scrollable body below. * The DialogContent is the flex parent; the header and body stack * naturally inside it without an explicit `calc(100% - 64px)` height * that would couple to DrillDrawerHeader's padding/font sizes. * * Error branching mirrors the peer drawers: * - `ApiError(404)` → "not_found" (no retry, the provider is gone) * - anything else → "network" (retry available) * - demo mode + unknown NPI → ApiError(404), routes to the same * "not_found" branch (the hook raises `ApiError(404, "Provider not * found")` in this case, matching the real backend 404 path). */ export function ProviderDrawer({ npi, onClose }: Props) { const { data, isLoading, isError, error, refetch } = useProviderDetail(npi); const errorKind: "not_found" | "network" | null = isError ? error instanceof ApiError && error.status === 404 ? "not_found" : "network" : null; return ( { if (!o) onClose(); }}> {errorKind ? ( { void refetch(); }} onClose={onClose} /> ) : isLoading || !data ? (
) : (
Overview Claims Activity
)}
); }