import { useNavigate, useParams } from 'react-router-dom'; import { useAuthServiceContext, useBodyStructureServiceContext, usePatientServiceContext } from '../../../../../services'; import { useCallback, useEffect, useState } from 'react'; import { BodyStructure } from 'fhir/r4'; import { FormProvider, useForm } from 'react-hook-form'; import { AppHeader, AppSpinner, HistoryNavigator, ProfileLayoutContainer, ScrollableTab } from '../../../../../components'; import { DismissibleAlert } from '../../../../../components/ui/dismissible-alert'; import { Flex, FlexItem } from '../../../../../components/ui/flex'; import { Text } from '../../../../../components/ui/text'; import { Spacer } from '../../../../../components/ui/spacer'; import { Modal } from '../../../../../components/ui/wp-modal-shim'; import { Check, FileText, Trash2 } from 'lucide-react'; import { formatFhirCodeableConcept } from '../../../../../utils/fhirCodeableConcept.tsx'; import FhirBodyStructure from '../../../../../components/FhirBodyStructure/FhirBodyStructure.tsx'; import { describeWriteFailure } from '../../../../../utils/fetchFailureMessage'; import { patientCacheGuard } from '../../../../../utils/cacheOwner'; export const EditBodyStructurePage = () => { const { bodyStructureId } = useParams<{ bodyStructureId: string }>(); const navigate = useNavigate(); const { currentUser } = useAuthServiceContext(); const { patientState } = usePatientServiceContext(); const { cachedForPatientId: bodyStructuresOwner, fetchBodyStructure, transformToFhirBodyStructure, transformFromFhirBodyStructure, createBodyStructure, updateBodyStructure, deleteBodyStructure, bodyStructuresList: rawBodyStructuresList } = useBodyStructureServiceContext(); // The cache outlives a change of patient: read only the patient on screen. const bodyStructuresGuard = patientCacheGuard(bodyStructuresOwner, patientState?.id); const bodyStructuresList = bodyStructuresGuard.list(rawBodyStructuresList); const [loading, setLoading] = useState(false); const [submitting, setSubmitting] = useState(false); const [success, setSuccess] = useState(); const [error, setError] = useState(); const [bodyStructure, setBodyStructure] = useState(); const [showDeleteModal, setShowDeleteModal] = useState(false); const isNew = bodyStructureId === 'new'; const spacerMargin = '24px'; const methods = useForm({ defaultValues: { description: '' } }); const { handleSubmit, reset } = methods; const init = useCallback((bodyStructure: BodyStructure) => { reset(transformFromFhirBodyStructure(bodyStructure)); setBodyStructure(bodyStructure); }, [transformFromFhirBodyStructure, reset]); useEffect(() => { const loadBodyStructure = async () => { if (isNew || bodyStructure) return; const foundBodyStructure = bodyStructuresList?.find(structure => structure.id === bodyStructureId); if (foundBodyStructure) { init(foundBodyStructure); return; } setLoading(true); try { const fetchedBodyStructure = await fetchBodyStructure(bodyStructureId as string); init(fetchedBodyStructure); } catch (err) { console.error('Error loading body structure:', err); setError('Could not load body structure. Try again.'); } finally { setLoading(false); } }; loadBodyStructure(); }, [bodyStructure, bodyStructuresList, bodyStructureId, fetchBodyStructure, init]); const onSubmit = async (data: any) => { if (!patientState) { setError('Patient information is missing. Please try again.'); return; } setSubmitting(true); setSuccess(undefined); setError(undefined); try { if (isNew) { await createBodyStructure(transformToFhirBodyStructure(data, patientState)); navigate('..', { relative: 'path' }); } else { await updateBodyStructure({ id: bodyStructure?.id, ...transformToFhirBodyStructure(data) }); } setSuccess(`Body structure ${isNew ? 'created' : 'updated'} successfully.`); setTimeout(() => setSuccess(undefined), 3_000); } catch (err: any) { console.error(`Error ${isNew ? 'creating' : 'updating'} body structure:`, err); setError(describeWriteFailure(err, `Failed to ${isNew ? 'create' : 'update'} body structure`)); } finally { setSubmitting(false); } }; const handleDeleteBodyStructure = async () => { if (!bodyStructure) return; try { } catch (error) { console.error('Failed to delete body structure:', error); // The save path above already reads a refusal correctly; the delete was left behind by // that sweep and is the same clinical write. setError(describeWriteFailure(error, 'Failed to delete body structure')); } finally { setShowDeleteModal(false); } }; if (loading) { return ; } return ( resourceType="BodyStructure" resourceId={bodyStructureId || ''}> {(showHistory) => (
{!isNew && ( )} {!isNew && ( )} {success && ( <> setSuccess(undefined)}> {success} )} {error && ( <> setError(undefined)}>
{error}
)} {/* Delete Confirmation Modal */} {showDeleteModal && ( setShowDeleteModal(false)}> Are you sure you want to delete the body structure for {formatFhirCodeableConcept(bodyStructure?.morphology)}? {/* Cancel removed: the Modal's own X calls the same setShowDeleteModal(false), so it was redundant. */} )}
)} ); }; export default EditBodyStructurePage;