Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make Doctor notes Realtime #6149

Closed
wants to merge 36 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
5356861
feat: add patient notes pop-up on consultation page
Bhavik-ag Jul 7, 2023
a7155e4
Migrate form elements to CAREUI
Bhavik-ag Jul 7, 2023
10a7761
made patient notes popup responsive
Bhavik-ag Jul 8, 2023
77e28e0
Merge branch 'coronasafe:develop' into doctor-notes-redesign
Bhavik-ag Jul 8, 2023
e3c3966
feat: updated ui of patient notes dedicated page
Bhavik-ag Jul 12, 2023
16bc28b
resolved merge conflicts
Bhavik-ag Jul 19, 2023
d59542a
Merge branch 'develop' into doctor-notes-redesign
Bhavik-ag Jul 19, 2023
6eeca25
fix merge develop
Bhavik-ag Jul 19, 2023
9156115
added doctor location
Bhavik-ag Jul 21, 2023
165f5b1
Merge branch 'develop' into doctor-notes-redesign
Bhavik-ag Jul 21, 2023
746f19e
used Page component in PatientNotes page
Bhavik-ag Jul 21, 2023
4cf45f6
Apply suggestions from code review
rithviknishad Jul 21, 2023
b22c31c
Merge branch 'develop' into doctor-notes-redesign
Bhavik-ag Jul 25, 2023
a4de10b
Merge branch 'develop' into doctor-notes-redesign
Bhavik-ag Jul 25, 2023
16861ae
Merge branch 'develop' into doctor-notes-redesign
Bhavik-ag Jul 26, 2023
5afb43f
added close button
Bhavik-ag Jul 26, 2023
5ee889d
Apply suggestions from code review
rithviknishad Jul 27, 2023
542c348
Merge branch 'develop' into doctor-notes-redesign
rithviknishad Jul 27, 2023
f41f7f6
enchance doctor notes ux
Bhavik-ag Jul 27, 2023
145b70b
merge develop branch
Bhavik-ag Aug 7, 2023
f63731d
Merge branch 'develop' into doctor-notes-redesign
Bhavik-ag Aug 7, 2023
6de71e0
Merge branch 'develop' into doctor-notes-redesign
Bhavik-ag Aug 9, 2023
73df9f4
replace usages of moment with dayjs
Bhavik-ag Aug 9, 2023
29bac82
Merge branch 'develop' into doctor-notes-redesign
Bhavik-ag Aug 9, 2023
0565695
Merge branch 'develop' into doctor-notes-redesign
Bhavik-ag Aug 11, 2023
888365d
Merge branch 'develop' into doctor-notes-redesign
Bhavik-ag Aug 15, 2023
5c68e1e
Merge branch 'develop' into doctor-notes-redesign
Bhavik-ag Aug 22, 2023
3bea8c1
Added user role in brackets
Bhavik-ag Aug 22, 2023
5ce435a
added message listener for patient notes
Bhavik-ag Aug 24, 2023
6c1c074
Merge branch 'develop' into doctor-notes-realtime
Bhavik-ag Aug 24, 2023
892640b
Merge branch 'develop' into doctor-notes-realtime
Bhavik-ag Aug 25, 2023
5f90cde
Merge branch 'develop' into doctor-notes-realtime
Bhavik-ag Aug 28, 2023
580a577
added notification on patient note creation
Bhavik-ag Aug 28, 2023
323294a
Merge branch 'develop' into doctor-notes-realtime
Bhavik-ag Aug 30, 2023
6bab528
Merge branch 'develop' into doctor-notes-realtime
Bhavik-ag Sep 1, 2023
f56edc1
Merge branch 'develop' into doctor-notes-realtime
Bhavik-ag Sep 5, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
"react-dom": "18.2.0",
"react-google-recaptcha": "^3.1.0",
"react-i18next": "^13.0.1",
"react-infinite-scroll-component": "^6.1.0",
"react-markdown": "^8.0.7",
"react-player": "^2.12.0",
"react-qr-reader": "^2.2.1",
Expand Down
12 changes: 3 additions & 9 deletions src/CAREUI/icons/UniconPaths.json
Original file line number Diff line number Diff line change
Expand Up @@ -3107,10 +3107,7 @@
24,
"M19,2H5A3,3,0,0,0,2,5V19a3,3,0,0,0,3,3H19a3,3,0,0,0,3-3V5A3,3,0,0,0,19,2Zm1,17a1,1,0,0,1-1,1H5a1,1,0,0,1-1-1V5A1,1,0,0,1,5,4H19a1,1,0,0,1,1,1Zm-4-8H8a1,1,0,0,0,0,2h8a1,1,0,0,0,0-2Z"
],
"l-minus": [
24,
"M19,11H5a1,1,0,0,0,0,2H19a1,1,0,0,0,0-2Z"
],
"l-minus": [24, "M19,11H5a1,1,0,0,0,0,2H19a1,1,0,0,0,0-2Z"],
"l-missed-call": [
24,
"M6,7.49a1,1,0,0,0,1-1V5.9L9.88,8.78a3,3,0,0,0,4.24,0l4.59-4.59a1,1,0,0,0,0-1.41,1,1,0,0,0-1.42,0L12.71,7.36a1,1,0,0,1-1.42,0L8.41,4.49H9a1,1,0,0,0,0-2H6a1,1,0,0,0-.92.61A1.09,1.09,0,0,0,5,3.49v3A1,1,0,0,0,6,7.49Zm15.94,7.36a16.27,16.27,0,0,0-19.88,0,2.69,2.69,0,0,0-1,2,2.66,2.66,0,0,0,.78,2.07L3.6,20.72A2.68,2.68,0,0,0,7.06,21l.47-.32a8.13,8.13,0,0,1,1-.55,1.85,1.85,0,0,0,1-2.3l-.09-.24a10.49,10.49,0,0,1,5.22,0l-.09.24a1.85,1.85,0,0,0,1,2.3,8.13,8.13,0,0,1,1,.55l.47.32a2.58,2.58,0,0,0,1.54.5,2.72,2.72,0,0,0,1.92-.79l1.81-1.82A2.66,2.66,0,0,0,23,16.83,2.69,2.69,0,0,0,21.94,14.85ZM20.8,17.49,19,19.3a.68.68,0,0,1-.86.1c-.19-.14-.38-.27-.59-.4a11.65,11.65,0,0,0-1.09-.61l.4-1.09a1,1,0,0,0-.6-1.28,12.42,12.42,0,0,0-8.5,0,1,1,0,0,0-.6,1.28l.4,1.1a9.8,9.8,0,0,0-1.1.6l-.58.4A.66.66,0,0,1,5,19.3L3.2,17.49A.67.67,0,0,1,3,17a.76.76,0,0,1,.28-.53,14.29,14.29,0,0,1,17.44,0A.76.76,0,0,1,21,17,.67.67,0,0,1,20.8,17.49Z"
Expand Down Expand Up @@ -4295,10 +4292,7 @@
24,
"M15,13H9a1,1,0,0,0,0,2h2v2a1,1,0,0,0,2,0V15h2a1,1,0,0,0,0-2Zm2-7H7A1,1,0,0,0,7,8h4v2a1,1,0,0,0,2,0V8h4a1,1,0,0,0,0-2Z"
],
"l-text": [
24,
"M17,6H7A1,1,0,0,0,7,8h4v9a1,1,0,0,0,2,0V8h4a1,1,0,0,0,0-2Z"
],
"l-text": [24, "M17,6H7A1,1,0,0,0,7,8h4v9a1,1,0,0,0,2,0V8h4a1,1,0,0,0,0-2Z"],
"l-th-large": [
24,
"M20,3H4A1,1,0,0,0,3,4V20a1,1,0,0,0,1,1H20a1,1,0,0,0,1-1V4A1,1,0,0,0,20,3ZM11,19H5V13h6Zm0-8H5V5h6Zm8,8H13V13h6Zm0-8H13V5h6Z"
Expand Down Expand Up @@ -4841,4 +4835,4 @@
256,
"M204.73 51.85A108.07 108.07 0 0 0 20 128v56a28 28 0 0 0 28 28h16a28 28 0 0 0 28-28v-40a28 28 0 0 0-28-28H44.84A84.05 84.05 0 0 1 128 44h.64a83.7 83.7 0 0 1 82.52 72H192a28 28 0 0 0-28 28v40a28 28 0 0 0 28 28h19.6a20 20 0 0 1-19.6 16h-56a12 12 0 0 0 0 24h56a44.05 44.05 0 0 0 44-44v-80a107.34 107.34 0 0 0-31.27-76.15ZM64 140a4 4 0 0 1 4 4v40a4 4 0 0 1-4 4H48a4 4 0 0 1-4-4v-44Zm124 44v-40a4 4 0 0 1 4-4h20v48h-20a4 4 0 0 1-4-4Z"
]
}
}
5 changes: 5 additions & 0 deletions src/Common/constants.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,11 @@ export const NOTIFICATION_EVENTS = [
text: "Shifting Updated",
icon: "fa-solid fa-truck-medical",
},
{
id: "PATIENT_NOTE_ADDED",
text: "Patient Note Added",
icon: "fa-solid fa-message",
},
];

