import { useState } from 'react'; import { Item, ItemGroup } from "../../../../components/ui/item-group"; import { useNavigate } from 'react-router-dom'; import { Icon } from "../../../../components/ui/icon"; import { Flex, FlexItem, FlexBlock } from '../../../../components/ui/flex'; import { Text } from '../../../../components/ui/text'; import { Spacer } from '../../../../components/ui/spacer'; // `calendar` and `shield` still feed WordPress icon components on each row - a separate sweep. import { Pencil, Plus, Calendar as calendar, Shield as shield } from 'lucide-react'; import { Immunization } from 'fhir/r4'; import { AppSpinner, FhirImmunizationDisplay, ScrollableTab } from '../../../../components'; import { ResourceListStatus } from '../../../../components/ui/resource-list-status'; import { formatFhirCodeableConcept } from '../../../../utils/fhirCodeableConcept.tsx'; import { formatDate } from '../../../../utils/dateUtils.ts'; import { useFhirImmunizationBroadcast, useFhirImmunizations, useFhirImmunizationTargetedBroadcast } from '../../../../hooks'; import { useAuthServiceContext, useImmunizationServiceContext } from '../../../../services'; import '../medicationRecords.css'; import { SourcePractice } from '../../../../components/ui/source-practice'; import { RecordPracticeNote, recordPracticeId, useRecordPracticeView, useRetireOnPracticeChange } from '../../../../contexts/RecordPracticeContext'; const Immunizations = () => { const navigate = useNavigate(); const { userRole, USER_ROLES } = useAuthServiceContext(); const { getImmunizationDisplay } = useImmunizationServiceContext(); const { loading, error, clearError, immunizationsList, attempted } = useFhirImmunizations(); const [selectedImmunization, setSelectedImmunization] = useState(null); const [showDisplayModal, setShowDisplayModal] = useState(false); // The record's practice context: its own immunizations under a named practice; the empty state speaks for the whole record. const practiceView = useRecordPracticeView(immunizationsList, recordPracticeId); useRetireOnPracticeChange(() => { setShowDisplayModal(false); setSelectedImmunization(null); }); useFhirImmunizationBroadcast(); useFhirImmunizationTargetedBroadcast({ immunization: selectedImmunization || undefined, isOpen: showDisplayModal, onUpdate: (updatedImmunization) => { setSelectedImmunization(updatedImmunization); }, onDelete: () => { setShowDisplayModal(false); setSelectedImmunization(null); } }); const viewImmunization = (immunization: Immunization) => { setSelectedImmunization(immunization); setShowDisplayModal(true); }; const editImmunization = (event: React.MouseEvent, immunization: Immunization) => { event.stopPropagation(); navigate(immunization.id as string, { relative: 'path' }); }; const addImmunization = () => { navigate('new', { relative: 'path' }); }; const isAuthorizedToEdit = () => { return userRole && [USER_ROLES.PRACTITIONER].includes(userRole as string); }; const getStatusDisplay = (immunization: Immunization): { text: string, color?: string } => { if (!immunization) return { text: 'Unknown' }; switch (immunization.status) { case 'completed': return { text: 'Completed', color: '#00a32a' }; case 'entered-in-error': return { text: 'Error', color: '#cc1818' }; case 'not-done': return { text: 'Not Done', color: '#cc1818' }; default: return { text: immunization.status.charAt(0).toUpperCase() + immunization.status.slice(1).replace('-', ' ') }; } }; return (
{isAuthorizedToEdit() && ( )} <> {loading ? ( ) : ( {practiceView.shown.length !== 0 && ( {practiceView.shown.map((immunization: Immunization) => { const displayTitle = getImmunizationDisplay(immunization); const { text: statusText, color: statusColor } = getStatusDisplay(immunization); const site = formatFhirCodeableConcept(immunization.site); const route = formatFhirCodeableConcept(immunization.route); const occurrenceDate = immunization.occurrenceDateTime ? formatDate(immunization.occurrenceDateTime) : ''; return ( viewImmunization(immunization)}> {/* Wraps: on a narrow row Edit moves below the whole title rather than being squeezed past the card's edge. */} {displayTitle} {(site || route) && ( {site && `Site: ${site}`} {site && route && ' • '} {route && `Route: ${route}`} )} {occurrenceDate && ( {occurrenceDate} )} {isAuthorizedToEdit() && ( )} ); })} )} )} {selectedImmunization && ( { setShowDisplayModal(false); setSelectedImmunization(null); }} /> )}
); }; export default Immunizations;