Skip to content

Commit

Permalink
Add Medicine Prescription Log Summary Section (#7584)
Browse files Browse the repository at this point in the history
* Add Medicine Summary Section

* add timeline view and show only changes

* switch to modal and use timeline view

* fix width of modal

* show clean message

* refactor files

* dont show mg twice and show discontinued

* show prescription type

* add disconitnue and no medicine card

* show discontinued in the summary

* update changes
  • Loading branch information
Pranshu1902 authored May 28, 2024
1 parent 5316402 commit 8c311c4
Show file tree
Hide file tree
Showing 3 changed files with 375 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { ConsultationTabProps } from "./index";
import PageTitle from "../../Common/PageHeadTitle";
import MedicineAdministrationSheet from "../../Medicine/MedicineAdministrationSheet";
import { MedicinePrescriptionSummary } from "../../Medicine/MedicinePrescriptionSummary";

export const ConsultationMedicinesTab = (props: ConsultationTabProps) => {
return (
Expand All @@ -15,6 +16,7 @@ export const ConsultationMedicinesTab = (props: ConsultationTabProps) => {
is_prn={true}
readonly={!!props.consultationData.discharge_date}
/>
<MedicinePrescriptionSummary consultation={props.consultationId} />
</div>
);
};
372 changes: 372 additions & 0 deletions src/Components/Medicine/MedicinePrescriptionSummary.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,372 @@
import MedicineRoutes from "../Medicine/routes";
import useQuery from "../../Utils/request/useQuery";
import DialogModal from "../Common/Dialog";
import { useState } from "react";
import { lazy } from "react";
import Timeline, { TimelineNode } from "../../CAREUI/display/Timeline";
import { MedibaseMedicine, Prescription } from "../Medicine/models";
import { useTranslation } from "react-i18next";

const Loading = lazy(() => import("../Common/Loading"));

interface MedicinePrescriptionSummaryProps {
consultation: string;
}

export const MedicinePrescriptionSummary = ({
consultation,
}: MedicinePrescriptionSummaryProps) => {
const { t } = useTranslation();
const [showMedicineModal, setShowMedicineModal] = useState({
open: false,
name: "",
medicineId: "",
});
const { data } = useQuery(MedicineRoutes.listPrescriptions, {
pathParams: { consultation },
query: { limit: 100 },
});

const closeMedicineModal = () => {
setShowMedicineModal({ ...showMedicineModal, open: false });
};

function extractUniqueMedicineObjects(
prescriptions: Prescription[],
): MedibaseMedicine[] {
const uniqueMedicineObjects: Set<string> = new Set();
const uniqueMedicines: MedibaseMedicine[] = [];

prescriptions.forEach((prescription: Prescription) => {
if (prescription?.medicine_object) {
const medicineId = prescription?.medicine_object.id;

if (!uniqueMedicineObjects.has(medicineId)) {
uniqueMedicineObjects.add(medicineId);
uniqueMedicines.push(prescription?.medicine_object);
}
}
});

return uniqueMedicines;
}

const medicinesList: MedibaseMedicine[] = extractUniqueMedicineObjects(
data?.results ?? [],
);

return (
<div className="pt-6">
<p className="text-xl font-bold text-gray-700">{t("summary")}</p>
<div className="flex flex-col gap-2 pt-4">
{medicinesList && medicinesList.length > 0 ? (
medicinesList?.map((med: MedibaseMedicine) => (
<div
key={med.id}
className="flex cursor-pointer items-center justify-between rounded-lg border bg-white p-4 shadow hover:bg-gray-200"
>
<div>{med.name}</div>
<button
onClick={() =>
setShowMedicineModal({
open: true,
name: med.name,
medicineId: med.id,
})
}
className="btn btn-default"
>
View
</button>
</div>
))
) : (
<div className="rounded-lg border shadow">
<div className="my-16 flex w-full flex-col items-center justify-center gap-4 text-gray-500">
<h3 className="text-lg font-medium">{"No Medicine Summary"}</h3>
</div>
</div>
)}
</div>

<DialogModal
title={
<p>
{showMedicineModal.name}: {t("prescription_logs")}
</p>
}
show={showMedicineModal.open}
onClose={closeMedicineModal}
fixedWidth={false}
className="md:w-3/4"
>
<ConsultationMedicineLogs
consultationId={consultation}
medicineId={showMedicineModal.medicineId}
/>
</DialogModal>
</div>
);
};

interface ConsultationMedicineLogsProps {
consultationId: string;
medicineId: string;
}

export default function ConsultationMedicineLogs({
consultationId,
medicineId,
}: ConsultationMedicineLogsProps) {
const { data, loading } = useQuery(MedicineRoutes.listPrescriptions, {
pathParams: { consultation: consultationId },
query: {
medicine: medicineId,
},
});

if (loading) {
return <Loading />;
}

const getDetailsMessage = (prescription: Prescription) => {
const message = `Details: ${
prescription.base_dosage != null
? `${prescription.dosage_type === "TITRATED" ? "Start Dosage" : "Dosage"}: ${prescription.base_dosage}, `
: ""
}${prescription.route != null ? `Route: ${prescription.route}, ` : ""}${
prescription.target_dosage != null
? `Target Dosage: ${prescription.target_dosage}, `
: ""
}${
prescription.instruction_on_titration != null
? `Instruction on Titration: ${prescription.instruction_on_titration}, `
: ""
}${
prescription.frequency != null
? `Frequency: ${prescription.frequency}, `
: ""
}${prescription.days != null ? `Days: ${prescription.days}, ` : ""}${
prescription.indicator != null
? `Indicator: ${prescription.indicator}, `
: ""
}${
prescription.max_dosage != null
? `Max Dosage: ${prescription.max_dosage}, `
: ""
}${
prescription.min_hours_between_doses != null
? `Min Hours Between Doses: ${prescription.min_hours_between_doses}, `
: ""
}${prescription.discontinued ? "Discontinued: Yes, " : ""}${
prescription.dosage_type
? `Prescription Type: ${prescription.dosage_type}, `
: ""
}`.replace(/, $/, "");

return message;
};

const calculateChanges = (prescriptions: Prescription[]) => {
prescriptions = prescriptions.reverse();
const changes = [];

const message = getDetailsMessage(prescriptions[0]);

changes.push({
prescriptionId: prescriptions[0].id,
changeMessage: message,
prescribed_by: prescriptions[0].prescribed_by,
created_date: prescriptions[0].created_date,
});

if (prescriptions[0].discontinued) {
changes.push({
prescriptionId: prescriptions[0].id,
changeMessage: "This prescription has been discontinued",
prescribed_by: prescriptions[0].prescribed_by,
created_date: prescriptions[0].discontinued_date,
});
}

for (let i = 1; i < prescriptions.length; i++) {
const prevPrescription = prescriptions[i - 1];
const currentPrescription = prescriptions[i];

const changesForPrescription: string[] = [];

// Check for changes in base dosage
if (prevPrescription.base_dosage !== currentPrescription.base_dosage) {
changesForPrescription.push(
`Base dosage changed to ${currentPrescription.base_dosage} from ${prevPrescription.base_dosage}`,
);
}

// Check for changes in route
if (prevPrescription.route !== currentPrescription.route) {
changesForPrescription.push(
`Route changed to ${
currentPrescription.route ?? "Not specified"
} from ${prevPrescription.route ?? "Not specified"}`,
);
}

// Check for changes in dosage type
if (prevPrescription.dosage_type !== currentPrescription.dosage_type) {
changesForPrescription.push(
`Dosage type changed to ${
currentPrescription.dosage_type ?? "Not specified"
} from ${prevPrescription.dosage_type ?? "Not specified"}`,
);
}

// Check for changes in target dosage
if (
prevPrescription.target_dosage !== currentPrescription.target_dosage
) {
changesForPrescription.push(
`Target dosage changed to ${
currentPrescription.target_dosage ?? "Not specified"
} from ${prevPrescription.target_dosage ?? "Not specified"}`,
);
}

// Check for changes in instruction on titration
if (
prevPrescription.instruction_on_titration !==
currentPrescription.instruction_on_titration
) {
changesForPrescription.push(
`Instruction on titration changed to ${
currentPrescription.instruction_on_titration ?? "Not specified"
} from ${
prevPrescription.instruction_on_titration ?? "Not specified"
}`,
);
}

// Check for changes in frequency
if (prevPrescription.frequency !== currentPrescription.frequency) {
changesForPrescription.push(
`Frequency changed to ${
currentPrescription.frequency ?? "Not specified"
} from ${prevPrescription.frequency ?? "Not specified"}`,
);
}

// Check for changes in days
if (prevPrescription.days !== currentPrescription.days) {
changesForPrescription.push(
`Days changed to ${
currentPrescription.days ?? "Not specified"
} from ${prevPrescription.days ?? "Not specified"}`,
);
}

// Check for changes in indicator
if (prevPrescription.indicator !== currentPrescription.indicator) {
changesForPrescription.push(
`Indicator changed to ${
currentPrescription.indicator ?? "Not specified"
} from ${prevPrescription.indicator ?? "Not specified"}`,
);
}

// Check for changes in max dosage
if (prevPrescription.max_dosage !== currentPrescription.max_dosage) {
changesForPrescription.push(
`Max dosage changed to ${
currentPrescription.max_dosage ?? "Not specified"
} from ${prevPrescription.max_dosage ?? "Not specified"}`,
);
}

// Check for changes in min hours between doses
if (
prevPrescription.min_hours_between_doses !==
currentPrescription.min_hours_between_doses
) {
changesForPrescription.push(
`Min hours between doses changed to ${
currentPrescription.min_hours_between_doses ?? "Not specified"
} from ${prevPrescription.min_hours_between_doses ?? "Not specified"}`,
);
}

// Check if discontinued
if (currentPrescription.discontinued && !prevPrescription.discontinued) {
changesForPrescription.push("Prescription was discontinued");
}

// Check if prescription type is changed
if (
prevPrescription.prescription_type !==
currentPrescription.prescription_type
) {
changesForPrescription.push(
`Prescription Type changed from ${prevPrescription.prescription_type} to ${currentPrescription.prescription_type}`,
);
}

// If there are changes, add them to the changes array
if (changesForPrescription.length > 0 && !prevPrescription.discontinued) {
const message = `Changes: ${changesForPrescription.join(", ")}`;
changes.push({
prescriptionId: currentPrescription.id,
changeMessage: message,
prescribed_by: currentPrescription.prescribed_by,
created_date: currentPrescription.created_date,
});
} else {
// If no changes, just list out the details of the prescription
const message = getDetailsMessage(currentPrescription);

changes.push({
prescriptionId: currentPrescription.id,
changeMessage: message,
prescribed_by: currentPrescription.prescribed_by,
created_date: currentPrescription.created_date,
});
}

if (currentPrescription.discontinued) {
changes.push({
prescriptionId: currentPrescription.id,
changeMessage: "This prescription has been discontinued",
prescribed_by: currentPrescription.prescribed_by,
created_date: currentPrescription.discontinued_date,
});
}
}

return changes.reverse();
};

return (
<div>
<Timeline
className="rounded-lg bg-white p-2 shadow"
name={data?.results[0].medicine_object?.name ?? ""}
>
{data?.results &&
(() => {
const changesArray = calculateChanges(data?.results);
return changesArray.map((changes, index) => (
<TimelineNode
key={changes.prescriptionId}
event={{
type: "prescribed",
timestamp: changes.created_date,
by: changes.prescribed_by,
icon: "l-syringe",
}}
isLast={index === changesArray.length - 1}
>
<p>{changes?.changeMessage}</p>
</TimelineNode>
));
})()}
</Timeline>
</div>
);
}
1 change: 1 addition & 0 deletions src/Locale/en/Medicine.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"prescription_discontinued": "Prescription discontinued",
"administration_notes": "Administration Notes",
"last_administered": "Last administered",
"prescription_logs": "Prescription Logs",
"modification_caution_note": "No modifications possible once added",
"discontinue_caution_note": "Are you sure you want to discontinue this prescription?",
"edit_caution_note": "A new prescription will be added to the consultation with the edited details and the current prescription will be discontinued.",
Expand Down

0 comments on commit 8c311c4

Please sign in to comment.