Skip to content

Commit

Permalink
cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
rithviknishad committed Oct 11, 2023
1 parent 61c8112 commit b7e8df7
Show file tree
Hide file tree
Showing 7 changed files with 1,464 additions and 776 deletions.
Original file line number Diff line number Diff line change
@@ -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 (
<div className="my-4 flex flex-col gap-16">
{/* eslint-disable-next-line i18next/no-literal-string */}
<PageTitle title="Medicines" />
<PrescriptionAdministrationsTable
consultation_id={props.consultationId}
<MedicineAdministrationSheet
readonly={!!props.consultationData.discharge_date}
prn={false}
is_prn={false}
/>
<PrescriptionAdministrationsTable
consultation_id={props.consultationId}
prn={true}
<MedicineAdministrationSheet
is_prn={true}
readonly={!!props.consultationData.discharge_date}
/>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -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 (
<Popover className="relative">
<Popover.Button className="scale-100 transition-transform duration-200 ease-in-out hover:scale-110">
<div className="tooltip">
<div className="relative mx-auto max-w-min">
<CareIcon
icon="l-check-circle"
className="text-xl text-primary-500"
/>
{administered.length > 1 && (
<span className="absolute -bottom-1 -right-2 flex h-4 w-4 items-center justify-center rounded-full bg-primary-500 text-xs font-semibold text-white">
{administered.length}
</span>
)}
</div>
{hasComment && (
<CareIcon icon="l-notes" className="text-xl text-primary-500" />
)}
<span className="tooltip-text tooltip-top -translate-x-1/2 text-xs">
{administered.length === 1 ? (
<p>
Administered on{" "}
<strong>
{formatTime(administered[0].administered_date)}
</strong>
</p>
) : (
<p>
<strong>{administered.length}</strong> administrations
</p>
)}
<p>Click to view details</p>
</span>
</div>
</Popover.Button>

<Transition
as={Fragment}
enter="transition ease-out duration-200"
enterFrom="opacity-0 translate-y-1"
enterTo="opacity-100 translate-y-0"
leave="transition ease-in duration-150"
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 translate-y-1"
>
<Popover.Panel className="absolute left-1/2 z-10 mt-3 -translate-x-1/2 px-4 sm:px-0">
<div className="overflow-hidden rounded-lg shadow-lg ring-1 ring-black/5">
<div className="relative flex flex-col gap-2 bg-white p-4">
{administered.map((administration) => (
<div>
<Disclosure defaultOpen={administered.length === 1}>
{({ open }) => (
<>
<Disclosure.Button
className={classNames(
"flex w-full justify-between border-gray-400 px-4 py-2 text-left text-sm focus:outline-none focus-visible:ring focus-visible:ring-primary-500/75",
open
? "rounded-t-lg border-l border-r border-t bg-gray-200"
: "rounded-lg border hover:bg-gray-200"
)}
>
<span className="text-gray-700">
Administered on{" "}
<strong className="font-semibold text-gray-900">
{formatTime(administration.administered_date)}
</strong>
</span>
{administration.notes && (
<CareIcon
icon="l-notes"
className="ml-2 text-lg"
/>
)}
<CareIcon
icon="l-angle-down"
className={classNames(
"ml-8 text-base",
open ? "rotate-180" : "rotate-0"
)}
/>
</Disclosure.Button>
<Disclosure.Panel className="flex flex-col items-start rounded-b-lg border border-gray-400 bg-gray-200 p-2 px-4 text-sm text-gray-700 shadow">
<div>
Administered by:{" "}
<span className="font-medium text-gray-900">
{administration.administered_by?.first_name}{" "}
{administration.administered_by?.last_name}
</span>
</div>
<div>
Notes:{" "}
<span className="font-medium text-gray-800">
{administration.notes || (
<span className="italic text-gray-700">
No notes
</span>
)}
</span>
</div>
</Disclosure.Panel>
</>
)}
</Disclosure>
</div>
))}
</div>
</div>
</Popover.Panel>
</Transition>
</Popover>
);
}

