feat:update-project
This commit is contained in:
@@ -28,6 +28,7 @@ import {
|
|||||||
TooltipProvider,
|
TooltipProvider,
|
||||||
TooltipTrigger,
|
TooltipTrigger,
|
||||||
} from "@radix-ui/react-tooltip";
|
} from "@radix-ui/react-tooltip";
|
||||||
|
import { SPECIALTY_DISPLAY_NAME, SPECIALTY_ORDER } from "@/constant/config";
|
||||||
|
|
||||||
const DetailConsultation = () => {
|
const DetailConsultation = () => {
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
@@ -37,9 +38,12 @@ const DetailConsultation = () => {
|
|||||||
|
|
||||||
const consultationId = params?.id as string;
|
const consultationId = params?.id as string;
|
||||||
|
|
||||||
|
const [openTooltip, setOpenTooltip] = useState(false);
|
||||||
const [prescriptionPage, setPrescriptionPage] = useState<number>(1);
|
const [prescriptionPage, setPrescriptionPage] = useState<number>(1);
|
||||||
const [prescriptionPageSize, setPrescriptionPageSize] = useState<number>(10);
|
const [prescriptionPageSize, setPrescriptionPageSize] = useState<number>(10);
|
||||||
|
|
||||||
|
const normalize = (text?: string) => (text ?? "").trim().toLowerCase();
|
||||||
|
|
||||||
const consulDetailQuery = useQuery<ConsultationDetail>({
|
const consulDetailQuery = useQuery<ConsultationDetail>({
|
||||||
queryKey: [QUERY_KEY.chi_tiet_phien_kham, consultationId],
|
queryKey: [QUERY_KEY.chi_tiet_phien_kham, consultationId],
|
||||||
|
|
||||||
@@ -79,15 +83,72 @@ const DetailConsultation = () => {
|
|||||||
consultation?.status !== TYPE_STATUS.Completed &&
|
consultation?.status !== TYPE_STATUS.Completed &&
|
||||||
consultation?.status !== TYPE_STATUS.Cancelled;
|
consultation?.status !== TYPE_STATUS.Cancelled;
|
||||||
|
|
||||||
|
// const specialtyTabs = useMemo(() => {
|
||||||
|
// return (
|
||||||
|
// consultation?.specialtyClinics?.map((item) => ({
|
||||||
|
// pathname: `/consultation/${consultationId}`,
|
||||||
|
// query: item.id,
|
||||||
|
// title: item.specialtyName,
|
||||||
|
// })) || []
|
||||||
|
// );
|
||||||
|
// }, [consultation?.specialtyClinics, consultationId]);
|
||||||
|
|
||||||
const specialtyTabs = useMemo(() => {
|
const specialtyTabs = useMemo(() => {
|
||||||
return (
|
if (!consultation?.specialtyClinics?.length) return [];
|
||||||
consultation?.specialtyClinics?.map((item) => ({
|
|
||||||
pathname: `/consultation/${consultationId}`,
|
//------------------------------------
|
||||||
query: item.id,
|
// Chuẩn hóa tên
|
||||||
title: item.specialtyName,
|
//------------------------------------
|
||||||
})) || []
|
|
||||||
);
|
const specialties = consultation.specialtyClinics.map((item) => ({
|
||||||
|
...item,
|
||||||
|
|
||||||
|
displayName:
|
||||||
|
SPECIALTY_DISPLAY_NAME[item.specialtyName] ?? item.specialtyName,
|
||||||
|
}));
|
||||||
|
|
||||||
|
//------------------------------------
|
||||||
|
// Ưu tiên chuyên khoa đã khám
|
||||||
|
//------------------------------------
|
||||||
|
|
||||||
|
specialties.sort((a, b) => {
|
||||||
|
const aVisited = a.specialtyStatus === 3;
|
||||||
|
const bVisited = b.specialtyStatus === 3;
|
||||||
|
|
||||||
|
// Đã khám lên trước
|
||||||
|
|
||||||
|
if (aVisited !== bVisited) {
|
||||||
|
return aVisited ? -1 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sau đó theo SPECIALTY_ORDER
|
||||||
|
|
||||||
|
const indexA = SPECIALTY_ORDER.findIndex(
|
||||||
|
(x) => normalize(x) === normalize(a.displayName),
|
||||||
|
);
|
||||||
|
|
||||||
|
const indexB = SPECIALTY_ORDER.findIndex(
|
||||||
|
(x) => normalize(x) === normalize(b.displayName),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (indexA === -1 && indexB === -1) {
|
||||||
|
return a.displayName.localeCompare(b.displayName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (indexA === -1) return 1;
|
||||||
|
|
||||||
|
if (indexB === -1) return -1;
|
||||||
|
|
||||||
|
return indexA - indexB;
|
||||||
|
});
|
||||||
|
|
||||||
|
return specialties.map((item) => ({
|
||||||
|
pathname: `/consultation/${consultationId}`,
|
||||||
|
query: item.id,
|
||||||
|
title: item.displayName,
|
||||||
|
}));
|
||||||
}, [consultation?.specialtyClinics, consultationId]);
|
}, [consultation?.specialtyClinics, consultationId]);
|
||||||
|
|
||||||
// Tính toán cắt mảng dữ liệu thuốc để hiển thị phân trang trên Client
|
// Tính toán cắt mảng dữ liệu thuốc để hiển thị phân trang trên Client
|
||||||
const paginatedPrescriptionItems = useMemo(() => {
|
const paginatedPrescriptionItems = useMemo(() => {
|
||||||
const items = consultation?.aggregatedPrescriptionItems || [];
|
const items = consultation?.aggregatedPrescriptionItems || [];
|
||||||
@@ -153,18 +214,18 @@ const DetailConsultation = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-4">
|
<div className="flex flex-col gap-4">
|
||||||
<div className="flex flex-row gap-4">
|
<GridColumn col={2}>
|
||||||
<div className="rounded-2xl border border-gray-200 bg-white p-6 shadow-sm">
|
<div className="rounded-2xl border border-gray-200 bg-white p-6 shadow-sm">
|
||||||
<div className="flex flex-col gap-6">
|
<div className="flex flex-col gap-6">
|
||||||
{/* HEADER */}
|
{/* HEADER */}
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex flex-col items-start gap-4 lg:flex-row lg:items-center lg:justify-between lg:gap-0">
|
||||||
<div
|
<div
|
||||||
className="flex cursor-pointer items-center gap-3"
|
className="flex cursor-pointer items-center gap-3"
|
||||||
onClick={() => router.back()}
|
onClick={() => router.back()}
|
||||||
>
|
>
|
||||||
<ArrowLeft className="h-6 w-6" />
|
<ArrowLeft className="h-6 w-6 shrink-0" />
|
||||||
|
|
||||||
<h2 className="text-[28px] font-semibold text-[#111827]">
|
<h2 className="text-[22px] font-semibold text-[#111827] sm:text-[28px]">
|
||||||
Chi tiết phiên khám
|
Chi tiết phiên khám
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
@@ -265,7 +326,7 @@ const DetailConsultation = () => {
|
|||||||
{/* CHẨN ĐOÁN */}
|
{/* CHẨN ĐOÁN */}
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
<p className="text-[14px] font-medium text-[#697586]">
|
<p className="text-[14px] font-medium text-[#697586]">
|
||||||
CHUẨN ĐOÁN
|
CHẨN ĐOÁN
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p className="text-[15px] font-medium text-[#202939]">
|
<p className="text-[15px] font-medium text-[#202939]">
|
||||||
@@ -338,18 +399,24 @@ const DetailConsultation = () => {
|
|||||||
</p>
|
</p>
|
||||||
{consultation.generalAttachmentUrls?.length > 0 ? (
|
{consultation.generalAttachmentUrls?.length > 0 ? (
|
||||||
<TooltipProvider>
|
<TooltipProvider>
|
||||||
<Tooltip>
|
<Tooltip open={openTooltip} onOpenChange={setOpenTooltip}>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<div className="inline-flex cursor-pointer items-center gap-2 rounded-lg border border-blue-100 bg-blue-50 px-3 py-2 text-sm font-medium text-blue-600 transition hover:bg-blue-100">
|
<div
|
||||||
|
onClick={() => setOpenTooltip((prev) => !prev)}
|
||||||
|
className="inline-flex cursor-pointer items-center gap-2 rounded-lg border border-blue-100 bg-blue-50 px-3 py-2 text-sm font-medium text-blue-600 transition hover:bg-blue-100 active:bg-blue-200"
|
||||||
|
>
|
||||||
<span>📎</span>
|
<span>📎</span>
|
||||||
<span>Chi tiết các file</span>
|
<span>
|
||||||
|
Chi tiết các file (
|
||||||
|
{consultation.generalAttachmentUrls.length})
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
|
|
||||||
<TooltipContent
|
<TooltipContent
|
||||||
side="bottom"
|
side="bottom"
|
||||||
align="start"
|
align="start"
|
||||||
className="w-[350px] rounded-xl border bg-white p-4 shadow-xl"
|
className="w-[calc(100vw-32px)] sm:w-[350px] rounded-xl border bg-white p-4 shadow-xl"
|
||||||
>
|
>
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
<h4 className="text-sm font-semibold text-gray-800">
|
<h4 className="text-sm font-semibold text-gray-800">
|
||||||
@@ -383,10 +450,10 @@ const DetailConsultation = () => {
|
|||||||
href={file.path}
|
href={file.path}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
className="flex items-center justify-between rounded-lg border border-gray-200 p-3 transition hover:bg-gray-50"
|
className="flex items-center justify-between rounded-lg border border-gray-200 p-3 transition hover:bg-gray-50 active:bg-gray-100"
|
||||||
>
|
>
|
||||||
<div className="flex min-w-0 items-center gap-3">
|
<div className="flex min-w-0 items-center gap-3">
|
||||||
<span className="text-xl">
|
<span className="text-xl shrink-0">
|
||||||
{isImage ? "🖼️" : "📄"}
|
{isImage ? "🖼️" : "📄"}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
@@ -401,7 +468,7 @@ const DetailConsultation = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span className="text-xs text-blue-500">
|
<span className="text-xs font-medium text-blue-500 shrink-0 ml-2">
|
||||||
Mở
|
Mở
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
@@ -414,7 +481,9 @@ const DetailConsultation = () => {
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
) : (
|
) : (
|
||||||
<div>Không có file nào được tải lên</div>
|
<div className="text-sm text-gray-500">
|
||||||
|
Không có file nào được tải lên
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -546,7 +615,7 @@ const DetailConsultation = () => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</GridColumn>
|
||||||
{/* TAB CHUYÊN KHOA */}
|
{/* TAB CHUYÊN KHOA */}
|
||||||
{specialtyTabs.length > 0 && (
|
{specialtyTabs.length > 0 && (
|
||||||
<div className="mt-4">
|
<div className="mt-4">
|
||||||
@@ -556,8 +625,8 @@ const DetailConsultation = () => {
|
|||||||
{/* CHI TIẾT CHUYÊN KHOA */}
|
{/* CHI TIẾT CHUYÊN KHOA */}
|
||||||
{selectedSpecialty && (
|
{selectedSpecialty && (
|
||||||
<div className="rounded-2xl border border-gray-200 bg-white p-6 shadow-sm">
|
<div className="rounded-2xl border border-gray-200 bg-white p-6 shadow-sm">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex flex-col items-start mb-6 gap-4 lg:flex-row lg:items-center lg:justify-between lg:gap-0">
|
||||||
<h3 className="mb-6 text-xl font-semibold">
|
<h3 className=" text-xl font-semibold">
|
||||||
Thông tin chuyên khoa: {selectedSpecialty.specialtyName}
|
Thông tin chuyên khoa: {selectedSpecialty.specialtyName}
|
||||||
</h3>
|
</h3>
|
||||||
{canUpdateConsultation && (
|
{canUpdateConsultation && (
|
||||||
@@ -611,9 +680,12 @@ const DetailConsultation = () => {
|
|||||||
</p>
|
</p>
|
||||||
{selectedSpecialty.attachmentUrls?.length > 0 ? (
|
{selectedSpecialty.attachmentUrls?.length > 0 ? (
|
||||||
<TooltipProvider>
|
<TooltipProvider>
|
||||||
<Tooltip>
|
<Tooltip open={openTooltip} onOpenChange={setOpenTooltip}>
|
||||||
<TooltipTrigger asChild>
|
<TooltipTrigger asChild>
|
||||||
<div className="inline-flex cursor-pointer items-center gap-2 rounded-lg border border-blue-100 bg-blue-50 px-3 py-2 text-sm font-medium text-blue-600 transition hover:bg-blue-100">
|
<div
|
||||||
|
onClick={() => setOpenTooltip((prev) => !prev)}
|
||||||
|
className="inline-flex cursor-pointer items-center gap-2 rounded-lg border border-blue-100 bg-blue-50 px-3 py-2 text-sm font-medium text-blue-600 transition hover:bg-blue-100 active:bg-blue-200"
|
||||||
|
>
|
||||||
<span>📎</span>
|
<span>📎</span>
|
||||||
<span>Chi tiết các file</span>
|
<span>Chi tiết các file</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -622,7 +694,7 @@ const DetailConsultation = () => {
|
|||||||
<TooltipContent
|
<TooltipContent
|
||||||
side="bottom"
|
side="bottom"
|
||||||
align="start"
|
align="start"
|
||||||
className="w-[350px] rounded-xl border bg-white p-4 shadow-xl"
|
className="w-[calc(100vw-32px)] sm:w-[350px] rounded-xl border bg-white p-4 shadow-xl"
|
||||||
>
|
>
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
<h4 className="text-sm font-semibold text-gray-800">
|
<h4 className="text-sm font-semibold text-gray-800">
|
||||||
@@ -654,10 +726,10 @@ const DetailConsultation = () => {
|
|||||||
href={file.path}
|
href={file.path}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
className="flex items-center justify-between rounded-lg border border-gray-200 p-3 transition hover:bg-gray-50"
|
className="flex items-center justify-between rounded-lg border border-gray-200 p-3 transition hover:bg-gray-50 active:bg-gray-100"
|
||||||
>
|
>
|
||||||
<div className="flex min-w-0 items-center gap-3">
|
<div className="flex min-w-0 items-center gap-3">
|
||||||
<span className="text-xl">
|
<span className="text-xl shrink-0">
|
||||||
{isImage ? "🖼️" : "📄"}
|
{isImage ? "🖼️" : "📄"}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
@@ -672,7 +744,7 @@ const DetailConsultation = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span className="text-xs text-blue-500">
|
<span className="ml-2 text-xs text-blue-500 shrink-0">
|
||||||
Mở
|
Mở
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
@@ -685,7 +757,9 @@ const DetailConsultation = () => {
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
) : (
|
) : (
|
||||||
<div>Không có file nào được tải lên</div>
|
<div className="text-sm text-gray-500">
|
||||||
|
Không có file nào được tải lên
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ import * as Popover from "@radix-ui/react-popover";
|
|||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import TabNavLink from "@/components/customs/custom-tabs";
|
import TabNavLink from "@/components/customs/custom-tabs";
|
||||||
import { removeVietnameseTones } from "@/common/funcs/optionConvert";
|
import { removeVietnameseTones } from "@/common/funcs/optionConvert";
|
||||||
|
import useSpecialtyTabs from "@/hooks/useSpecialtyTabs";
|
||||||
|
|
||||||
const MainPageConsultation = () => {
|
const MainPageConsultation = () => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@@ -98,6 +99,10 @@ const MainPageConsultation = () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const { tabs: specialtyTabs } = useSpecialtyTabs(
|
||||||
|
consultationQuery.data?.items ?? [],
|
||||||
|
);
|
||||||
|
|
||||||
const specialtyQuery = useQuery({
|
const specialtyQuery = useQuery({
|
||||||
queryKey: [QUERY_KEY.list_specialty_lookup],
|
queryKey: [QUERY_KEY.list_specialty_lookup],
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
@@ -183,30 +188,30 @@ const MainPageConsultation = () => {
|
|||||||
|
|
||||||
const consultation = consultationQuery.data;
|
const consultation = consultationQuery.data;
|
||||||
|
|
||||||
const specialtyTabs = useMemo(() => {
|
// const specialtyTabs = useMemo(() => {
|
||||||
const specialtyMap = new Map();
|
// const specialtyMap = new Map();
|
||||||
|
|
||||||
consultation?.items?.forEach((consultationItem) => {
|
// consultation?.items?.forEach((consultationItem) => {
|
||||||
consultationItem.specialtyClinics?.forEach((specialty) => {
|
// consultationItem.specialtyClinics?.forEach((specialty) => {
|
||||||
if (!specialtyMap.has(specialty.specialtyId)) {
|
// if (!specialtyMap.has(specialty.specialtyId)) {
|
||||||
specialtyMap.set(specialty.specialtyId, {
|
// specialtyMap.set(specialty.specialtyId, {
|
||||||
pathname: "/consultation",
|
// pathname: "/consultation",
|
||||||
query: specialty.specialtyId,
|
// query: specialty.specialtyId,
|
||||||
title: specialty.specialtyName,
|
// title: specialty.specialtyName,
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
});
|
// });
|
||||||
|
|
||||||
return [
|
// return [
|
||||||
{
|
// {
|
||||||
pathname: "/consultation",
|
// pathname: "/consultation",
|
||||||
query: "all",
|
// query: "all",
|
||||||
title: "Tất cả",
|
// title: "Tất cả",
|
||||||
},
|
// },
|
||||||
...Array.from(specialtyMap.values()),
|
// ...Array.from(specialtyMap.values()),
|
||||||
];
|
// ];
|
||||||
}, [consultation?.items]);
|
// }, [consultation?.items]);
|
||||||
|
|
||||||
const handleOpenCancel = (item: ConsultationItem) => {
|
const handleOpenCancel = (item: ConsultationItem) => {
|
||||||
setSelectedConsultationId(item.id);
|
setSelectedConsultationId(item.id);
|
||||||
@@ -381,7 +386,6 @@ const MainPageConsultation = () => {
|
|||||||
column={[
|
column={[
|
||||||
{
|
{
|
||||||
title: "TÊN BỆNH NHÂN",
|
title: "TÊN BỆNH NHÂN",
|
||||||
|
|
||||||
render: (item: ConsultationItem) => (
|
render: (item: ConsultationItem) => (
|
||||||
<TooltipProvider>
|
<TooltipProvider>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
@@ -393,9 +397,8 @@ const MainPageConsultation = () => {
|
|||||||
{item.patientName}
|
{item.patientName}
|
||||||
</Link>
|
</Link>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
|
|
||||||
<TooltipContent>
|
<TooltipContent>
|
||||||
<p className="p-2 bg-gray-400 border rounded-full">
|
<p className="rounded-full border bg-gray-400 p-2">
|
||||||
Chi tiết bệnh nhân
|
Chi tiết bệnh nhân
|
||||||
</p>
|
</p>
|
||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
@@ -427,7 +430,6 @@ const MainPageConsultation = () => {
|
|||||||
{item.sessionCode}
|
{item.sessionCode}
|
||||||
</Link>
|
</Link>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
|
|
||||||
<TooltipContent>
|
<TooltipContent>
|
||||||
<p className="rounded-full border bg-gray-400 p-2">
|
<p className="rounded-full border bg-gray-400 p-2">
|
||||||
Chi tiết phiên khám
|
Chi tiết phiên khám
|
||||||
@@ -450,41 +452,72 @@ const MainPageConsultation = () => {
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
// 🔴 ẨN "DẤU HIỆU" khi KHÔNG PHẢI Tab All (!isAllTab)
|
||||||
|
isAllTab && {
|
||||||
title: "DẤU HIỆU",
|
title: "DẤU HIỆU",
|
||||||
|
|
||||||
render: (item: ConsultationItem) => (
|
render: (item: ConsultationItem) => (
|
||||||
<span>{item.symptomsText || "---"}</span>
|
<span>{item.symptomsText || "---"}</span>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
title: "CHUẨN ĐOÁN",
|
title: "CHẨN ĐOÁN",
|
||||||
|
render: (item: ConsultationItem) => {
|
||||||
render: (item: ConsultationItem) => (
|
if (!isAllTab) {
|
||||||
<span>{item.diagnosis || "---"}</span>
|
const specialty = item.specialtyClinics.find(
|
||||||
),
|
(x) => x.specialtyId === _type,
|
||||||
|
);
|
||||||
|
return <span>{specialty?.diagnosis || "---"}</span>;
|
||||||
|
}
|
||||||
|
return <span>{item.diagnosis || "---"}</span>;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
// 🔴 ẨN "DẤU HIỆU" khi KHÔNG PHẢI Tab All (!isAllTab)
|
||||||
title: "KẾ HOẠCH ĐIỀU TRỊ",
|
// !isAllTab && {
|
||||||
|
// title: "BÁC SĨ KHÁM",
|
||||||
|
// render: (item: ConsultationItem) => {
|
||||||
|
// const doctorNames = item.doctors?.join(", ");
|
||||||
|
|
||||||
|
// return <span>{doctorNames || "---"}</span>;
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
|
||||||
|
// 🔴 ẨN "KẾ HOẠCH ĐIỀU TRỊ" khi KHÔNG PHẢI Tab All (!isAllTab)
|
||||||
|
isAllTab && {
|
||||||
|
title: "KẾ HOẠCH ĐIỀU TRỊ",
|
||||||
render: (item: ConsultationItem) => (
|
render: (item: ConsultationItem) => (
|
||||||
<span>{item.treatmentPlan || "---"}</span>
|
<span>{item.treatmentPlan || "---"}</span>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
title: "GHI CHÚ BÁC SĨ",
|
title: isAllTab ? "GHI CHÚ BÁC SĨ" : "GHI CHÚ KHÁM",
|
||||||
|
render: (item: ConsultationItem) => {
|
||||||
render: (item: ConsultationItem) => (
|
if (!isAllTab) {
|
||||||
<span>{item.doctorNotes || "---"}</span>
|
const specialty = item.specialtyClinics.find(
|
||||||
),
|
(x) => x.specialtyId === _type,
|
||||||
|
);
|
||||||
|
return <span>{specialty?.specialtyNotes || "---"}</span>;
|
||||||
|
}
|
||||||
|
return <span>{item.doctorNotes || "---"}</span>;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 🔴 ẨN "THỦ THUẬT" khi LÀ Tab All (isAllTab)
|
||||||
|
!isAllTab && {
|
||||||
|
title: "THỦ THUẬT",
|
||||||
|
render: (item: ConsultationItem) => {
|
||||||
|
const specialty = item.specialtyClinics.find(
|
||||||
|
(x) => x.specialtyId === _type,
|
||||||
|
);
|
||||||
|
return <span>{specialty?.procedureNotes || "---"}</span>;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
title: "TRẠNG THÁI",
|
title: "TRẠNG THÁI",
|
||||||
render: (item: ConsultationItem) => {
|
render: (item: ConsultationItem) => {
|
||||||
// ===== TAB CHUYÊN KHOA =====
|
|
||||||
if (!isAllTab) {
|
if (!isAllTab) {
|
||||||
const specialty = item.specialtyClinics.find(
|
const specialty = item.specialtyClinics.find(
|
||||||
(x) => x.specialtyId === _type,
|
(x) => x.specialtyId === _type,
|
||||||
@@ -517,7 +550,6 @@ const MainPageConsultation = () => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===== TAB TẤT CẢ =====
|
|
||||||
return (
|
return (
|
||||||
<StateActive
|
<StateActive
|
||||||
stateActive={item.status}
|
stateActive={item.status}
|
||||||
@@ -563,19 +595,15 @@ const MainPageConsultation = () => {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
fixedRight: true,
|
fixedRight: true,
|
||||||
|
|
||||||
title: "ACTION",
|
title: "ACTION",
|
||||||
|
|
||||||
render: (item: ConsultationItem) => {
|
render: (item: ConsultationItem) => {
|
||||||
const isCancelled = item.status === TYPE_STATUS.Cancelled;
|
const isCancelled = item.status === TYPE_STATUS.Cancelled;
|
||||||
|
|
||||||
const isCompleted = item.status === TYPE_STATUS.Completed;
|
const isCompleted = item.status === TYPE_STATUS.Completed;
|
||||||
|
|
||||||
const isDisabled = isCancelled || isCompleted;
|
const isDisabled = isCancelled || isCompleted;
|
||||||
|
|
||||||
// ===== TAB CHUYÊN KHOA =====
|
|
||||||
if (!isAllTab) {
|
if (!isAllTab) {
|
||||||
const specialty = item.specialtyClinics.find(
|
const specialty = item.specialtyClinics.find(
|
||||||
(x) => x.specialtyId === _type,
|
(x) => x.specialtyId === _type,
|
||||||
@@ -599,14 +627,7 @@ const MainPageConsultation = () => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===== TAB TẤT CẢ =====
|
|
||||||
return (
|
return (
|
||||||
/*
|
|
||||||
Chỉnh sửa tại đây:
|
|
||||||
- flex-col: xếp dọc trên màn mobile
|
|
||||||
- sm:flex-row: quay lại xếp ngang trên tablet / desktop (>= 640px)
|
|
||||||
- w-full sm:w-auto: mở rộng full chiều rộng ô khi ở màn mobile cho cân đối
|
|
||||||
*/
|
|
||||||
<div className="flex flex-col sm:flex-row items-center justify-center gap-2 w-full sm:w-auto">
|
<div className="flex flex-col sm:flex-row items-center justify-center gap-2 w-full sm:w-auto">
|
||||||
<Popover.Root>
|
<Popover.Root>
|
||||||
<Popover.Trigger asChild>
|
<Popover.Trigger asChild>
|
||||||
@@ -628,27 +649,14 @@ const MainPageConsultation = () => {
|
|||||||
side="bottom"
|
side="bottom"
|
||||||
align="end"
|
align="end"
|
||||||
sideOffset={8}
|
sideOffset={8}
|
||||||
className="
|
className="z-50 min-w-[300px] rounded-xl border bg-white p-2 shadow-xl"
|
||||||
z-50
|
|
||||||
min-w-[300px]
|
|
||||||
rounded-xl
|
|
||||||
border
|
|
||||||
bg-white
|
|
||||||
p-2
|
|
||||||
shadow-xl
|
|
||||||
"
|
|
||||||
>
|
>
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
{item.specialtyClinics.map((specialty) => (
|
{item.specialtyClinics.map((specialty) => (
|
||||||
<Link
|
<Link
|
||||||
key={specialty.id}
|
key={specialty.id}
|
||||||
href={`/consultation/update-specialty?_id=${item.id}&specialtyClinicId=${specialty.id}`}
|
href={`/consultation/update-specialty?_id=${item.id}&specialtyClinicId=${specialty.id}`}
|
||||||
className="
|
className="flex items-center gap-2 rounded-lg px-3 py-2 text-sm hover:bg-blue-50"
|
||||||
flex items-center gap-2
|
|
||||||
rounded-lg px-3 py-2
|
|
||||||
text-sm
|
|
||||||
hover:bg-blue-50
|
|
||||||
"
|
|
||||||
>
|
>
|
||||||
<Pencil size={15} />
|
<Pencil size={15} />
|
||||||
<span>{specialty.specialtyName}</span>
|
<span>{specialty.specialtyName}</span>
|
||||||
@@ -682,7 +690,7 @@ const MainPageConsultation = () => {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]}
|
].filter(Boolean)} // 💡 Lọc bỏ các giá trị false để ẩn cột
|
||||||
/>
|
/>
|
||||||
</DataWrapper>
|
</DataWrapper>
|
||||||
<Pagination
|
<Pagination
|
||||||
|
|||||||
@@ -150,6 +150,47 @@ const TableHistoryPatient = () => {
|
|||||||
<span>{item.diagnosis || "---"}</span>
|
<span>{item.diagnosis || "---"}</span>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: "KẾ HOẠCH ĐIỀU TRỊ",
|
||||||
|
|
||||||
|
render: (item: ConsultationItem) => (
|
||||||
|
<span>{item.treatmentPlan || "---"}</span>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
title: "CÁC CHUYÊN KHOA ĐANG CHỜ KHÁM",
|
||||||
|
|
||||||
|
render: (item: ConsultationItem) => {
|
||||||
|
const waitingSpecialties = item.specialtyClinics
|
||||||
|
?.filter((specialty) => specialty.specialtyStatus === 1)
|
||||||
|
.map((specialty) => specialty.specialtyName)
|
||||||
|
.join(", ");
|
||||||
|
|
||||||
|
return <span>{waitingSpecialties || "---"}</span>;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "CÁC CHUYÊN KHOA ĐÃ KHÁM",
|
||||||
|
|
||||||
|
render: (item: ConsultationItem) => {
|
||||||
|
const completedSpecialties = item.specialtyClinics
|
||||||
|
?.filter((specialty) => specialty.specialtyStatus === 3)
|
||||||
|
.map((specialty) => specialty.specialtyName)
|
||||||
|
.join(", ");
|
||||||
|
|
||||||
|
return <span>{completedSpecialties || "---"}</span>;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
title: "BÁC SĨ KHÁM",
|
||||||
|
render: (item: ConsultationItem) => {
|
||||||
|
const doctorNames = item.doctors?.join(", ");
|
||||||
|
|
||||||
|
return <span>{doctorNames || "---"}</span>;
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: "TRẠNG THÁI",
|
title: "TRẠNG THÁI",
|
||||||
render: (item: ConsultationItem) => (
|
render: (item: ConsultationItem) => (
|
||||||
|
|||||||
@@ -324,7 +324,7 @@ const DetailPatient = () => {
|
|||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
title: "CHUẨN ĐOÁN",
|
title: "CHẨN ĐOÁN",
|
||||||
|
|
||||||
render: (item: ConsultationItem) => (
|
render: (item: ConsultationItem) => (
|
||||||
<span>{item.diagnosis || "---"}</span>
|
<span>{item.diagnosis || "---"}</span>
|
||||||
@@ -339,13 +339,6 @@ const DetailPatient = () => {
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
|
||||||
title: "GHI CHÚ BÁC SĨ",
|
|
||||||
|
|
||||||
render: (item: ConsultationItem) => (
|
|
||||||
<span>{item.doctorNotes || "---"}</span>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
title: "CÁC CHUYÊN KHOA ĐANG CHỜ KHÁM",
|
title: "CÁC CHUYÊN KHOA ĐANG CHỜ KHÁM",
|
||||||
|
|
||||||
@@ -370,6 +363,15 @@ const DetailPatient = () => {
|
|||||||
return <span>{completedSpecialties || "---"}</span>;
|
return <span>{completedSpecialties || "---"}</span>;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
title: "BÁC SĨ KHÁM",
|
||||||
|
render: (item: ConsultationItem) => {
|
||||||
|
const doctorNames = item.doctors?.join(", ");
|
||||||
|
|
||||||
|
return <span>{doctorNames || "---"}</span>;
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: "TRẠNG THÁI",
|
title: "TRẠNG THÁI",
|
||||||
fixedRight: true,
|
fixedRight: true,
|
||||||
|
|||||||
@@ -509,7 +509,7 @@ const CreatePrescription = () => {
|
|||||||
<InputForm
|
<InputForm
|
||||||
label={
|
label={
|
||||||
<span>
|
<span>
|
||||||
Thời gian dùng<span style={{ color: "red" }}>*</span>
|
Số lượng thuốc<span style={{ color: "red" }}>*</span>
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
isRequired
|
isRequired
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import { useParams, useRouter } from "next/navigation";
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import CustomPopup from "@/components/customs/custom-popup";
|
import CustomPopup from "@/components/customs/custom-popup";
|
||||||
import { ArrowLeft } from "lucide-react";
|
import { ArrowLeft } from "lucide-react";
|
||||||
|
import Link from "next/link";
|
||||||
|
|
||||||
const DetailPrescription = () => {
|
const DetailPrescription = () => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@@ -104,16 +105,25 @@ const DetailPrescription = () => {
|
|||||||
<div>
|
<div>
|
||||||
<strong>Mã đơn thuốc:</strong> {data.prescriptionCode}
|
<strong>Mã đơn thuốc:</strong> {data.prescriptionCode}
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<strong>Mã bệnh nhân:</strong>
|
||||||
|
<Link
|
||||||
|
href={`/patient/${data.patientId}`}
|
||||||
|
className="text-blue-500 hover:underline"
|
||||||
|
>
|
||||||
|
{data.patientCode || "---"}
|
||||||
|
</Link>
|
||||||
|
</div>{" "}
|
||||||
|
<div>
|
||||||
|
<strong>Tên bệnh nhân:</strong> {data.patientName || "---"}
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<strong>Chuyên khoa:</strong>{" "}
|
<strong>Chuyên khoa:</strong>{" "}
|
||||||
{specialtyName || data.examinationSessionSpecialtyId || "---"}
|
{specialtyName || data.examinationSessionSpecialtyId || "---"}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<strong>Ghi chú:</strong> {data.notes || "---"}
|
<strong>Ghi chú:</strong> {data.notes || "---"}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* IMAGE */}
|
{/* IMAGE */}
|
||||||
<div>
|
<div>
|
||||||
<strong>Ảnh đơn thuốc:</strong>
|
<strong>Ảnh đơn thuốc:</strong>
|
||||||
@@ -152,7 +162,6 @@ const DetailPrescription = () => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* ITEMS */}
|
{/* ITEMS */}
|
||||||
<div>
|
<div>
|
||||||
<strong>Danh sách thuốc:</strong>
|
<strong>Danh sách thuốc:</strong>
|
||||||
@@ -171,7 +180,7 @@ const DetailPrescription = () => {
|
|||||||
<b>Tần suất:</b> {item.frequency}
|
<b>Tần suất:</b> {item.frequency}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<b>Thời gian:</b> {item.duration}
|
<b>Số lượng thuốc:</b> {item.quantity}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<b>Hướng dẫn:</b> {item.instructions}
|
<b>Hướng dẫn:</b> {item.instructions}
|
||||||
|
|||||||
@@ -148,12 +148,37 @@ const MainPrescription = () => {
|
|||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|
||||||
// ================= NOTES =================
|
|
||||||
{
|
{
|
||||||
title: "GHI CHÚ",
|
title: "MÃ BỆNH NHÂN",
|
||||||
render: (item: any) => <span>{item.notes || "-"}</span>,
|
render: (item: any) => (
|
||||||
},
|
<TooltipProvider>
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger asChild>
|
||||||
|
<Link
|
||||||
|
href={`/patient/${item.patientId}`}
|
||||||
|
className="text-blue-500 hover:underline"
|
||||||
|
>
|
||||||
|
{item.patientCode}
|
||||||
|
</Link>
|
||||||
|
</TooltipTrigger>
|
||||||
|
|
||||||
|
<TooltipContent>
|
||||||
|
<p className="p-2 bg-gray-400 border rounded-full">
|
||||||
|
Chi tiết bệnh nhân
|
||||||
|
</p>
|
||||||
|
</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "TÊN BỆNH NHÂN",
|
||||||
|
render: (item: any) => <span>{item.patientName || "-"}</span>,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "TÊN CHUYÊN KHOA",
|
||||||
|
render: (item: any) => <span>{item.specialtyName || "-"}</span>,
|
||||||
|
},
|
||||||
// ================= IMAGE =================
|
// ================= IMAGE =================
|
||||||
{
|
{
|
||||||
title: "ẢNH ĐƠN THUỐC",
|
title: "ẢNH ĐƠN THUỐC",
|
||||||
@@ -174,11 +199,15 @@ const MainPrescription = () => {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// ================= ITEMS COUNT =================
|
// ================= ITEMS COUNT =================
|
||||||
|
// {
|
||||||
|
// title: "SỐ THUỐC",
|
||||||
|
// render: (item: any) => <span>{item.items?.length || 0}</span>,
|
||||||
|
// },
|
||||||
|
// ================= NOTES =================
|
||||||
{
|
{
|
||||||
title: "SỐ THUỐC",
|
title: "GHI CHÚ",
|
||||||
render: (item: any) => <span>{item.items?.length || 0}</span>,
|
render: (item: any) => <span>{item.notes || "-"}</span>,
|
||||||
},
|
},
|
||||||
|
|
||||||
// ================= ACTION =================
|
// ================= ACTION =================
|
||||||
{
|
{
|
||||||
fixedRight: true,
|
fixedRight: true,
|
||||||
|
|||||||
@@ -113,4 +113,47 @@ export const ListOptionFilterDate: {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export const SPECIALTY_ORDER = [
|
||||||
|
"Khám Nội",
|
||||||
|
"Khám Răng",
|
||||||
|
"Khám Tai Mũi Họng",
|
||||||
|
"Khám Mắt",
|
||||||
|
"Khám Sản phụ khoa",
|
||||||
|
"Xét nghiệm máu",
|
||||||
|
"Xét nghiệm nước tiểu",
|
||||||
|
"X-quang",
|
||||||
|
"Điện tim",
|
||||||
|
"Siêu Âm",
|
||||||
|
];
|
||||||
|
|
||||||
|
export const SPECIALTY_DISPLAY_NAME: Record<string, string> = {
|
||||||
|
Nội: "Khám Nội",
|
||||||
|
"Khám Nội": "Khám Nội",
|
||||||
|
|
||||||
|
Răng: "Khám Răng",
|
||||||
|
"Khám Răng": "Khám Răng",
|
||||||
|
|
||||||
|
"Tai Mũi Họng": "Khám Tai Mũi Họng",
|
||||||
|
"Khám Tai Mũi Họng": "Khám Tai Mũi Họng",
|
||||||
|
|
||||||
|
Mắt: "Khám Mắt",
|
||||||
|
"Khám Mắt": "Khám Mắt",
|
||||||
|
|
||||||
|
"Sản Phụ Khoa": "Khám Sản phụ khoa",
|
||||||
|
"Sản phụ khoa": "Khám Sản phụ khoa",
|
||||||
|
"Khám Sản phụ khoa": "Khám Sản phụ khoa",
|
||||||
|
|
||||||
|
"Xét nghiệm máu": "Xét nghiệm máu",
|
||||||
|
|
||||||
|
"Xét nghiệm nước tiểu": "Xét nghiệm nước tiểu",
|
||||||
|
|
||||||
|
"X-Quang": "X-quang",
|
||||||
|
"X-quang": "X-quang",
|
||||||
|
|
||||||
|
"Điện Tim": "Điện tim",
|
||||||
|
"Điện tim": "Điện tim",
|
||||||
|
|
||||||
|
"Siêu Âm": "Siêu Âm",
|
||||||
|
};
|
||||||
|
|
||||||
export const KEY_STORE = "management-kham-benh";
|
export const KEY_STORE = "management-kham-benh";
|
||||||
|
|||||||
@@ -0,0 +1,121 @@
|
|||||||
|
import { useMemo } from "react";
|
||||||
|
import { useQuery } from "@tanstack/react-query";
|
||||||
|
|
||||||
|
import { QUERY_KEY } from "@/constant/config/enum";
|
||||||
|
import { httpRequest } from "@/services";
|
||||||
|
import specialtyServices, { SpecialtyItem } from "@/services/specialtyServices";
|
||||||
|
|
||||||
|
import { SPECIALTY_ORDER, SPECIALTY_DISPLAY_NAME } from "@/constant/config";
|
||||||
|
|
||||||
|
interface ConsultationSpecialty {
|
||||||
|
specialtyClinics?: {
|
||||||
|
specialtyId: string;
|
||||||
|
specialtyName: string;
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
|
||||||
|
const normalize = (text: string) => text.trim().toLowerCase();
|
||||||
|
|
||||||
|
export default function useSpecialtyTabs(
|
||||||
|
consultationItems: ConsultationSpecialty[] = [],
|
||||||
|
) {
|
||||||
|
const specialtyQuery = useQuery({
|
||||||
|
queryKey: [QUERY_KEY.list_specialty_lookup],
|
||||||
|
|
||||||
|
queryFn: async () => {
|
||||||
|
const res = await httpRequest<SpecialtyItem[]>({
|
||||||
|
http: specialtyServices.getSpecialty(),
|
||||||
|
showMessageFailed: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
return res || [];
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const tabs = useMemo(() => {
|
||||||
|
const lookup = [...(specialtyQuery.data ?? [])];
|
||||||
|
|
||||||
|
//-----------------------------------------
|
||||||
|
// Các chuyên khoa đã xuất hiện trong phiên khám
|
||||||
|
//-----------------------------------------
|
||||||
|
|
||||||
|
const existed = new Set<string>();
|
||||||
|
|
||||||
|
consultationItems.forEach((item) => {
|
||||||
|
item.specialtyClinics?.forEach((specialty) => {
|
||||||
|
const displayName =
|
||||||
|
SPECIALTY_DISPLAY_NAME[specialty.specialtyName] ??
|
||||||
|
specialty.specialtyName;
|
||||||
|
|
||||||
|
existed.add(displayName);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
//-----------------------------------------
|
||||||
|
// Chuẩn hóa tên
|
||||||
|
//-----------------------------------------
|
||||||
|
|
||||||
|
const specialties = lookup.map((item) => ({
|
||||||
|
...item,
|
||||||
|
displayName: SPECIALTY_DISPLAY_NAME[item.name] ?? item.name,
|
||||||
|
}));
|
||||||
|
|
||||||
|
//-----------------------------------------
|
||||||
|
// Sort
|
||||||
|
//-----------------------------------------
|
||||||
|
|
||||||
|
specialties.sort((a, b) => {
|
||||||
|
const aVisited = existed.has(a.displayName);
|
||||||
|
const bVisited = existed.has(b.displayName);
|
||||||
|
|
||||||
|
//---------------------------------
|
||||||
|
// Ưu tiên chuyên khoa đã khám
|
||||||
|
//---------------------------------
|
||||||
|
|
||||||
|
if (aVisited !== bVisited) {
|
||||||
|
return aVisited ? -1 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------
|
||||||
|
// Sau đó theo SPECIALTY_ORDER
|
||||||
|
//---------------------------------
|
||||||
|
|
||||||
|
const orderA = SPECIALTY_ORDER.findIndex(
|
||||||
|
(x) => normalize(x) === normalize(a.displayName),
|
||||||
|
);
|
||||||
|
|
||||||
|
const orderB = SPECIALTY_ORDER.findIndex(
|
||||||
|
(x) => normalize(x) === normalize(b.displayName),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (orderA === -1 && orderB === -1) {
|
||||||
|
return a.displayName.localeCompare(b.displayName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (orderA === -1) return 1;
|
||||||
|
|
||||||
|
if (orderB === -1) return -1;
|
||||||
|
|
||||||
|
return orderA - orderB;
|
||||||
|
});
|
||||||
|
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
pathname: "/consultation",
|
||||||
|
query: "all",
|
||||||
|
title: "Tất cả",
|
||||||
|
},
|
||||||
|
|
||||||
|
...specialties.map((item) => ({
|
||||||
|
pathname: "/consultation",
|
||||||
|
query: item.id,
|
||||||
|
title: item.displayName,
|
||||||
|
})),
|
||||||
|
];
|
||||||
|
}, [specialtyQuery.data, consultationItems]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
tabs,
|
||||||
|
loading: specialtyQuery.isLoading,
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -45,6 +45,7 @@ export interface ConsultationItem {
|
|||||||
instructions: string;
|
instructions: string;
|
||||||
}[];
|
}[];
|
||||||
}[];
|
}[];
|
||||||
|
doctors: string[] | null;
|
||||||
aggregatedPrescriptionItems: {
|
aggregatedPrescriptionItems: {
|
||||||
id: string;
|
id: string;
|
||||||
prescriptionId: string;
|
prescriptionId: string;
|
||||||
|
|||||||
@@ -33,13 +33,16 @@ export interface PrescriptionDetail {
|
|||||||
prescriptionImg: string;
|
prescriptionImg: string;
|
||||||
notes: string;
|
notes: string;
|
||||||
createdBy: string;
|
createdBy: string;
|
||||||
|
patientId: string;
|
||||||
|
patientCode: string;
|
||||||
|
patientName: string;
|
||||||
items: {
|
items: {
|
||||||
id: string;
|
id: string;
|
||||||
prescriptionId: string;
|
prescriptionId: string;
|
||||||
medicineName: string;
|
medicineName: string;
|
||||||
dosage: string;
|
dosage: string;
|
||||||
frequency: string;
|
frequency: string;
|
||||||
duration: string;
|
quantity: string;
|
||||||
instructions: string;
|
instructions: string;
|
||||||
}[];
|
}[];
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user