Skip to content

Commit

Permalink
Encounter Info Card (#10792)
Browse files Browse the repository at this point in the history
  • Loading branch information
amjithtitus09 authored Feb 27, 2025
1 parent cdb10f9 commit 9b82db3
Show file tree
Hide file tree
Showing 2 changed files with 181 additions and 123 deletions.
80 changes: 59 additions & 21 deletions src/components/Patient/EncounterQuestionnaire.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
import { useQuery } from "@tanstack/react-query";
import { t } from "i18next";
import { navigate } from "raviger";

import { Card, CardContent } from "@/components/ui/card";

import Page from "@/components/Common/Page";
import PatientInfoCard from "@/components/Patient/PatientInfoCard";
import { QuestionnaireForm } from "@/components/Questionnaire/QuestionnaireForm";

import useAppHistory from "@/hooks/useAppHistory";

import routes from "@/Utils/request/api";
import query from "@/Utils/request/query";
import { formatDateTime } from "@/Utils/utils";

interface Props {
facilityId: string;
patientId: string;
Expand All @@ -24,29 +30,61 @@ export default function EncounterQuestionnaire({
subjectType,
}: Props) {
const { goBack } = useAppHistory();
const { data: encounter } = useQuery({
queryKey: ["encounter", encounterId],
queryFn: query(routes.encounter.get, {
pathParams: { id: encounterId ?? "" },
queryParams: { facility: facilityId },
}),
enabled: !!encounterId,
});
return (
<Page title={t("questionnaire")}>
<Card className="mt-2">
<CardContent className="lg:p-4 p-0">
<QuestionnaireForm
facilityId={facilityId}
patientId={patientId}
subjectType={subjectType}
encounterId={encounterId}
questionnaireSlug={questionnaireSlug}
onSubmit={() => {
if (encounterId) {
navigate(
`/facility/${facilityId}/patient/${patientId}/encounter/${encounterId}/updates`,
);
} else {
navigate(`/patient/${patientId}/updates`);
}
}}
onCancel={() => goBack()}
/>
</CardContent>
</Card>
<div className="flex flex-col space-y-4 mt-4">
{encounter && (
<div className="size-full rounded-lg border bg-white text-black shadow">
<PatientInfoCard
patient={encounter.patient}
encounter={encounter}
fetchPatientData={() => {}}
disableButtons={true}
/>

<div className="flex flex-col justify-between gap-2 px-4 py-1 md:flex-row">
<div className="font-base flex flex-col text-xs leading-relaxed text-secondary-700 md:text-right">
<div className="flex items-center">
<span className="text-secondary-900">
{t("last_modified")}:{" "}
</span>
&nbsp;
{formatDateTime(encounter.modified_date)}
</div>
</div>
</div>
</div>
)}
<Card className="mt-2">
<CardContent className="lg:p-4 p-0">
<QuestionnaireForm
facilityId={facilityId}
patientId={patientId}
subjectType={subjectType}
encounterId={encounterId}
questionnaireSlug={questionnaireSlug}
onSubmit={() => {
if (encounterId) {
navigate(
`/facility/${facilityId}/patient/${patientId}/encounter/${encounterId}/updates`,
);
} else {
navigate(`/patient/${patientId}/updates`);
}
}}
onCancel={() => goBack()}
/>
</CardContent>
</Card>
</div>
</Page>
);
}
224 changes: 122 additions & 102 deletions src/components/Patient/PatientInfoCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,24 +45,25 @@ import {
import { Avatar } from "@/components/Common/Avatar";
import { LocationHistorySheet } from "@/components/Location/LocationHistorySheet";
import { LocationTree } from "@/components/Location/LocationTree";
import LinkDepartmentsSheet from "@/components/Patient/LinkDepartmentsSheet";

import { PLUGIN_Component } from "@/PluginEngine";
import routes from "@/Utils/request/api";
import mutate from "@/Utils/request/mutate";
import { formatDateTime, formatPatientAge } from "@/Utils/utils";
import { Encounter, completedEncounterStatus } from "@/types/emr/encounter";
import { Patient } from "@/types/emr/newPatient";

import LinkDepartmentsSheet from "./LinkDepartmentsSheet";
import { FacilityOrganization } from "@/types/facilityOrganization/facilityOrganization";

export interface PatientInfoCardProps {
patient: Patient;
encounter: Encounter;
fetchPatientData?: (state: { aborted: boolean }) => void;
disableButtons?: boolean;
}

export default function PatientInfoCard(props: PatientInfoCardProps) {
const { patient, encounter } = props;
const { patient, encounter, disableButtons = false } = props;
const { t } = useTranslation();
const queryClient = useQueryClient();

Expand Down Expand Up @@ -331,17 +332,9 @@ export default function PatientInfoCard(props: PatientInfoCardProps) {
facilityId={encounter.facility.id}
trigger={
<div className="flex flex-wrap gap-2">
{encounter.organizations.map((org) => (
<Badge
key={org.id}
className="capitalize gap-1 py-1 px-2 cursor-pointer hover:bg-secondary-100"
variant="outline"
title={`Organization: ${org.name}${org.description ? ` - ${org.description}` : ""}`}
>
<Building className="w-4 h-4 text-blue-400" />
{org.name}
</Badge>
))}
{encounter.organizations.map((org) =>
organizationBadge(org),
)}
{encounter.organizations.length === 0 && (
<Badge
className="capitalize gap-1 py-1 px-2 cursor-pointer hover:bg-secondary-100"
Expand Down Expand Up @@ -401,34 +394,41 @@ export default function PatientInfoCard(props: PatientInfoCardProps) {
<LocationTree
location={props.encounter.current_location}
/>
<div className="border-b border-dashed border-gray-200 my-2" />
<Button
variant="outline"
className="border-gray-400 w-full"
>
<Link
href={`/facility/${props.encounter.facility.id}/patient/${props.patient.id}/encounter/${props.encounter.id}/questionnaire/location_association`}
className="text-sm text-gray-950 font-semibold"
>
{t("update_location")}
</Link>
</Button>
{!disableButtons && (
<>
<div className="border-b border-dashed border-gray-200 my-2" />
<Button
variant="outline"
className="border-gray-400 w-full"
>
<Link
href={`/facility/${props.encounter.facility.id}/patient/${props.patient.id}/encounter/${props.encounter.id}/questionnaire/location_association`}
className="text-sm text-gray-950 font-semibold"
>
{t("update_location")}
</Link>
</Button>
</>
)}
</div>
</PopoverContent>
</Popover>
) : (
<Badge variant="outline">
<Link
href={`/facility/${props.encounter.facility.id}/patient/${props.patient.id}/encounter/${props.encounter.id}/questionnaire/location_association`}
className="flex items-center gap-1 text-gray-950 py-0.5"
>
<CareIcon
icon="l-location-point"
className="h-4 w-4 text-green-600"
/>
{t("add_location")}
</Link>
</Badge>
encounter.status !== "completed" &&
!disableButtons && (
<Badge variant="outline">
<Link
href={`/facility/${props.encounter.facility.id}/patient/${props.patient.id}/encounter/${props.encounter.id}/questionnaire/location_association`}
className="flex items-center gap-1 text-gray-950 py-0.5"
>
<CareIcon
icon="l-location-point"
className="h-4 w-4 text-green-600"
/>
{t("add_location")}
</Link>
</Badge>
)
)}
</div>
</div>
Expand All @@ -439,78 +439,98 @@ export default function PatientInfoCard(props: PatientInfoCardProps) {
className="flex flex-col items-center justify-end gap-4 px-4 py-1 2xl:flex-row"
id="consultation-buttons"
>
{!completedEncounterStatus.includes(encounter.status) && (
<div
className="flex w-full flex-col gap-3 lg:w-auto 2xl:flex-row"
data-cy="update-encounter-button"
>
<AlertDialog>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="primary">
{t("update")}
<ChevronDown className="ml-2 h-4 w-4" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuLabel>{t("actions")}</DropdownMenuLabel>
<DropdownMenuItem>
<Link
href={`/facility/${encounter.facility.id}/patient/${patient.id}/encounter/${encounter.id}/treatment_summary`}
className="cursor-pointer text-gray-800"
>
{t("treatment_summary")}
</Link>
</DropdownMenuItem>
<DropdownMenuItem asChild>
<Link
href={`/facility/${encounter.facility.id}/patient/${patient.id}/encounter/${encounter.id}/files/discharge_summary`}
className="cursor-pointer text-gray-800"
>
{t("discharge_summary")}
</Link>
</DropdownMenuItem>
<AlertDialogTrigger asChild>
<DropdownMenuItem onSelect={(e) => e.preventDefault()}>
{t("mark_as_complete")}
{!completedEncounterStatus.includes(encounter.status) &&
!disableButtons && (
<div
className="flex w-full flex-col gap-3 lg:w-auto 2xl:flex-row"
data-cy="update-encounter-button"
>
<AlertDialog>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="primary">
{t("update")}
<ChevronDown className="ml-2 h-4 w-4" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuLabel>{t("actions")}</DropdownMenuLabel>
<DropdownMenuItem>
<Link
href={`/facility/${encounter.facility.id}/patient/${patient.id}/encounter/${encounter.id}/treatment_summary`}
className="cursor-pointer text-gray-800"
>
{t("treatment_summary")}
</Link>
</DropdownMenuItem>
</AlertDialogTrigger>
<DropdownMenuItem asChild>
<Link
href={`/facility/${encounter.facility.id}/patient/${patient.id}/encounter/${encounter.id}/files/discharge_summary`}
className="cursor-pointer text-gray-800"
>
{t("discharge_summary")}
</Link>
</DropdownMenuItem>
<AlertDialogTrigger asChild>
<DropdownMenuItem onSelect={(e) => e.preventDefault()}>
{t("mark_as_complete")}
</DropdownMenuItem>
</AlertDialogTrigger>
<PLUGIN_Component
__name="PatientInfoCardActions"
encounter={encounter}
/>
</DropdownMenuContent>
</DropdownMenu>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>
{t("mark_as_complete")}
</AlertDialogTitle>
<AlertDialogDescription>
{t("mark_encounter_as_complete_confirmation")}
</AlertDialogDescription>
</AlertDialogHeader>

<PLUGIN_Component
__name="PatientInfoCardActions"
__name="PatientInfoCardMarkAsComplete"
encounter={encounter}
/>
</DropdownMenuContent>
</DropdownMenu>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>{t("mark_as_complete")}</AlertDialogTitle>
<AlertDialogDescription>
{t("mark_encounter_as_complete_confirmation")}
</AlertDialogDescription>
</AlertDialogHeader>

<PLUGIN_Component
__name="PatientInfoCardMarkAsComplete"
encounter={encounter}
/>

<AlertDialogFooter>
<AlertDialogCancel>{t("cancel")}</AlertDialogCancel>
<AlertDialogFooter>
<AlertDialogCancel>{t("cancel")}</AlertDialogCancel>

<AlertDialogAction
className={cn(buttonVariants({ variant: "primary" }))}
onClick={handleMarkAsComplete}
data-cy="mark-encounter-as-complete"
>
{t("mark_as_complete")}
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
</div>
)}
<AlertDialogAction
className={cn(buttonVariants({ variant: "primary" }))}
onClick={handleMarkAsComplete}
data-cy="mark-encounter-as-complete"
>
{t("mark_as_complete")}
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
</div>
)}
</div>
</section>
</>
);

function organizationBadge(org: FacilityOrganization) {
return (
<Badge
key={org.id}
className={cn(
"capitalize gap-1 py-1 px-2 hover:bg-secondary-100",
!disableButtons && "cursor-pointer ",
)}
variant="outline"
title={`Organization: ${org.name}${org.description ? ` - ${org.description}` : ""}`}
>
<Building className="w-4 h-4 text-blue-400" />
{org.name}
</Badge>
);
}
}

0 comments on commit 9b82db3

Please sign in to comment.