feat:update web

This commit is contained in:
TuanVT
2026-05-24 23:33:43 +07:00
parent b6ccde2c74
commit b0baa509d9
58 changed files with 4920 additions and 292 deletions
@@ -0,0 +1,237 @@
"use client";
import React from "react";
import { useParams, useRouter } from "next/navigation";
import { useQuery } from "@tanstack/react-query";
import { httpRequest } from "@/services";
import { QUERY_KEY, TYPE_STATUS } from "@/constant/config/enum";
import { ArrowLeft } from "lucide-react";
import consultationServices, {
ConsultationDetail,
} from "@/services/consultationServices";
import StateActive from "@/components/customs/StateActive";
const DetailConsultation = () => {
const params = useParams();
const router = useRouter();
const consultationId = params?.id as string;
const consulDetailQuery = useQuery<ConsultationDetail>({
queryKey: [QUERY_KEY.chi_tiet_phien_kham, consultationId],
enabled: !!consultationId,
queryFn: async () => {
const res = await httpRequest<ConsultationDetail>({
showMessageFailed: true,
http: consultationServices.detailConsultations(consultationId),
});
return (
res || {
id: "",
patientId: "",
sessionCode: "",
visitDate: "",
status: 1,
chiefComplaint: null,
symptomsText: null,
vitalSigns: null,
diagnosis: null,
treatmentPlan: null,
doctorNotes: null,
createdBy: "",
isDeleted: false,
}
);
},
});
const consultation = consulDetailQuery.data;
if (consulDetailQuery.isLoading) {
return <div>Đang tải dữ liệu...</div>;
}
if (!consultation) {
return <div>Không tìm thấy dữ liệu phiên khám</div>;
}
return (
<div className="flex flex-col gap-4">
<div className="rounded-2xl border border-gray-200 bg-white p-6 shadow-sm">
<div className="flex flex-col gap-6">
{/* HEADER */}
<div className="flex items-center gap-3">
<ArrowLeft
onClick={() => router.back()}
className="cursor-pointer"
/>
<h2 className="text-[28px] font-semibold text-[#111827]">
Chi tiết phiên khám
</h2>
</div>
{/* CONTENT */}
<div className="grid grid-cols-1 gap-5 md:grid-cols-2">
{/* ID PHIÊN KHÁM */}
<div className="space-y-1">
<p className="text-[14px] font-medium text-[#697586]">
ID PHIÊN KHÁM
</p>
<p className="text-[15px] font-medium text-[#202939]">
{consultation.id}
</p>
</div>
{/* MÃ PHIÊN KHÁM */}
<div className="space-y-1">
<p className="text-[14px] font-medium text-[#697586]">
PHIÊN KHÁM
</p>
<p className="text-[15px] font-medium text-[#202939]">
{consultation.sessionCode}
</p>
</div>
{/* NGÀY GIỜ KHÁM */}
<div className="space-y-1">
<p className="text-[14px] font-medium text-[#697586]">
NGÀY, GIỜ KHÁM
</p>
<p className="text-[15px] font-medium text-[#202939]">
{consultation.visitDate}
</p>
</div>
{/* TRIỆU CHỨNG */}
<div className="space-y-1">
<p className="text-[14px] font-medium text-[#697586]">DẤU HIỆU</p>
<p className="text-[15px] font-medium text-[#202939]">
{consultation.symptomsText || "---"}
</p>
</div>
{/* KHIẾU NẠI CHÍNH */}
<div className="space-y-1">
<p className="text-[14px] font-medium text-[#697586]">
KHIẾU NẠI CHÍNH
</p>
<p className="text-[15px] font-medium text-[#202939]">
{consultation.chiefComplaint || "---"}
</p>
</div>
{/* DẤU HIỆU SINH TỒN */}
<div className="space-y-1">
<p className="text-[14px] font-medium text-[#697586]">
DẤU HIỆU SINH TỒN
</p>
<p className="text-[15px] font-medium text-[#202939]">
{consultation.vitalSigns || "---"}
</p>
</div>
{/* CHẨN ĐOÁN */}
<div className="space-y-1">
<p className="text-[14px] font-medium text-[#697586]">
CHUẨN ĐOÁN
</p>
<p className="text-[15px] font-medium text-[#202939]">
{consultation.diagnosis || "---"}
</p>
</div>
{/* KẾ HOẠCH ĐIỀU TRỊ */}
<div className="space-y-1">
<p className="text-[14px] font-medium text-[#697586]">
KẾ HOẠCH ĐIỀU TRỊ
</p>
<p className="text-[15px] font-medium text-[#202939]">
{consultation.treatmentPlan || "---"}
</p>
</div>
{/* GHI CHÚ BÁC SĨ */}
<div className="space-y-1">
<p className="text-[14px] font-medium text-[#697586]">
GHI CHÚ BÁC
</p>
<p className="text-[15px] font-medium text-[#202939]">
{consultation.doctorNotes || "---"}
</p>
</div>
{/* NGƯỜI TẠO */}
<div className="space-y-1">
<p className="text-[14px] font-medium text-[#697586]">
NGƯỜI TẠO
</p>
<p className="text-[15px] font-medium text-[#202939]">
{consultation.createdBy || "---"}
</p>
</div>
{/* TRẠNG THÁI */}
<div className="space-y-1">
<p className="text-[14px] font-medium text-[#697586]">
TRẠNG THÁI
</p>
<StateActive
stateActive={consultation.status}
listState={[
{
state: TYPE_STATUS.Draft,
text: "Đang chờ",
textColor: "#000",
backgroundColor: "#FFE4C4",
},
{
state: TYPE_STATUS.InProgress,
text: "Đang thực hiện",
textColor: "#000",
backgroundColor: "#ff3300",
},
{
state: TYPE_STATUS.Completed,
text: "Hoàn thành",
textColor: "#000",
backgroundColor: "#3d69eb",
},
{
state: TYPE_STATUS.Cancelled,
text: "Đã hủy",
textColor: "#000",
backgroundColor: "#cccc",
},
]}
/>
</div>
</div>
</div>
</div>
</div>
);
};
export default DetailConsultation;
@@ -0,0 +1 @@
export { default } from "./DetailConsultation";
@@ -0,0 +1,481 @@
"use client";
import CustomButton from "@/components/customs/custom-button";
import CustomDialog from "@/components/customs/custom-dialog";
import CustomPopup from "@/components/customs/custom-popup";
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 } from "lucide-react";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import React, { useMemo, useState } from "react";
import PopupUpdateConsultation from "../PopupUpdateConsultation";
import PopupCreateConsultation from "../PopupCreateConsultation";
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 _create = searchParams.get("_create");
const _update = searchParams.get("_update");
/* =========================
STATE
========================= */
const [selectedConsultationId, setSelectedConsultationId] =
useState<string>("");
const [openCancelDialog, setOpenCancelDialog] = useState(false);
const [openCompleteDialog, setOpenCompleteDialog] = useState(false);
/* =========================
GET LIST
========================= */
const consultationQuery = useQuery<ConsultationResponse>({
queryKey: [QUERY_KEY.table_list_consultation, _page, _pageSize, _keyword],
queryFn: async () => {
const res = await httpRequest<ConsultationResponse>({
showMessageFailed: true,
http: consultationServices.getConsultations({
Page: Number(_page || 1),
PageSize: Number(_pageSize || 10),
Search: _keyword || "",
SortBy: "id",
Desc: true,
}),
});
return (
res || {
items: [],
page: 1,
pageSize: 10,
total: 0,
totalPages: 0,
}
);
},
});
/* =========================
DATA
========================= */
const consultationData = useMemo(() => {
return consultationQuery.data?.items || [];
}, [consultationQuery.data]);
/* =========================
UPDATE QUERY
========================= */
const updateQuery = (key: string, value: string | number) => {
const params = new URLSearchParams(searchParams.toString());
if (!value || value === "" || (key === "_page" && value === 1)) {
params.delete(key);
} else {
params.set(key, String(value));
}
if (key === "_pageSize") {
params.delete("_page");
}
const queryString = params.toString();
router.push(queryString ? `?${queryString}` : pathname);
};
/* =========================
CREATE POPUP
========================= */
const handleOpenCreate = () => {
const params = new URLSearchParams(searchParams.toString());
params.set("_create", "true");
router.push(`?${params.toString()}`);
};
/* =========================
UPDATE POPUP
========================= */
const handleOpenUpdate = (item: ConsultationItem) => {
const params = new URLSearchParams(searchParams.toString());
params.set("_update", item.id);
router.push(`?${params.toString()}`);
};
/* =========================
CLOSE POPUP
========================= */
const handleClosePopup = () => {
const params = new URLSearchParams(searchParams.toString());
params.delete("_create");
params.delete("_update");
const queryString = params.toString();
router.push(queryString ? `?${queryString}` : pathname);
};
/* =========================
DIALOG
========================= */
const handleOpenCancel = (item: ConsultationItem) => {
setSelectedConsultationId(item.id);
setOpenCancelDialog(true);
};
const handleOpenComplete = (item: ConsultationItem) => {
setSelectedConsultationId(item.id);
setOpenCompleteDialog(true);
};
const handleCloseDialog = () => {
setOpenCancelDialog(false);
setOpenCompleteDialog(false);
};
/* =========================
CANCEL
========================= */
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();
},
});
/* =========================
COMPLETE
========================= */
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();
},
});
/* =========================
CONFIRM
========================= */
const handleConfirmCancel = () => {
cancelConsultationMutation.mutate();
};
const handleConfirmComplete = () => {
completeConsultationMutation.mutate();
};
return (
<div className="flex flex-col gap-4 rounded-lg bg-white p-6 shadow">
{/* HEADER */}
<div className="flex items-center justify-between">
<h2 className="text-xl font-semibold text-black">Phiên khám</h2>
<CustomButton
variant="midnightBlue"
fullWidth={false}
icon={<ClipboardPlus />}
onClick={handleOpenCreate}
>
Thêm mới
</CustomButton>
</div>
{/* SEARCH */}
<div className="flex items-center justify-between gap-4">
<div className="w-full md:min-w-[400px]">
<Search
keyword={_keyword ?? ""}
setKeyword={(value) => updateQuery("_keyword", value)}
placeholder="Tìm kiếm phiên khám..."
/>
</div>
</div>
{/* TABLE */}
<DataWrapper
data={consultationData}
loading={consultationQuery.isLoading}
title="Không có dữ liệu"
note="Vui lòng thử lại sau"
>
<Table
rowKey={(item) => item.id}
data={consultationData}
column={[
{
fixedLeft: true,
title: "ID PHIÊN KHÁM",
render: (item: ConsultationItem) => (
<Link
href={`/consultation/${item.id}`}
className="text-blue-500 hover:underline"
>
{item.id}
</Link>
),
},
{
title: "MÃ PHIÊN KHÁM",
render: (item: ConsultationItem) => (
<span>{item.sessionCode}</span>
),
},
{
title: "NGÀY KHÁM",
render: (item: ConsultationItem) => <span>{item.visitDate}</span>,
},
{
title: "DẤU HIỆU",
render: (item: ConsultationItem) => (
<span>{item.symptomsText || "---"}</span>
),
},
{
title: "CHUẨN ĐOÁN",
render: (item: ConsultationItem) => (
<span>{item.diagnosis || "---"}</span>
),
},
{
title: "KẾ HOẠCH ĐIỀU TRỊ",
render: (item: ConsultationItem) => (
<span>{item.treatmentPlan || "---"}</span>
),
},
{
title: "GHI CHÚ BÁC SĨ",
render: (item: ConsultationItem) => (
<span>{item.doctorNotes || "---"}</span>
),
},
{
title: "TRẠNG THÁI",
render: (item: ConsultationItem) => (
<StateActive
stateActive={item.status}
listState={[
{
state: 1,
text: "Đang khám",
textColor: "#000",
backgroundColor: "#FFE4C4",
},
{
state: 2,
text: "Hoàn thành",
textColor: "#fff",
backgroundColor: "#22c55e",
},
{
state: 3,
text: "Đã hủy",
textColor: "#fff",
backgroundColor: "#ef4444",
},
]}
/>
),
},
{
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;
return (
<div className="flex items-center gap-2">
{/* UPDATE */}
<CustomButton
size="sm"
disabled={isDisabled}
icon={<Pencil className="text-blue-400" />}
onClick={() => handleOpenUpdate(item)}
/>
{/* CANCEL */}
<CustomButton
size="sm"
variant="red"
disabled={isDisabled}
onClick={() => handleOpenCancel(item)}
>
Hủy
</CustomButton>
{/* COMPLETE */}
<CustomButton
size="sm"
variant="green"
disabled={isDisabled}
onClick={() => handleOpenComplete(item)}
>
Hoàn thành
</CustomButton>
</div>
);
},
},
]}
/>
</DataWrapper>
{/* CANCEL DIALOG */}
<CustomDialog
open={openCancelDialog}
title="Hủy phiên khám"
note="Bạn có chắc chắn muốn hủy phiên khám này không?"
type="error"
onClose={handleCloseDialog}
onSubmit={handleConfirmCancel}
titleCancel="Đóng"
titleSubmit="Xác nhận"
/>
{/* COMPLETE DIALOG */}
<CustomDialog
open={openCompleteDialog}
title="Hoàn thành phiên khám"
note="Bạn có chắc chắn muốn hoàn thành phiên khám này không?"
type="success"
onClose={handleCloseDialog}
onSubmit={handleConfirmComplete}
titleCancel="Đóng"
titleSubmit="Xác nhận"
/>
{/* CREATE */}
<CustomPopup open={!!_create} onClose={handleClosePopup}>
<PopupCreateConsultation onClose={handleClosePopup} />
</CustomPopup>
{/* UPDATE */}
<CustomPopup open={!!_update} onClose={handleClosePopup}>
<PopupUpdateConsultation
id={_update || ""}
onClose={handleClosePopup}
/>
</CustomPopup>
</div>
);
};
export default MainPageConsultation;
@@ -0,0 +1 @@
export { default } from "./MainPageConsultation";
@@ -0,0 +1,222 @@
"use client";
import React, { useMemo, useState } from "react";
import { X } from "lucide-react";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import FormCustom from "@/components/utils/FormCustom/FormCustom";
import SelectForm from "@/components/utils/FormCustom/components/SelectForm";
import { httpRequest } from "@/services";
import consultationServices from "@/services/consultationServices";
import patientServices, {
PatientItem,
PatientResponse,
} from "@/services/patientServices";
import { QUERY_KEY } from "@/constant/config/enum";
import CustomButton from "@/components/customs/custom-button";
export interface PopupCreateConsultationProps {
onClose: () => void;
}
const PopupCreateConsultation = ({ onClose }: PopupCreateConsultationProps) => {
const queryClient = useQueryClient();
const [form, setForm] = useState<{
patientId: string;
}>({
patientId: "",
});
/* =========================
GET LIST PATIENT
========================= */
const patientQuery = useQuery<PatientResponse>({
queryKey: [QUERY_KEY.table_list_patient],
queryFn: async () => {
const res = await httpRequest<PatientResponse>({
showMessageFailed: true,
http: patientServices.getPatient({
Page: 1,
PageSize: 1000,
Search: "",
SortBy: "id",
Desc: true,
}),
});
return (
res || {
items: [],
page: 1,
pageSize: 10,
total: 0,
totalPages: 0,
}
);
},
});
/* =========================
OPTIONS SELECT
========================= */
const patientOptions = useMemo(() => {
return patientQuery.data?.items || [];
}, [patientQuery.data]);
/* =========================
CREATE CONSULTATION
========================= */
const createConsultationMutation = useMutation({
mutationFn: async () => {
return await httpRequest({
showMessageFailed: true,
showMessageSuccess: true,
msgSuccess: "Tạo phiên khám thành công!",
http: consultationServices.createConsultations({
patientId: form.patientId,
}),
});
},
onSuccess() {
queryClient.invalidateQueries({
queryKey: [QUERY_KEY.table_list_consultation],
});
onClose();
},
});
const handleSubmit = () => {
createConsultationMutation.mutate();
};
return (
<FormCustom form={form} setForm={setForm} onSubmit={handleSubmit}>
<div
className="
relative
h-[400px]
w-[640px]
max-w-[95vw]
rounded-3xl
bg-white
shadow-xl
flex
flex-col
overflow-hidden
"
>
{/* CLOSE */}
<button
type="button"
onClick={onClose}
className="
absolute
right-5
top-5
z-10
text-gray-400
transition
hover:text-gray-600
"
>
<X size={22} />
</button>
{/* HEADER */}
<div
className="
shrink-0
border-b
px-7
py-5
bg-white
"
>
<h2 className="text-[30px] font-semibold text-[#111827]">
Thêm phiên khám
</h2>
</div>
{/* BODY */}
<div className="flex-1 overflow-y-auto px-7 py-5">
<div className="space-y-5">
<SelectForm
label={
<span className="text-[14px] font-medium text-[#374151]">
Bệnh nhân
<span className="text-red-500">*</span>
</span>
}
placeholder="Chọn bệnh nhân"
value={form.patientId}
options={patientOptions}
// loading={patientQuery.isLoading}
onSelect={(item: PatientItem) =>
setForm((prev) => ({
...prev,
patientId: item.id,
}))
}
onClean={() =>
setForm((prev) => ({
...prev,
patientId: "",
}))
}
getOptionLabel={(item: PatientItem) =>
`${item.fullName} - ${item.identificationNumber}`
}
getOptionValue={(item: PatientItem) => item.id}
/>
</div>
</div>
{/* FOOTER */}
<div
className="
shrink-0
border-t
bg-white
px-7
py-5
flex
items-center
justify-end
gap-3
"
>
<CustomButton variant="grey" rounded="md" onClick={onClose}>
Hủy bỏ
</CustomButton>
<CustomButton
disabled={!form.patientId || createConsultationMutation.isPending}
variant="midnightBlue"
rounded="md"
onClick={handleSubmit}
>
{createConsultationMutation.isPending
? "Đang tạo..."
: "Tạo phiên khám"}
</CustomButton>
</div>
</div>
</FormCustom>
);
};
export default PopupCreateConsultation;
@@ -0,0 +1 @@
export { default } from "./PopupCreateConsultation";
@@ -0,0 +1,281 @@
"use client";
import React, { useEffect, useState } from "react";
import { X } from "lucide-react";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import CustomButton from "@/components/customs/custom-button";
import FormCustom from "@/components/utils/FormCustom";
import InputForm from "@/components/utils/FormCustom/components/InputForm";
import TextArea from "@/components/utils/FormCustom/components/TextArea";
import { QUERY_KEY } from "@/constant/config/enum";
import { httpRequest } from "@/services";
import consultationServices, {
ConsultationDetail,
} from "@/services/consultationServices";
import { ContextFormCustom } from "@/components/utils/FormCustom/contexts";
interface PopupUpdateConsultationProps {
id: string;
onClose: () => void;
}
interface IUpdateConsul {
chiefComplaint: string;
symptomsText: string;
vitalSigns: string;
diagnosis: string;
treatmentPlan: string;
doctorNotes: string;
}
const defaultForm: IUpdateConsul = {
chiefComplaint: "",
symptomsText: "",
vitalSigns: "",
diagnosis: "",
treatmentPlan: "",
doctorNotes: "",
};
const PopupUpdateConsultation = ({
id,
onClose,
}: PopupUpdateConsultationProps) => {
const queryClient = useQueryClient();
const [form, setForm] = useState<IUpdateConsul>(defaultForm);
const consulDetailQuery = useQuery<ConsultationDetail>({
queryKey: [QUERY_KEY.chi_tiet_phien_kham, id],
enabled: !!id,
queryFn: async () => {
const res = await httpRequest<ConsultationDetail>({
showMessageFailed: true,
http: consultationServices.detailConsultations(id),
});
return (
res || {
id: "",
patientId: "",
sessionCode: "",
visitDate: "",
status: 1,
chiefComplaint: null,
symptomsText: null,
vitalSigns: null,
diagnosis: null,
treatmentPlan: null,
doctorNotes: null,
createdBy: "",
isDeleted: false,
}
);
},
});
useEffect(() => {
const consul = consulDetailQuery.data;
if (!consul) return;
setForm({
chiefComplaint: consul.chiefComplaint || "",
symptomsText: consul.symptomsText || "",
vitalSigns: consul.vitalSigns || "",
diagnosis: consul.diagnosis || "",
treatmentPlan: consul.treatmentPlan || "",
doctorNotes: consul.doctorNotes || "",
});
}, [consulDetailQuery.data]);
/* =========================
SUBMIT
========================= */
const updateConsultationMutation = useMutation({
mutationFn: async () => {
return httpRequest({
showMessageFailed: true,
showMessageSuccess: true,
msgSuccess: "Cập nhật phiên khám thành công!",
http: consultationServices.putConsultations(id, {
chiefComplaint: form.chiefComplaint,
symptomsText: form.symptomsText,
vitalSigns: form.vitalSigns,
diagnosis: form.diagnosis,
treatmentPlan: form.treatmentPlan,
doctorNotes: form.doctorNotes,
}),
});
},
onSuccess(data) {
if (!data) return;
queryClient.invalidateQueries({
queryKey: [QUERY_KEY.table_list_consultation],
});
queryClient.invalidateQueries({
queryKey: [QUERY_KEY.chi_tiet_phien_kham, id],
});
onClose();
},
});
const handleSubmit = () => {
updateConsultationMutation.mutate();
};
if (consulDetailQuery.isLoading) {
return (
<div className="flex items-center justify-center p-10">
Đang tải dữ liệu...
</div>
);
}
return (
<FormCustom form={form} setForm={setForm} onSubmit={handleSubmit}>
<div
className="
relative
h-[680px]
w-[640px]
max-w-[95vw]
rounded-3xl
bg-white
shadow-xl
flex
flex-col
overflow-hidden
"
>
{/* CLOSE */}
<button
type="button"
onClick={onClose}
className="
absolute
right-5
top-5
z-10
text-gray-400
transition
hover:text-gray-600
"
>
<X size={22} />
</button>
{/* HEADER */}
<div
className="
shrink-0
border-b
px-7
py-5
bg-white
"
>
<h2 className="text-[30px] font-semibold text-[#111827]">
Chỉnh sửa phiên khám
</h2>
</div>
{/* BODY */}
<div className="flex-1 overflow-y-auto px-7 py-5">
<div className="space-y-5">
<InputForm
label="Lý do khám"
name="chiefComplaint"
type="text"
value={form.chiefComplaint}
placeholder="Nhập lý do khám"
/>
<TextArea
label="Triệu chứng"
name="symptomsText"
placeholder="Nhập triệu chứng"
value={form.symptomsText}
/>
<TextArea
label="Dấu hiệu sinh tồn"
name="vitalSigns"
placeholder="Nhập dấu hiệu sinh tồn"
value={form.vitalSigns}
/>
<TextArea
label="Chẩn đoán"
name="diagnosis"
placeholder="Nhập chẩn đoán"
value={form.diagnosis}
/>
<TextArea
label="Kế hoạch điều trị"
name="treatmentPlan"
placeholder="Nhập kế hoạch điều trị"
value={form.treatmentPlan}
/>
<TextArea
label="Ghi chú bác sĩ"
name="doctorNotes"
placeholder="Nhập ghi chú"
value={form.doctorNotes}
/>
</div>
</div>
{/* FOOTER */}
<div
className="
shrink-0
border-t
bg-white
px-7
py-5
flex
items-center
justify-end
gap-3
"
>
<CustomButton variant="grey" rounded="md" onClick={onClose}>
Hủy bỏ
</CustomButton>
<ContextFormCustom.Consumer>
{({ isDone }) => (
<CustomButton
disabled={!isDone || updateConsultationMutation.isPending}
variant="midnightBlue"
rounded="md"
type="submit"
>
{updateConsultationMutation.isPending
? "Đang cập nhật..."
: "Cập nhật"}
</CustomButton>
)}
</ContextFormCustom.Consumer>
</div>
</div>
</FormCustom>
);
};
export default PopupUpdateConsultation;
@@ -0,0 +1 @@
export { default } from "./PopupUpdateConsultation";