HMS_Group5/HMS_Frontend/app/components/subs/PatientInfoDisplay.tsx
2025-04-30 17:28:58 +01:00

166 lines
5.7 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useEffect, useState } from 'react';
import { ActionIcon, Button, Group, Modal, Stack, Text, Loader } from '@mantine/core';
import { showErrorMessage } from '~/utils/utils.ts';
import { apiGetPatientsList } from '~/utils/hms_api.ts';
import type { PatientData } from '~/utils/models.ts';
import InfoIcon from 'mdi-react/InfoIcon';
import { iconMStyle } from '~/styles.ts';
// 缓存已加载的患者数据,避免重复请求
const patientCache = new Map<number, PatientData>();
interface PatientInfoDisplayProps {
patientId: number;
showIcon?: boolean;
}
export function PatientInfoDisplay({ patientId, showIcon = true }: PatientInfoDisplayProps) {
const [patientInfo, setPatientInfo] = useState<PatientData | null>(null);
const [loading, setLoading] = useState(true);
const [modalOpen, setModalOpen] = useState(false);
const [initialLoad, setInitialLoad] = useState(true);
useEffect(() => {
// 如果已经在缓存中,直接使用缓存数据
if (patientCache.has(patientId)) {
setPatientInfo(patientCache.get(patientId) || null);
setLoading(false);
setInitialLoad(false);
return;
}
// 否则加载患者数据
fetchPatientInfo();
}, [patientId]);
const fetchPatientInfo = async () => {
try {
setLoading(true);
// 获取所有患者信息,传递-1表示不分页获取所有患者
const response = await apiGetPatientsList(-1);
if (response.success) {
const patients = response.data.patients;
// 将所有患者添加到缓存
patients.forEach(patient => {
patientCache.set(patient.id, patient);
});
// 查找当前需要的患者
const patient = patients.find(p => p.id === patientId);
if (patient) {
setPatientInfo(patient);
} else {
console.warn(`Patient with ID ${patientId} not found`);
}
} else {
showErrorMessage(response.message, "Failed to load patient information");
}
} catch (error) {
showErrorMessage("Error loading patient information", "Error");
console.error("Error fetching patient information:", error);
} finally {
setLoading(false);
setInitialLoad(false);
}
};
const openModal = () => {
setModalOpen(true);
};
const closeModal = () => {
setModalOpen(false);
};
// 初始加载时显示加载状态
if (initialLoad) {
return <Loader size="xs" />;
}
// 如果无法找到患者信息,显示 ID
if (!patientInfo) {
return (
<Group gap="xs">
<Text>ID: {patientId}</Text>
{showIcon && (
<ActionIcon
size="sm"
onClick={fetchPatientInfo}
loading={loading}
title="Refresh patient information"
>
<InfoIcon style={iconMStyle} />
</ActionIcon>
)}
</Group>
);
}
return (
<>
<Group gap="xs">
<Text
style={{ cursor: 'pointer' }}
onClick={openModal}
title="Click to view details"
>
{`${patientInfo.title} ${patientInfo.name}`}
</Text>
{showIcon && (
<ActionIcon
size="sm"
onClick={openModal}
title="View patient details"
>
<InfoIcon style={iconMStyle} />
</ActionIcon>
)}
</Group>
<Modal
opened={modalOpen}
onClose={closeModal}
title="Patient Information"
centered
size="md"
>
<Stack gap="md">
<Group>
<Text fw={500} w={100}>Name:</Text>
<Text>{`${patientInfo.title} ${patientInfo.name}`}</Text>
</Group>
<Group>
<Text fw={500} w={100}>Gender:</Text>
<Text>{patientInfo.gender}</Text>
</Group>
<Group>
<Text fw={500} w={100}>Birth Date:</Text>
<Text>{patientInfo.birth_date}</Text>
</Group>
<Group>
<Text fw={500} w={100}>Email:</Text>
<Text>{patientInfo.email}</Text>
</Group>
<Group>
<Text fw={500} w={100}>Phone:</Text>
<Text>{patientInfo.phone}</Text>
</Group>
<Group>
<Text fw={500} w={100}>Address:</Text>
<Text>{patientInfo.address}</Text>
</Group>
<Group>
<Text fw={500} w={100}>Postcode:</Text>
<Text>{patientInfo.postcode}</Text>
</Group>
<Group justify="flex-end" mt="md">
<Button onClick={closeModal}>Close</Button>
</Group>
</Stack>
</Modal>
</>
);
}