diff --git a/src/Utils/request/api.tsx b/src/Utils/request/api.tsx index e9bb04cbbbe..b6cedd3d599 100644 --- a/src/Utils/request/api.tsx +++ b/src/Utils/request/api.tsx @@ -44,6 +44,7 @@ import { MinimumQuantityItemResponse, PatientNotesEditModel, PatientNotesModel, + PatientNotesRequest, PatientTransferResponse, ResourceModel, ShiftingModel, @@ -658,12 +659,7 @@ const routes = { path: "/api/v1/patient/{patientId}/notes/", method: "POST", TRes: Type(), - TBody: Type< - Pick & { - consultation?: string; - reply_to?: string; - } - >(), + TBody: Type(), }, updatePatientNote: { path: "/api/v1/patient/{patientId}/notes/{noteId}/", diff --git a/src/components/Facility/PatientNotesDetailedView.tsx b/src/components/Facility/PatientNotesDetailedView.tsx index 47e27e183a8..f8e883c6f30 100644 --- a/src/components/Facility/PatientNotesDetailedView.tsx +++ b/src/components/Facility/PatientNotesDetailedView.tsx @@ -1,4 +1,4 @@ -import { useQuery } from "@tanstack/react-query"; +import { useMutation, useQuery } from "@tanstack/react-query"; import { t } from "i18next"; import { useEffect, useRef, useState } from "react"; @@ -13,6 +13,7 @@ import PatientNoteCard from "@/components/Facility/PatientNoteCard"; import { PatientNotesModel, PatientNotesReplyModel, + PatientNotesRequest, } from "@/components/Facility/models"; import * as Notification from "@/Utils/Notifications"; @@ -60,6 +61,7 @@ const PatientNotesDetailedView = (props: Props) => { thread, }, }), + enabled: !!noteId && !!patientId, }); const scrollToBottom = () => { @@ -74,6 +76,24 @@ const PatientNotesDetailedView = (props: Props) => { } }, [state]); + const addNoteMutation = useMutation({ + mutationFn: (noteData: PatientNotesRequest) => + request(routes.addPatientNote, { + pathParams: { patientId }, + body: noteData, + }), + onSuccess: () => { + Notification.Success({ msg: "Note added successfully" }); + setNoteField(""); + setReplyTo(undefined); + setTimeout(scrollToBottom, 100); + refetch(); + }, + onError: () => { + Notification.Error({ msg: "An error occurred while adding the note." }); + }, + }); + const onAddNote = async () => { if (!/\S+/.test(noteField)) { Notification.Error({ @@ -82,34 +102,14 @@ const PatientNotesDetailedView = (props: Props) => { return; } - try { - const { res, data } = await request(routes.addPatientNote, { - pathParams: { - patientId: patientId, - }, - body: { - note: noteField, - thread, - consultation: consultationId, - reply_to: reply_to?.id || noteId, - }, - }); + const result = await addNoteMutation.mutateAsync({ + note: noteField, + thread: thread, + consultation: consultationId, + reply_to: reply_to?.id ?? noteId, + }); - setReplyTo(undefined); - - if (res?.status === 201) { - Notification.Success({ msg: "Note added successfully" }); - setNoteField(""); - setTimeout(scrollToBottom, 100); - } else { - Notification.Error({ msg: "Failed to add note. Please try again." }); - } - - return data?.id; - } catch (error) { - Notification.Error({ msg: "An error occurred while adding the note." }); - return undefined; - } + return result.data?.id; }; if (isLoading || isRefetching) { diff --git a/src/components/Facility/PatientNotesListComponent.tsx b/src/components/Facility/PatientNotesListComponent.tsx index 3b546cccddd..9e28b07696d 100644 --- a/src/components/Facility/PatientNotesListComponent.tsx +++ b/src/components/Facility/PatientNotesListComponent.tsx @@ -1,4 +1,4 @@ -import { useQuery } from "@tanstack/react-query"; +import { useMutation, useQuery } from "@tanstack/react-query"; import { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; @@ -12,6 +12,7 @@ import PatientNotesList from "@/components/Facility/PatientNotesList"; import { PatientNoteStateType, PatientNotesModel, + PatientNotesRequest, } from "@/components/Facility/models"; import useAuthUser from "@/hooks/useAuthUser"; @@ -92,6 +93,7 @@ const PatientNotesListComponent = (props: PatientNotesProps) => { thread, }, }), + enabled: !!patientId, }); useEffect(() => { @@ -105,11 +107,12 @@ const PatientNotesListComponent = (props: PatientNotesProps) => { totalPages: Math.ceil(notesData.count / RESULTS_PER_PAGE_LIMIT), })); } - }, [notesData]); + }, [notesData, isRefetching]); useEffect(() => { setThreadViewNote(""); - setState((prev) => ({ ...prev, notes: [], cPage: 1 })); + setState(initialData); + refetchNotes(); }, [thread]); const { data: patientData } = useQuery({ @@ -125,6 +128,24 @@ const PatientNotesListComponent = (props: PatientNotesProps) => { } }, [patientData]); + const addNoteMutation = useMutation({ + mutationFn: (noteData: PatientNotesRequest) => + request(routes.addPatientNote, { + pathParams: { patientId }, + body: noteData, + }), + onSuccess: () => { + Notification.Success({ msg: "Note added successfully" }); + setState((prev) => ({ ...prev, cPage: 1 })); + setNoteField(""); + setReplyTo(undefined); + refetchNotes(); + }, + onError: () => { + Notification.Error({ msg: "An error occurred while adding the note." }); + }, + }); + const onAddNote = async () => { if (!/\S+/.test(noteField)) { Notification.Error({ @@ -133,33 +154,14 @@ const PatientNotesListComponent = (props: PatientNotesProps) => { return; } - try { - const { res, data } = await request(routes.addPatientNote, { - pathParams: { - patientId: patientId, - }, - body: { - note: noteField, - thread, - consultation: consultationId, - reply_to: reply_to?.id, - }, - }); - - if (res?.status === 201) { - Notification.Success({ msg: "Note added successfully" }); - setState({ ...state, cPage: 1 }); - setNoteField(""); - setReplyTo(undefined); - } else { - Notification.Error({ msg: "Failed to add note. Please try again." }); - } + const result = await addNoteMutation.mutateAsync({ + note: noteField, + thread: thread, + consultation: consultationId, + reply_to: reply_to?.id, + }); - return data?.id; - } catch (error) { - Notification.Error({ msg: "An error occurred while adding the note." }); - return undefined; - } + return result.data?.id; }; useMessageListener((data) => { diff --git a/src/components/Facility/PatientNotesSlideover.tsx b/src/components/Facility/PatientNotesSlideover.tsx index d591156e52e..61c14b36dbf 100644 --- a/src/components/Facility/PatientNotesSlideover.tsx +++ b/src/components/Facility/PatientNotesSlideover.tsx @@ -1,4 +1,4 @@ -import { useQuery } from "@tanstack/react-query"; +import { useMutation, useQuery } from "@tanstack/react-query"; import { Link } from "raviger"; import { Dispatch, SetStateAction, useEffect, useRef, useState } from "react"; import { useTranslation } from "react-i18next"; @@ -12,6 +12,7 @@ import PatientNotesList from "@/components/Facility/PatientNotesList"; import { PatientNoteStateType, PatientNotesReplyModel, + PatientNotesRequest, } from "@/components/Facility/models"; import useAuthUser from "@/hooks/useAuthUser"; @@ -98,7 +99,7 @@ export default function PatientNotesSlideover(props: PatientNotesProps) { totalPages: Math.ceil(notesData.count / RESULTS_PER_PAGE_LIMIT), })); } - }, [notesData, state.cPage]); + }, [notesData, isRefetching]); const { data: patientData } = useQuery({ queryKey: [routes.getPatient.path, patientId], @@ -126,6 +127,24 @@ export default function PatientNotesSlideover(props: PatientNotesProps) { } }, [notificationSubscriptionState]); + const addNoteMutation = useMutation({ + mutationFn: (noteData: PatientNotesRequest) => + request(routes.addPatientNote, { + pathParams: { patientId }, + body: noteData, + }), + onSuccess: () => { + Notification.Success({ msg: "Note added successfully" }); + setNoteField(""); + setState((prev) => ({ ...prev, cPage: 1 })); + setReplyTo(undefined); + refetchNotes(); + }, + onError: () => { + Notification.Error({ msg: "An error occurred while adding the note." }); + }, + }); + const onAddNote = async () => { if (!/\S+/.test(noteField)) { Notification.Error({ @@ -134,30 +153,14 @@ export default function PatientNotesSlideover(props: PatientNotesProps) { return; } - try { - const { res, data } = await request(routes.addPatientNote, { - pathParams: { patientId: patientId }, - body: { - note: noteField, - consultation: consultationId, - thread, - reply_to: reply_to?.id, - }, - }); + const result = await addNoteMutation.mutateAsync({ + note: noteField, + thread: thread, + consultation: consultationId, + reply_to: reply_to?.id, + }); - if (res?.status === 201) { - Notification.Success({ msg: "Note added successfully" }); - setNoteField(""); - setState({ ...state, cPage: 1 }); - setReplyTo(undefined); - } else { - Notification.Error({ msg: "Failed to add note. Please try again." }); - } - return data?.id; - } catch (error) { - Notification.Error({ msg: "An error occurred while adding the note." }); - return undefined; - } + return result.data?.id; }; useMessageListener((data) => { @@ -176,6 +179,11 @@ export default function PatientNotesSlideover(props: PatientNotesProps) { localStorage.setItem(localStorageKey, noteField); }, [noteField, localStorageKey]); + useEffect(() => { + setState(initialData); + refetchNotes(); + }, [thread]); + const notesActionIcons = (
{show && ( diff --git a/src/components/Facility/models.tsx b/src/components/Facility/models.tsx index 4261dfe0f6f..bfaac620163 100644 --- a/src/components/Facility/models.tsx +++ b/src/components/Facility/models.tsx @@ -561,13 +561,16 @@ export interface PatientNotesReplyModel { reply_to?: string; } +export type ThreadCategory = + (typeof PATIENT_NOTES_THREADS)[keyof typeof PATIENT_NOTES_THREADS]; + export interface PatientNotesModel { id: string; note: string; facility: BaseFacilityModel; created_by_object: BaseUserModel; user_type?: UserRole | "RemoteSpecialist"; - thread: (typeof PATIENT_NOTES_THREADS)[keyof typeof PATIENT_NOTES_THREADS]; + thread: ThreadCategory; created_date: string; last_edited_by?: BaseUserModel; last_edited_date?: string; @@ -579,6 +582,13 @@ export interface PatientNotesModel { mentioned_users: UserBareMinimum[]; } +export interface PatientNotesRequest { + note: string; + thread: ThreadCategory; + consultation?: string; + reply_to?: string; +} + export interface PatientNoteStateType { notes: PatientNotesModel[]; patientId?: string;