import React, { useState, useCallback, useRef, useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import { Button, ModalHeader, ModalBody, ModalFooter, InlineLoading, Tile, Tag } from '@carbon/react'; import type { MedicationDispense } from '../types'; import MedicationEvent from '../components/medication-event.component'; import styles from './duplicate-dispense-modal.scss'; import { getCoreTranslation, parseDate, formatDatetime } from '@openmrs/esm-framework'; interface DuplicateDispenseModalProps { onClose: () => void; onConfirm: () => Promise; title?: string; message?: string; medicationName?: string; previousDispenseDate?: string; previousQuantity?: number; previousQuantityUnit?: string; previousPerformer?: string; previousRoute?: string; previousSchedule?: string; previousDispense?: MedicationDispense; } const DuplicateDispenseModal: React.FC = ({ onClose, onConfirm, title, message, medicationName, previousDispenseDate, previousQuantity, previousQuantityUnit, previousPerformer, previousRoute, previousSchedule, previousDispense, }) => { const { t } = useTranslation(); const [isProcessing, setIsProcessing] = useState(false); const [error, setError] = useState(null); const isMountedRef = useRef(true); useEffect(() => { return () => { isMountedRef.current = false; }; }, []); const formatDateSafe = (dateString?: string) => { if (!dateString) return ''; try { const parsed = parseDate(dateString); if (!parsed || Number.isNaN(parsed.getTime())) { const d = new Date(dateString); if (Number.isNaN(d.getTime())) { return dateString; } return d.toLocaleString(); } return formatDatetime(parsed); } catch { const d = new Date(dateString); if (Number.isNaN(d.getTime())) { return dateString; } return d.toLocaleString(); } }; const handleConfirm = useCallback(async () => { setError(null); setIsProcessing(true); try { await onConfirm(); onClose(); } catch (err) { console.error('Error during dispensing:', err); setError(t('duplicateDispenseError', 'Error dispensing medication')); } finally { if (isMountedRef.current) { setIsProcessing(false); } } }, [onConfirm, onClose, t]); const modalTitle = title ?? t('duplicatePrescriptionTitle', 'Potential duplicate dispense detected'); const modalMessage = message ?? (!previousDispense ? t('duplicatePrescriptionMessageNoPrevious', 'A previous dispense could not be found.') : ''); return ( <> {!previousDispense && modalMessage &&

{modalMessage}

} {medicationName && !previousDispense && (
{t('medication', 'Medication')} {medicationName}
)} {previousDispense ? (
{t('dispensed', 'Dispensed')} {medicationName && {medicationName}}
{previousPerformer && ( {t('dispensedBy', 'Dispensed by')}: {previousPerformer} )} {previousPerformer && previousDispenseDate && } {previousDispenseDate && {formatDateSafe(previousDispenseDate)}}
) : ( <> {previousDispenseDate && previousQuantity !== undefined && (

{t('previousDispenseDetails', 'Previous dispense on')}{' '} {formatDateSafe(previousDispenseDate)} {t('withQuantity', 'with quantity')}{' '} {previousQuantity} {previousQuantityUnit ? ` ${previousQuantityUnit}` : ''} .

)} {previousRoute && (

{t('route', 'Route')}: {previousRoute}

)} {previousSchedule && (

{t('schedule', 'Schedule')}: {previousSchedule}

)} )}

{t( 'duplicateDispenseConfirmationPrompt', 'Do you want to proceed with dispensing? Proceeding will create another dispense record.', )}

{error &&

{error}

}
); }; export default DuplicateDispenseModal;