173 lines
6.0 KiB
TypeScript
173 lines
6.0 KiB
TypeScript
import React, { useEffect, useState } from 'react';
|
||
import { ActionIcon, Button, Group, Modal, Stack, Text, Loader } from '@mantine/core';
|
||
import { showErrorMessage } from '~/utils/utils.ts';
|
||
import { apiGetDoctorsList } from '~/utils/hms_api.ts';
|
||
import type { DoctorData, DoctorDataWithPermission } from '~/utils/models.ts';
|
||
import InfoIcon from 'mdi-react/InfoIcon';
|
||
import { iconMStyle } from '~/styles.ts';
|
||
import { DoctorGrade } from '~/utils/hms_enums.ts';
|
||
|
||
// 缓存已加载的医生数据,避免重复请求
|
||
const doctorCache = new Map<number, DoctorDataWithPermission>();
|
||
|
||
interface DoctorInfoDisplayProps {
|
||
doctorId: number;
|
||
showIcon?: boolean;
|
||
}
|
||
|
||
export function DoctorInfoDisplay({ doctorId, showIcon = true }: DoctorInfoDisplayProps) {
|
||
const [doctorInfo, setDoctorInfo] = useState<DoctorDataWithPermission | null>(null);
|
||
const [loading, setLoading] = useState(true);
|
||
const [modalOpen, setModalOpen] = useState(false);
|
||
const [initialLoad, setInitialLoad] = useState(true);
|
||
|
||
useEffect(() => {
|
||
// 如果已经在缓存中,直接使用缓存数据
|
||
if (doctorCache.has(doctorId)) {
|
||
setDoctorInfo(doctorCache.get(doctorId) || null);
|
||
setLoading(false);
|
||
setInitialLoad(false);
|
||
return;
|
||
}
|
||
|
||
// 否则加载医生数据
|
||
fetchDoctorInfo();
|
||
}, [doctorId]);
|
||
|
||
const fetchDoctorInfo = async () => {
|
||
try {
|
||
setLoading(true);
|
||
// 获取所有医生信息,传递-1表示不分页,获取所有医生
|
||
const response = await apiGetDoctorsList(-1);
|
||
|
||
if (response.success) {
|
||
const doctors = response.data.doctors;
|
||
// 将所有医生添加到缓存
|
||
doctors.forEach(doctor => {
|
||
doctorCache.set(doctor.id, doctor);
|
||
});
|
||
|
||
// 查找当前需要的医生
|
||
const doctor = doctors.find(d => d.id === doctorId);
|
||
|
||
if (doctor) {
|
||
setDoctorInfo(doctor);
|
||
} else {
|
||
console.warn(`Doctor with ID ${doctorId} not found`);
|
||
}
|
||
} else {
|
||
showErrorMessage(response.message, "Failed to load doctor information");
|
||
}
|
||
} catch (error) {
|
||
showErrorMessage("Error loading doctor information", "Error");
|
||
console.error("Error fetching doctor information:", error);
|
||
} finally {
|
||
setLoading(false);
|
||
setInitialLoad(false);
|
||
}
|
||
};
|
||
|
||
const openModal = () => {
|
||
setModalOpen(true);
|
||
};
|
||
|
||
const closeModal = () => {
|
||
setModalOpen(false);
|
||
};
|
||
|
||
// 初始加载时显示加载状态
|
||
if (initialLoad) {
|
||
return <Loader size="xs" />;
|
||
}
|
||
|
||
// 如果无法找到医生信息,显示 ID
|
||
if (!doctorInfo) {
|
||
return (
|
||
<Group gap="xs">
|
||
<Text>ID: {doctorId}</Text>
|
||
{showIcon && (
|
||
<ActionIcon
|
||
size="sm"
|
||
onClick={fetchDoctorInfo}
|
||
loading={loading}
|
||
title="Refresh doctor information"
|
||
>
|
||
<InfoIcon style={iconMStyle} />
|
||
</ActionIcon>
|
||
)}
|
||
</Group>
|
||
);
|
||
}
|
||
|
||
return (
|
||
<>
|
||
<Group gap="xs">
|
||
<Text
|
||
style={{ cursor: 'pointer' }}
|
||
onClick={openModal}
|
||
title="Click to view details"
|
||
>
|
||
{`${doctorInfo.title} ${doctorInfo.name}`}
|
||
</Text>
|
||
{showIcon && (
|
||
<ActionIcon
|
||
size="sm"
|
||
onClick={openModal}
|
||
title="View doctor details"
|
||
>
|
||
<InfoIcon style={iconMStyle} />
|
||
</ActionIcon>
|
||
)}
|
||
</Group>
|
||
|
||
<Modal
|
||
opened={modalOpen}
|
||
onClose={closeModal}
|
||
title="Doctor Information"
|
||
centered
|
||
size="md"
|
||
>
|
||
<Stack gap="md">
|
||
<Group>
|
||
<Text fw={500} w={100}>Name:</Text>
|
||
<Text>{`${doctorInfo.title} ${doctorInfo.name}`}</Text>
|
||
</Group>
|
||
<Group>
|
||
<Text fw={500} w={100}>Gender:</Text>
|
||
<Text>{doctorInfo.gender}</Text>
|
||
</Group>
|
||
<Group>
|
||
<Text fw={500} w={100}>Grade:</Text>
|
||
<Text>{DoctorGrade[doctorInfo.grade]}</Text>
|
||
</Group>
|
||
<Group>
|
||
<Text fw={500} w={100}>Birth Date:</Text>
|
||
<Text>{doctorInfo.birth_date}</Text>
|
||
</Group>
|
||
<Group>
|
||
<Text fw={500} w={100}>Email:</Text>
|
||
<Text>{doctorInfo.email}</Text>
|
||
</Group>
|
||
<Group>
|
||
<Text fw={500} w={100}>Phone:</Text>
|
||
<Text>{doctorInfo.phone}</Text>
|
||
</Group>
|
||
<Group>
|
||
<Text fw={500} w={100}>Admin:</Text>
|
||
<Text>{doctorInfo.is_admin ? 'Yes' : 'No'}</Text>
|
||
</Group>
|
||
<Group>
|
||
<Text fw={500} w={100}>Status:</Text>
|
||
<Text color={doctorInfo.is_resigned ? 'red' : 'green'}>
|
||
{doctorInfo.is_resigned ? 'Resigned' : 'Active'}
|
||
</Text>
|
||
</Group>
|
||
|
||
<Group justify="flex-end" mt="md">
|
||
<Button onClick={closeModal}>Close</Button>
|
||
</Group>
|
||
</Stack>
|
||
</Modal>
|
||
</>
|
||
);
|
||
}
|