import React, { useState, useEffect, useCallback } from 'react'; import { useNavigate, useParams } from 'react-router-dom'; import { DismissibleAlert } from '../../../../../components/ui/dismissible-alert'; import { Spacer } from '../../../../../components/ui/spacer'; import { useForm, FormProvider } from 'react-hook-form'; import { DeviceUseStatement } from 'fhir/r4'; import { Check, FileText } from 'lucide-react'; import { useAuthServiceContext, useDeviceUseStatementServiceContext, usePatientServiceContext } from '../../../../../services'; import { AppHeader, AppSpinner, ProfileLayoutContainer, ScrollableTab, HistoryNavigator, FhirDeviceUseStatement } from '../../../../../components'; import { useFhirDeviceUseStatementTargetedBroadcast } from '../../../../../hooks'; import { useArchive } from '../../../../../hooks/useArchive'; import ArchiveConfirmModal from '../../../../../components/ArchiveConfirmModal/ArchiveConfirmModal'; import { describeWriteFailure } from '../../../../../utils/fetchFailureMessage'; import { useProxyCannotAddToRecord } from '../../../../../hooks/useProxyCannotAddToRecord'; import { describeProxyCannotAddToRecord } from '../../../../../utils/proxyFormAuthority'; import { patientCacheGuard } from '../../../../../utils/cacheOwner'; const EditDeviceUseStatementPage: React.FC = () => { const { deviceUseStatementId } = useParams<{ deviceUseStatementId: string }>(); const proxyCannotAdd = useProxyCannotAddToRecord(); const navigate = useNavigate(); const { currentUser } = useAuthServiceContext(); const { patientState } = usePatientServiceContext(); const { cachedForPatientId: deviceUseStatementsOwner, fetchDeviceUseStatement, transformToFhirDeviceUseStatement, transformFromFhirDeviceUseStatement, createDeviceUseStatement, updateDeviceUseStatement, archiveDeviceUseStatement, deviceUseStatementsList: rawDeviceUseStatementsList } = useDeviceUseStatementServiceContext(); // The cache outlives a change of patient: read only the patient on screen. const deviceUseStatementsGuard = patientCacheGuard(deviceUseStatementsOwner, patientState?.id); const deviceUseStatementsList = deviceUseStatementsGuard.list(rawDeviceUseStatementsList); const [loading, setLoading] = useState(false); const [submitting, setSubmitting] = useState(false); const [success, setSuccess] = useState(); const [error, setError] = useState(); const [deviceUseStatement, setDeviceUseStatement] = useState(); const archive = useArchive((reason, note) => archiveDeviceUseStatement(deviceUseStatement!, reason, note)); useEffect(() => { if (proxyCannotAdd) archive.close(); }, [proxyCannotAdd, archive.close]); const isNew = deviceUseStatementId === 'new'; const spacerMargin = '24px'; const methods = useForm({ defaultValues: { status: '', device: null, bodySite: null, timingType: 'dateTime', timingDateTime: '', timingTiming: null, reasonCode: [], reasonReference: [], note: [], derivedFrom: [] } }); const { handleSubmit, reset } = methods; const init = useCallback((deviceUseStatement: DeviceUseStatement) => { reset(transformFromFhirDeviceUseStatement(deviceUseStatement)); setDeviceUseStatement(deviceUseStatement); }, [transformFromFhirDeviceUseStatement]); useFhirDeviceUseStatementTargetedBroadcast({ deviceUseStatement, deviceUseStatementId, onUpdate: init, onDelete: () => navigate('..', { relative: 'path' }) }); useEffect(() => { const loadDeviceUseStatement = async () => { if (isNew || deviceUseStatement) return; const foundDeviceUseStatement = deviceUseStatementsList?.find(dus => dus.id === deviceUseStatementId); if (foundDeviceUseStatement) { init(foundDeviceUseStatement); return; } setLoading(true); try { const fetchedDeviceUseStatement = await fetchDeviceUseStatement(deviceUseStatementId as string); init(fetchedDeviceUseStatement); } catch (err) { console.error('Error loading device use statement:', err); setError('Could not load device use statement. Try again.'); } finally { setLoading(false); } }; loadDeviceUseStatement(); }, [deviceUseStatement, deviceUseStatementsList, deviceUseStatementId, fetchDeviceUseStatement, init]); const onSubmit = async (data: any) => { if (proxyCannotAdd) return; if (!patientState) { setError('Patient information is missing. Please try again.'); return; } setSubmitting(true); setSuccess(undefined); setError(undefined); try { if (isNew) { await createDeviceUseStatement(transformToFhirDeviceUseStatement(data, patientState, currentUser?.fhir)); navigate('..', { relative: 'path' }); } else { await updateDeviceUseStatement({ id: deviceUseStatement?.id, ...transformToFhirDeviceUseStatement(data) }); } setSuccess(`Device use statement ${isNew ? 'created' : 'updated'} successfully.`); setTimeout(() => setSuccess(undefined), 3_000); } catch (err: any) { console.error(`Error ${isNew ? 'creating' : 'updating'} device use statement:`, err); setError(describeWriteFailure(err, `Failed to ${isNew ? 'create' : 'update'} device use statement`)); } finally { setSubmitting(false); } }; if (loading) { return ; } return ( resourceType="DeviceUseStatement" resourceId={deviceUseStatementId || ''}> {(showHistory) => (
{!isNew && ( )} {!proxyCannotAdd && ( )} {!isNew && !proxyCannotAdd && ( )} {proxyCannotAdd &&

{describeProxyCannotAddToRecord(undefined)}

} {success && ( <> setSuccess(undefined)}> {success} )} {error && ( <> setError(undefined)}>
{error}
)} { if (!o) archive.close(); }} resourceLabel="Device Use Statement" submitting={archive.submitting} error={archive.error} onConfirm={async (reason, note) => { if (!proxyCannotAdd && await archive.submit(reason, note)) { navigate('..', { relative: 'path' }); } }} />
)} ); }; export default EditDeviceUseStatementPage;