From d85a3eecf1a8da574a5b005c4767d12c285b1f96 Mon Sep 17 00:00:00 2001 From: Uday Sagar Date: Fri, 6 Dec 2024 01:33:07 +0530 Subject: [PATCH] refactored a lot of compoents related to notes --- src/Routers/routes/ConsultationRoutes.tsx | 4 +- src/components/Facility/DoctorNote.tsx | 98 ---------- .../Facility/PatientConsultationNotesList.tsx | 127 ------------- src/components/Facility/PatientNoteCard.tsx | 6 +- .../Facility/PatientNotesDetailedView.tsx | 161 ++++++++-------- src/components/Facility/PatientNotesList.tsx | 160 ++++++++-------- ...ndex.tsx => PatientNotesListComponent.tsx} | 173 +++++++++++------- .../Facility/PatientNotesSlideover.tsx | 49 ++++- .../Patient/PatientDetailsTab/Notes.tsx | 165 +---------------- src/components/Patient/PatientNotes.tsx | 161 ++-------------- 10 files changed, 334 insertions(+), 770 deletions(-) delete mode 100644 src/components/Facility/DoctorNote.tsx delete mode 100644 src/components/Facility/PatientConsultationNotesList.tsx rename src/components/Facility/{ConsultationDoctorNotes/index.tsx => PatientNotesListComponent.tsx} (51%) diff --git a/src/Routers/routes/ConsultationRoutes.tsx b/src/Routers/routes/ConsultationRoutes.tsx index da3c30b5093..3d11f301aa3 100644 --- a/src/Routers/routes/ConsultationRoutes.tsx +++ b/src/Routers/routes/ConsultationRoutes.tsx @@ -1,5 +1,4 @@ import { ConsultationDetails } from "@/components/Facility/ConsultationDetails"; -import ConsultationDoctorNotes from "@/components/Facility/ConsultationDoctorNotes"; import { ConsultationForm } from "@/components/Facility/ConsultationForm"; import Investigation from "@/components/Facility/Investigations"; import InvestigationPrintPreview from "@/components/Facility/Investigations/InvestigationsPrintPreview"; @@ -13,6 +12,7 @@ import { DailyRoundListDetails } from "@/components/Patient/DailyRoundListDetail import { DailyRounds } from "@/components/Patient/DailyRounds"; import FileUploadPage from "@/components/Patient/FileUploadPage"; import PatientConsentRecords from "@/components/Patient/PatientConsentRecords"; +import PatientNotes from "@/components/Patient/PatientNotes"; import { AppRoutes } from "@/Routers/AppRouter"; @@ -153,7 +153,7 @@ const consultationRoutes: AppRoutes = { ), "/facility/:facilityId/patient/:patientId/consultation/:consultationId/notes": ({ facilityId, patientId, consultationId }) => ( - void; - handleNext: () => void; - disableEdit?: boolean; - setReplyTo?: (reply_to: PatientNotesModel | undefined) => void; - mode?: "thread-view" | "default-view"; - setThreadViewNote?: (noteId: string) => void; -} - -const DoctorNote = (props: DoctorNoteProps) => { - const { - state, - handleNext, - setReload, - disableEdit, - setReplyTo, - mode, - setThreadViewNote, - } = props; - - const notes = - mode === "thread-view" - ? state.notes.filter((note) => !note.root_note_object) - : state.notes; - - return ( -
- {notes.length ? ( - - -
- } - className="flex h-full flex-col-reverse overflow-hidden" - inverse={true} - dataLength={notes.length} - scrollableTarget="patient-notes-list" - > - {notes.map((note) => { - const noteCard = ( - - ); - if (mode === "thread-view") { - return ( -
- {noteCard} -
- ); - } else { - return ( - -
- {noteCard} -
-
- ); - } - })} - - ) : ( -
- No Notes Found -
- )} - - ); -}; - -export default DoctorNote; diff --git a/src/components/Facility/PatientConsultationNotesList.tsx b/src/components/Facility/PatientConsultationNotesList.tsx deleted file mode 100644 index 36b09b443a8..00000000000 --- a/src/components/Facility/PatientConsultationNotesList.tsx +++ /dev/null @@ -1,127 +0,0 @@ -import { Dispatch, SetStateAction, useEffect, useState } from "react"; - -import CircularProgress from "@/components/Common/CircularProgress"; -import DoctorNote from "@/components/Facility/DoctorNote"; -import { - PatientNoteStateType, - PatientNotesModel, -} from "@/components/Facility/models"; - -import useSlug from "@/hooks/useSlug"; - -import { RESULTS_PER_PAGE_LIMIT } from "@/common/constants"; - -import routes from "@/Utils/request/api"; -import request from "@/Utils/request/request"; - -interface PatientNotesProps { - state: PatientNoteStateType; - setState: Dispatch>; - reload?: boolean; - setReload?: (value: boolean) => void; - disableEdit?: boolean; - thread: PatientNotesModel["thread"]; - setReplyTo?: (value: PatientNotesModel | undefined) => void; - mode?: "thread-view" | "default-view"; - setThreadViewNote?: (noteId: string) => void; -} - -const pageSize = RESULTS_PER_PAGE_LIMIT; - -const PatientConsultationNotesList = (props: PatientNotesProps) => { - const { - state, - setState, - reload, - setReload, - disableEdit, - thread, - setReplyTo, - mode = "default-view", - setThreadViewNote, - } = props; - const consultationId = useSlug("consultation") ?? ""; - - const [isLoading, setIsLoading] = useState(true); - - const fetchNotes = async (currentPage: number) => { - setIsLoading(true); - - const { data } = await request(routes.getPatientNotes, { - pathParams: { - patientId: props.state.patientId || "", - }, - query: { - consultation: consultationId, - thread, - offset: (currentPage - 1) * RESULTS_PER_PAGE_LIMIT, - }, - }); - - if (data) { - setState((prevState) => ({ - ...prevState, - notes: - currentPage === 1 - ? data.results - : [...prevState.notes, ...data.results], - totalPages: Math.ceil(data.count / pageSize), - })); - } - setIsLoading(false); - setReload?.(false); - }; - - useEffect(() => { - if (reload) { - fetchNotes(state.cPage); - } - }, [reload]); - - useEffect(() => { - setState((prev) => ({ ...prev, notes: [], cPage: 1 })); - // Fetch notes for the first page when thread changes and prevent loading a different page when changing threads - fetchNotes(1); - }, [thread]); - - useEffect(() => { - setThreadViewNote?.(""); - }, [thread, mode]); - - useEffect(() => { - setReload?.(true); - }, []); - - const handleNext = () => { - if (state.cPage < state.totalPages) { - setState((prevState) => ({ - ...prevState, - cPage: prevState.cPage + 1, - })); - setReload?.(true); - } - }; - - // only show during initial fetch, to prevent scroll position from being reset - if (isLoading && state.cPage === 1) { - return ( -
- -
- ); - } - - return ( - - ); -}; - -export default PatientConsultationNotesList; diff --git a/src/components/Facility/PatientNoteCard.tsx b/src/components/Facility/PatientNoteCard.tsx index b36be904ae2..9ba44586311 100644 --- a/src/components/Facility/PatientNoteCard.tsx +++ b/src/components/Facility/PatientNoteCard.tsx @@ -35,7 +35,7 @@ import { const PatientNoteCard = ({ note, - setReload, + refetch, disableEdit, allowReply = true, allowThreadView = false, @@ -44,7 +44,7 @@ const PatientNoteCard = ({ setThreadViewNote, }: { note: PatientNotesModel; - setReload: any; + refetch?: () => void; disableEdit?: boolean; allowReply?: boolean; allowThreadView?: boolean; @@ -92,7 +92,7 @@ const PatientNoteCard = ({ if (res?.status === 200) { Success({ msg: "Note updated successfully" }); setIsEditing(false); - setReload(true); + refetch?.(); } }; diff --git a/src/components/Facility/PatientNotesDetailedView.tsx b/src/components/Facility/PatientNotesDetailedView.tsx index 8f04a3b56ca..f4628c474c4 100644 --- a/src/components/Facility/PatientNotesDetailedView.tsx +++ b/src/components/Facility/PatientNotesDetailedView.tsx @@ -14,10 +14,11 @@ import { import * as Notification from "@/Utils/Notifications"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; +import useQuery from "@/Utils/request/useQuery"; interface Props { patientId: string; - consultationId: string; + consultationId?: string; noteId: string; thread: PatientNotesModel["thread"]; setThreadViewNote?: (note: string) => void; @@ -26,20 +27,39 @@ interface Props { const PatientNotesDetailedView = (props: Props) => { const { patientId, consultationId, noteId, thread, setThreadViewNote } = props; - const [isLoading, setIsLoading] = useState(true); - const [reload, setReload] = useState(false); - const [state, setState] = useState(); const [noteField, setNoteField] = useState(""); const [reply_to, setReplyTo] = useState( undefined, ); const scrollRef = useRef(null); + const { + data: state, + loading, + refetch, + } = useQuery(routes.getPatientNote, { + pathParams: { + patientId: patientId, + noteId, + }, + query: { + consultation: consultationId, + thread, + }, + }); + const scrollToBottom = () => { if (scrollRef.current) { scrollRef.current.scrollTop = scrollRef.current.scrollHeight; } }; + + useEffect(() => { + if (state) { + setTimeout(scrollToBottom, 100); + } + }, [state]); + const onAddNote = async () => { if (!/\S+/.test(noteField)) { Notification.Error({ @@ -77,58 +97,20 @@ const PatientNotesDetailedView = (props: Props) => { return undefined; } }; - const fetchNotes = async () => { - setIsLoading(true); - - const { data } = await request(routes.getPatientNote, { - pathParams: { - patientId: patientId, - noteId, - }, - query: { - consultation: consultationId, - thread, - }, - }); - - if (data) { - setState(data); - setTimeout(scrollToBottom, 100); - } - setIsLoading(false); - setReload(false); - }; - - // Fetch notes when reload is triggered - useEffect(() => { - if (reload) { - fetchNotes(); - } - }, [reload]); - - // Fetch notes when thread or noteId changes - useEffect(() => { - fetchNotes(); - }, [thread, noteId]); - // Set reload to true on component mount - useEffect(() => { - setReload(true); - }, []); - - if (isLoading) { + if (loading) { return ( -
+
); } return ( -
+
{state && (
-
+

Note

-
-
+
+

Replies

{state.child_notes.length > 0 && (
@@ -157,31 +139,36 @@ const PatientNotesDetailedView = (props: Props) => { )}
-
+
{state.child_notes.length > 0 ? ( - state.child_notes.map((note) => { - const parentNote = state.child_notes.find( - (n) => n.id === note.reply_to, - ); - return ( - -
- -
-
- ); - }) +
+ {state.child_notes.map((note) => { + const parentNote = state.child_notes.find( + (n) => n.id === note.reply_to, + ); + return ( + +
+ +
+
+ ); + })} +
) : ( -
+
{
)}
-
-
- setReplyTo(undefined)} - > - setReload(true)} - maxRows={10} - /> - +
+ setReplyTo(undefined)} + > + refetch()} + maxRows={10} + /> + +
)} diff --git a/src/components/Facility/PatientNotesList.tsx b/src/components/Facility/PatientNotesList.tsx index 5602266662b..4abd36c5a63 100644 --- a/src/components/Facility/PatientNotesList.tsx +++ b/src/components/Facility/PatientNotesList.tsx @@ -1,99 +1,107 @@ -import { Dispatch, SetStateAction, useEffect, useState } from "react"; +import InfiniteScroll from "react-infinite-scroll-component"; import CircularProgress from "@/components/Common/CircularProgress"; -import DoctorNote from "@/components/Facility/DoctorNote"; +import DoctorNoteReplyPreviewCard from "@/components/Facility/DoctorNoteReplyPreviewCard"; +import PatientNoteCard from "@/components/Facility/PatientNoteCard"; import { PatientNoteStateType, PatientNotesModel, } from "@/components/Facility/models"; -import { RESULTS_PER_PAGE_LIMIT } from "@/common/constants"; - -import routes from "@/Utils/request/api"; -import request from "@/Utils/request/request"; - -interface PatientNotesProps { +interface PatientNotesListProps { state: PatientNoteStateType; - setState: Dispatch>; - patientId: string; - facilityId: string; - reload?: boolean; - setReload?: (value: boolean) => void; - thread: PatientNotesModel["thread"]; + refetch?: () => void; + handleNext: () => void; + disableEdit?: boolean; setReplyTo?: (reply_to: PatientNotesModel | undefined) => void; + mode?: "thread-view" | "default-view"; + setThreadViewNote?: (noteId: string) => void; + isLoading?: boolean; } -const pageSize = RESULTS_PER_PAGE_LIMIT; - -const PatientNotesList = (props: PatientNotesProps) => { - const { state, setState, reload, setReload, thread, setReplyTo } = props; - - const [isLoading, setIsLoading] = useState(true); - - const fetchNotes = async (currentPage: number) => { - setIsLoading(true); - const { data } = await request(routes.getPatientNotes, { - pathParams: { patientId: props.patientId }, - query: { - offset: (state.cPage - 1) * RESULTS_PER_PAGE_LIMIT, - thread, - }, - }); - - if (data) { - setState((prevState) => ({ - ...prevState, - notes: - currentPage === 1 - ? data.results - : [...prevState.notes, ...data.results], - totalPages: Math.ceil(data.count / pageSize), - })); - } - - setIsLoading(false); - setReload?.(false); - }; - - useEffect(() => { - if (reload) { - fetchNotes(state.cPage); - } - }, [reload]); - - useEffect(() => { - fetchNotes(state.cPage); - }, [thread]); - - useEffect(() => { - setReload?.(true); - }, []); - - const handleNext = () => { - if (state.cPage < state.totalPages) { - setState((prevState) => ({ - ...prevState, - cPage: prevState.cPage + 1, - })); - setReload?.(true); - } - }; +const PatientNotesList = (props: PatientNotesListProps) => { + const { + state, + handleNext, + refetch, + disableEdit, + setReplyTo, + mode, + setThreadViewNote, + isLoading, + } = props; + + const notes = + mode === "thread-view" + ? state.notes.filter((note) => !note.root_note_object) + : state.notes; if (isLoading && state.cPage === 1) { return ( -
+
); } return ( - +
+ {notes.length ? ( + + +
+ } + className="flex h-full flex-col-reverse overflow-hidden" + inverse={true} + dataLength={notes.length} + scrollableTarget="patient-notes-list" + > + {notes.map((note) => { + const noteCard = ( + + ); + if (mode === "thread-view") { + return ( +
+ {noteCard} +
+ ); + } else { + return ( + +
+ {noteCard} +
+
+ ); + } + })} + + ) : ( +
+ No Notes Found +
+ )} +
); }; diff --git a/src/components/Facility/ConsultationDoctorNotes/index.tsx b/src/components/Facility/PatientNotesListComponent.tsx similarity index 51% rename from src/components/Facility/ConsultationDoctorNotes/index.tsx rename to src/components/Facility/PatientNotesListComponent.tsx index b169db60b6e..568f8323504 100644 --- a/src/components/Facility/ConsultationDoctorNotes/index.tsx +++ b/src/components/Facility/PatientNotesListComponent.tsx @@ -1,12 +1,13 @@ -import { useState } from "react"; +import { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; +import AuthorizedChild from "@/CAREUI/misc/AuthorizedChild"; + import DiscussionNotesEditor from "@/components/Common/DiscussionNotesEditor"; -import Page from "@/components/Common/Page"; import Tabs from "@/components/Common/Tabs"; import DoctorNoteReplyPreviewCard from "@/components/Facility/DoctorNoteReplyPreviewCard"; -import PatientConsultationNotesList from "@/components/Facility/PatientConsultationNotesList"; import PatientNotesDetailedView from "@/components/Facility/PatientNotesDetailedView"; +import PatientNotesList from "@/components/Facility/PatientNotesList"; import { PatientNoteStateType, PatientNotesModel, @@ -15,22 +16,33 @@ import { import useAuthUser from "@/hooks/useAuthUser"; import { useMessageListener } from "@/hooks/useMessageListener"; -import { PATIENT_NOTES_THREADS } from "@/common/constants"; +import { + PATIENT_NOTES_THREADS, + RESULTS_PER_PAGE_LIMIT, +} from "@/common/constants"; +import { NonReadOnlyUsers } from "@/Utils/AuthorizeFor"; import * as Notification from "@/Utils/Notifications"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; import useQuery from "@/Utils/request/useQuery"; import { classNames, keysOf } from "@/Utils/utils"; -interface ConsultationDoctorNotesProps { +interface PatientNotesProps { patientId: string; facilityId: string; - consultationId: string; + consultationId?: string; + className?: string; + allowThreadView?: boolean; } -const ConsultationDoctorNotes = (props: ConsultationDoctorNotesProps) => { - const { patientId, facilityId, consultationId } = props; +const PatientNotesListComponent = (props: PatientNotesProps) => { + const { + patientId, + facilityId, + consultationId, + allowThreadView = true, + } = props; const { t } = useTranslation(); const authUser = useAuthUser(); const [thread, setThread] = useState( @@ -41,9 +53,6 @@ const ConsultationDoctorNotes = (props: ConsultationDoctorNotesProps) => { const [patientActive, setPatientActive] = useState(true); const [noteField, setNoteField] = useState(""); - const [reload, setReload] = useState(false); - const [facilityName, setFacilityName] = useState(""); - const [patientName, setPatientName] = useState(""); const [reply_to, setReplyTo] = useState( undefined, ); @@ -61,6 +70,32 @@ const ConsultationDoctorNotes = (props: ConsultationDoctorNotesProps) => { }; const [state, setState] = useState(initialData); + const { refetch, loading } = useQuery(routes.getPatientNotes, { + pathParams: { patientId }, + query: { + consultation: consultationId, + offset: (state.cPage - 1) * RESULTS_PER_PAGE_LIMIT, + thread, + }, + onResponse: ({ data }) => { + if (data) { + setState((prevState) => ({ + ...prevState, + notes: + state.cPage === 1 + ? data.results + : [...prevState.notes, ...data.results], + totalPages: Math.ceil(data.count / RESULTS_PER_PAGE_LIMIT), + })); + } + }, + }); + + useEffect(() => { + setThreadViewNote(""); + setState((prev) => ({ ...prev, notes: [], cPage: 1 })); + }, [thread]); + const onAddNote = async () => { if (!/\S+/.test(noteField)) { Notification.Error({ @@ -96,8 +131,6 @@ const ConsultationDoctorNotes = (props: ConsultationDoctorNotesProps) => { onResponse: ({ data }) => { if (data) { setPatientActive(data.is_active ?? true); - setPatientName(data.name ?? ""); - setFacilityName(data.facility_object?.name ?? ""); } }, }); @@ -110,32 +143,28 @@ const ConsultationDoctorNotes = (props: ConsultationDoctorNotesProps) => { message?.facility_id == facilityId && message?.patient_id == patientId ) { - setReload(true); + refetch(); } }); return ( - -
- setMode(tab as "thread-view" | "default-view")} - /> -
-
+
+ {allowThreadView && ( +
+ + setMode(tab as "thread-view" | "default-view") + } + /> +
+ )} +
{keysOf(PATIENT_NOTES_THREADS).map((current) => ( ))}
-
+
- { + if (state.cPage < state.totalPages) { + setState((prevState) => ({ + ...prevState, + cPage: prevState.cPage + 1, + })); + } + }} + refetch={refetch} + disableEdit={!patientActive} setReplyTo={setReplyTo} mode={mode} setThreadViewNote={setThreadViewNote} + isLoading={loading} />
- setReplyTo(undefined)} - > - setReload(true)} - maxRows={10} - /> - + + {({ isAuthorized }) => ( + setReplyTo(undefined)} + > + + + )} +
{threadViewNote && ( - +
+ +
)}
- +
); }; -export default ConsultationDoctorNotes; +export default PatientNotesListComponent; diff --git a/src/components/Facility/PatientNotesSlideover.tsx b/src/components/Facility/PatientNotesSlideover.tsx index 69f3a155a24..24fd315ce6e 100644 --- a/src/components/Facility/PatientNotesSlideover.tsx +++ b/src/components/Facility/PatientNotesSlideover.tsx @@ -7,7 +7,7 @@ import AuthorizedChild from "@/CAREUI/misc/AuthorizedChild"; import DiscussionNotesEditor from "@/components/Common/DiscussionNotesEditor"; import DoctorNoteReplyPreviewCard from "@/components/Facility/DoctorNoteReplyPreviewCard"; -import PatientConsultationNotesList from "@/components/Facility/PatientConsultationNotesList"; +import PatientNotesList from "@/components/Facility/PatientNotesList"; import { PatientNoteStateType, PatientNotesReplyModel, @@ -17,12 +17,16 @@ import useAuthUser from "@/hooks/useAuthUser"; import { useMessageListener } from "@/hooks/useMessageListener"; import useNotificationSubscriptionState from "@/hooks/useNotificationSubscriptionState"; -import { PATIENT_NOTES_THREADS } from "@/common/constants"; +import { + PATIENT_NOTES_THREADS, + RESULTS_PER_PAGE_LIMIT, +} from "@/common/constants"; import { NonReadOnlyUsers } from "@/Utils/AuthorizeFor"; import * as Notification from "@/Utils/Notifications"; import routes from "@/Utils/request/api"; import request from "@/Utils/request/request"; +import useQuery from "@/Utils/request/useQuery"; import { classNames, keysOf } from "@/Utils/utils"; interface PatientNotesProps { @@ -43,7 +47,6 @@ export default function PatientNotesSlideover(props: PatientNotesProps) { ); const [show, setShow] = useState(true); const [patientActive, setPatientActive] = useState(true); - const [reload, setReload] = useState(false); const [reply_to, setReplyTo] = useState( undefined, ); @@ -77,6 +80,26 @@ export default function PatientNotesSlideover(props: PatientNotesProps) { localStorage.getItem(localStorageKey) || "", ); + const { refetch, loading } = useQuery(routes.getPatientNotes, { + pathParams: { patientId }, + query: { + offset: (state.cPage - 1) * RESULTS_PER_PAGE_LIMIT, + thread, + }, + onResponse: ({ data }) => { + if (data) { + setState((prevState) => ({ + ...prevState, + notes: + state.cPage === 1 + ? data.results + : [...prevState.notes, ...data.results], + totalPages: Math.ceil(data.count / RESULTS_PER_PAGE_LIMIT), + })); + } + }, + }); + const onAddNote = async () => { if (!/\S+/.test(noteField)) { Notification.Error({ @@ -110,7 +133,7 @@ export default function PatientNotesSlideover(props: PatientNotesProps) { message?.facility_id == facilityId && message?.patient_id == patientId ) { - setReload(true); + refetch(); } }); @@ -228,14 +251,20 @@ export default function PatientNotesSlideover(props: PatientNotesProps) { ))}
- { + if (state.cPage < state.totalPages) { + setState((prevState) => ({ + ...prevState, + cPage: prevState.cPage + 1, + })); + } + }} + refetch={refetch} disableEdit={!patientActive} - thread={thread} setReplyTo={setReplyTo} + isLoading={loading} /> {patientActive && ( @@ -249,7 +278,7 @@ export default function PatientNotesSlideover(props: PatientNotesProps) { onChange={setNoteField} onAddNote={onAddNote} isAuthorized={isAuthorized} - onRefetch={() => setReload(true)} + onRefetch={refetch} maxRows={10} className="mt-2" /> diff --git a/src/components/Patient/PatientDetailsTab/Notes.tsx b/src/components/Patient/PatientDetailsTab/Notes.tsx index de35d6c43aa..3c8fb8852ba 100644 --- a/src/components/Patient/PatientDetailsTab/Notes.tsx +++ b/src/components/Patient/PatientDetailsTab/Notes.tsx @@ -1,27 +1,4 @@ -import { t } from "i18next"; -import { useEffect, useState } from "react"; - -import AuthorizedChild from "@/CAREUI/misc/AuthorizedChild"; - -import DiscussionNotesEditor from "@/components/Common/DiscussionNotesEditor"; -import DoctorNoteReplyPreviewCard from "@/components/Facility/DoctorNoteReplyPreviewCard"; -import PatientNotesList from "@/components/Facility/PatientNotesList"; -import { - PatientNoteStateType, - PatientNotesModel, -} from "@/components/Facility/models"; - -import useAuthUser from "@/hooks/useAuthUser"; -import { useMessageListener } from "@/hooks/useMessageListener"; - -import { PATIENT_NOTES_THREADS } from "@/common/constants"; - -import { NonReadOnlyUsers } from "@/Utils/AuthorizeFor"; -import routes from "@/Utils/request/api"; -import request from "@/Utils/request/request"; -import { classNames, keysOf } from "@/Utils/utils"; - -import * as Notification from "../../../Utils/Notifications"; +import PatientNotesListComponent from "@/components/Facility/PatientNotesListComponent"; interface PatientNotesProps { id: string; @@ -31,141 +8,13 @@ interface PatientNotesProps { const PatientNotes = (props: PatientNotesProps) => { const { id: patientId, facilityId } = props; - const authUser = useAuthUser(); - const [thread, setThread] = useState( - authUser.user_type === "Nurse" - ? PATIENT_NOTES_THREADS.Nurses - : PATIENT_NOTES_THREADS.Doctors, - ); - - const [patientActive, setPatientActive] = useState(true); - const [noteField, setNoteField] = useState(""); - const [reload, setReload] = useState(false); - const [reply_to, setReplyTo] = useState( - undefined, - ); - - const initialData: PatientNoteStateType = { - notes: [], - cPage: 1, - totalPages: 1, - }; - const [state, setState] = useState(initialData); - - const onAddNote = async () => { - if (!/\S+/.test(noteField)) { - Notification.Error({ - msg: "Note Should Contain At Least 1 Character", - }); - return; - } - - try { - const { res, data } = await request(routes.addPatientNote, { - pathParams: { patientId: patientId }, - body: { - note: noteField, - thread, - reply_to: reply_to?.id, - }, - }); - if (res?.status === 201) { - setNoteField(""); - setState({ ...state, cPage: 1 }); - setReplyTo(undefined); - Notification.Success({ msg: "Note added successfully" }); - } - - return data?.id; - } catch (error) { - Notification.Error({ - msg: "Failed to add note. Please try again.", - }); - } - }; - - useEffect(() => { - async function fetchPatientName() { - if (patientId) { - try { - const { data } = await request(routes.getPatient, { - pathParams: { id: patientId }, - }); - if (data) { - setPatientActive(data.is_active ?? true); - } - } catch (error) { - Notification.Error({ - msg: "Failed to fetch patient status", - }); - } - } - } - fetchPatientName(); - }, [patientId]); - - useMessageListener((data) => { - const message = data?.message; - if ( - (message?.from == "patient/doctor_notes/create" || - message?.from == "patient/doctor_notes/edit") && - message?.facility_id == facilityId && - message?.patient_id == patientId - ) { - setReload(true); - } - }); - return ( -
-
-
- {keysOf(PATIENT_NOTES_THREADS).map((current) => ( - - ))} -
- - - {({ isAuthorized }) => ( - setReplyTo(undefined)} - > - setReload(true)} - maxRows={10} - className="mt-2" - /> - - )} - -
-
+ ); }; diff --git a/src/components/Patient/PatientNotes.tsx b/src/components/Patient/PatientNotes.tsx index 144f4e7a66a..f747032e5e9 100644 --- a/src/components/Patient/PatientNotes.tsx +++ b/src/components/Patient/PatientNotes.tsx @@ -1,176 +1,49 @@ -import { useEffect, useState } from "react"; -import { useTranslation } from "react-i18next"; +import { useState } from "react"; -import AuthorizedChild from "@/CAREUI/misc/AuthorizedChild"; - -import DiscussionNotesEditor from "@/components/Common/DiscussionNotesEditor"; import Page from "@/components/Common/Page"; -import DoctorNoteReplyPreviewCard from "@/components/Facility/DoctorNoteReplyPreviewCard"; -import PatientNotesList from "@/components/Facility/PatientNotesList"; -import { - PatientNoteStateType, - PatientNotesModel, -} from "@/components/Facility/models"; - -import useAuthUser from "@/hooks/useAuthUser"; -import { useMessageListener } from "@/hooks/useMessageListener"; - -import { PATIENT_NOTES_THREADS } from "@/common/constants"; +import PatientNotesListComponent from "@/components/Facility/PatientNotesListComponent"; -import { NonReadOnlyUsers } from "@/Utils/AuthorizeFor"; -import * as Notification from "@/Utils/Notifications"; import routes from "@/Utils/request/api"; -import request from "@/Utils/request/request"; -import { classNames, keysOf } from "@/Utils/utils"; +import useQuery from "@/Utils/request/useQuery"; interface PatientNotesProps { patientId: string; facilityId: string; + consultationId?: string; } const PatientNotes = (props: PatientNotesProps) => { - const { patientId, facilityId } = props; - const { t } = useTranslation(); - const authUser = useAuthUser(); - const [thread, setThread] = useState( - authUser.user_type === "Nurse" - ? PATIENT_NOTES_THREADS.Nurses - : PATIENT_NOTES_THREADS.Doctors, - ); + const { patientId, facilityId, consultationId } = props; - const [patientActive, setPatientActive] = useState(true); - const [noteField, setNoteField] = useState(""); - const [reload, setReload] = useState(false); const [facilityName, setFacilityName] = useState(""); const [patientName, setPatientName] = useState(""); - const [reply_to, setReplyTo] = useState(); - - const initialData: PatientNoteStateType = { - notes: [], - cPage: 1, - totalPages: 1, - }; - const [state, setState] = useState(initialData); - const onAddNote = async () => { - if (!/\S+/.test(noteField)) { - Notification.Error({ - msg: "Note Should Contain At Least 1 Character", - }); - return; - } - - try { - const { res, data } = await request(routes.addPatientNote, { - pathParams: { patientId: patientId }, - body: { - note: noteField, - thread, - reply_to: reply_to?.id, - }, - }); - if (res?.status === 201) { - Notification.Success({ msg: "Note added successfully" }); - setNoteField(""); - setReload(!reload); - setState({ ...state, cPage: 1 }); - setReplyTo(undefined); - return data?.id; - } else { - throw new Error("Failed to add note"); - } - } catch (error) { - Notification.Error({ - msg: "Failed to add note. Please try again.", - }); - return undefined; - } - }; - - useEffect(() => { - async function fetchPatientName() { - if (patientId) { - const { data } = await request(routes.getPatient, { - pathParams: { id: patientId }, - }); - if (data) { - setPatientActive(data.is_active ?? true); - setPatientName(data.name ?? ""); - setFacilityName(data.facility_object?.name ?? ""); - } + useQuery(routes.getPatient, { + pathParams: { id: patientId }, + onResponse: ({ data }) => { + if (data) { + setPatientName(data.name ?? ""); + setFacilityName(data.facility_object?.name ?? ""); } - } - fetchPatientName(); - }, [patientId]); - - useMessageListener((data) => { - const message = data?.message; - if ( - (message?.from == "patient/doctor_notes/create" || - message?.from == "patient/doctor_notes/edit") && - message?.facility_id == facilityId && - message?.patient_id == patientId - ) { - setReload(true); - } + }, }); return ( -
-
- {keysOf(PATIENT_NOTES_THREADS).map((current) => ( - - ))} -
- + - - {({ isAuthorized }) => ( - setReplyTo(undefined)} - > - setReload(true)} - maxRows={10} - className="mt-2" - /> - - )} -
);