"use client"; import CustomButton from "@/components/customs/custom-button"; import CustomDialog from "@/components/customs/custom-dialog"; import DataWrapper from "@/components/customs/DataWrapper"; import Search from "@/components/customs/custom-search"; import StateActive from "@/components/customs/StateActive"; import Table from "@/components/customs/custom-table"; import { QUERY_KEY, TYPE_STATUS } from "@/constant/config/enum"; import { httpRequest } from "@/services"; import consultationServices, { ConsultationItem, ConsultationResponse, } from "@/services/consultationServices"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import Link from "next/link"; import { Pencil, ClipboardPlus, Ellipsis } from "lucide-react"; import { usePathname, useRouter, useSearchParams } from "next/navigation"; import React, { useEffect, useMemo, useState } from "react"; import Pagination from "@/components/customs/custom-pagination"; import moment from "moment"; import specialtyServices, { SpecialtyItem } from "@/services/specialtyServices"; import FilterCustom from "@/components/customs/FilterCustom"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, } from "@radix-ui/react-tooltip"; import * as Popover from "@radix-ui/react-popover"; import clsx from "clsx"; import TabNavLink from "@/components/customs/custom-tabs"; import { removeVietnameseTones } from "@/common/funcs/optionConvert"; import useSpecialtyTabs from "@/hooks/useSpecialtyTabs"; const MainPageConsultation = () => { const router = useRouter(); const pathname = usePathname(); const searchParams = useSearchParams(); const queryClient = useQueryClient(); /* ========================= QUERY PARAMS ========================= */ const _page = searchParams.get("_page"); const _pageSize = searchParams.get("_pageSize"); const _keyword = searchParams.get("_keyword"); const _status = searchParams.get("_status"); const _specialtyId = searchParams.get("_specialtyId"); const _type = searchParams.get("_type"); const isAllTab = !_type || _type === "all"; const [selectedConsultationId, setSelectedConsultationId] = useState(""); const [openCancelDialog, setOpenCancelDialog] = useState(false); const [openCompleteDialog, setOpenCompleteDialog] = useState(false); const consultationQuery = useQuery({ queryKey: [QUERY_KEY.table_list_consultation, _page, _pageSize, _keyword], queryFn: async () => { const res = await httpRequest({ showMessageFailed: true, http: consultationServices.getConsultations({ Page: Number(_page || 1), PageSize: Number(_pageSize || 10), Search: _keyword || "", SortBy: _specialtyId || undefined, Desc: true, }), }); return ( res || { items: [], page: 1, pageSize: 10, total: 0, totalPages: 0, } ); }, }); const { tabs: specialtyTabs } = useSpecialtyTabs( consultationQuery.data?.items ?? [], ); const specialtyQuery = useQuery({ queryKey: [QUERY_KEY.list_specialty_lookup], queryFn: async () => { const res = await httpRequest({ http: specialtyServices.getSpecialty(), showMessageFailed: true, }); return res || []; }, }); const consultationData = useMemo(() => { let data = consultationQuery.data?.items || []; // ========================= // TAB CHUYÊN KHOA // ========================= if (_type && _type !== "all") { data = data.filter((item) => item.specialtyClinics?.some( (specialty) => specialty.specialtyId === _type, ), ); } // ========================= // FILTER CHUYÊN KHOA // ========================= if (_specialtyId) { data = data.filter((item) => item.specialtyClinics?.some( (specialty) => specialty.specialtyId === _specialtyId, ), ); } // ========================= // FILTER TRẠNG THÁI // ========================= if (_status) { data = data.filter((item) => item.status === Number(_status)); } return data; }, [consultationQuery.data, _type, _specialtyId, _status]); // Bỏ _keyword khỏi dependencies vì không dùng lọc client nữa const page = _page ? Number(_page) : 1; const pageSize = _pageSize ? Number(_pageSize) : 10; useEffect(() => { if (!_type) { const params = new URLSearchParams(searchParams.toString()); params.set("_type", "all"); router.replace(`${pathname}?${params.toString()}`); } }, [_type, pathname, router, searchParams]); const updateQuery = (key: string, value: string | number) => { const params = new URLSearchParams(searchParams.toString()); if (!value || value === "") { params.delete(key); } else { params.set(key, String(value)); } if ( key === "_pageSize" || key === "_keyword" || key === "_status" || key === "_specialtyId" ) { params.delete("_page"); } const queryString = params.toString(); router.push(queryString ? `?${queryString}` : pathname); }; const consultation = consultationQuery.data; // const specialtyTabs = useMemo(() => { // const specialtyMap = new Map(); // consultation?.items?.forEach((consultationItem) => { // consultationItem.specialtyClinics?.forEach((specialty) => { // if (!specialtyMap.has(specialty.specialtyId)) { // specialtyMap.set(specialty.specialtyId, { // pathname: "/consultation", // query: specialty.specialtyId, // title: specialty.specialtyName, // }); // } // }); // }); // return [ // { // pathname: "/consultation", // query: "all", // title: "Tất cả", // }, // ...Array.from(specialtyMap.values()), // ]; // }, [consultation?.items]); const handleOpenCancel = (item: ConsultationItem) => { setSelectedConsultationId(item.id); setOpenCancelDialog(true); }; const handleOpenComplete = (item: ConsultationItem) => { setSelectedConsultationId(item.id); setOpenCompleteDialog(true); }; const handleCloseDialog = () => { setOpenCancelDialog(false); setOpenCompleteDialog(false); }; const cancelConsultationMutation = useMutation({ mutationFn: async () => { return await httpRequest({ showMessageFailed: true, showMessageSuccess: true, msgSuccess: "Hủy phiên khám thành công!", http: consultationServices.cancelConsultations(selectedConsultationId), }); }, onSuccess() { queryClient.invalidateQueries({ queryKey: [QUERY_KEY.table_list_consultation], }); handleCloseDialog(); }, }); const completeConsultationMutation = useMutation({ mutationFn: async () => { return await httpRequest({ showMessageFailed: true, showMessageSuccess: true, msgSuccess: "Hoàn thành phiên khám thành công!", http: consultationServices.completeConsultations( selectedConsultationId, ), }); }, onSuccess() { queryClient.invalidateQueries({ queryKey: [QUERY_KEY.table_list_consultation], }); handleCloseDialog(); }, }); const handleConfirmCancel = () => { cancelConsultationMutation.mutate(); }; const handleConfirmComplete = () => { completeConsultationMutation.mutate(); }; return (
{/* HEADER */}

Phiên khám

{isAllTab && ( } // onClick={handleOpenCreate} href="/consultation/create" > Tạo phiên khám )}
{/* SEARCH */}
updateQuery("_keyword", value)} placeholder="Tìm kiếm phiên khám..." />
{isAllTab && (
name="Chuyên khoa" value={_specialtyId} onChange={(value) => updateQuery("_specialtyId", value ?? "")} listOption={ specialtyQuery.data?.map((item) => ({ uuid: item.id, name: item.name, })) || [] } /> name="Trạng thái" value={_status ? Number(_status) : null} onChange={(value) => updateQuery("_status", value ?? "")} listOption={[ { uuid: TYPE_STATUS.Draft, name: "Đang chờ khám", }, { uuid: TYPE_STATUS.InProgress, name: "Đang khám tổng quát", }, { uuid: TYPE_STATUS.ToSpecialty, name: "Chờ khám chuyên khoa", }, { uuid: TYPE_STATUS.PendingPrescription, name: "Chờ nhận thuốc", }, { uuid: TYPE_STATUS.Completed, name: "Hoàn thành", }, { uuid: TYPE_STATUS.Cancelled, name: "Đã hủy", }, ]} />
)}
{/* TABLE */} item.id} data={consultationData} column={[ { title: "TÊN BỆNH NHÂN", render: (item: ConsultationItem) => ( {item.patientName}

Chi tiết bệnh nhân

), }, { title: "MÃ PHIÊN KHÁM", fixedLeft: true, render: (item: ConsultationItem) => { const specialty = item.specialtyClinics.find( (x) => x.specialtyId === _type, ); const detailHref = isAllTab ? `/consultation/${item.id}` : `/consultation/${item.id}?_type=${specialty?.id ?? ""}`; return ( {item.sessionCode}

Chi tiết phiên khám

); }, }, { title: "NGÀY KHÁM", render: (item: ConsultationItem) => ( {item.visitDate ? moment(item.visitDate).format("DD/MM/YYYY") : "---"} ), }, // 🔴 ẨN "DẤU HIỆU" khi KHÔNG PHẢI Tab All (!isAllTab) isAllTab && { title: "DẤU HIỆU", render: (item: ConsultationItem) => ( {item.symptomsText || "---"} ), }, { title: "CHẨN ĐOÁN", render: (item: ConsultationItem) => { if (!isAllTab) { const specialty = item.specialtyClinics.find( (x) => x.specialtyId === _type, ); return {specialty?.diagnosis || "---"}; } return {item.diagnosis || "---"}; }, }, // 🔴 ẨN "DẤU HIỆU" khi KHÔNG PHẢI Tab All (!isAllTab) // !isAllTab && { // title: "BÁC SĨ KHÁM", // render: (item: ConsultationItem) => { // const doctorNames = item.doctors?.join(", "); // return {doctorNames || "---"}; // }, // }, // 🔴 Ẩ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) => ( {item.treatmentPlan || "---"} ), }, { title: isAllTab ? "GHI CHÚ BÁC SĨ" : "GHI CHÚ KHÁM", render: (item: ConsultationItem) => { if (!isAllTab) { const specialty = item.specialtyClinics.find( (x) => x.specialtyId === _type, ); return {specialty?.specialtyNotes || "---"}; } return {item.doctorNotes || "---"}; }, }, // 🔴 Ẩ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 {specialty?.procedureNotes || "---"}; }, }, { title: "TRẠNG THÁI", render: (item: ConsultationItem) => { if (!isAllTab) { const specialty = item.specialtyClinics.find( (x) => x.specialtyId === _type, ); return ( ); } return ( ); }, }, { fixedRight: true, title: "ACTION", render: (item: ConsultationItem) => { const isCancelled = item.status === TYPE_STATUS.Cancelled; const isCompleted = item.status === TYPE_STATUS.Completed; const isDisabled = isCancelled || isCompleted; if (!isAllTab) { const specialty = item.specialtyClinics.find( (x) => x.specialtyId === _type, ); if (!specialty) return null; return ( Cập nhật ); } return (
{!isDisabled && (
{item.specialtyClinics.map((specialty) => ( {specialty.specialtyName} ))}
)}
handleOpenCancel(item)} className="w-full sm:w-auto" > Hủy handleOpenComplete(item)} className="w-full sm:w-auto" > Hoàn thành
); }, }, ].filter(Boolean)} // 💡 Lọc bỏ các giá trị false để ẩn cột /> updateQuery("_page", value)} onSetPageSize={(value) => updateQuery("_pageSize", value)} dependencies={[_pageSize, _keyword, _specialtyId, _status]} /> {/* CANCEL DIALOG */} {/* COMPLETE DIALOG */} ); }; export default MainPageConsultation;