diff --git a/src/app/auth/register/page.tsx b/src/app/auth/register/page.tsx new file mode 100644 index 0000000..337913b --- /dev/null +++ b/src/app/auth/register/page.tsx @@ -0,0 +1,15 @@ +"use client"; + +import LayoutAuth from "@/components/layouts/LayoutAuth‎"; +import MainRegister from "@/components/page/auth/MainRegister"; +import React from "react"; + +const page = () => { + return ( + + + + ); +}; + +export default page; diff --git a/src/app/consultation/[id]/page.tsx b/src/app/consultation/[id]/page.tsx new file mode 100644 index 0000000..1eb43d8 --- /dev/null +++ b/src/app/consultation/[id]/page.tsx @@ -0,0 +1,16 @@ +"use client"; + +import React from "react"; + +import BaseLayout from "@/components/layouts/BaseLayout"; +import DetailConsultation from "@/components/page/consultation/DetailConsultation"; + +const Page = () => { + return ( + + + + ); +}; + +export default Page; diff --git a/src/app/consultation/page.tsx b/src/app/consultation/page.tsx index 348f97d..08f9f17 100644 --- a/src/app/consultation/page.tsx +++ b/src/app/consultation/page.tsx @@ -1,9 +1,14 @@ "use client"; import BaseLayout from "@/components/layouts/BaseLayout"; +import MainPageConsultation from "@/components/page/consultation/MainPageConsultation"; import React from "react"; const page = () => { - return Phiên khám; + return ( + + + + ); }; export default page; diff --git a/src/app/page.tsx b/src/app/page.tsx index 1e187e4..ceaf716 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,11 +1,10 @@ import BaseLayout from "@/components/layouts/BaseLayout/BaseLayout"; -import MainPageHome from "@/components/page/Home/MainPageHome/MainPageHome"; -import Image from "next/image"; +import MainPagePatient from "@/components/page/patient/MainPagePatient"; export default function Home() { return ( - - + + ); } diff --git a/src/app/patient/[id]/page.tsx b/src/app/patient/[id]/page.tsx new file mode 100644 index 0000000..92d7b8a --- /dev/null +++ b/src/app/patient/[id]/page.tsx @@ -0,0 +1,16 @@ +"use client"; + +import React from "react"; + +import DetailPatient from "@/components/page/patient/DetailPatient"; +import BaseLayout from "@/components/layouts/BaseLayout"; + +const Page = () => { + return ( + + + + ); +}; + +export default Page; diff --git a/src/app/patient/page.tsx b/src/app/patient/page.tsx index 4a75145..89b4560 100644 --- a/src/app/patient/page.tsx +++ b/src/app/patient/page.tsx @@ -1,12 +1,15 @@ "use client"; import BaseLayout from "@/components/layouts/BaseLayout"; +import MainPagePatient from "@/components/page/patient/MainPagePatient/MainPagePatient"; import React from "react"; const page = () => { return (
- Bệnh nhân + + +
); }; diff --git a/src/app/prescription/[id]/page.tsx b/src/app/prescription/[id]/page.tsx new file mode 100644 index 0000000..73f81c1 --- /dev/null +++ b/src/app/prescription/[id]/page.tsx @@ -0,0 +1,14 @@ +"use client"; +import BaseLayout from "@/components/layouts/BaseLayout"; +import DetailPrescription from "@/components/page/prescription/DetailPrescription"; +import React from "react"; + +const page = () => { + return ( + + + + ); +}; + +export default page; diff --git a/src/app/prescription/create/page.tsx b/src/app/prescription/create/page.tsx new file mode 100644 index 0000000..2c0f5a0 --- /dev/null +++ b/src/app/prescription/create/page.tsx @@ -0,0 +1,14 @@ +"use client"; +import BaseLayout from "@/components/layouts/BaseLayout"; +import CreatePrescription from "@/components/page/prescription/CreatePrescription"; +import React from "react"; + +const page = () => { + return ( + + + + ); +}; + +export default page; diff --git a/src/app/prescription/page.tsx b/src/app/prescription/page.tsx index 404852d..8a86f47 100644 --- a/src/app/prescription/page.tsx +++ b/src/app/prescription/page.tsx @@ -1,9 +1,14 @@ "use client"; import BaseLayout from "@/components/layouts/BaseLayout"; +import MainPrescription from "@/components/page/prescription/MainPrescription"; import React from "react"; const page = () => { - return Đơn thuốc; + return ( + + + + ); }; export default page; diff --git a/src/app/prescription/update/page.tsx b/src/app/prescription/update/page.tsx new file mode 100644 index 0000000..615386c --- /dev/null +++ b/src/app/prescription/update/page.tsx @@ -0,0 +1,14 @@ +"use client"; +import BaseLayout from "@/components/layouts/BaseLayout"; +import UpdatePrescription from "@/components/page/prescription/UpdatePrescription"; +import React from "react"; + +const page = () => { + return ( + + + + ); +}; + +export default page; diff --git a/src/components/customs/custom-button.tsx b/src/components/customs/custom-button.tsx index d0443d0..59caf87 100644 --- a/src/components/customs/custom-button.tsx +++ b/src/components/customs/custom-button.tsx @@ -13,6 +13,8 @@ export interface PropsButton { target?: string; disabled?: boolean; + type?: "button" | "submit" | "reset"; + variant?: | "default" | "midnightBlue" @@ -36,6 +38,9 @@ export default function CustomButton({ className, target, disabled = false, + + type = "button", + variant = "default", size = "md", rounded = "md", @@ -112,7 +117,7 @@ export default function CustomButton({ // 🔘 Button mode return ( +
+ {/* LOGIN */} + + Đăng nhập + + {/* REGISTER */} + router.push(PATH.REGISTER)} + > + Đăng ký + +
{/* LINE */} -
+ /> */} {/* FORGOT PASSWORD */} - + */}
diff --git a/src/components/page/auth/MainRegister/MainRegister.tsx b/src/components/page/auth/MainRegister/MainRegister.tsx new file mode 100644 index 0000000..1936ff1 --- /dev/null +++ b/src/components/page/auth/MainRegister/MainRegister.tsx @@ -0,0 +1,200 @@ +"use client"; + +import React, { useState } from "react"; + +import { useRouter } from "next/navigation"; +import { useMutation } from "@tanstack/react-query"; +import { ShieldPlus, User, Mail, BadgeInfo } from "lucide-react"; + +import authServices from "@/services/authServices"; +import { httpRequest } from "@/services"; + +import { PATH } from "@/constant/config"; + +import FormCustom from "@/components/utils/FormCustom"; +import InputForm from "@/components/utils/FormCustom/components/InputForm"; +import CustomLoading from "@/components/customs/custom-loading"; +import CustomButton from "@/components/customs/custom-button"; + +export default function MainRegister() { + const router = useRouter(); + + const [form, setForm] = useState({ + username: "", + password: "", + fullName: "", + email: "", + }); + + const registerMutation = useMutation({ + mutationFn: async () => { + return httpRequest({ + showMessageFailed: true, + showMessageSuccess: true, + msgSuccess: "Đăng ký thành công!", + http: authServices.register({ + username: form.username, + password: form.password, + fullName: form.fullName, + email: form.email, + }), + }); + }, + + onSuccess(data: any) { + if (!data) return; + + router.replace(PATH.LOGIN); + }, + }); + + const handleRegister = () => { + registerMutation.mutate(); + }; + + return ( +
+ + + + {/* TITLE */} +

+ Đăng ký +

+ +

+ Tạo tài khoản mới cho hệ thống +

+ + {/* FORM */} +
+ {/* FULL NAME */} + + Họ và tên + * + + } + placeholder="Nhập họ và tên" + type="text" + name="fullName" + onClean + isRequired + isBlur + showDone + icon={} + /> + + {/* EMAIL */} +
+ + Email + * + + } + placeholder="Nhập email" + type="email" + name="email" + onClean + isRequired + isBlur + showDone + icon={} + /> +
+ + {/* USERNAME */} +
+ + Tài khoản + * + + } + placeholder="Nhập tài khoản" + type="text" + name="username" + onClean + isRequired + isBlur + showDone + icon={} + /> +
+ + {/* PASSWORD */} +
+ + Mật khẩu + * + + } + placeholder="Nhập mật khẩu" + type="password" + name="password" + onClean + isRequired + isBlur + showDone + icon={} + /> +
+ + {/* BUTTON */} +
+ {/* REGISTER */} + + Đăng ký + + + {/* LOGIN */} + router.push(PATH.LOGIN)} + > + Đăng nhập + +
+
+
+
+ ); +} diff --git a/src/components/page/auth/MainRegister/index.ts b/src/components/page/auth/MainRegister/index.ts new file mode 100644 index 0000000..2457a6d --- /dev/null +++ b/src/components/page/auth/MainRegister/index.ts @@ -0,0 +1 @@ +export { default } from "./MainRegister"; diff --git a/src/components/page/consultation/DetailConsultation/DetailConsultation.tsx b/src/components/page/consultation/DetailConsultation/DetailConsultation.tsx new file mode 100644 index 0000000..41ee9d7 --- /dev/null +++ b/src/components/page/consultation/DetailConsultation/DetailConsultation.tsx @@ -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({ + queryKey: [QUERY_KEY.chi_tiet_phien_kham, consultationId], + + enabled: !!consultationId, + + queryFn: async () => { + const res = await httpRequest({ + 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
Đang tải dữ liệu...
; + } + + if (!consultation) { + return
Không tìm thấy dữ liệu phiên khám
; + } + + return ( +
+
+
+ {/* HEADER */} +
+ router.back()} + className="cursor-pointer" + /> + +

+ Chi tiết phiên khám +

+
+ + {/* CONTENT */} +
+ {/* ID PHIÊN KHÁM */} +
+

+ ID PHIÊN KHÁM +

+ +

+ {consultation.id} +

+
+ + {/* MÃ PHIÊN KHÁM */} +
+

+ MÃ PHIÊN KHÁM +

+ +

+ {consultation.sessionCode} +

+
+ + {/* NGÀY GIỜ KHÁM */} +
+

+ NGÀY, GIỜ KHÁM +

+ +

+ {consultation.visitDate} +

+
+ + {/* TRIỆU CHỨNG */} +
+

DẤU HIỆU

+ +

+ {consultation.symptomsText || "---"} +

+
+ + {/* KHIẾU NẠI CHÍNH */} +
+

+ KHIẾU NẠI CHÍNH +

+ +

+ {consultation.chiefComplaint || "---"} +

+
+ + {/* DẤU HIỆU SINH TỒN */} +
+

+ DẤU HIỆU SINH TỒN +

+ +

+ {consultation.vitalSigns || "---"} +

+
+ + {/* CHẨN ĐOÁN */} +
+

+ CHUẨN ĐOÁN +

+ +

+ {consultation.diagnosis || "---"} +

+
+ + {/* KẾ HOẠCH ĐIỀU TRỊ */} +
+

+ KẾ HOẠCH ĐIỀU TRỊ +

+ +

+ {consultation.treatmentPlan || "---"} +

+
+ + {/* GHI CHÚ BÁC SĨ */} +
+

+ GHI CHÚ BÁC SĨ +

+ +

+ {consultation.doctorNotes || "---"} +

+
+ + {/* NGƯỜI TẠO */} +
+

+ NGƯỜI TẠO +

+ +

+ {consultation.createdBy || "---"} +

+
+ + {/* TRẠNG THÁI */} +
+

+ TRẠNG THÁI +

+ + +
+
+
+
+
+ ); +}; + +export default DetailConsultation; diff --git a/src/components/page/consultation/DetailConsultation/index.ts b/src/components/page/consultation/DetailConsultation/index.ts new file mode 100644 index 0000000..2038c73 --- /dev/null +++ b/src/components/page/consultation/DetailConsultation/index.ts @@ -0,0 +1 @@ +export { default } from "./DetailConsultation"; diff --git a/src/components/page/consultation/MainPageConsultation/MainPageConsultation.tsx b/src/components/page/consultation/MainPageConsultation/MainPageConsultation.tsx new file mode 100644 index 0000000..b7f61f3 --- /dev/null +++ b/src/components/page/consultation/MainPageConsultation/MainPageConsultation.tsx @@ -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(""); + + const [openCancelDialog, setOpenCancelDialog] = useState(false); + + const [openCompleteDialog, setOpenCompleteDialog] = useState(false); + + /* ========================= + GET LIST + ========================= */ + + 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: "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 ( +
+ {/* HEADER */} +
+

Phiên khám

+ + } + onClick={handleOpenCreate} + > + Thêm mới + +
+ + {/* SEARCH */} +
+
+ updateQuery("_keyword", value)} + placeholder="Tìm kiếm phiên khám..." + /> +
+
+ + {/* TABLE */} + + item.id} + data={consultationData} + column={[ + { + fixedLeft: true, + + title: "ID PHIÊN KHÁM", + + render: (item: ConsultationItem) => ( + + {item.id} + + ), + }, + + { + title: "MÃ PHIÊN KHÁM", + + render: (item: ConsultationItem) => ( + {item.sessionCode} + ), + }, + + { + title: "NGÀY KHÁM", + + render: (item: ConsultationItem) => {item.visitDate}, + }, + + { + title: "DẤU HIỆU", + + render: (item: ConsultationItem) => ( + {item.symptomsText || "---"} + ), + }, + + { + title: "CHUẨN ĐOÁN", + + render: (item: ConsultationItem) => ( + {item.diagnosis || "---"} + ), + }, + + { + title: "KẾ HOẠCH ĐIỀU TRỊ", + + render: (item: ConsultationItem) => ( + {item.treatmentPlan || "---"} + ), + }, + + { + title: "GHI CHÚ BÁC SĨ", + + render: (item: ConsultationItem) => ( + {item.doctorNotes || "---"} + ), + }, + + { + title: "TRẠNG THÁI", + + render: (item: ConsultationItem) => ( + + ), + }, + + { + 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 ( +
+ {/* UPDATE */} + } + onClick={() => handleOpenUpdate(item)} + /> + + {/* CANCEL */} + handleOpenCancel(item)} + > + Hủy + + + {/* COMPLETE */} + handleOpenComplete(item)} + > + Hoàn thành + +
+ ); + }, + }, + ]} + /> + + + {/* CANCEL DIALOG */} + + + {/* COMPLETE DIALOG */} + + + {/* CREATE */} + + + + + {/* UPDATE */} + + + + + ); +}; + +export default MainPageConsultation; diff --git a/src/components/page/consultation/MainPageConsultation/index.ts b/src/components/page/consultation/MainPageConsultation/index.ts new file mode 100644 index 0000000..5f96bbb --- /dev/null +++ b/src/components/page/consultation/MainPageConsultation/index.ts @@ -0,0 +1 @@ +export { default } from "./MainPageConsultation"; diff --git a/src/components/page/consultation/PopupCreateConsultation/PopupCreateConsultation.tsx b/src/components/page/consultation/PopupCreateConsultation/PopupCreateConsultation.tsx new file mode 100644 index 0000000..b0fe972 --- /dev/null +++ b/src/components/page/consultation/PopupCreateConsultation/PopupCreateConsultation.tsx @@ -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({ + queryKey: [QUERY_KEY.table_list_patient], + + queryFn: async () => { + const res = await httpRequest({ + 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 ( + +
+ {/* CLOSE */} + + + {/* HEADER */} +
+

+ Thêm phiên khám +

+
+ + {/* BODY */} +
+
+ + Bệnh nhân + * + + } + 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} + /> +
+
+ + {/* FOOTER */} +
+ + Hủy bỏ + + + + {createConsultationMutation.isPending + ? "Đang tạo..." + : "Tạo phiên khám"} + +
+
+
+ ); +}; + +export default PopupCreateConsultation; diff --git a/src/components/page/consultation/PopupCreateConsultation/index.ts b/src/components/page/consultation/PopupCreateConsultation/index.ts new file mode 100644 index 0000000..2953914 --- /dev/null +++ b/src/components/page/consultation/PopupCreateConsultation/index.ts @@ -0,0 +1 @@ +export { default } from "./PopupCreateConsultation"; diff --git a/src/components/page/consultation/PopupUpdateConsultation/PopupUpdateConsultation.tsx b/src/components/page/consultation/PopupUpdateConsultation/PopupUpdateConsultation.tsx new file mode 100644 index 0000000..72c28e6 --- /dev/null +++ b/src/components/page/consultation/PopupUpdateConsultation/PopupUpdateConsultation.tsx @@ -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(defaultForm); + + const consulDetailQuery = useQuery({ + queryKey: [QUERY_KEY.chi_tiet_phien_kham, id], + enabled: !!id, + queryFn: async () => { + const res = await httpRequest({ + 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 ( +
+ Đang tải dữ liệu... +
+ ); + } + + return ( + +
+ {/* CLOSE */} + + + {/* HEADER */} +
+

+ Chỉnh sửa phiên khám +

+
+ + {/* BODY */} +
+
+ + +