Skip to content

Commit

Permalink
Patient | Mark death (#10843)
Browse files Browse the repository at this point in the history
  • Loading branch information
amjithtitus09 authored Feb 28, 2025
1 parent e502bfb commit 10c9b22
Show file tree
Hide file tree
Showing 13 changed files with 152 additions and 28 deletions.
6 changes: 6 additions & 0 deletions public/locale/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -733,6 +733,7 @@
"dashboard": "Dashboard",
"date": "Date",
"date_and_time": "Date and Time",
"date_and_time_of_death": "Date and Time of Death",
"date_declared_positive": "Date of declaring positive",
"date_of_admission": "Date of Admission",
"date_of_birth": "Date of Birth",
Expand All @@ -748,6 +749,8 @@
"dates_and_identifiers": "Dates & Identifiers",
"day": "Day",
"death_report": "Death Report",
"deceased_disclaimer": "Please provide the date and time of death for record-keeping purposes. This information is handled with utmost sensitivity and respect.",
"deceased_status": "Deceased Status",
"delete": "Delete",
"delete_account": "Delete account",
"delete_account_btn": "Yes, delete this account",
Expand Down Expand Up @@ -1297,6 +1300,7 @@
"is_it_upshift": "is it upshift",
"is_phone_a_whatsapp_number": "Is the phone number a WhatsApp number?",
"is_pregnant": "Is pregnant",
"is_the_patient_deceased": "Is the patient deceased",
"is_this_administration_for_a_past_time": "Is this administration for a past time",
"is_this_an_emergency": "Is this an Emergency?",
"is_this_an_emergency_request": "Is this an emergency request?",
Expand Down Expand Up @@ -1651,6 +1655,7 @@
"ongoing_medications": "Ongoing Medications",
"online": "Online",
"only_indian_mobile_numbers_supported": "Currently only Indian numbers are supported",
"only_mark_if_applicable": "Only mark if applicable",
"onset": "Onset",
"op_encounter": "OP Encounter",
"op_file_closed": "OP file closed",
Expand Down Expand Up @@ -1729,6 +1734,7 @@
"patient_face": "Patient Face",
"patient_files": "Patient Files",
"patient_information": "Patient Information",
"patient_is_deceased": "Patient is deceased",
"patient_name": "Patient Name",
"patient_name_uhid": "Patient Name/UHID",
"patient_no": "OP/IP No",
Expand Down
2 changes: 1 addition & 1 deletion src/components/Common/DebugPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export function DebugPreview({ data, title, className }: DebugPreviewProps) {
</CardTitle>
</CardHeader>
<CardContent>
<pre className="text-sm text-muted-foreground whitespace-pre-wrap overflow-auto max-h-[500px]">
<pre className="text-sm text-gray-500 whitespace-pre-wrap overflow-auto max-h-[500px]">
{JSON.stringify(data, null, 2)}
</pre>
</CardContent>
Expand Down
16 changes: 6 additions & 10 deletions src/components/Location/LocationSheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -262,9 +262,7 @@ export function LocationSheet({
location.status === "planned" ||
location.status === "reserved") && (
<div className="flex flex-col gap-2">
<label className="text-sm text-muted-foreground">
{t("start_time")}
</label>
<label className="text-sm text-gray-500">{t("start_time")}</label>
<Input
type="datetime-local"
value={format(
Expand All @@ -283,9 +281,7 @@ export function LocationSheet({
)}
{location.status !== "active" && (
<div className="flex flex-col gap-2">
<label className="text-sm text-muted-foreground">
{t("end_time")}
</label>
<label className="text-sm text-gray-500">{t("end_time")}</label>
<Input
type="datetime-local"
value={
Expand Down Expand Up @@ -329,7 +325,7 @@ export function LocationSheet({
<SheetTitle className="text-xl font-semibold">
{t("update_location")}
</SheetTitle>
<p className="text-sm text-muted-foreground">
<p className="text-sm text-gray-500">
{t("manage_patient_location_and_transfers")}
</p>
</SheetHeader>
Expand Down Expand Up @@ -361,7 +357,7 @@ export function LocationSheet({
{selectedLocation && (
<div className="space-y-3 pt-3 border-t">
<div className="grid gap-2">
<label className="text-sm text-muted-foreground">
<label className="text-sm text-gray-500">
{t("status")}
</label>
<Select
Expand All @@ -388,7 +384,7 @@ export function LocationSheet({
newLocation.status === "planned" ||
newLocation.status === "reserved") && (
<div className="grid gap-2">
<label className="text-sm text-muted-foreground">
<label className="text-sm text-gray-500">
{t("start_time")}
</label>
<Input
Expand All @@ -406,7 +402,7 @@ export function LocationSheet({
)}
{newLocation.status !== "active" && (
<div className="grid gap-2">
<label className="text-sm text-muted-foreground">
<label className="text-sm text-gray-500">
{t("end_time")}
</label>
<Input
Expand Down
29 changes: 23 additions & 6 deletions src/components/Patient/PatientHome.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { useQuery } from "@tanstack/react-query";
import dayjs from "dayjs";
import { Link, navigate } from "raviger";
import { useTranslation } from "react-i18next";

import CareIcon from "@/CAREUI/icons/CareIcon";

import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import {
Tooltip,
Expand Down Expand Up @@ -87,13 +89,28 @@ export const PatientHome = (props: {
name={patientData.name}
/>
</div>

<div>
<h1
id="patient-name"
className="text-xl font-bold capitalize text-gray-950"
>
{patientData.name}
</h1>
<div className="flex flex-row gap-x-4">
<h1
id="patient-name"
className="text-xl font-bold capitalize text-gray-950"
>
{patientData.name}
</h1>
{patientData.death_datetime && (
<Badge variant="destructive">
<h3 className="text-sm font-medium">
{t("expired_on")}
{": "}
{dayjs(patientData.death_datetime).format(
"DD MMM YYYY, hh:mm A",
)}
</h3>
</Badge>
)}
</div>

<h3 className="text-sm font-medium text-gray-600 capitalize">
{formatPatientAge(patientData, true)},{" "}
{t(`GENDER__${patientData.gender}`)}, {" "}
Expand Down
23 changes: 23 additions & 0 deletions src/components/Patient/PatientInfoCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import { LocationTree } from "@/components/Location/LocationTree";
import LinkDepartmentsSheet from "@/components/Patient/LinkDepartmentsSheet";

import { PLUGIN_Component } from "@/PluginEngine";
import dayjs from "@/Utils/dayjs";
import routes from "@/Utils/request/api";
import mutate from "@/Utils/request/mutate";
import { formatDateTime, formatPatientAge } from "@/Utils/utils";
Expand Down Expand Up @@ -133,6 +134,17 @@ export default function PatientInfoCard(props: PatientInfoCardProps) {
{formatPatientAge(patient, true)}{" "}
{t(`GENDER__${patient.gender}`)}
</div>
{patient.death_datetime && (
<Badge variant="destructive">
<h3 className="text-sm font-medium">
{t("expired_on")}
{": "}
{dayjs(patient.death_datetime).format(
"DD MMM YYYY, hh:mm A",
)}
</h3>
</Badge>
)}
</div>
</div>
</div>
Expand All @@ -158,6 +170,17 @@ export default function PatientInfoCard(props: PatientInfoCardProps) {
{formatPatientAge(patient, true)}{" "}
{t(`GENDER__${patient.gender}`)}
</div>
{patient.death_datetime && (
<Badge variant="destructive">
<h3 className="text-sm font-medium">
{t("expired_on")}
{": "}
{dayjs(patient.death_datetime).format(
"DD MMM YYYY, hh:mm A",
)}
</h3>
</Badge>
)}
</div>
<div className="grid gap-4 grid-cols-3 mt-2 md:mt-0">
<div className="flex flex-col space-y-1">
Expand Down
77 changes: 77 additions & 0 deletions src/components/Patient/PatientRegistration.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { zodResolver } from "@hookform/resolvers/zod";
import { useMutation, useQuery } from "@tanstack/react-query";
import { InfoIcon } from "lucide-react";
import { navigate, useNavigationPrompt, useQueryParams } from "raviger";
import { useEffect, useMemo, useState } from "react";
import { useForm } from "react-hook-form";
Expand Down Expand Up @@ -77,6 +78,7 @@ export default function PatientRegistration(
const [suppressDuplicateWarning, setSuppressDuplicateWarning] =
useState(!!patientId);
const [selectedLevels, setSelectedLevels] = useState<Organization[]>([]);
const [isDeceased, setIsDeceased] = useState(false);

const formSchema = useMemo(
() =>
Expand All @@ -99,6 +101,7 @@ export default function PatientRegistration(
return parsedDate.isValid() && !parsedDate.isAfter(dayjs());
}, t("enter_valid_dob"))
.optional(),
death_datetime: z.string().nullable().optional(),
age: z
.number()
.int()
Expand Down Expand Up @@ -261,6 +264,7 @@ export default function PatientRegistration(
setSelectedLevels([
patientQuery.data.geo_organization as unknown as Organization,
]);
setIsDeceased(!!patientQuery.data.death_datetime);
form.reset({
name: patientQuery.data.name || "",
phone_number: patientQuery.data.phone_number || "",
Expand Down Expand Up @@ -584,6 +588,79 @@ export default function PatientRegistration(
</TabsContent>
</Tabs>

<div className="space-y-4 rounded-lg bg-white p-4 border border-gray-200">
<div className="flex items-center justify-between">
<div className="flex items-center gap-2">
<h2 className="text-sm font-semibold">
{t("deceased_status")}
</h2>
<span
className="text-sm text-gray-500
"
>
({t("only_mark_if_applicable")})
</span>
</div>
<div className="flex items-center gap-2">
<Checkbox
id="is-deceased"
checked={isDeceased}
onCheckedChange={(checked) => {
setIsDeceased(checked as boolean);
form.setValue(
"death_datetime",
checked ? form.getValues("death_datetime") : null,
);
}}
data-cy="is-deceased-checkbox"
/>
<label
htmlFor="is-deceased"
className="text-sm font-medium"
>
{t("patient_is_deceased")}
</label>
</div>
</div>

{(isDeceased || form.watch("death_datetime")) && (
<div className="mt-4">
<div className="flex items-center gap-2 mb-4 text-gray-500">
<InfoIcon className="w-4 h-4" />
<p className="text-sm text-gray-500">
{t("deceased_disclaimer")}
</p>
</div>

<FormField
control={form.control}
name="death_datetime"
render={({ field }) => (
<FormItem>
<FormLabel>{t("date_and_time_of_death")}</FormLabel>
<FormControl>
<Input
type="datetime-local"
{...field}
value={field.value ?? ""}
onChange={(e) => {
const value = e.target.value || undefined;
field.onChange(value);
setIsDeceased(!!value);
}}
max={dayjs().format("YYYY-MM-DDTHH:mm")}
id="death-datetime"
data-cy="death-datetime-input"
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>
)}
</div>

<FormField
control={form.control}
name="address"
Expand Down
2 changes: 1 addition & 1 deletion src/components/Questionnaire/CodingEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ export function CodingEditor({ code, onChange }: CodingEditorProps) {
<Input
value={code.display}
placeholder="Unverified"
className={!code.display ? "text-muted-foreground" : undefined}
className={!code.display ? "text-gray-500" : undefined}
readOnly
/>
</div>
Expand Down
8 changes: 4 additions & 4 deletions src/components/Questionnaire/QuestionnaireEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1384,7 +1384,7 @@ function QuestionEditor({
<div className="space-y-6">
<div className="border rounded-lg bg-gray-100 p-4">
<h3 className="text-sm font-medium mb-2">Question Settings</h3>
<p className="text-sm text-muted-foreground mb-4">
<p className="text-sm text-gray-500 mb-4">
Configure the basic behavior: mark as required, allow multiple
entries, or set as read only.
</p>
Expand Down Expand Up @@ -1430,7 +1430,7 @@ function QuestionEditor({
<h3 className="text-sm font-medium mb-2">
Data Collection Details
</h3>
<p className="text-sm text-muted-foreground mb-4">
<p className="text-sm text-gray-500 mb-4">
Specify key collection info: time, performer, body site, and
method.
</p>
Expand Down Expand Up @@ -1498,7 +1498,7 @@ function QuestionEditor({
<h3 className="text-sm font-medium mb-2">
Group Layout Options
</h3>
<p className="text-sm text-muted-foreground mb-4">
<p className="text-sm text-gray-500 mb-4">
Choose the layout style that best fits your sub-questions from
the available options.
</p>
Expand Down Expand Up @@ -1540,7 +1540,7 @@ function QuestionEditor({
<CardTitle className="text-base font-medium">
Answer Options
</CardTitle>
<p className="text-sm text-muted-foreground">
<p className="text-sm text-gray-500">
Define possible answers for this question
</p>
</div>
Expand Down
4 changes: 1 addition & 3 deletions src/components/ValueSet/ValueSetForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,7 @@ function ConceptFields({
<Input
{...field}
placeholder="Unverified"
className={
!field.value ? "text-muted-foreground" : undefined
}
className={!field.value ? "text-gray-500" : undefined}
readOnly
/>
</FormControl>
Expand Down
7 changes: 7 additions & 0 deletions src/pages/Encounters/EncounterList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -703,6 +703,13 @@ export function EncounterList({
>
<CardTitle className="group-hover:text-primary transition-colors">
{encounter.patient.name}
{encounter.patient.death_datetime && (
<Badge variant="destructive" className="ml-2 py-0">
<h3 className="text-xs font-medium">
{t("expired")}
</h3>
</Badge>
)}
</CardTitle>
</Link>
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/pages/Facility/settings/devices/UpdateDevice.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export default function UpdateDevice({ facilityId, deviceId }: Props) {
</div>
) : (
<div className="flex flex-col items-center justify-center gap-4 py-16">
<p className="text-muted-foreground">{t("device_not_found")}</p>
<p className="text-gray-500">{t("device_not_found")}</p>
<Link href={`/facility/${facilityId}/settings/devices/${deviceId}`}>
<Button variant="outline">{t("back")}</Button>
</Link>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ export default function DeviceForm({ facilityId, device, onSuccess }: Props) {

<div className="space-y-2">
<div className="flex items-center justify-between">
<h3 className="text-sm font-medium text-muted-foreground">
<h3 className="text-sm font-medium text-gray-500">
{t("contact_points")}
</h3>
<Button
Expand Down
Loading

0 comments on commit 10c9b22

Please sign in to comment.