diff --git a/src/Components/Facility/ConsultationDetails/index.tsx b/src/Components/Facility/ConsultationDetails/index.tsx
index 54eee52878e..c1086a67221 100644
--- a/src/Components/Facility/ConsultationDetails/index.tsx
+++ b/src/Components/Facility/ConsultationDetails/index.tsx
@@ -475,6 +475,7 @@ export const ConsultationDetails = (props: any) => {
)}
diff --git a/src/Components/Facility/ConsultationDoctorNotes/index.tsx b/src/Components/Facility/ConsultationDoctorNotes/index.tsx
new file mode 100644
index 00000000000..dd96ef9af1e
--- /dev/null
+++ b/src/Components/Facility/ConsultationDoctorNotes/index.tsx
@@ -0,0 +1,135 @@
+import { useState } from "react";
+import * as Notification from "../../../Utils/Notifications.js";
+import Page from "../../Common/components/Page";
+import TextFormField from "../../Form/FormFields/TextFormField";
+import ButtonV2 from "../../Common/components/ButtonV2";
+import CareIcon from "../../../CAREUI/icons/CareIcon";
+import { NonReadOnlyUsers } from "../../../Utils/AuthorizeFor";
+import { useMessageListener } from "../../../Common/hooks/useMessageListener";
+import PatientConsultationNotesList from "../PatientConsultationNotesList.js";
+import { PatientNoteStateType } from "../models.js";
+import routes from "../../../Redux/api.js";
+import request from "../../../Utils/request/request.js";
+import useQuery from "../../../Utils/request/useQuery.js";
+
+interface ConsultationDoctorNotesProps {
+ patientId: string;
+ facilityId: string;
+ consultationId: string;
+}
+
+const ConsultationDoctorNotes = (props: ConsultationDoctorNotesProps) => {
+ 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 initialData: PatientNoteStateType = {
+ notes: [],
+ cPage: 1,
+ totalPages: 1,
+ };
+ const [state, setState] = useState(initialData);
+
+ const onAddNote = async () => {
+ const payload = {
+ note: noteField,
+ consultation: consultationId,
+ };
+ if (!/\S+/.test(noteField)) {
+ Notification.Error({
+ msg: "Note Should Contain At Least 1 Character",
+ });
+ return;
+ }
+
+ const { res } = await request(routes.addPatientNote, {
+ pathParams: {
+ patientId: patientId,
+ },
+ body: payload,
+ });
+
+ if (res?.status === 201) {
+ Notification.Success({ msg: "Note added successfully" });
+ setState({ ...state, cPage: 1 });
+ setNoteField("");
+ setReload(true);
+ }
+ };
+
+ useQuery(routes.getPatient, {
+ pathParams: { id: patientId },
+ onResponse: ({ data }) => {
+ if (data) {
+ setPatientActive(data.is_active ?? true);
+ setPatientName(data.name ?? "");
+ setFacilityName(data.facility_object?.name ?? "");
+ }
+ },
+ });
+
+ 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 (
+
+
+
+
+
+ setNoteField(e.value)}
+ className="grow"
+ type="text"
+ errorClassName="hidden"
+ placeholder="Type your Note"
+ disabled={!patientActive}
+ />
+
+
+
+
+
+
+ );
+};
+
+export default ConsultationDoctorNotes;
diff --git a/src/Components/Facility/DoctorNote.tsx b/src/Components/Facility/DoctorNote.tsx
new file mode 100644
index 00000000000..85703a1e3d8
--- /dev/null
+++ b/src/Components/Facility/DoctorNote.tsx
@@ -0,0 +1,45 @@
+import InfiniteScroll from "react-infinite-scroll-component";
+import CircularProgress from "../Common/components/CircularProgress";
+import PatientNoteCard from "./PatientNoteCard";
+import { PatientNoteStateType } from "./models";
+
+interface DoctorNoteProps {
+ state: PatientNoteStateType;
+ handleNext: () => void;
+}
+
+const DoctorNote = (props: DoctorNoteProps) => {
+ const { state, handleNext } = props;
+ return (
+
+ {state.notes.length ? (
+
+
+
+ }
+ className="flex h-full flex-col-reverse p-2"
+ inverse={true}
+ dataLength={state.notes.length}
+ scrollableTarget="patient-notes-list"
+ >
+ {state.notes.map((note: any) => (
+
+ ))}
+
+ ) : (
+
+ No Notes Found
+
+ )}
+
+ );
+};
+
+export default DoctorNote;
diff --git a/src/Components/Facility/PatientConsultationNotesList.tsx b/src/Components/Facility/PatientConsultationNotesList.tsx
new file mode 100644
index 00000000000..f38de51110b
--- /dev/null
+++ b/src/Components/Facility/PatientConsultationNotesList.tsx
@@ -0,0 +1,87 @@
+import { useEffect, useState } from "react";
+import { RESULTS_PER_PAGE_LIMIT } from "../../Common/constants";
+import CircularProgress from "../Common/components/CircularProgress";
+import routes from "../../Redux/api";
+import { PatientNoteStateType } from "./models";
+import useSlug from "../../Common/hooks/useSlug";
+import DoctorNote from "./DoctorNote";
+import request from "../../Utils/request/request";
+
+interface PatientNotesProps {
+ state: PatientNoteStateType;
+ setState: any;
+ patientId: string;
+ facilityId: string;
+ reload?: boolean;
+ setReload?: any;
+}
+
+const pageSize = RESULTS_PER_PAGE_LIMIT;
+
+const PatientConsultationNotesList = (props: PatientNotesProps) => {
+ const { state, setState, reload, setReload } = props;
+ const consultationId = useSlug("consultation") ?? "";
+
+ const [isLoading, setIsLoading] = useState(true);
+
+ const fetchNotes = async () => {
+ setIsLoading(true);
+ const { data }: any = await request(routes.getPatientNotes, {
+ pathParams: {
+ patientId: props.patientId,
+ },
+ query: {
+ consultation: consultationId,
+ offset: (state.cPage - 1) * RESULTS_PER_PAGE_LIMIT,
+ },
+ });
+
+ if (state.cPage === 1) {
+ setState((prevState: any) => ({
+ ...prevState,
+ notes: data.results,
+ totalPages: Math.ceil(data.count / pageSize),
+ }));
+ } else {
+ setState((prevState: any) => ({
+ ...prevState,
+ notes: [...prevState.notes, ...data.results],
+ totalPages: Math.ceil(data.count / pageSize),
+ }));
+ }
+ setIsLoading(false);
+ setReload(false);
+ };
+
+ useEffect(() => {
+ if (reload) {
+ fetchNotes();
+ }
+ }, [reload]);
+
+ useEffect(() => {
+ setReload(true);
+ }, []);
+
+ const handleNext = () => {
+ if (state.cPage < state.totalPages) {
+ setState((prevState: any) => ({
+ ...prevState,
+ cPage: prevState.cPage + 1,
+ }));
+ setReload(true);
+ }
+ };
+
+ if (isLoading && !state.notes.length) {
+ return (
+
+
+
+ );
+ }
+
+ return ;
+};
+
+export default PatientConsultationNotesList;
diff --git a/src/Components/Facility/PatientNotesList.tsx b/src/Components/Facility/PatientNotesList.tsx
index 330bca4b06d..96f9dcad871 100644
--- a/src/Components/Facility/PatientNotesList.tsx
+++ b/src/Components/Facility/PatientNotesList.tsx
@@ -1,86 +1,68 @@
-import { useCallback, useState, useEffect } from "react";
-import { useDispatch } from "react-redux";
-import { statusType, useAbortableEffect } from "../../Common/utils";
-import { getPatientNotes } from "../../Redux/actions";
+import { useState, useEffect } from "react";
import { RESULTS_PER_PAGE_LIMIT } from "../../Common/constants";
import CircularProgress from "../Common/components/CircularProgress";
-import PatientNoteCard from "./PatientNoteCard";
-import InfiniteScroll from "react-infinite-scroll-component";
-import { NoteType } from "./PatientNoteCard";
+import DoctorNote from "./DoctorNote";
+import { PatientNoteStateType } from "./models";
+import routes from "../../Redux/api";
+import request from "../../Utils/request/request";
interface PatientNotesProps {
- patientId: any;
- facilityId: any;
+ state: PatientNoteStateType;
+ setState: any;
+ patientId: string;
+ facilityId: string;
reload?: boolean;
setReload?: any;
}
-interface StateType {
- notes: NoteType[];
- cPage: number;
- totalPages: number;
-}
-
const pageSize = RESULTS_PER_PAGE_LIMIT;
const PatientNotesList = (props: PatientNotesProps) => {
- const { reload, setReload } = props;
+ const { state, setState, reload, setReload } = props;
- const dispatch: any = useDispatch();
- const initialData: StateType = { notes: [], cPage: 1, totalPages: 1 };
- const [state, setState] = useState(initialData);
const [isLoading, setIsLoading] = useState(true);
- const fetchData = useCallback(
- async (page = 1, status: statusType = { aborted: false }) => {
- setIsLoading(true);
- const res = await dispatch(
- getPatientNotes(props.patientId, pageSize, (page - 1) * pageSize)
- );
- if (!status.aborted) {
- if (res && res.data) {
- if (page === 1) {
- setState({
- notes: res.data?.results,
- cPage: page,
- totalPages: Math.ceil(res.data.count / pageSize),
- });
- } else {
- setState((prevState: any) => ({
- ...prevState,
- notes: [...prevState.notes, ...res.data.results],
- cPage: page,
- totalPages: Math.ceil(res.data.count / pageSize),
- }));
- }
- }
- setIsLoading(false);
- }
- },
- [props.patientId, dispatch]
- );
+ const fetchNotes = async () => {
+ setIsLoading(true);
+ const { data }: any = await request(routes.getPatientNotes, {
+ pathParams: { patientId: props.patientId },
+ query: { offset: (state.cPage - 1) * RESULTS_PER_PAGE_LIMIT },
+ });
+
+ if (state.cPage === 1) {
+ setState((prevState: any) => ({
+ ...prevState,
+ notes: data.results,
+ totalPages: Math.ceil(data.count / pageSize),
+ }));
+ } else {
+ setState((prevState: any) => ({
+ ...prevState,
+ notes: [...prevState.notes, ...data.results],
+ totalPages: Math.ceil(data.count / pageSize),
+ }));
+ }
+ setIsLoading(false);
+ setReload(false);
+ };
useEffect(() => {
if (reload) {
- fetchData(1);
- setReload(false);
+ fetchNotes();
}
}, [reload]);
- useAbortableEffect(
- (status: statusType) => {
- fetchData(1, status);
- },
- [fetchData]
- );
+ useEffect(() => {
+ setReload(true);
+ }, []);
const handleNext = () => {
if (state.cPage < state.totalPages) {
- fetchData(state.cPage + 1);
setState((prevState: any) => ({
...prevState,
cPage: prevState.cPage + 1,
}));
+ setReload(true);
}
};
@@ -92,36 +74,7 @@ const PatientNotesList = (props: PatientNotesProps) => {
);
}
- return (
-
- {state.notes.length ? (
-
-
-
- }
- className="flex h-full flex-col-reverse p-2"
- inverse={true}
- dataLength={state.notes.length}
- scrollableTarget="patient-notes-list"
- >
- {state.notes.map((note: any) => (
-
- ))}
-
- ) : (
-
- No Notes Found
-
- )}
-
- );
+ return ;
};
export default PatientNotesList;
diff --git a/src/Components/Facility/PatientNotesSlideover.tsx b/src/Components/Facility/PatientNotesSlideover.tsx
index b268500f6cf..8b08d9767db 100644
--- a/src/Components/Facility/PatientNotesSlideover.tsx
+++ b/src/Components/Facility/PatientNotesSlideover.tsx
@@ -1,8 +1,5 @@
import { useState, useEffect, Dispatch, SetStateAction } from "react";
-import { getPatient, addPatientNote } from "../../Redux/actions";
import * as Notification from "../../Utils/Notifications.js";
-import { useDispatch } from "react-redux";
-import PatientNotesList from "./PatientNotesList";
import { NonReadOnlyUsers } from "../../Utils/AuthorizeFor";
import CareIcon from "../../CAREUI/icons/CareIcon";
import { classNames } from "../../Utils/utils";
@@ -10,10 +7,15 @@ import TextFormField from "../Form/FormFields/TextFormField";
import ButtonV2 from "../Common/components/ButtonV2";
import { make as Link } from "../Common/components/Link.bs";
import { useMessageListener } from "../../Common/hooks/useMessageListener";
+import PatientConsultationNotesList from "./PatientConsultationNotesList";
+import request from "../../Utils/request/request";
+import routes from "../../Redux/api";
+import { PatientNoteStateType } from "./models";
interface PatientNotesProps {
patientId: string;
facilityId: string;
+ consultationId: string;
setShowPatientNotesPopup: Dispatch>;
}
@@ -23,13 +25,20 @@ export default function PatientNotesSlideover(props: PatientNotesProps) {
const [noteField, setNoteField] = useState("");
const [reload, setReload] = useState(false);
- const dispatch = useDispatch();
+ const initialData: PatientNoteStateType = {
+ notes: [],
+ cPage: 1,
+ totalPages: 1,
+ };
+ const [state, setState] = useState(initialData);
- const { facilityId, patientId, setShowPatientNotesPopup } = props;
+ const { facilityId, patientId, consultationId, setShowPatientNotesPopup } =
+ props;
- const onAddNote = () => {
+ const onAddNote = async () => {
const payload = {
note: noteField,
+ consultation: consultationId,
};
if (!/\S+/.test(noteField)) {
Notification.Error({
@@ -37,11 +46,16 @@ export default function PatientNotesSlideover(props: PatientNotesProps) {
});
return;
}
- dispatch(addPatientNote(patientId, payload)).then(() => {
+ const { res } = await request(routes.addPatientNote, {
+ pathParams: { patientId: patientId },
+ body: payload,
+ });
+ if (res?.status === 201) {
Notification.Success({ msg: "Note added successfully" });
setNoteField("");
- setReload(!reload);
- });
+ setState({ ...state, cPage: 1 });
+ setReload(true);
+ }
};
useMessageListener((data) => {
@@ -59,21 +73,23 @@ export default function PatientNotesSlideover(props: PatientNotesProps) {
useEffect(() => {
async function fetchPatientName() {
if (patientId) {
- const res = await dispatch(getPatient({ id: patientId }));
- if (res.data) {
- setPatientActive(res.data.is_active);
+ const { data } = await request(routes.getPatient, {
+ pathParams: { id: patientId },
+ });
+ if (data) {
+ setPatientActive(data.is_active ?? true);
}
}
}
fetchPatientName();
- }, [dispatch, patientId]);
+ }, [patientId]);
const notesActionIcons = (
{show && (
@@ -122,7 +138,9 @@ export default function PatientNotesSlideover(props: PatientNotesProps) {
{notesActionIcons}
{/* Doctor Notes Body */}
- {
const [facilityName, setFacilityName] = useState("");
const [patientName, setPatientName] = useState("");
- const dispatch = useDispatch();
+ const initialData: PatientNoteStateType = {
+ notes: [],
+ cPage: 1,
+ totalPages: 1,
+ };
+ const [state, setState] = useState(initialData);
- const onAddNote = () => {
+ const onAddNote = async () => {
const payload = {
note: noteField,
};
@@ -36,26 +42,34 @@ const PatientNotes = (props: PatientNotesProps) => {
});
return;
}
- dispatch(addPatientNote(patientId, payload)).then(() => {
+
+ const { res } = await request(routes.addPatientNote, {
+ pathParams: { patientId: patientId },
+ body: payload,
+ });
+ if (res?.status === 201) {
Notification.Success({ msg: "Note added successfully" });
setNoteField("");
setReload(!reload);
- });
+ setState({ ...state, cPage: 1 });
+ }
};
useEffect(() => {
async function fetchPatientName() {
if (patientId) {
- const res = await dispatch(getPatient({ id: patientId }));
- if (res.data) {
- setPatientActive(res.data.is_active);
- setPatientName(res.data.name);
- setFacilityName(res.data.facility_object.name);
+ const { data } = await request(routes.getPatient, {
+ pathParams: { id: patientId },
+ });
+ if (data) {
+ setPatientActive(data.is_active ?? true);
+ setPatientName(data.name ?? "");
+ setFacilityName(data.facility_object?.name ?? "");
}
}
}
fetchPatientName();
- }, [dispatch, patientId]);
+ }, [patientId]);
useMessageListener((data) => {
const message = data?.message;
@@ -81,6 +95,8 @@ const PatientNotes = (props: PatientNotesProps) => {
>
(),
TRes: Type(),
},
updatePatient: {
@@ -614,10 +616,13 @@ const routes = {
getPatientNotes: {
path: "/api/v1/patient/{patientId}/notes/",
method: "GET",
+ TBody: Type(),
+ TRes: Type>(),
},
addPatientNote: {
path: "/api/v1/patient/{patientId}/notes/",
method: "POST",
+ TRes: Type(),
},
sampleTestList: {
path: "/api/v1/patient/{patientId}/test_sample/",
diff --git a/src/Routers/routes/ConsultationRoutes.tsx b/src/Routers/routes/ConsultationRoutes.tsx
index 4f1d6e7d75d..401358717eb 100644
--- a/src/Routers/routes/ConsultationRoutes.tsx
+++ b/src/Routers/routes/ConsultationRoutes.tsx
@@ -8,6 +8,7 @@ import { FileUpload } from "../../Components/Patient/FileUpload";
import { make as CriticalCareRecording } from "../../Components/CriticalCareRecording/CriticalCareRecording.bs";
import { ConsultationDetails } from "../../Components/Facility/ConsultationDetails";
import TreatmentSummary from "../../Components/Facility/TreatmentSummary";
+import ConsultationDoctorNotes from "../../Components/Facility/ConsultationDoctorNotes";
export default {
"/facility/:facilityId/patient/:patientId/consultation": ({
@@ -129,6 +130,14 @@ export default {
dailyRoundsListData={[]}
/>
),
+ "/facility/:facilityId/patient/:patientId/consultation/:consultationId/notes":
+ ({ facilityId, patientId, consultationId }: any) => (
+
+ ),
"/facility/:facilityId/patient/:patientId/consultation/:consultationId/:tab":
({ facilityId, patientId, consultationId, tab }: any) => (