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

Rebuild questionnaireForm updateHandler #10115

Merged
merged 11 commits into from
Jan 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions public/locale/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,7 @@
"bed_type__500": "Others",
"before": "before",
"beta": "beta",
"biologic": "Biologic",
"bladder": "Bladder",
"blood_group": "Blood Group",
"blood_group_is_required": "Blood group is required",
Expand Down Expand Up @@ -989,6 +990,7 @@
"enter_year_of_birth_to_verify": "Enter year of birth to verify",
"entered_in_error": "Entered in Error",
"entered_in_error_warning": "This action cannot be undone. The appointment will be marked as entered in error and removed from the system.",
"environment": "Environment",
"error_404": "Error 404",
"error_deleting_shifting": "Error while deleting Shifting record",
"error_fetching_facility_data": "Error while fetching facility data",
Expand Down Expand Up @@ -1078,6 +1080,7 @@
"filter_by_date": "Filter by Date",
"filters": "Filters",
"first_name": "First Name",
"food": "Food",
"footer_body": "Open Healthcare Network is an open-source public utility designed by a multi-disciplinary team of innovators and volunteers. Open Healthcare Network CARE is a Digital Public Good recognised by the United Nations.",
"forget_password": "Forgot password?",
"forget_password_instruction": "Enter your username, and if it exists, we will send you a link to reset your password.",
Expand Down Expand Up @@ -2109,6 +2112,7 @@
"type_to_search": "Type to search",
"type_your_comment": "Type your comment",
"type_your_reason_here": "Type your reason here",
"unable_to_assess": "Unable to Assess",
"unable_to_get_current_position": "Unable to get current position.",
"unable_to_get_location: ": "Unable to get location: ",
"unassign": "Unassign",
Expand Down Expand Up @@ -2260,6 +2264,7 @@
"video_conference_link": "Video Conference Link",
"view": "View",
"view_abdm_records": "View ABDM Records",
"view_all": "view all",
"view_all_details": "View All Details",
"view_and_manage_patient_encounters": "View and manage patient encounters",
"view_asset": "View Assets",
Expand Down
5 changes: 3 additions & 2 deletions src/components/Common/ComboboxQuantityInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export function ComboboxQuantityInput({
const showDropdown = /^\d+$/.test(inputValue);

const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
if (disabled) return;
const value = e.target.value;
if (value === "" || /^\d+$/.test(value)) {
setInputValue(value);
Expand All @@ -65,7 +66,7 @@ export function ComboboxQuantityInput({
};

const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (!showDropdown) return;
if (disabled || !showDropdown) return;

if (e.key === "ArrowDown") {
e.preventDefault();
Expand Down Expand Up @@ -102,7 +103,7 @@ export function ComboboxQuantityInput({

return (
<div className="relative flex w-full lg:max-w-[200px] flex-col gap-1">
<Popover open={open && showDropdown} onOpenChange={setOpen}>
<Popover open={!disabled && open && showDropdown} onOpenChange={setOpen}>
<PopoverTrigger asChild>
<div className="relative">
<Input
Expand Down
197 changes: 113 additions & 84 deletions src/components/Patient/MedicationStatementList.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { useQuery } from "@tanstack/react-query";
import { useState } from "react";
import { useTranslation } from "react-i18next";

import { cn } from "@/lib/utils";

import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Skeleton } from "@/components/ui/skeleton";
import {
Expand All @@ -28,10 +28,84 @@ interface MedicationStatementListProps {
patientId: string;
}

interface MedicationRowProps {
statement: any;
isEnteredInError?: boolean;
index: number;
}

function MedicationRow({
statement,
isEnteredInError,
index,
}: MedicationRowProps) {
return (
<TableRow
key={index}
className={isEnteredInError ? "opacity-50 bg-gray-50/50" : undefined}
>
<TableCell className="font-medium">
<Tooltip>
<TooltipTrigger asChild className="max-w-60 truncate">
<p>{statement.medication.display ?? statement.medication.code}</p>
</TooltipTrigger>
<TooltipContent>
<p>{statement.medication.display ?? statement.medication.code}</p>
</TooltipContent>
</Tooltip>
</TableCell>
<TableCell>
<Tooltip>
<TooltipTrigger asChild className="max-w-36 truncate">
<p>{statement.dosage_text}</p>
</TooltipTrigger>
<TooltipContent>
<p>{statement.dosage_text}</p>
</TooltipContent>
</Tooltip>
</TableCell>
<TableCell>
<Badge
variant={isEnteredInError ? "destructive" : "outline"}
className="whitespace-nowrap capitalize"
>
{statement.status}
</Badge>
</TableCell>
<TableCell className="whitespace-nowrap">
{[statement.effective_period?.start, statement.effective_period?.end]
.map((date) => formatDateTime(date))
.join(" - ")}
</TableCell>
<TableCell>
<Tooltip>
<TooltipTrigger asChild className="max-w-60 truncate">
<p>{statement.reason}</p>
</TooltipTrigger>
<TooltipContent>
<p>{statement.reason}</p>
</TooltipContent>
</Tooltip>
</TableCell>
<TableCell>
<Tooltip>
<TooltipTrigger asChild className="max-w-60 truncate">
<p>{statement.note}</p>
</TooltipTrigger>
<TooltipContent>
<p>{statement.note}</p>
</TooltipContent>
</Tooltip>
</TableCell>
</TableRow>
);
}

export function MedicationStatementList({
patientId,
}: MedicationStatementListProps) {
const { t } = useTranslation();
const [showEnteredInError, setShowEnteredInError] = useState(false);

const { data: medications, isLoading } = useQuery({
queryKey: ["medication_statement", patientId],
Expand All @@ -53,7 +127,16 @@ export function MedicationStatementList({
);
}

if (!medications?.results?.length) {
const filteredMedications = medications?.results?.filter(
(medication) =>
showEnteredInError || medication.status !== "entered_in_error",
);

const hasEnteredInErrorRecords = medications?.results?.some(
(medication) => medication.status === "entered_in_error",
);

if (!filteredMedications?.length) {
return (
<Card>
<CardHeader>
Expand All @@ -66,22 +149,11 @@ export function MedicationStatementList({
);
}

const getStatusBadgeStyle = (status: string | undefined) => {
switch (status?.toLowerCase()) {
case "active":
return "bg-green-100 text-green-800 border-green-200";
case "on_hold":
return "bg-gray-100 text-gray-800 border-blue-200";
default:
return "bg-gray-100 text-gray-800 border-gray-200";
}
};

return (
<Card className="p-0">
<CardHeader className="px-4 py-0 pt-4">
<CardTitle>
{t("ongoing_medications")} ({medications.count})
{t("ongoing_medications")} ({filteredMedications.length})
</CardTitle>
</CardHeader>
<CardContent className="p-2">
Expand All @@ -97,77 +169,34 @@ export function MedicationStatementList({
</TableRow>
</TableHeader>
<TableBody>
{medications.results.map((statement, index) => (
<TableRow key={index}>
<TableCell className="font-medium">
<Tooltip>
<TooltipTrigger asChild className="max-w-60 truncate">
<p>
{statement.medication.display ??
statement.medication.code}
</p>
</TooltipTrigger>
<TooltipContent>
<p>
{statement.medication.display ??
statement.medication.code}
</p>
</TooltipContent>
</Tooltip>
</TableCell>
<TableCell>
<Tooltip>
<TooltipTrigger asChild className="max-w-36 truncate">
<p>{statement.dosage_text}</p>
</TooltipTrigger>
<TooltipContent>
<p>{statement.dosage_text}</p>
</TooltipContent>
</Tooltip>
</TableCell>
<TableCell>
<Badge
variant="outline"
className={cn(
"whitespace-nowrap capitalize",
getStatusBadgeStyle(statement.status),
)}
>
{statement.status}
</Badge>
</TableCell>
<TableCell className="whitespace-nowrap">
{[
statement.effective_period?.start,
statement.effective_period?.end,
]
.map((date) => formatDateTime(date))
.join(" - ")}
</TableCell>
<TableCell>
<Tooltip>
<TooltipTrigger asChild className="max-w-60 truncate">
<p>{statement.reason ?? "-"}</p>
</TooltipTrigger>
<TooltipContent>
<p>{statement.reason ?? "Not Specified"}</p>
</TooltipContent>
</Tooltip>
</TableCell>
<TableCell>
<Tooltip>
<TooltipTrigger asChild className="max-w-60 truncate">
<p>{statement.note ?? "-"}</p>
</TooltipTrigger>
<TooltipContent>
<p>{statement.note ?? "Not Specified"}</p>
</TooltipContent>
</Tooltip>
</TableCell>
</TableRow>
))}
{filteredMedications.map((statement, index) => {
const isEnteredInError = statement.status === "entered_in_error";

return (
<>
<MedicationRow
key={statement.id}
statement={statement}
isEnteredInError={isEnteredInError}
index={index}
/>
</>
);
})}
</TableBody>
</Table>
{hasEnteredInErrorRecords && !showEnteredInError && (
<div className="flex justify-start">
<Button
variant="ghost"
size="xs"
onClick={() => setShowEnteredInError(true)}
className="text-xs underline text-gray-500"
>
{t("view_all")}
</Button>
</div>
)}
</CardContent>
</Card>
);
Expand Down
Loading
Loading