// 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 (
<div className="tooltip">
<CareIcon
icon="l-ban"
className={classNames(
"text-xl",
dayjs(prescription.discontinued_date).isBetween(start, end)
? "text-danger-700"
: "text-gray-400"
)}
/>
<span className="tooltip-text tooltip-top -translate-x-1/2 text-xs">
<p>
Discontinued on{" "}
<strong>{formatDateTime(prescription.discontinued_date)}</strong>
</p>
<p>
Reason:{" "}
{prescription.discontinued_reason ? (
<strong>{prescription.discontinued_reason}</strong>
) : (
<span className="italic">Not specified</span>
)}
</p>
</span>
</div>
);
}
}
Original file line number Diff line number Diff line change
@@ -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 (
<div className="mx-auto flex h-[58px] flex-col items-center justify-center bg-gray-300 text-center text-xs font-bold text-gray-600 transition-all duration-200 ease-in-out group-hover:bg-primary-500 group-hover:text-white">
<span className="-rotate-90 uppercase duration-500 ease-in-out">
<p> {formatDateTime(date, "DD/MM")}</p>
</span>
</div>
);
}

return (
<div className="mx-auto flex h-[58px] flex-col items-center justify-center text-center text-xs font-bold text-gray-500 transition-all duration-200 ease-in-out">
<span className="font-bold duration-500 ease-in-out">
<p>{formatDateTime(date, "HH")}</p>
</span>
</div>
);
}
Original file line number Diff line number Diff line change
@@ -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<typeof useRangePagination>;
onRefetch: () => void;
}

export default function MedicineAdministrationTable({
pagination,
prescriptions,
onRefetch,
}: Props) {
const { t } = useTranslation();

return (
<table className="w-full whitespace-nowrap rounded">
<thead className="sticky top-0 z-10 bg-white text-xs font-medium text-black">
<tr>
<th className="sticky left-0 z-10 bg-white py-3 pl-4 text-left">
<div className="flex justify-between gap-2">
<span className="text-sm">{t("medicine")}</span>
<span className="hidden px-2 text-center text-xs leading-none lg:block">
<p>Dosage &</p>
<p>{!prescriptions[0]?.is_prn ? "Frequency" : "Indicator"}</p>
</span>
</div>
</th>

<th>
<ButtonV2
size="small"
circle
ghost
border
className="mx-2 px-1"
variant="secondary"
disabled={!pagination.hasPrevious}
onClick={pagination.previous}
tooltip="Previous 24 hours"
tooltipClassName="tooltip-bottom -translate-x-1/2 text-xs"
>
<CareIcon icon="l-angle-left-b" className="text-base" />
</ButtonV2>
</th>
{pagination.slots?.map(({ start }, index) => (
<>
<th
key={`administration-interval-${index}`}
className={classNames(
"leading-none",
start.getHours() === 0
? "text-base font-bold text-gray-800"
: "text-sm font-semibold text-gray-700"
)}
>
{formatDateTime(
start,
start.getHours() === 0 ? "DD/MM" : "HH:mm"
)}
</th>
<th key={`administration-slot-${index}`} className="flex w-6" />
</>
))}
<th>
<ButtonV2
size="small"
circle
ghost
border
className="mx-2 px-1"
variant="secondary"
disabled={!pagination.hasNext}
onClick={pagination.next}
tooltip="Next 24 hours"
tooltipClassName="tooltip-bottom -translate-x-1/2 text-xs"
>
<CareIcon icon="l-angle-right-b" className="text-base" />
</ButtonV2>
</th>

<th className="py-3 pr-2 text-right"></th>
</tr>
</thead>

<tbody className="divide-y divide-gray-200">
{prescriptions.map((obj) => (
<MedicineAdministrationTableRow
key={obj.id}
prescription={obj}
intervals={pagination.slots!}
refetch={onRefetch}
/>
))}
</tbody>
</table>
);
}
Loading

0 comments on commit b7e8df7

Please sign in to comment.