export const BREATHLESSNESS_LEVEL = [
Expand Down
16 changes: 13 additions & 3 deletions src/Components/Facility/ConsultationDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import { useQueryParams } from "raviger";
import { useTranslation } from "react-i18next";
import { triggerGoal } from "../Common/Plausible";
import useVitalsAspectRatioConfig from "../VitalsMonitor/useVitalsAspectRatioConfig";
import PatientNotesSlideover from "./PatientNotesSlideover";
import useAuthUser from "../../Common/hooks/useAuthUser";
import PrescriptionAdministrationsTable from "../Medicine/PrescriptionAdministrationsTable";

Expand All @@ -79,6 +80,7 @@ export const ConsultationDetails = (props: any) => {
useState(false);
const [openDischargeDialog, setOpenDischargeDialog] = useState(false);
const [showAutomatedRounds, setShowAutomatedRounds] = useState(true);
const [showPatientNotesPopup, setShowPatientNotesPopup] = useState(false);

const getPatientGender = (patientData: any) =>
GENDER_TYPES.find((i) => i.id === patientData.gender)?.text;
Expand Down Expand Up @@ -368,12 +370,12 @@ export const ConsultationDetails = (props: any) => {
>
Patient Details
</Link>
<Link
href={`/facility/${patientData.facility}/patient/${patientData.id}/notes`}
<ButtonV2
onClick={() => setShowPatientNotesPopup(true)}
className="btn btn-primary m-1 w-full hover:text-white"
>
Doctor&apos;s Notes
</Link>
</ButtonV2>
</div>
</div>
</nav>
Expand Down Expand Up @@ -1300,6 +1302,14 @@ export const ConsultationDetails = (props: any) => {
show={showDoctors}
setShow={setShowDoctors}
/>

{showPatientNotesPopup && (
<PatientNotesSlideover
patientId={patientId}
facilityId={facilityId}
setShowPatientNotesPopup={setShowPatientNotesPopup}
/>
)}
</div>
);
};
37 changes: 37 additions & 0 deletions src/Components/Facility/PatientNoteCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { relativeDate, formatDateTime } from "../../Utils/utils";

const PatientNoteCard = ({ note }: { note: any }) => {
return (
<div
key={note.id}
className="mt-4 flex w-full flex-col rounded-lg border border-gray-300 bg-white p-3 text-gray-800"
>
<div className="flex">
<span className="text-sm font-semibold text-gray-700">
{note.created_by_object?.first_name || "Unknown"}{" "}
{note.created_by_object?.last_name}
</span>
<span className="pl-1 text-sm text-gray-700">
{" ("}
{note.created_by_object.user_type === "Doctor"
? note.created_by_local_user
? ""
: "Remote Specialist"
: note.created_by_object.user_type}
{")"}
</span>
</div>
<span className="whitespace-pre-wrap break-words">{note.note}</span>
<div className="mt-3 text-end text-xs text-gray-500">
<div className="tooltip inline">
<span className="tooltip-text tooltip-left">
{formatDateTime(note.created_date)}
</span>
{relativeDate(note.created_date)}
</div>
</div>
</div>
);
};

export default PatientNoteCard;
120 changes: 120 additions & 0 deletions src/Components/Facility/PatientNotesList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import { useCallback, useState, useEffect } from "react";
import { useDispatch } from "react-redux";
import { statusType, useAbortableEffect } from "../../Common/utils";
import { getPatientNotes } from "../../Redux/actions";
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";

interface PatientNotesProps {
patientId: any;
facilityId: any;
reload?: boolean;
setReload?: any;
}

const pageSize = RESULTS_PER_PAGE_LIMIT;

const PatientNotesList = (props: PatientNotesProps) => {
const { reload, setReload } = props;

const dispatch: any = useDispatch();
const initialData: any = { 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]
);

useEffect(() => {
if (reload) {
fetchData(1);
setReload(false);
}
}, [reload]);

useAbortableEffect(
(status: statusType) => {
fetchData(1, status);
},
[fetchData]
);

const handleNext = () => {
if (state.cPage < state.totalPages) {
fetchData(state.cPage + 1);
setState((prevState: any) => ({
...prevState,
cPage: prevState.cPage + 1,
}));
}
};

if (isLoading && !state.notes.length) {
return (
<div className=" flex h-[400px] w-full items-center justify-center bg-white">
<CircularProgress />
</div>
);
}

return (
<div
className="m-2 flex h-[390px] grow flex-col-reverse overflow-auto bg-white"
id="patient-notes-list"
>
{state.notes.length ? (
<InfiniteScroll
next={handleNext}
hasMore={state.cPage < state.totalPages}
loader={
<div className="flex items-center justify-center">
<CircularProgress />
</div>
}
className="flex h-full flex-col-reverse p-2"
inverse={true}
dataLength={state.notes.length}
scrollableTarget="patient-notes-list"
>
{state.notes.map((note: any) => (
<PatientNoteCard note={note} key={note.id} />
))}
</InfiniteScroll>
) : (
<div className="mt-2 flex items-center justify-center text-2xl font-bold text-gray-500">
No Notes Found
</div>
)}
</div>
);
};

export default PatientNotesList;
Loading