Skip to content

Commit

Permalink
Clean up medication request type
Browse files Browse the repository at this point in the history
  • Loading branch information
bodhish committed Jan 14, 2025
1 parent 18efb6e commit 0230f5c
Show file tree
Hide file tree
Showing 8 changed files with 767 additions and 599 deletions.
198 changes: 0 additions & 198 deletions src/common/constants.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { IconName } from "@/CAREUI/icons/CareIcon";

import { MedicationRequest } from "@/types/emr/medicationRequest";

export const RESULTS_PER_PAGE_LIMIT = 14;

/**
Expand Down Expand Up @@ -911,199 +909,3 @@ export const HEADER_CONTENT_TYPES = {
} as const;

export const ADMIN_USER_TYPES = ["DistrictAdmin", "StateAdmin"] as const;

export const MEDICATION_REQUEST_TIMING_OPTIONS = {
BID: {
display: "BID (1-0-1)",
timing: {
repeat: { frequency: 2, period: 1, period_unit: "d" },
code: {
code: "BID",
display: "Two times a day",
system: "http://terminology.hl7.org/CodeSystem/v3-GTSAbbreviation",
},
},
},
TID: {
display: "TID (1-1-1)",
timing: {
repeat: { frequency: 3, period: 1, period_unit: "d" },
code: {
code: "TID",
display: "Three times a day",
system: "http://terminology.hl7.org/CodeSystem/v3-GTSAbbreviation",
},
},
},
QID: {
display: "QID (1-1-1-1)",
timing: {
repeat: { frequency: 4, period: 1, period_unit: "d" },
code: {
code: "QID",
display: "Four times a day",
system: "http://terminology.hl7.org/CodeSystem/v3-GTSAbbreviation",
},
},
},
AM: {
display: "AM (1-0-0)",
timing: {
repeat: { frequency: 1, period: 1, period_unit: "d" },
code: {
code: "AM",
display: "Every morning",
system: "http://terminology.hl7.org/CodeSystem/v3-GTSAbbreviation",
},
},
},
PM: {
display: "PM (0-0-1)",
timing: {
repeat: { frequency: 1, period: 1, period_unit: "d" },
code: {
code: "PM",
display: "Every afternoon",
system: "http://terminology.hl7.org/CodeSystem/v3-GTSAbbreviation",
},
},
},
QD: {
display: "QD (Once a day)",
timing: {
repeat: { frequency: 1, period: 1, period_unit: "d" },
code: {
code: "QD",
display: "Once a day",
system: "http://terminology.hl7.org/CodeSystem/v3-GTSAbbreviation",
},
},
},
QOD: {
display: "QOD (Alternate days)",
timing: {
repeat: { frequency: 1, period: 2, period_unit: "d" },
code: {
code: "QOD",
display: "Alternate days",
system: "http://terminology.hl7.org/CodeSystem/v3-GTSAbbreviation",
},
},
},
Q1H: {
display: "Q1H (Every 1 hour)",
timing: {
repeat: { frequency: 1, period: 1, period_unit: "h" },
code: {
code: "Q1H",
display: "Every 1 hour",
system: "http://terminology.hl7.org/CodeSystem/v3-GTSAbbreviation",
},
},
},
Q2H: {
display: "Q2H (Every 2 hours)",
timing: {
repeat: { frequency: 1, period: 2, period_unit: "h" },
code: {
code: "Q2H",
display: "Every 2 hours",
system: "http://terminology.hl7.org/CodeSystem/v3-GTSAbbreviation",
},
},
},
Q3H: {
display: "Q3H (Every 3 hours)",
timing: {
repeat: { frequency: 1, period: 3, period_unit: "h" },
code: {
code: "Q3H",
display: "Every 3 hours",
system: "http://terminology.hl7.org/CodeSystem/v3-GTSAbbreviation",
},
},
},
Q4H: {
display: "Q4H (Every 4 hours)",
timing: {
repeat: { frequency: 1, period: 4, period_unit: "h" },
code: {
code: "Q4H",
display: "Every 4 hours",
system: "http://terminology.hl7.org/CodeSystem/v3-GTSAbbreviation",
},
},
},
Q6H: {
display: "Q6H (Every 6 hours)",
timing: {
repeat: { frequency: 1, period: 6, period_unit: "h" },
code: {
code: "Q6H",
display: "Every 6 hours",
system: "http://terminology.hl7.org/CodeSystem/v3-GTSAbbreviation",
},
},
},
Q8H: {
display: "Q8H (Every 8 hours)",
timing: {
repeat: { frequency: 1, period: 8, period_unit: "h" },
code: {
code: "Q8H",
display: "Every 8 hours",
system: "http://terminology.hl7.org/CodeSystem/v3-GTSAbbreviation",
},
},
},
BED: {
display: "BED (0-0-1)",
timing: {
repeat: { frequency: 1, period: 1, period_unit: "d" },
code: {
code: "BED",
display: "Bedtime",
system: "http://terminology.hl7.org/CodeSystem/v3-GTSAbbreviation",
},
},
},
WK: {
display: "WK (Weekly)",
timing: {
repeat: { frequency: 1, period: 1, period_unit: "wk" },
code: {
code: "WK",
display: "Weekly",
system: "http://terminology.hl7.org/CodeSystem/v3-GTSAbbreviation",
},
},
},
MO: {
display: "MO (Monthly)",
timing: {
repeat: { frequency: 1, period: 1, period_unit: "mo" },
code: {
code: "MO",
display: "Monthly",
system: "http://terminology.hl7.org/CodeSystem/v3-GTSAbbreviation",
},
},
},
STAT: {
display: "STAT (Immediately)",
timing: {
repeat: { frequency: 1, period: 1, period_unit: "s" },
code: {
code: "STAT",
display: "Immediately",
system: "http://terminology.hl7.org/CodeSystem/v3-GTSAbbreviation",
},
},
},
} as const satisfies Record<
string,
{
display: string;
timing: MedicationRequest["dosage_instruction"][0]["timing"];
}
>;
75 changes: 34 additions & 41 deletions src/components/Common/ComboboxQuantityInput.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"use client";

import { t } from "i18next";
import { Check } from "lucide-react";
import * as React from "react";

Expand All @@ -20,35 +19,31 @@ import {
PopoverTrigger,
} from "@/components/ui/popover";

interface Props<TUnit extends string> {
quantity?: QuantityValue<TUnit> | null;
onChange: (quantity: QuantityValue<TUnit>) => void;
units: readonly TUnit[];
import {
DOSAGE_UNITS_CODES,
DosageQuantity,
} from "@/types/emr/medicationRequest";

interface Props {
quantity?: DosageQuantity;
onChange: (quantity: DosageQuantity) => void;
disabled?: boolean;
placeholder?: string;
autoFocus?: boolean;
}

interface QuantityValue<TUnit extends string> {
value?: number;
unit?: TUnit;
}

export function ComboboxQuantityInput<TUnit extends string>({
quantity = { value: undefined, unit: undefined },
export function ComboboxQuantityInput({
quantity,
onChange,
units,
disabled,
placeholder = "Enter a number...",
autoFocus,
}: Props<TUnit>) {
}: Props) {
const [open, setOpen] = React.useState(false);
const [inputValue, setInputValue] = React.useState(
quantity?.value?.toString() || "",
);
const [selectedUnit, setSelectedUnit] = React.useState<TUnit | undefined>(
quantity?.unit,
quantity?.value.toString() || "",
);
const [selectedUnit, setSelectedUnit] = React.useState(quantity?.unit);
const inputRef = React.useRef<HTMLInputElement>(null);
const [activeIndex, setActiveIndex] = React.useState<number>(-1);

Expand All @@ -59,12 +54,13 @@ export function ComboboxQuantityInput<TUnit extends string>({
if (value === "" || /^\d+$/.test(value)) {
setInputValue(value);
setOpen(true);
setSelectedUnit(undefined);
setActiveIndex(0);
onChange({
value: value ? parseInt(value, 10) : undefined,
unit: selectedUnit,
});
if (value && selectedUnit) {
onChange({
value: parseInt(value, 10),
unit: selectedUnit,
});
}
}
};

Expand All @@ -75,15 +71,19 @@ export function ComboboxQuantityInput<TUnit extends string>({
e.preventDefault();
setOpen(true);
setActiveIndex((prev) =>
prev === -1 ? 0 : prev < units.length - 1 ? prev + 1 : prev,
prev === -1
? 0
: prev < DOSAGE_UNITS_CODES.length - 1
? prev + 1
: prev,
);
} else if (e.key === "ArrowUp") {
e.preventDefault();
setActiveIndex((prev) => (prev > 0 ? prev - 1 : prev));
} else if (e.key === "Enter") {
e.preventDefault();
if (activeIndex >= 0 && activeIndex < units.length) {
const unit = units[activeIndex];
if (activeIndex >= 0 && activeIndex < DOSAGE_UNITS_CODES.length) {
const unit = DOSAGE_UNITS_CODES[activeIndex];
setSelectedUnit(unit);
setOpen(false);
setActiveIndex(-1);
Expand All @@ -92,15 +92,6 @@ export function ComboboxQuantityInput<TUnit extends string>({
}
};

React.useEffect(() => {
if (quantity?.value !== undefined) {
setInputValue(quantity.value.toString());
}
if (quantity?.unit !== undefined) {
setSelectedUnit(quantity.unit);
}
}, [quantity]);

return (
<div className="relative flex w-full lg:max-w-[200px] flex-col gap-1">
<Popover open={open && showDropdown} onOpenChange={setOpen}>
Expand All @@ -121,7 +112,7 @@ export function ComboboxQuantityInput<TUnit extends string>({
/>
{selectedUnit && (
<div className="absolute right-1.5 top-1/2 -translate-y-1/2 text-sm text-muted-foreground">
{t(`unit_${selectedUnit}`)}
{selectedUnit.display}
</div>
)}
</div>
Expand All @@ -138,10 +129,10 @@ export function ComboboxQuantityInput<TUnit extends string>({
<CommandList>
<CommandEmpty>No results found.</CommandEmpty>
<CommandGroup>
{units.map((unit, index) => (
{DOSAGE_UNITS_CODES.map((unit, index) => (
<CommandItem
key={unit}
value={unit}
key={unit.code}
value={unit.code}
onSelect={() => {
setSelectedUnit(unit);
setOpen(false);
Expand All @@ -155,12 +146,14 @@ export function ComboboxQuantityInput<TUnit extends string>({
)}
>
<div>
{inputValue} {t(`unit_${unit}`)}
{inputValue} {unit.display}
</div>
<Check
className={cn(
"ml-auto h-4 w-4",
selectedUnit === unit ? "opacity-100" : "opacity-0",
selectedUnit?.code === unit.code
? "opacity-100"
: "opacity-0",
)}
/>
</CommandItem>
Expand Down
5 changes: 3 additions & 2 deletions src/components/Medicine/MedicineAdministrationSheet/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,8 @@ const PrescriptionEntry = ({
<div className="mt-1.5 flex flex-wrap items-baseline gap-x-3 gap-y-1 text-xs">
{instruction.dose_and_rate && (
<span className="font-medium">
{instruction.dose_and_rate.type === "calculated" ? (
{/* TODO: Rebuild Medicine Administration Sheet */}
{/* {instruction.dose_and_rate.type === "calculated" ? (
<span>
{instruction.dose_and_rate.dose_range?.low.value}{" "}
{instruction.dose_and_rate.dose_range?.low.unit} →{" "}
Expand All @@ -296,7 +297,7 @@ const PrescriptionEntry = ({
{instruction.dose_and_rate.dose_quantity?.value}{" "}
{instruction.dose_and_rate.dose_quantity?.unit}
</span>
)}
)} */}
</span>
)}
{instruction.route && (
Expand Down
Loading

0 comments on commit 0230f5c

Please sign in to comment.