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 `info` still feed WordPress icon components on each row - `info` also fed // the Help button, so it survives its Button's conversion. A separate sweep. import { Pencil, Plus, Calendar as calendar, Info as info } from 'lucide-react'; import { MedicationAdministration } from 'fhir/r4'; import { AppSpinner, FhirMedicationAdministrationDisplay, ScrollableTab } from '../../../../components'; import { ResourceListStatus } from '../../../../components/ui/resource-list-status'; import { formatFhirCodeableConcept } from '../../../../utils/fhirCodeableConcept.tsx'; import { formatDate } from '../../../../utils/dateUtils.ts'; import { useFhirMedicationAdministrationBroadcast, useFhirMedicationAdministrations, useFhirMedicationAdministrationTargetedBroadcast } from '../../../../hooks'; import { useAuthServiceContext, useMedicationAdministrationServiceContext } from '../../../../services'; import '../medicationRecords.css'; import { SourcePractice } from '../../../../components/ui/source-practice'; import { RecordPracticeNote, recordPracticeId, useRecordPracticeView, useRetireOnPracticeChange } from '../../../../contexts/RecordPracticeContext'; const MedicationAdministrations = () => { const navigate = useNavigate(); const { userRole, USER_ROLES } = useAuthServiceContext(); const { getMedicationAdministrationDisplay } = useMedicationAdministrationServiceContext(); const { loading, error, clearError, medicationAdministrationsList, attempted } = useFhirMedicationAdministrations(); const [selectedMedicationAdministration, setSelectedMedicationAdministration] = useState(null); const [showDisplayModal, setShowDisplayModal] = useState(false); // The record's practice context: its own administrations under a named practice; the empty state speaks for the whole record. const practiceView = useRecordPracticeView(medicationAdministrationsList, recordPracticeId); useRetireOnPracticeChange(() => { setShowDisplayModal(false); setSelectedMedicationAdministration(null); }); useFhirMedicationAdministrationBroadcast(); useFhirMedicationAdministrationTargetedBroadcast({ medicationAdministration: selectedMedicationAdministration || undefined, isOpen: showDisplayModal, onUpdate: (updatedMedicationAdministration) => { setSelectedMedicationAdministration(updatedMedicationAdministration); }, onDelete: () => { setShowDisplayModal(false); setSelectedMedicationAdministration(null); } }); const viewMedicationAdministration = (medicationAdministration: MedicationAdministration) => { setSelectedMedicationAdministration(medicationAdministration); setShowDisplayModal(true); }; const editMedicationAdministration = (event: React.MouseEvent, medicationAdministration: MedicationAdministration) => { event.stopPropagation(); navigate(medicationAdministration.id as string, { relative: 'path' }); }; const addMedicationAdministration = () => { navigate('new', { relative: 'path' }); }; const isAuthorizedToEdit = () => { return userRole && [USER_ROLES.PRACTITIONER].includes(userRole as string); }; const getStatusDisplay = (medicationAdministration: MedicationAdministration): { text: string, color?: string } => { if (!medicationAdministration) return { text: 'Unknown' }; switch (medicationAdministration.status) { case 'in-progress': return { text: 'In Progress', color: '#e39700' }; case 'not-done': return { text: 'Not Done', color: '#cc1818' }; case 'on-hold': return { text: 'On Hold', color: '#e39700' }; case 'completed': return { text: 'Completed', color: '#00a32a' }; case 'entered-in-error': return { text: 'Error', color: '#cc1818' }; case 'stopped': return { text: 'Stopped', color: '#cc1818' }; case 'unknown': default: return { text: medicationAdministration.status?.charAt(0).toUpperCase() + medicationAdministration.status?.slice(1) || 'Unknown' }; } }; const getEffectiveTimeDisplay = (medicationAdministration: MedicationAdministration): string => { if (medicationAdministration.effectiveDateTime) { return formatDate(medicationAdministration.effectiveDateTime); } if (medicationAdministration.effectivePeriod) { const start = medicationAdministration.effectivePeriod.start ? formatDate(medicationAdministration.effectivePeriod.start) : ''; const end = medicationAdministration.effectivePeriod.end ? formatDate(medicationAdministration.effectivePeriod.end) : ''; if (start && end) { return `${start} to ${end}`; } else if (start) { return `From ${start}`; } else if (end) { return `Until ${end}`; } } return ''; }; const getCategoryDisplay = (medicationAdministration: MedicationAdministration): string => { if (medicationAdministration.category) { return formatFhirCodeableConcept(medicationAdministration.category); } return ''; }; return (
{isAuthorizedToEdit() && ( )} <> {loading ? ( ) : ( {practiceView.shown.length !== 0 && ( {practiceView.shown.map((medicationAdministration: MedicationAdministration) => { const displayTitle = getMedicationAdministrationDisplay(medicationAdministration); const { text: statusText, color: statusColor } = getStatusDisplay(medicationAdministration); const effectiveTime = getEffectiveTimeDisplay(medicationAdministration); const category = getCategoryDisplay(medicationAdministration); return ( viewMedicationAdministration(medicationAdministration)}> {/* Wraps: on a narrow row Edit moves below the whole title rather than being squeezed past the card's edge. */} {displayTitle} {category && ( Category: {category} )} {effectiveTime && ( {effectiveTime} )} {isAuthorizedToEdit() && ( )} ); })} )} )} {selectedMedicationAdministration && ( { setShowDisplayModal(false); setSelectedMedicationAdministration(null); }} /> )}
); }; export default MedicationAdministrations;