diff --git a/src/Components/Facility/ConsultationDetails/ConsultationMedicinesTab.tsx b/src/Components/Facility/ConsultationDetails/ConsultationMedicinesTab.tsx
index 0643765339f..e1e72c2f936 100644
--- a/src/Components/Facility/ConsultationDetails/ConsultationMedicinesTab.tsx
+++ b/src/Components/Facility/ConsultationDetails/ConsultationMedicinesTab.tsx
@@ -1,20 +1,18 @@
import { ConsultationTabProps } from "./index";
-import PrescriptionAdministrationsTable from "../../Medicine/PrescriptionAdministrationsTable";
import PageTitle from "../../Common/PageHeadTitle";
+import MedicineAdministrationSheet from "../../Medicine/MedicineAdministrationSheet";
export const ConsultationMedicinesTab = (props: ConsultationTabProps) => {
return (
{/* eslint-disable-next-line i18next/no-literal-string */}
-
-
diff --git a/src/Components/Medicine/MedicineAdministrationSheet/AdministrationEventCell.tsx b/src/Components/Medicine/MedicineAdministrationSheet/AdministrationEventCell.tsx
new file mode 100644
index 00000000000..ddfc5b63c12
--- /dev/null
+++ b/src/Components/Medicine/MedicineAdministrationSheet/AdministrationEventCell.tsx
@@ -0,0 +1,181 @@
+import { Disclosure, Popover, Transition } from "@headlessui/react";
+import dayjs from "../../../Utils/dayjs";
+import { MedicineAdministrationRecord, Prescription } from "../models";
+import CareIcon from "../../../CAREUI/icons/CareIcon";
+import { Fragment } from "react";
+import { classNames, formatDateTime, formatTime } from "../../../Utils/utils";
+
+interface Props {
+ administrations: MedicineAdministrationRecord[];
+ interval: { start: Date; end: Date };
+ prescription: Prescription;
+}
+
+export default function AdministrationEventCell({
+ administrations,
+ interval: { start, end },
+ prescription,
+}: Props) {
+ // Check if cell belongs to an administered prescription
+ const administered = administrations
+ .filter((administration) =>
+ dayjs(administration.administered_date).isBetween(start, end)
+ )
+ .sort(
+ (a, b) =>
+ new Date(a.administered_date!).getTime() -
+ new Date(b.administered_date!).getTime()
+ );
+
+ const hasComment = administered.some((obj) => !!obj.notes);
+
+ if (administered.length) {
+ return (
+
+
+
+
+
+ {administered.length > 1 && (
+
+ {administered.length}
+
+ )}
+
+ {hasComment && (
+
+ )}
+
+ {administered.length === 1 ? (
+
+ Administered on{" "}
+
+ {formatTime(administered[0].administered_date)}
+
+
+ ) : (
+
+ {administered.length} administrations
+
+ )}
+ Click to view details
+
+
+
+
+
+
+
+
+ {administered.map((administration) => (
+
+
+ {({ open }) => (
+ <>
+
+
+ Administered on{" "}
+
+ {formatTime(administration.administered_date)}
+
+
+ {administration.notes && (
+
+ )}
+
+
+
+
+ Administered by:{" "}
+
+ {administration.administered_by?.first_name}{" "}
+ {administration.administered_by?.last_name}
+
+
+
+ Notes:{" "}
+
+ {administration.notes || (
+
+ No notes
+
+ )}
+
+
+
+ >
+ )}
+
+
+ ))}
+
+
+
+
+
+ );
+ }
+
+ // Check if cell belongs to a discontinued prescription
+ if (
+ prescription.discontinued &&
+ dayjs(end).isAfter(prescription.discontinued_date)
+ ) {
+ if (!dayjs(prescription.discontinued_date).isBetween(start, end)) return;
+
+ return (
+
+
+
+
+ Discontinued on{" "}
+ {formatDateTime(prescription.discontinued_date)}
+
+
+ Reason:{" "}
+ {prescription.discontinued_reason ? (
+ {prescription.discontinued_reason}
+ ) : (
+ Not specified
+ )}
+
+
+
+ );
+ }
+}
diff --git a/src/Components/Medicine/MedicineAdministrationSheet/AdministrationEventSeperator.tsx b/src/Components/Medicine/MedicineAdministrationSheet/AdministrationEventSeperator.tsx
new file mode 100644
index 00000000000..e38e558e6d5
--- /dev/null
+++ b/src/Components/Medicine/MedicineAdministrationSheet/AdministrationEventSeperator.tsx
@@ -0,0 +1,22 @@
+import { formatDateTime } from "../../../Utils/utils";
+
+export default function AdministrationEventSeperator({ date }: { date: Date }) {
+ // Show date if it's 00:00
+ if (date.getHours() === 0) {
+ return (
+
+
+ {formatDateTime(date, "DD/MM")}
+
+
+ );
+ }
+
+ return (
+
+
+ {formatDateTime(date, "HH")}
+
+
+ );
+}
diff --git a/src/Components/Medicine/MedicineAdministrationSheet/AdministrationTable.tsx b/src/Components/Medicine/MedicineAdministrationSheet/AdministrationTable.tsx
new file mode 100644
index 00000000000..0417a0e93c0
--- /dev/null
+++ b/src/Components/Medicine/MedicineAdministrationSheet/AdministrationTable.tsx
@@ -0,0 +1,104 @@
+import { useTranslation } from "react-i18next";
+import CareIcon from "../../../CAREUI/icons/CareIcon";
+import useRangePagination from "../../../Common/hooks/useRangePagination";
+import { classNames, formatDateTime } from "../../../Utils/utils";
+import ButtonV2 from "../../Common/components/ButtonV2";
+import { Prescription } from "../models";
+import MedicineAdministrationTableRow from "./AdministrationTableRow";
+
+interface Props {
+ prescriptions: Prescription[];
+ pagination: ReturnType;
+ onRefetch: () => void;
+}
+
+export default function MedicineAdministrationTable({
+ pagination,
+ prescriptions,
+ onRefetch,
+}: Props) {
+ const { t } = useTranslation();
+
+ return (
+
+
+
+
+
+ {t("medicine")}
+
+ Dosage &
+ {!prescriptions[0]?.is_prn ? "Frequency" : "Indicator"}
+
+
+ |
+
+
+
+
+
+ |
+ {pagination.slots?.map(({ start }, index) => (
+ <>
+
+ {formatDateTime(
+ start,
+ start.getHours() === 0 ? "DD/MM" : "HH:mm"
+ )}
+ |
+ |
+ >
+ ))}
+
+
+
+
+ |
+
+ |
+
+
+
+
+ {prescriptions.map((obj) => (
+
+ ))}
+
+
+ );
+}
diff --git a/src/Components/Medicine/MedicineAdministrationSheet/AdministrationTableRow.tsx b/src/Components/Medicine/MedicineAdministrationSheet/AdministrationTableRow.tsx
new file mode 100644
index 00000000000..326f6072e38
--- /dev/null
+++ b/src/Components/Medicine/MedicineAdministrationSheet/AdministrationTableRow.tsx
@@ -0,0 +1,244 @@
+import { useTranslation } from "react-i18next";
+import { Prescription } from "../models";
+import { useState } from "react";
+import useQuery from "../../../Utils/request/useQuery";
+import MedicineRoutes from "../routes";
+import { classNames, formatDateTime } from "../../../Utils/utils";
+import useSlug from "../../../Common/hooks/useSlug";
+import DiscontinuePrescription from "../DiscontinuePrescription";
+import AdministerMedicine from "../AdministerMedicine";
+import DialogModal from "../../Common/Dialog";
+import PrescriptionDetailCard from "../PrescriptionDetailCard";
+import ButtonV2, { Cancel, Submit } from "../../Common/components/ButtonV2";
+import CareIcon from "../../../CAREUI/icons/CareIcon";
+import EditPrescriptionForm from "../EditPrescriptionForm";
+import AdministrationEventSeperator from "./AdministrationEventSeperator";
+import AdministrationEventCell from "./AdministrationEventCell";
+
+interface Props {
+ prescription: Prescription;
+ intervals: { start: Date; end: Date }[];
+ refetch: () => void;
+}
+
+export default function MedicineAdministrationTableRow({
+ prescription,
+ ...props
+}: Props) {
+ const { t } = useTranslation();
+ const consultation = useSlug("consultation");
+ // const [showActions, setShowActions] = useState(false);
+ const [showDetails, setShowDetails] = useState(false);
+ const [showEdit, setShowEdit] = useState(false);
+ const [showAdminister, setShowAdminister] = useState(false);
+ const [showDiscontinue, setShowDiscontinue] = useState(false);
+
+ const { data, loading } = useQuery(MedicineRoutes.listAdministrations, {
+ pathParams: { consultation },
+ query: {
+ prescription: prescription.id,
+
+ administered_date_after: formatDateTime(
+ props.intervals[0].start,
+ "YYYY-MM-DD"
+ ),
+ administered_date_before: formatDateTime(
+ props.intervals[props.intervals.length - 1].end,
+ "YYYY-MM-DD"
+ ),
+ },
+ });
+
+ return (
+
+ {showDiscontinue && (
+ {
+ setShowDiscontinue(false);
+ if (success) {
+ props.refetch();
+ }
+ }}
+ />
+ )}
+ {showAdminister && (
+ {
+ setShowAdminister(false);
+ if (success) {
+ props.refetch();
+ }
+ }}
+ />
+ )}
+ {showDetails && (
+ setShowDetails(false)}
+ className="w-full md:max-w-4xl"
+ show
+ >
+
+
+
+ setShowDetails(false)}
+ label={t("close")}
+ />
+ setShowDiscontinue(true)}
+ >
+
+ {t("discontinue")}
+
+ {
+ setShowDetails(false);
+ setShowEdit(true);
+ }}
+ >
+
+ {t("edit")}
+
+ setShowAdminister(true)}
+ >
+
+ {t("administer")}
+
+
+
+
+ )}
+ {showEdit && (
+ setShowEdit(false)}
+ show={showEdit}
+ title={`${t("edit")} ${t(
+ prescription.is_prn ? "prn_prescription" : "prescription_medication"
+ )}: ${
+ prescription.medicine_object?.name ?? prescription.medicine_old
+ }`}
+ description={
+
+
+ {t("edit_caution_note")}
+
+ }
+ className="w-full max-w-3xl lg:min-w-[600px]"
+ >
+ {
+ setShowEdit(false);
+ if (success) {
+ props.refetch();
+ }
+ }}
+ />
+
+ )}
+ setShowDetails(true)}
+ >
+
+
+
+ {prescription.medicine_object?.name ?? prescription.medicine_old}
+
+
+ {prescription.discontinued && (
+
+ {t("discontinued")}
+
+ )}
+
+ {prescription.route && (
+
+ {t(prescription.route)}
+
+ )}
+
+
+
+ {prescription.dosage}
+
+ {!prescription.is_prn
+ ? t("PRESCRIPTION_FREQUENCY_" + prescription.frequency)
+ : prescription.indicator}
+
+
+
+ |
+
+ |
+
+ {/* Administration Cells */}
+ {props.intervals.map(({ start, end }, index) => (
+ <>
+
+
+ |
+
+
+ {data?.results === undefined ? (
+
+ ) : (
+
+ )}
+ |
+ >
+ ))}
+ |
+
+ {/* Action Buttons */}
+
+ setShowAdminister(true)}
+ >
+ {t("administer")}
+
+ |
+
+ );
+}
diff --git a/src/Components/Medicine/MedicineAdministrationSheet/index.tsx b/src/Components/Medicine/MedicineAdministrationSheet/index.tsx
new file mode 100644
index 00000000000..16b1f78c85d
--- /dev/null
+++ b/src/Components/Medicine/MedicineAdministrationSheet/index.tsx
@@ -0,0 +1,139 @@
+import { useTranslation } from "react-i18next";
+import useSlug from "../../../Common/hooks/useSlug";
+import useQuery from "../../../Utils/request/useQuery";
+import MedicineRoutes from "../routes";
+import { useMemo, useState } from "react";
+import { computeActivityBounds } from "./utils";
+import useBreakpoints from "../../../Common/hooks/useBreakpoints";
+import SubHeading from "../../../CAREUI/display/SubHeading";
+import ButtonV2 from "../../Common/components/ButtonV2";
+import CareIcon from "../../../CAREUI/icons/CareIcon";
+import BulkAdminister from "./BulkAdminister";
+import useRangePagination from "../../../Common/hooks/useRangePagination";
+import MedicineAdministrationTable from "./AdministrationTable";
+
+interface Props {
+ readonly?: boolean;
+ is_prn: boolean;
+}
+
+const DEFAULT_BOUNDS = { start: new Date(), end: new Date() };
+
+const MedicineAdministrationSheet = ({ readonly, is_prn }: Props) => {
+ const { t } = useTranslation();
+ const consultation = useSlug("consultation");
+
+ const [showDiscontinued, setShowDiscontinued] = useState(false);
+
+ const filters = { is_prn, prescription_type: "REGULAR", limit: 100 };
+
+ const { data, refetch } = useQuery(MedicineRoutes.listPrescriptions, {
+ pathParams: { consultation },
+ query: { ...filters, discontinued: showDiscontinued ? undefined : false },
+ });
+
+ const discontinuedCount = useQuery(MedicineRoutes.listPrescriptions, {
+ pathParams: { consultation },
+ query: { ...filters, discontinued: true },
+ prefetch: !showDiscontinued,
+ }).data?.count;
+
+ const { activityTimelineBounds, prescriptions } = useMemo(
+ () => ({
+ prescriptions: data?.results?.sort(
+ (a, b) => +a.discontinued - +b.discontinued
+ ),
+ activityTimelineBounds: data
+ ? computeActivityBounds(data.results)
+ : undefined,
+ }),
+ [data]
+ );
+
+ const daysPerPage = useBreakpoints({ default: 1, "2xl": 2 });
+ const pagination = useRangePagination({
+ bounds: activityTimelineBounds ?? DEFAULT_BOUNDS,
+ perPage: daysPerPage * 24 * 60 * 60 * 1000,
+ slots: (daysPerPage * 24) / 4, // Grouped by 4 hours
+ defaultEnd: true,
+ });
+
+ return (
+ <>
+
+
+
+
+ {t("edit_prescriptions")}
+
+ {t("edit")}
+
+ refetch()}
+ />
+ >
+ )
+ }
+ />
+
+
+ {prescriptions?.length === 0 && }
+
+ {prescriptions?.length && (
+
+ )}
+
+ {!showDiscontinued && !!discontinuedCount && (
+ setShowDiscontinued(true)}
+ >
+
+
+
+ Show {discontinuedCount} other discontinued
+ prescription(s)
+
+
+
+ )}
+
+ >
+ );
+};
+
+export default MedicineAdministrationSheet;
+
+const NoPrescriptions = ({ prn }: { prn: boolean }) => {
+ return (
+
+
+
+ {prn
+ ? "No PRN Prescriptions Prescribed"
+ : "No Prescriptions Prescribed"}
+
+
+ );
+};
diff --git a/src/Components/Medicine/PrescriptionAdministrationsTable.tsx b/src/Components/Medicine/PrescriptionAdministrationsTable.tsx
index a454df96b2c..981be72e8ce 100644
--- a/src/Components/Medicine/PrescriptionAdministrationsTable.tsx
+++ b/src/Components/Medicine/PrescriptionAdministrationsTable.tsx
@@ -1,769 +1,769 @@
-import { Fragment, useCallback, useEffect, useMemo, useState } from "react";
-import { PrescriptionActions } from "../../Redux/actions";
-import { useDispatch } from "react-redux";
-import { MedicineAdministrationRecord, Prescription } from "./models";
-import CareIcon from "../../CAREUI/icons/CareIcon";
-import ButtonV2, { Cancel, Submit } from "../Common/components/ButtonV2";
-import SlideOver from "../../CAREUI/interactive/SlideOver";
-import MedicineAdministration from "./MedicineAdministration";
-import DiscontinuePrescription from "./DiscontinuePrescription";
-import AdministerMedicine from "./AdministerMedicine";
-import DialogModal from "../Common/Dialog";
-import PrescriptionDetailCard from "./PrescriptionDetailCard";
-import { useTranslation } from "react-i18next";
-import SubHeading from "../../CAREUI/display/SubHeading";
-import dayjs from "../../Utils/dayjs";
-import { classNames, formatDateTime, formatTime } from "../../Utils/utils";
-import useRangePagination from "../../Common/hooks/useRangePagination";
-import EditPrescriptionForm from "./EditPrescriptionForm";
-import useBreakpoints from "../../Common/hooks/useBreakpoints";
-import { Disclosure, Popover, Transition } from "@headlessui/react";
-
-interface DateRange {
- start: Date;
- end: Date;
-}
-
-interface Props {
- prn: boolean;
- prescription_type?: Prescription["prescription_type"];
- consultation_id: string;
- readonly?: boolean;
-}
-
-interface State {
- prescriptions: Prescription[];
- administrationsTimeBounds: DateRange;
-}
-
-export default function PrescriptionAdministrationsTable({
- prn,
- consultation_id,
- readonly,
-}: Props) {
- const dispatch = useDispatch();
- const { t } = useTranslation();
-
- const [state, setState] = useState();
- const [showDiscontinued, setShowDiscontinued] = useState(false);
- const [discontinuedCount, setDiscontinuedCount] = useState();
- const daysPerPage = useBreakpoints({ default: 1, "2xl": 2 });
- const pagination = useRangePagination({
- bounds: state?.administrationsTimeBounds ?? {
- start: new Date(),
- end: new Date(),
- },
- perPage: daysPerPage * 24 * 60 * 60 * 1000,
- slots: (daysPerPage * 24) / 4, // Grouped by 4 hours
- defaultEnd: true,
- });
- const [showBulkAdminister, setShowBulkAdminister] = useState(false);
-
- const { list, prescription } = useMemo(
- () => PrescriptionActions(consultation_id),
- [consultation_id]
- );
-
- const refetch = useCallback(async () => {
- const filters = {
- is_prn: prn,
- prescription_type: "REGULAR",
- limit: 100,
- };
-
- const res = await dispatch(
- list(showDiscontinued ? filters : { ...filters, discontinued: false })
- );
-
- setState({
- prescriptions: (res.data.results as Prescription[]).sort(
- (a, b) => (a.discontinued ? 1 : 0) - (b.discontinued ? 1 : 0)
- ),
- administrationsTimeBounds: getAdministrationBounds(res.data.results),
- });
-
- if (showDiscontinued === false) {
- const discontinuedRes = await dispatch(
- list({ ...filters, discontinued: true, limit: 0 })
- );
- setDiscontinuedCount(discontinuedRes.data.count);
- }
- }, [consultation_id, showDiscontinued, dispatch]);
-
- useEffect(() => {
- refetch();
- }, [refetch]);
-
- return (
-
- {state?.prescriptions && (
-
- {
- setShowBulkAdminister(false);
- refetch();
- }}
- />
-
- )}
-
-
-
-
-
- {t("edit_prescriptions")}
-
- {t("edit")}
-
- setShowBulkAdminister(true)}
- className="w-full"
- disabled={
- state === undefined || state.prescriptions.length === 0
- }
- >
-
-
- {t("administer_medicines")}
-
- {t("administer")}
-
- >
- )
- }
- />
-
-
- {state?.prescriptions.length === 0 ? (
-
-
-
- {prn
- ? "No PRN Prescriptions Prescribed"
- : "No Prescriptions Prescribed"}
-
-
- ) : (
-
-
-
-
-
- {t("medicine")}
-
- Dosage &
-
- {!state?.prescriptions[0]?.is_prn
- ? "Frequency"
- : "Indicator"}
-
-
-
- |
-
-
-
-
-
- |
- {state === undefined
- ? Array.from({ length: 12 }, (_, i) => i).map((i) => (
-
-
- |
- ))
- : pagination.slots?.map(({ start }, index) => (
- <>
-
- {formatDateTime(
- start,
- start.getHours() === 0 ? "DD/MM" : "HH:mm"
- )}
- |
- |
- >
- ))}
-
-
-
-
- |
-
- |
-
-
-
-
- {state?.prescriptions?.map((item) => (
-
- ))}
-
-
- )}
-
- {showDiscontinued === false && !!discontinuedCount && (
-
setShowDiscontinued(true)}
- >
-
-
-
- Show {discontinuedCount} other discontinued
- prescription(s)
-
-
-
- )}
-
-
- );
-}
-
-interface PrescriptionRowProps {
- prescription: Prescription;
- intervals: DateRange[];
- actions: ReturnType["prescription"]>;
- refetch: () => void;
-}
-
-const PrescriptionRow = ({ prescription, ...props }: PrescriptionRowProps) => {
- const dispatch = useDispatch();
- const { t } = useTranslation();
- // const [showActions, setShowActions] = useState(false);
- const [showDetails, setShowDetails] = useState(false);
- const [showEdit, setShowEdit] = useState(false);
- const [showAdminister, setShowAdminister] = useState(false);
- const [showDiscontinue, setShowDiscontinue] = useState(false);
- const [administrations, setAdministrations] =
- useState();
-
- useEffect(() => {
- setAdministrations(undefined);
-
- const getAdministrations = async () => {
- const res = await dispatch(
- props.actions.listAdministrations({
- administered_date_after: formatDateTime(
- props.intervals[0].start,
- "YYYY-MM-DD"
- ),
- administered_date_before: formatDateTime(
- props.intervals[props.intervals.length - 1].end,
- "YYYY-MM-DD"
- ),
- })
- );
-
- setAdministrations(res.data.results);
- };
-
- getAdministrations();
- }, [prescription.id, dispatch, props.intervals]);
-
- return (
-
- {showDiscontinue && (
- {
- setShowDiscontinue(false);
- if (success) {
- props.refetch();
- }
- }}
- />
- )}
- {showAdminister && (
- {
- setShowAdminister(false);
- if (success) {
- props.refetch();
- }
- }}
- />
- )}
- {showDetails && (
- setShowDetails(false)}
- className="w-full md:max-w-4xl"
- show
- >
-
-
-
- setShowDetails(false)}
- label={t("close")}
- />
- setShowDiscontinue(true)}
- >
-
- {t("discontinue")}
-
- {
- setShowDetails(false);
- setShowEdit(true);
- }}
- >
-
- {t("edit")}
-
- setShowAdminister(true)}
- >
-
- {t("administer")}
-
-
-
-
- )}
- {showEdit && (
- setShowEdit(false)}
- show={showEdit}
- title={`${t("edit")} ${t(
- prescription.is_prn ? "prn_prescription" : "prescription_medication"
- )}: ${
- prescription.medicine_object?.name ?? prescription.medicine_old
- }`}
- description={
-
-
- {t("edit_caution_note")}
-
- }
- className="w-full max-w-3xl lg:min-w-[600px]"
- >
- {
- setShowEdit(false);
- if (success) {
- props.refetch();
- }
- }}
- />
-
- )}
- setShowDetails(true)}
- >
-
-
-
- {prescription.medicine_object?.name ?? prescription.medicine_old}
-
-
- {prescription.discontinued && (
-
- {t("discontinued")}
-
- )}
-
- {prescription.route && (
-
- {t(prescription.route)}
-
- )}
-
-
-
- {prescription.dosage}
-
- {!prescription.is_prn
- ? t("PRESCRIPTION_FREQUENCY_" + prescription.frequency)
- : prescription.indicator}
-
-
-
- |
-
- |
- {/* Administration Cells */}
- {props.intervals.map(({ start, end }, index) => (
- <>
-
-
- |
-
- {administrations === undefined ? (
-
- ) : (
-
- )}
- |
- >
- ))}
- |
-
- {/* Action Buttons */}
-
- setShowAdminister(true)}
- >
- {t("administer")}
-
- |
-
- );
-};
-
-const AdministrationCellSeperator = ({ date }: { date: Date }) => {
- // Show date if it's 00:00
- if (date.getHours() === 0) {
- return (
-
-
- {formatDateTime(date, "DD/MM")}
-
-
- );
- }
-
- return (
-
-
- {formatDateTime(date, "HH")}
-
-
- );
-};
-
-interface AdministrationCellProps {
- administrations: MedicineAdministrationRecord[];
- interval: DateRange;
- prescription: Prescription;
-}
-
-const AdministrationCell = ({
- administrations,
- interval: { start, end },
- prescription,
-}: AdministrationCellProps) => {
- // Check if cell belongs to an administered prescription
- const administered = administrations
- .filter((administration) =>
- dayjs(administration.administered_date).isBetween(start, end)
- )
- .sort(
- (a, b) =>
- new Date(a.administered_date!).getTime() -
- new Date(b.administered_date!).getTime()
- );
-
- const hasComment = administered.some((obj) => !!obj.notes);
-
- if (administered.length) {
- return (
-
-
-
-
-
- {administered.length > 1 && (
-
- {administered.length}
-
- )}
-
- {hasComment && (
-
- )}
-
- {administered.length === 1 ? (
-
- Administered on{" "}
-
- {formatTime(administered[0].administered_date)}
-
-
- ) : (
-
- {administered.length} administrations
-
- )}
- Click to view details
-
-
-
-
-
-
-
-
- {administered.map((administration) => (
-
-
- {({ open }) => (
- <>
-
-
- Administered on{" "}
-
- {formatTime(administration.administered_date)}
-
-
- {administration.notes && (
-
- )}
-
-
-
-
- Administered by:{" "}
-
- {administration.administered_by?.first_name}{" "}
- {administration.administered_by?.last_name}
-
-
-
- Notes:{" "}
-
- {administration.notes || (
-
- No notes
-
- )}
-
-
-
- >
- )}
-
-
- ))}
-
-
-
-
-
- );
- }
-
- // Check if cell belongs to a discontinued prescription
- if (
- prescription.discontinued &&
- dayjs(end).isAfter(prescription.discontinued_date)
- ) {
- if (!dayjs(prescription.discontinued_date).isBetween(start, end)) return;
-
- return (
-
-
-
-
- Discontinued on{" "}
- {formatDateTime(prescription.discontinued_date)}
-
-
- Reason:{" "}
- {prescription.discontinued_reason ? (
- {prescription.discontinued_reason}
- ) : (
- Not specified
- )}
-
-
-
- );
- }
-
- // Check if cell belongs to after prescription.created_date
- // if (dayjs(start).isAfter(prescription.created_date)) {
- // return ;
- // }
-
- // Check if prescription.created_date is between start and end
- // if (dayjs(prescription.created_date).isBetween(start, end)) {
- // return (
- //
- //
- //
- //
- // Prescribed on{" "}
- // {formatDateTime(prescription.created_date)}
- //
- //
- //
- // );
- // }
-};
-
-function getAdministrationBounds(prescriptions: Prescription[]) {
- // get start by finding earliest of all presciption's created_date
- const start = new Date(
- prescriptions.reduce(
- (earliest, curr) =>
- earliest < curr.created_date ? earliest : curr.created_date,
- prescriptions[0]?.created_date ?? new Date()
- )
- );
-
- // get end by finding latest of all presciption's last_administered_on
- const end = new Date(
- prescriptions
- .filter((prescription) => prescription.last_administered_on)
- .reduce(
- (latest, curr) =>
- curr.last_administered_on && curr.last_administered_on > latest
- ? curr.last_administered_on
- : latest,
- prescriptions[0]?.created_date ?? new Date()
- )
- );
-
- // floor start to 00:00 of the day
- start.setHours(0, 0, 0, 0);
-
- // ceil end to 00:00 of the next day
- end.setHours(0, 0, 0, 0);
- end.setDate(end.getDate() + 1);
-
- return { start, end };
-}
+// import { Fragment, useCallback, useEffect, useMemo, useState } from "react";
+// import { PrescriptionActions } from "../../Redux/actions";
+// import { useDispatch } from "react-redux";
+// import { MedicineAdministrationRecord, Prescription } from "./models";
+// import CareIcon from "../../CAREUI/icons/CareIcon";
+// import ButtonV2, { Cancel, Submit } from "../Common/components/ButtonV2";
+// import SlideOver from "../../CAREUI/interactive/SlideOver";
+// import MedicineAdministration from "./MedicineAdministration";
+// import DiscontinuePrescription from "./DiscontinuePrescription";
+// import AdministerMedicine from "./AdministerMedicine";
+// import DialogModal from "../Common/Dialog";
+// import PrescriptionDetailCard from "./PrescriptionDetailCard";
+// import { useTranslation } from "react-i18next";
+// import SubHeading from "../../CAREUI/display/SubHeading";
+// import dayjs from "../../Utils/dayjs";
+// import { classNames, formatDateTime, formatTime } from "../../Utils/utils";
+// import useRangePagination from "../../Common/hooks/useRangePagination";
+// import EditPrescriptionForm from "./EditPrescriptionForm";
+// import useBreakpoints from "../../Common/hooks/useBreakpoints";
+// import { Disclosure, Popover, Transition } from "@headlessui/react";
+
+// interface DateRange {
+// start: Date;
+// end: Date;
+// }
+
+// interface Props {
+// prn: boolean;
+// prescription_type?: Prescription["prescription_type"];
+// consultation_id: string;
+// readonly?: boolean;
+// }
+
+// interface State {
+// prescriptions: Prescription[];
+// administrationsTimeBounds: DateRange;
+// }
+
+// export default function PrescriptionAdministrationsTable({
+// prn,
+// consultation_id,
+// readonly,
+// }: Props) {
+// const dispatch = useDispatch();
+// const { t } = useTranslation();
+
+// const [state, setState] = useState();
+// const [showDiscontinued, setShowDiscontinued] = useState(false);
+// const [discontinuedCount, setDiscontinuedCount] = useState();
+// const daysPerPage = useBreakpoints({ default: 1, "2xl": 2 });
+// const pagination = useRangePagination({
+// bounds: state?.administrationsTimeBounds ?? {
+// start: new Date(),
+// end: new Date(),
+// },
+// perPage: daysPerPage * 24 * 60 * 60 * 1000,
+// slots: (daysPerPage * 24) / 4, // Grouped by 4 hours
+// defaultEnd: true,
+// });
+// const [showBulkAdminister, setShowBulkAdminister] = useState(false);
+
+// const { list, prescription } = useMemo(
+// () => PrescriptionActions(consultation_id),
+// [consultation_id]
+// );
+
+// const refetch = useCallback(async () => {
+// const filters = {
+// is_prn: prn,
+// prescription_type: "REGULAR",
+// limit: 100,
+// };
+
+// const res = await dispatch(
+// list(showDiscontinued ? filters : { ...filters, discontinued: false })
+// );
+
+// setState({
+// prescriptions: (res.data.results as Prescription[]).sort(
+// (a, b) => +a.discontinued - +b.discontinued
+// ),
+// administrationsTimeBounds: getAdministrationBounds(res.data.results),
+// });
+
+// if (showDiscontinued === false) {
+// const discontinuedRes = await dispatch(
+// list({ ...filters, discontinued: true, limit: 0 })
+// );
+// setDiscontinuedCount(discontinuedRes.data.count);
+// }
+// }, [consultation_id, showDiscontinued, dispatch]);
+
+// useEffect(() => {
+// refetch();
+// }, [refetch]);
+
+// return (
+//
+// {state?.prescriptions && (
+//
+// {
+// setShowBulkAdminister(false);
+// refetch();
+// }}
+// />
+//
+// )}
+
+//
+//
+//
+//
+// {t("edit_prescriptions")}
+//
+// {t("edit")}
+//
+// setShowBulkAdminister(true)}
+// className="w-full"
+// disabled={
+// state === undefined || state.prescriptions.length === 0
+// }
+// >
+//
+//
+// {t("administer_medicines")}
+//
+// {t("administer")}
+//
+// >
+// )
+// }
+// />
+
+//
+// {state?.prescriptions.length === 0 ? (
+//
+//
+//
+// {prn
+// ? "No PRN Prescriptions Prescribed"
+// : "No Prescriptions Prescribed"}
+//
+//
+// ) : (
+//
+//
+//
+//
+//
+// {t("medicine")}
+//
+// Dosage &
+//
+// {!state?.prescriptions[0]?.is_prn
+// ? "Frequency"
+// : "Indicator"}
+//
+//
+//
+// |
+
+//
+//
+//
+//
+// |
+// {state === undefined
+// ? Array.from({ length: 12 }, (_, i) => i).map((i) => (
+//
+//
+// |
+// ))
+// : pagination.slots?.map(({ start }, index) => (
+// <>
+//
+// {formatDateTime(
+// start,
+// start.getHours() === 0 ? "DD/MM" : "HH:mm"
+// )}
+// |
+// |
+// >
+// ))}
+//
+//
+//
+//
+// |
+
+// |
+//
+//
+
+//
+// {state?.prescriptions?.map((item) => (
+//
+// ))}
+//
+//
+// )}
+
+// {showDiscontinued === false && !!discontinuedCount && (
+//
setShowDiscontinued(true)}
+// >
+//
+//
+//
+// Show {discontinuedCount} other discontinued
+// prescription(s)
+//
+//
+//
+// )}
+//
+//
+// );
+// }
+
+// interface PrescriptionRowProps {
+// prescription: Prescription;
+// intervals: DateRange[];
+// actions: ReturnType["prescription"]>;
+// refetch: () => void;
+// }
+
+// const PrescriptionRow = ({ prescription, ...props }: PrescriptionRowProps) => {
+// const dispatch = useDispatch();
+// const { t } = useTranslation();
+// // const [showActions, setShowActions] = useState(false);
+// const [showDetails, setShowDetails] = useState(false);
+// const [showEdit, setShowEdit] = useState(false);
+// const [showAdminister, setShowAdminister] = useState(false);
+// const [showDiscontinue, setShowDiscontinue] = useState(false);
+// const [administrations, setAdministrations] =
+// useState();
+
+// useEffect(() => {
+// setAdministrations(undefined);
+
+// const getAdministrations = async () => {
+// const res = await dispatch(
+// props.actions.listAdministrations({
+// administered_date_after: formatDateTime(
+// props.intervals[0].start,
+// "YYYY-MM-DD"
+// ),
+// administered_date_before: formatDateTime(
+// props.intervals[props.intervals.length - 1].end,
+// "YYYY-MM-DD"
+// ),
+// })
+// );
+
+// setAdministrations(res.data.results);
+// };
+
+// getAdministrations();
+// }, [prescription.id, dispatch, props.intervals]);
+
+// return (
+//
+// {showDiscontinue && (
+// {
+// setShowDiscontinue(false);
+// if (success) {
+// props.refetch();
+// }
+// }}
+// />
+// )}
+// {showAdminister && (
+// {
+// setShowAdminister(false);
+// if (success) {
+// props.refetch();
+// }
+// }}
+// />
+// )}
+// {showDetails && (
+// setShowDetails(false)}
+// className="w-full md:max-w-4xl"
+// show
+// >
+//
+//
+//
+// setShowDetails(false)}
+// label={t("close")}
+// />
+// setShowDiscontinue(true)}
+// >
+//
+// {t("discontinue")}
+//
+// {
+// setShowDetails(false);
+// setShowEdit(true);
+// }}
+// >
+//
+// {t("edit")}
+//
+// setShowAdminister(true)}
+// >
+//
+// {t("administer")}
+//
+//
+//
+//
+// )}
+// {showEdit && (
+// setShowEdit(false)}
+// show={showEdit}
+// title={`${t("edit")} ${t(
+// prescription.is_prn ? "prn_prescription" : "prescription_medication"
+// )}: ${
+// prescription.medicine_object?.name ?? prescription.medicine_old
+// }`}
+// description={
+//
+//
+// {t("edit_caution_note")}
+//
+// }
+// className="w-full max-w-3xl lg:min-w-[600px]"
+// >
+// {
+// setShowEdit(false);
+// if (success) {
+// props.refetch();
+// }
+// }}
+// />
+//
+// )}
+// setShowDetails(true)}
+// >
+//
+//
+//
+// {prescription.medicine_object?.name ?? prescription.medicine_old}
+//
+
+// {prescription.discontinued && (
+//
+// {t("discontinued")}
+//
+// )}
+
+// {prescription.route && (
+//
+// {t(prescription.route)}
+//
+// )}
+//
+
+//
+// {prescription.dosage}
+//
+// {!prescription.is_prn
+// ? t("PRESCRIPTION_FREQUENCY_" + prescription.frequency)
+// : prescription.indicator}
+//
+//
+//
+// |
+
+// |
+// {/* Administration Cells */}
+// {props.intervals.map(({ start, end }, index) => (
+// <>
+//
+//
+// |
+//
+// {administrations === undefined ? (
+//
+// ) : (
+//
+// )}
+// |
+// >
+// ))}
+// |
+
+// {/* Action Buttons */}
+//
+// setShowAdminister(true)}
+// >
+// {t("administer")}
+//
+// |
+//
+// );
+// };
+
+// const AdministrationCellSeperator = ({ date }: { date: Date }) => {
+// // Show date if it's 00:00
+// if (date.getHours() === 0) {
+// return (
+//
+//
+// {formatDateTime(date, "DD/MM")}
+//
+//
+// );
+// }
+
+// return (
+//
+//
+// {formatDateTime(date, "HH")}
+//
+//
+// );
+// };
+
+// interface AdministrationCellProps {
+// administrations: MedicineAdministrationRecord[];
+// interval: DateRange;
+// prescription: Prescription;
+// }
+
+// const AdministrationCell = ({
+// administrations,
+// interval: { start, end },
+// prescription,
+// }: AdministrationCellProps) => {
+// // Check if cell belongs to an administered prescription
+// const administered = administrations
+// .filter((administration) =>
+// dayjs(administration.administered_date).isBetween(start, end)
+// )
+// .sort(
+// (a, b) =>
+// new Date(a.administered_date!).getTime() -
+// new Date(b.administered_date!).getTime()
+// );
+
+// const hasComment = administered.some((obj) => !!obj.notes);
+
+// if (administered.length) {
+// return (
+//
+//
+//
+//
+//
+// {administered.length > 1 && (
+//
+// {administered.length}
+//
+// )}
+//
+// {hasComment && (
+//
+// )}
+//
+// {administered.length === 1 ? (
+//
+// Administered on{" "}
+//
+// {formatTime(administered[0].administered_date)}
+//
+//
+// ) : (
+//
+// {administered.length} administrations
+//
+// )}
+// Click to view details
+//
+//
+//
+
+//
+//
+//
+//
+// {administered.map((administration) => (
+//
+//
+// {({ open }) => (
+// <>
+//
+//
+// Administered on{" "}
+//
+// {formatTime(administration.administered_date)}
+//
+//
+// {administration.notes && (
+//
+// )}
+//
+//
+//
+//
+// Administered by:{" "}
+//
+// {administration.administered_by?.first_name}{" "}
+// {administration.administered_by?.last_name}
+//
+//
+//
+// Notes:{" "}
+//
+// {administration.notes || (
+//
+// No notes
+//
+// )}
+//
+//
+//
+// >
+// )}
+//
+//
+// ))}
+//
+//
+//
+//
+//
+// );
+// }
+
+// // Check if cell belongs to a discontinued prescription
+// if (
+// prescription.discontinued &&
+// dayjs(end).isAfter(prescription.discontinued_date)
+// ) {
+// if (!dayjs(prescription.discontinued_date).isBetween(start, end)) return;
+
+// return (
+//
+//
+//
+//
+// Discontinued on{" "}
+// {formatDateTime(prescription.discontinued_date)}
+//
+//
+// Reason:{" "}
+// {prescription.discontinued_reason ? (
+// {prescription.discontinued_reason}
+// ) : (
+// Not specified
+// )}
+//
+//
+//
+// );
+// }
+
+// // Check if cell belongs to after prescription.created_date
+// // if (dayjs(start).isAfter(prescription.created_date)) {
+// // return ;
+// // }
+
+// // Check if prescription.created_date is between start and end
+// // if (dayjs(prescription.created_date).isBetween(start, end)) {
+// // return (
+// //
+// //
+// //
+// //
+// // Prescribed on{" "}
+// // {formatDateTime(prescription.created_date)}
+// //
+// //
+// //
+// // );
+// // }
+// };
+
+// function getAdministrationBounds(prescriptions: Prescription[]) {
+// // get start by finding earliest of all presciption's created_date
+// const start = new Date(
+// prescriptions.reduce(
+// (earliest, curr) =>
+// earliest < curr.created_date ? earliest : curr.created_date,
+// prescriptions[0]?.created_date ?? new Date()
+// )
+// );
+
+// // get end by finding latest of all presciption's last_administered_on
+// const end = new Date(
+// prescriptions
+// .filter((prescription) => prescription.last_administered_on)
+// .reduce(
+// (latest, curr) =>
+// curr.last_administered_on && curr.last_administered_on > latest
+// ? curr.last_administered_on
+// : latest,
+// prescriptions[0]?.created_date ?? new Date()
+// )
+// );
+
+// // floor start to 00:00 of the day
+// start.setHours(0, 0, 0, 0);
+
+// // ceil end to 00:00 of the next day
+// end.setHours(0, 0, 0, 0);
+// end.setDate(end.getDate() + 1);
+
+// return { start, end };
+// }