import React from "react"; import { CodeableConcept, HealthcareService } from "fhir/r4"; import { Card, CardContent, CardHeader } from "../ui/card"; import { Dialog, DialogContent, DialogTitle } from "../ui/dialog"; import { FhirCodeableConceptDisplay } from "../../utils/fhirCodeableConcept"; import { FhirReferenceDisplay } from "../../utils/fhirReference"; import { FhirPeriodDisplay } from "../../utils/fhirPeriod"; import { FhirOperationalHoursDisplay } from "../../utils/fhirOperationalHours"; import { FHIRContactPointDisplay } from "../../utils/fhirContactPoint"; import ProfilePhoto from "../ProfilePhoto/ProfilePhoto"; import { FieldHistoryProvider, FieldHistoryScope } from "../FieldHistory/FieldHistoryProvider"; import { ShowFieldHistoryToggle } from "../FieldHistory/ShowFieldHistoryToggle"; import { RecordEditedMarker } from "../FieldHistory/RecordEditedMarker"; import { Field } from "../FieldHistory/Field"; import { FieldGroup, Section } from "../FieldHistory/FieldLayout"; interface FhirHealthcareServiceDisplayProps { healthcareService: HealthcareService; isOpen?: boolean; onClose?: () => void; title?: string; asModal?: boolean; } /** * Per-active pill colors (explicit hex, never the `text-green-*`/`bg-green-*` Tailwind palette -- * matches the convention set by `FhirCarePlanDisplay`'s `STATUS_STYLES`). */ const ACTIVE_STYLES: Record<"active" | "inactive", { bg: string; text: string }> = { active: { bg: "var(--green-soft)", text: "var(--success)" }, inactive: { bg: "var(--red-soft)", text: "var(--danger)" }, }; const renderActivePill = (active: boolean | undefined): React.ReactNode => { if (active === undefined) return undefined; const style = active ? ACTIVE_STYLES.active : ACTIVE_STYLES.inactive; return ( {active ? "Active" : "Inactive"} ); }; const renderYesNo = (value: boolean | undefined): string | undefined => { if (value === undefined) return undefined; return value ? "Yes" : "No"; }; /** * `FhirCodeableConceptDisplay` (and the codebase's other CC helpers) render `concept.text` only. * Several HealthcareService CC fields are commonly coded without a `.text` convenience string, so * this backfills `.text` from `coding[0].display` before handing off to the shared display * component -- fixes the "blank chip" bug without touching the shared util. */ function withCodeableConceptTextFallback( input: CodeableConcept | CodeableConcept[] | undefined, ): CodeableConcept | CodeableConcept[] | undefined { if (!input) { return input; } const applyFallback = (concept: CodeableConcept): CodeableConcept => ({ ...concept, text: concept.text || concept.coding?.[0]?.display, }); return Array.isArray(input) ? input.map(applyFallback) : applyFallback(input); } export const FhirHealthcareServiceDisplay: React.FC< FhirHealthcareServiceDisplayProps > = ({ healthcareService, isOpen = true, onClose, title = "Healthcare Service Details", asModal = true, }) => { const renderNotAvailable = () => { if (!healthcareService.notAvailable || healthcareService.notAvailable.length === 0) { return (

No unavailable periods recorded

); } return (
{healthcareService.notAvailable.map((notAvailable, index) => (
Unavailable Period {index + 1}
} />
))}
); }; const renderEligibility = () => { if (!healthcareService.eligibility || healthcareService.eligibility.length === 0) { return (

No eligibility requirements recorded

); } return (
{healthcareService.eligibility.map((item, index) => (
Eligibility {index + 1}
} />
))}
); }; const renderContent = () => (
{healthcareService.photo && ( )}

{title}

} /> } /> } /> } /> } /> } /> } /> } /> } /> } />
} /> } />
{renderNotAvailable()}
{renderEligibility()}
); if (!asModal) { return (
{renderContent()}
); } if (!isOpen) return null; return ( { if (!next) onClose?.(); }} > {title} {renderContent()} ); }; export default FhirHealthcareServiceDisplay;