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

GSoC - Doctor Notes Enhancement #8016

Draft
wants to merge 39 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
7443efd
reply feature for doctor notes
UdaySagar-Git May 13, 2024
3128fd7
code reviews
UdaySagar-Git May 15, 2024
51edb8d
code review
UdaySagar-Git May 16, 2024
ab2ec7e
Merge branch 'develop' into doctors-notes
rithviknishad May 20, 2024
2a3793a
Merge branch 'develop' into doctors-notes
nihal467 May 22, 2024
c23309f
profile picture feature
UdaySagar-Git Jun 7, 2024
7abc974
bug fix
UdaySagar-Git Jun 8, 2024
8eb0dd2
minor ui fix
UdaySagar-Git Jun 8, 2024
1bb7be9
add profile image in the side bar
UdaySagar-Git Jun 11, 2024
9852ae5
Merge branch 'doctors-notes' into gsoc-doctor-notes
UdaySagar-Git Jun 11, 2024
37a5947
Merge branch 'issues/3924/support-for-profile-pic' into gsoc-doctor-n…
UdaySagar-Git Jun 11, 2024
81450b4
Rich text editor
UdaySagar-Git Jun 20, 2024
6600560
Merge branch 'develop' into rich-text-editor
UdaySagar-Git Jun 20, 2024
de5a78e
Merge branch 'rich-text-editor' into gsoc-doctor-notes
UdaySagar-Git Jun 20, 2024
b955e78
code suggestions
UdaySagar-Git Jun 27, 2024
966970f
removes npm i packages
UdaySagar-Git Jun 27, 2024
9b2ae15
thread view
UdaySagar-Git Jun 28, 2024
a1446bd
code suggestions
UdaySagar-Git Jul 3, 2024
f1caca3
Merge branch 'develop' into rich-text-editor
UdaySagar-Git Jul 4, 2024
a3d1bc3
removes depricated commands
UdaySagar-Git Jul 4, 2024
16853d1
use usereducer
UdaySagar-Git Jul 4, 2024
10941b6
removes undo rendo
UdaySagar-Git Jul 4, 2024
e0ee2f5
support for mentions
UdaySagar-Git Jul 4, 2024
02ce215
mention style and strike through style
UdaySagar-Git Jul 5, 2024
d5a450e
file uploads
UdaySagar-Git Jul 5, 2024
ccafa0f
improved ui
UdaySagar-Git Jul 5, 2024
c2709a1
bug fix for file preview
UdaySagar-Git Jul 6, 2024
704cfba
support for camera captures and audio recordings
UdaySagar-Git Jul 6, 2024
9a88d4b
Merge branch 'issues/3924/support-for-profile-pic' into gsoc-doctor-n…
UdaySagar-Git Jul 6, 2024
dd73c02
Merge branch 'rich-text-editor' into gsoc-doctor-notes
UdaySagar-Git Jul 6, 2024
3956329
Merge branch 'rich-text-editor' into gsoc-doctor-notes
UdaySagar-Git Jul 6, 2024
2b93ad7
Merge branch 'thread-view' into gsoc-doctor-notes
UdaySagar-Git Jul 6, 2024
eeeab48
Merge branch 'develop' into gsoc-doctor-notes
UdaySagar-Git Jul 6, 2024
a2b9061
mention hover card
UdaySagar-Git Jul 7, 2024
b926262
Merge branch 'rich-text-editor' into gsoc-doctor-notes
UdaySagar-Git Jul 7, 2024
2943843
code refactor for a reusable component
UdaySagar-Git Jul 8, 2024
891cfbf
Merge branch 'rich-text-editor' into gsoc-doctor-notes
UdaySagar-Git Jul 8, 2024
720d8da
integrated with doctor notes
UdaySagar-Git Jul 8, 2024
c8d8935
ui improvements
UdaySagar-Git Jul 8, 2024
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
10 changes: 8 additions & 2 deletions src/Components/Common/Sidebar/SidebarUserCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,14 @@ const SidebarUserCard = ({ shrinked }: { shrinked: boolean }) => {
shrinked ? "mx-auto flex-col" : "mx-5"
} transition-all duration-200 ease-in-out`}
>
<Link href="/user/profile" className="flex-none py-3">
<CareIcon icon="l-user-circle" className="text-3xl text-white" />
<Link href="/user/profile">
<img
src={user.read_profile_picture_url || "/images/empty_avatar.jpg"}
alt="profile"
className={`h-10 w-10 rounded-full object-cover ${
shrinked ? "mb-3" : "mb-2 mt-1"
}`}
/>
</Link>
<div className="flex cursor-pointer justify-center" onClick={signOut}>
<CareIcon
Expand Down
71 changes: 41 additions & 30 deletions src/Components/Facility/ConsultationDoctorNotes/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ 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 { PatientNoteStateType, PaitentNotesReplyModel } from "../models.js";
import routes from "../../../Redux/api.js";
import request from "../../../Utils/request/request.js";
import useQuery from "../../../Utils/request/useQuery.js";
Expand All @@ -15,6 +15,7 @@ import { classNames, isAppleDevice } from "../../../Utils/utils.js";
import AutoExpandingTextInputFormField from "../../Form/FormFields/AutoExpandingTextInputFormField.js";
import { PATIENT_NOTES_THREADS } from "../../../Common/constants.js";
import useAuthUser from "../../../Common/hooks/useAuthUser.js";
import DoctorNoteReplyPreviewCard from "../DoctorNoteReplyPreviewCard.js";

interface ConsultationDoctorNotesProps {
patientId: string;
Expand All @@ -38,6 +39,9 @@ const ConsultationDoctorNotes = (props: ConsultationDoctorNotesProps) => {
const [facilityName, setFacilityName] = useState("");
const [patientName, setPatientName] = useState("");
const [focused, setFocused] = useState(false);
const [reply_to, setReplyTo] = useState<PaitentNotesReplyModel | undefined>(
undefined,
);

const initialData: PatientNoteStateType = {
notes: [],
Expand All @@ -64,6 +68,7 @@ const ConsultationDoctorNotes = (props: ConsultationDoctorNotesProps) => {
note: noteField,
thread,
consultation: consultationId,
reply_to: reply_to?.id,
},
});

Expand All @@ -72,6 +77,7 @@ const ConsultationDoctorNotes = (props: ConsultationDoctorNotesProps) => {
setState({ ...state, cPage: 1 });
setNoteField("");
setReload(true);
setReplyTo(undefined);
}
};

Expand Down Expand Up @@ -148,36 +154,41 @@ const ConsultationDoctorNotes = (props: ConsultationDoctorNotesProps) => {
reload={reload}
setReload={setReload}
thread={thread}
setReplyTo={setReplyTo}
/>

<div className="relative mx-4 flex items-center">
<AutoExpandingTextInputFormField
id="doctor_consultation_notes"
maxHeight={160}
rows={1}
name="note"
value={noteField}
onChange={(e) => setNoteField(e.value)}
className="w-full grow"
innerClassName="pr-10"
errorClassName="hidden"
placeholder="Type your Note"
disabled={!patientActive}
onFocus={() => setFocused(true)}
onBlur={() => setFocused(false)}
/>
<ButtonV2
onClick={onAddNote}
border={false}
className="absolute right-2"
ghost
size="small"
disabled={!patientActive}
authorizeFor={NonReadOnlyUsers}
>
<CareIcon icon="l-message" className="text-lg" />
</ButtonV2>
</div>
<DoctorNoteReplyPreviewCard
parentNote={reply_to}
cancelReply={() => setReplyTo(undefined)}
>
<div className="relative mx-4 flex items-center">
<AutoExpandingTextInputFormField
id="doctor_consultation_notes"
maxHeight={160}
rows={1}
name="note"
value={noteField}
onChange={(e) => setNoteField(e.value)}
className="w-full grow"
innerClassName="pr-10"
errorClassName="hidden"
placeholder="Type your Note"
disabled={!patientActive}
onFocus={() => setFocused(true)}
onBlur={() => setFocused(false)}
/>
<ButtonV2
onClick={onAddNote}
border={false}
className="absolute right-2"
ghost
size="small"
disabled={!patientActive}
authorizeFor={NonReadOnlyUsers}
>
<CareIcon icon="l-message" className="text-lg" />
</ButtonV2>
</div>
</DoctorNoteReplyPreviewCard>
</div>
</Page>
);
Expand Down
21 changes: 14 additions & 7 deletions src/Components/Facility/DoctorNote.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import InfiniteScroll from "react-infinite-scroll-component";
import CircularProgress from "../Common/components/CircularProgress";
import PatientNoteCard from "./PatientNoteCard";
import { PatientNoteStateType } from "./models";
import { PatientNoteStateType, PatientNotesModel } from "./models";
import DoctorNoteReplyPreviewCard from "./DoctorNoteReplyPreviewCard";

interface DoctorNoteProps {
state: PatientNoteStateType;
setReload: any;
handleNext: () => void;
disableEdit?: boolean;
setReplyTo?: (reply_to: PatientNotesModel | undefined) => void;
}

const DoctorNote = (props: DoctorNoteProps) => {
const { state, handleNext, setReload, disableEdit } = props;
const { state, handleNext, setReload, disableEdit, setReplyTo } = props;

return (
<div
Expand All @@ -33,12 +35,17 @@ const DoctorNote = (props: DoctorNoteProps) => {
scrollableTarget="patient-notes-list"
>
{state.notes.map((note) => (
<PatientNoteCard
note={note}
<DoctorNoteReplyPreviewCard
key={note.id}
setReload={setReload}
disableEdit={disableEdit}
/>
parentNote={note.reply_to_object}
>
<PatientNoteCard
note={note}
setReload={setReload}
disableEdit={disableEdit}
setReplyTo={setReplyTo}
/>
</DoctorNoteReplyPreviewCard>
))}
</InfiniteScroll>
) : (
Expand Down
64 changes: 64 additions & 0 deletions src/Components/Facility/DoctorNoteReplyPreviewCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import React from "react";
import { PaitentNotesReplyModel } from "./models";
import { USER_TYPES_MAP } from "../../Common/constants";
import { formatDateTime, relativeDate } from "../../Utils/utils";

interface Props {
parentNote: PaitentNotesReplyModel | undefined;
children: React.ReactNode;
cancelReply?: () => void;
}

const DoctorNoteReplyPreviewCard = ({
parentNote,
children,
cancelReply,
}: Props) => {
return (
<div className="">
{parentNote ? (
<div className="mt-4 flex w-full flex-col rounded-lg border border-gray-300 bg-gray-200 p-2 text-gray-800">
<div className="flex flex-col px-2">
<div className="flex justify-between">
<div>
<div>
<span className="text-sm font-semibold text-gray-700">
{parentNote.created_by_object?.first_name || "Unknown"}{" "}
{parentNote.created_by_object?.last_name}
</span>
{parentNote.user_type && (
<span className="pl-2 text-sm text-gray-700">
{`(${USER_TYPES_MAP[parentNote.user_type]})`}
</span>
)}
</div>
<div className="text-xs text-gray-600">
<div className="tooltip inline">
<span className="tooltip-text tooltip-bottom">
{formatDateTime(parentNote.created_date)}
</span>
Created {relativeDate(parentNote.created_date, true)}
</div>
</div>
</div>
{cancelReply && (
<div
className="cursor-pointer text-xs text-gray-600"
onClick={cancelReply}
>
Cancel
</div>
)}
</div>
<div className="pb-2 text-sm text-gray-700">{parentNote.note}</div>
</div>
<div>{children}</div>
</div>
) : (
<div>{children}</div>
)}
</div>
);
};

export default DoctorNoteReplyPreviewCard;
12 changes: 11 additions & 1 deletion src/Components/Facility/PatientConsultationNotesList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,21 @@ interface PatientNotesProps {
setReload?: (value: boolean) => void;
disableEdit?: boolean;
thread: PatientNotesModel["thread"];
setReplyTo?: (value: PatientNotesModel | undefined) => void;
}

const pageSize = RESULTS_PER_PAGE_LIMIT;

const PatientConsultationNotesList = (props: PatientNotesProps) => {
const { state, setState, reload, setReload, disableEdit, thread } = props;
const {
state,
setState,
reload,
setReload,
disableEdit,
thread,
setReplyTo,
} = props;
const consultationId = useSlug("consultation") ?? "";

const [isLoading, setIsLoading] = useState(true);
Expand Down Expand Up @@ -95,6 +104,7 @@ const PatientConsultationNotesList = (props: PatientNotesProps) => {
handleNext={handleNext}
setReload={setReload}
disableEdit={disableEdit}
setReplyTo={setReplyTo}
/>
);
};
Expand Down
37 changes: 24 additions & 13 deletions src/Components/Facility/PatientNoteCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ const PatientNoteCard = ({
note,
setReload,
disableEdit,
setReplyTo,
}: {
note: PatientNotesModel;
setReload: any;
disableEdit?: boolean;
setReplyTo?: (reply_to: PatientNotesModel | undefined) => void;
}) => {
const patientId = useSlug("patient");
const [isEditing, setIsEditing] = useState(false);
Expand Down Expand Up @@ -124,19 +126,28 @@ const PatientNoteCard = ({
)
}
</div>

{!disableEdit &&
note.created_by_object.id === authUser.id &&
!isEditing && (
<ButtonV2
ghost
onClick={() => {
setIsEditing(true);
}}
>
<CareIcon icon="l-pen" className="h-5 w-5" />
</ButtonV2>
)}
<div className="flex gap-2">
{!disableEdit &&
note.created_by_object.id === authUser.id &&
!isEditing && (
<ButtonV2
ghost
onClick={() => {
setIsEditing(true);
}}
>
<CareIcon icon="l-pen" className="h-5 w-5" />
</ButtonV2>
)}
<ButtonV2
ghost
onClick={() => {
setReplyTo && setReplyTo(note);
}}
>
<CareIcon icon="l-corner-up-left-alt" className="h-5 w-5" />
</ButtonV2>
</div>
</div>
{
<div className="mt-2">
Expand Down
10 changes: 8 additions & 2 deletions src/Components/Facility/PatientNotesList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ interface PatientNotesProps {
reload?: boolean;
setReload?: any;
thread: PatientNotesModel["thread"];
setReplyTo?: (reply_to: PatientNotesModel | undefined) => void;
}

const pageSize = RESULTS_PER_PAGE_LIMIT;

const PatientNotesList = (props: PatientNotesProps) => {
const { state, setState, reload, setReload, thread } = props;
const { state, setState, reload, setReload, thread, setReplyTo } = props;

const [isLoading, setIsLoading] = useState(true);

Expand Down Expand Up @@ -83,7 +84,12 @@ const PatientNotesList = (props: PatientNotesProps) => {
}

return (
<DoctorNote state={state} handleNext={handleNext} setReload={setReload} />
<DoctorNote
state={state}
handleNext={handleNext}
setReload={setReload}
setReplyTo={setReplyTo}
/>
);
};

Expand Down
Loading
Loading