From 4f1e423a005b0fa2054ac8930d66dca226508fa5 Mon Sep 17 00:00:00 2001 From: Amjith Titus Date: Fri, 31 Jan 2025 10:15:05 +0530 Subject: [PATCH 1/9] Patient Updates Tab, Structured responses filter by Encounter in Questionnaire --- .../QuestionnaireResponsesList.tsx | 12 +++-- .../Patient/PatientDetailsTab/index.tsx | 3 +- src/components/Patient/PatientHome.tsx | 1 + .../QuestionTypes/AllergyQuestion.tsx | 3 ++ .../QuestionTypes/DiagnosisQuestion.tsx | 3 ++ .../MedicationRequestQuestion.tsx | 3 ++ .../MedicationStatementQuestion.tsx | 3 ++ .../QuestionTypes/QuestionInput.tsx | 47 ++++++++++++++++--- .../QuestionTypes/SymptomQuestion.tsx | 3 ++ .../Encounters/tabs/EncounterUpdatesTab.tsx | 5 +- 10 files changed, 71 insertions(+), 12 deletions(-) diff --git a/src/components/Facility/ConsultationDetails/QuestionnaireResponsesList.tsx b/src/components/Facility/ConsultationDetails/QuestionnaireResponsesList.tsx index 11ba2b75c7b..39eaad920bb 100644 --- a/src/components/Facility/ConsultationDetails/QuestionnaireResponsesList.tsx +++ b/src/components/Facility/ConsultationDetails/QuestionnaireResponsesList.tsx @@ -14,7 +14,8 @@ import { Question } from "@/types/questionnaire/question"; import { QuestionnaireResponse } from "@/types/questionnaire/questionnaireResponse"; interface Props { - encounter: Encounter; + encounter?: Encounter; + patientId: string; } function formatValue(value: string, type: string): string { @@ -124,17 +125,20 @@ function QuestionGroup({ ); } -export default function QuestionnaireResponsesList({ encounter }: Props) { +export default function QuestionnaireResponsesList({ + encounter, + patientId, +}: Props) { const { t } = useTranslation(); return ( {() => ( diff --git a/src/components/Patient/PatientDetailsTab/index.tsx b/src/components/Patient/PatientDetailsTab/index.tsx index c6bf06c8ce6..8dbc367b8bf 100644 --- a/src/components/Patient/PatientDetailsTab/index.tsx +++ b/src/components/Patient/PatientDetailsTab/index.tsx @@ -1,3 +1,4 @@ +import QuestionnaireResponsesList from "@/components/Facility/ConsultationDetails/QuestionnaireResponsesList"; import EncounterHistory from "@/components/Patient/PatientDetailsTab//EncounterHistory"; import { HealthProfileSummary } from "@/components/Patient/PatientDetailsTab//HealthProfileSummary"; import { Demography } from "@/components/Patient/PatientDetailsTab/Demography"; @@ -66,7 +67,7 @@ export const facilityPatientTabs = [ }, { route: "updates", - component: Updates, + component: QuestionnaireResponsesList, }, { route: "resource_requests", diff --git a/src/components/Patient/PatientHome.tsx b/src/components/Patient/PatientHome.tsx index 373494a4a3f..aae34f64434 100644 --- a/src/components/Patient/PatientHome.tsx +++ b/src/components/Patient/PatientHome.tsx @@ -135,6 +135,7 @@ export const PatientHome = (props: { )} diff --git a/src/components/Questionnaire/QuestionTypes/AllergyQuestion.tsx b/src/components/Questionnaire/QuestionTypes/AllergyQuestion.tsx index 8270ae98c71..640e2e77f2d 100644 --- a/src/components/Questionnaire/QuestionTypes/AllergyQuestion.tsx +++ b/src/components/Questionnaire/QuestionTypes/AllergyQuestion.tsx @@ -61,6 +61,7 @@ import { Question } from "@/types/questionnaire/question"; interface AllergyQuestionProps { patientId: string; + encounterId: string; question: Question; questionnaireResponse: QuestionnaireResponse; updateQuestionnaireResponseCB: ( @@ -116,6 +117,7 @@ export function AllergyQuestion({ updateQuestionnaireResponseCB, disabled, patientId, + encounterId, }: AllergyQuestionProps) { const allergies = (questionnaireResponse.values?.[0]?.value as AllergyIntoleranceRequest[]) || @@ -126,6 +128,7 @@ export function AllergyQuestion({ queryFn: query(allergyIntoleranceApi.getAllergy, { pathParams: { patientId }, queryParams: { + encounter: encounterId, limit: 100, }, }), diff --git a/src/components/Questionnaire/QuestionTypes/DiagnosisQuestion.tsx b/src/components/Questionnaire/QuestionTypes/DiagnosisQuestion.tsx index b4aab2c07c4..f40485d97c0 100644 --- a/src/components/Questionnaire/QuestionTypes/DiagnosisQuestion.tsx +++ b/src/components/Questionnaire/QuestionTypes/DiagnosisQuestion.tsx @@ -46,6 +46,7 @@ import { interface DiagnosisQuestionProps { patientId: string; + encounterId: string; questionnaireResponse: QuestionnaireResponse; updateQuestionnaireResponseCB: ( values: ResponseValue[], @@ -84,6 +85,7 @@ function convertToDiagnosisRequest(diagnosis: Diagnosis): DiagnosisRequest { export function DiagnosisQuestion({ patientId, + encounterId, questionnaireResponse, updateQuestionnaireResponseCB, disabled, @@ -96,6 +98,7 @@ export function DiagnosisQuestion({ queryFn: query(diagnosisApi.listDiagnosis, { pathParams: { patientId }, queryParams: { + encounter: encounterId, limit: 100, }, }), diff --git a/src/components/Questionnaire/QuestionTypes/MedicationRequestQuestion.tsx b/src/components/Questionnaire/QuestionTypes/MedicationRequestQuestion.tsx index fb2fb85fd54..f9ff069f431 100644 --- a/src/components/Questionnaire/QuestionTypes/MedicationRequestQuestion.tsx +++ b/src/components/Questionnaire/QuestionTypes/MedicationRequestQuestion.tsx @@ -78,6 +78,7 @@ interface MedicationRequestQuestionProps { note?: string, ) => void; disabled?: boolean; + encounterId: string; } export function MedicationRequestQuestion({ @@ -85,6 +86,7 @@ export function MedicationRequestQuestion({ updateQuestionnaireResponseCB, disabled, patientId, + encounterId, }: MedicationRequestQuestionProps) { const medications = (questionnaireResponse.values?.[0]?.value as MedicationRequest[]) || []; @@ -94,6 +96,7 @@ export function MedicationRequestQuestion({ queryFn: query(medicationRequestApi.list, { pathParams: { patientId }, queryParams: { + encounter: encounterId, limit: 100, }, }), diff --git a/src/components/Questionnaire/QuestionTypes/MedicationStatementQuestion.tsx b/src/components/Questionnaire/QuestionTypes/MedicationStatementQuestion.tsx index 936a2b3b0b3..f56be1b82dc 100644 --- a/src/components/Questionnaire/QuestionTypes/MedicationStatementQuestion.tsx +++ b/src/components/Questionnaire/QuestionTypes/MedicationStatementQuestion.tsx @@ -61,6 +61,7 @@ import { Question } from "@/types/questionnaire/question"; interface MedicationStatementQuestionProps { patientId: string; + encounterId: string; question: Question; questionnaireResponse: QuestionnaireResponse; updateQuestionnaireResponseCB: ( @@ -90,6 +91,7 @@ export function MedicationStatementQuestion({ updateQuestionnaireResponseCB, disabled, patientId, + encounterId, }: MedicationStatementQuestionProps) { const { t } = useTranslation(); const desktopLayout = useBreakpoints({ lg: true, default: false }); @@ -110,6 +112,7 @@ export function MedicationStatementQuestion({ pathParams: { patientId }, queryParams: { limit: 100, + encounter: encounterId, }, }), }); diff --git a/src/components/Questionnaire/QuestionTypes/QuestionInput.tsx b/src/components/Questionnaire/QuestionTypes/QuestionInput.tsx index 16957d63c68..867e47d401c 100644 --- a/src/components/Questionnaire/QuestionTypes/QuestionInput.tsx +++ b/src/components/Questionnaire/QuestionTypes/QuestionInput.tsx @@ -115,15 +115,50 @@ export function QuestionInput({ case "structured": switch (question.structured_type) { case "medication_request": - return ; + if (encounterId) { + return ( + + ); + } + return null; case "medication_statement": - return ; + if (encounterId) { + return ( + + ); + } + return null; case "allergy_intolerance": - return ; + if (encounterId) { + return ( + + ); + } + return null; case "symptom": - return ; + if (encounterId) { + return ( + + ); + } + return null; case "diagnosis": - return ; + if (encounterId) { + return ( + + ); + } + return null; case "appointment": return ; case "encounter": @@ -131,8 +166,8 @@ export function QuestionInput({ return ( ); } diff --git a/src/components/Questionnaire/QuestionTypes/SymptomQuestion.tsx b/src/components/Questionnaire/QuestionTypes/SymptomQuestion.tsx index 94eba927251..0a175ae9219 100644 --- a/src/components/Questionnaire/QuestionTypes/SymptomQuestion.tsx +++ b/src/components/Questionnaire/QuestionTypes/SymptomQuestion.tsx @@ -47,6 +47,7 @@ import { interface SymptomQuestionProps { patientId: string; + encounterId: string; questionnaireResponse: QuestionnaireResponse; updateQuestionnaireResponseCB: ( values: ResponseValue[], @@ -281,6 +282,7 @@ export function SymptomQuestion({ questionnaireResponse, updateQuestionnaireResponseCB, disabled, + encounterId, }: SymptomQuestionProps) { const symptoms = (questionnaireResponse.values?.[0]?.value as SymptomRequest[]) || []; @@ -291,6 +293,7 @@ export function SymptomQuestion({ pathParams: { patientId }, queryParams: { limit: 100, + encounter: encounterId, }, }), }); diff --git a/src/pages/Encounters/tabs/EncounterUpdatesTab.tsx b/src/pages/Encounters/tabs/EncounterUpdatesTab.tsx index b1f01ac6b16..e44706a6d9b 100644 --- a/src/pages/Encounters/tabs/EncounterUpdatesTab.tsx +++ b/src/pages/Encounters/tabs/EncounterUpdatesTab.tsx @@ -46,7 +46,10 @@ export const EncounterUpdatesTab = ({ {/* Questionnaire Responses Section */}
- +
From 1840946cb48c0b8700ecaac1fbbed986f9737918 Mon Sep 17 00:00:00 2001 From: Amjith Titus Date: Fri, 31 Jan 2025 11:22:28 +0530 Subject: [PATCH 2/9] Update src/components/Facility/ConsultationDetails/QuestionnaireResponsesList.tsx Co-authored-by: Rithvik Nishad --- .../Facility/ConsultationDetails/QuestionnaireResponsesList.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Facility/ConsultationDetails/QuestionnaireResponsesList.tsx b/src/components/Facility/ConsultationDetails/QuestionnaireResponsesList.tsx index 39eaad920bb..7972e41ff1b 100644 --- a/src/components/Facility/ConsultationDetails/QuestionnaireResponsesList.tsx +++ b/src/components/Facility/ConsultationDetails/QuestionnaireResponsesList.tsx @@ -138,7 +138,7 @@ export default function QuestionnaireResponsesList({ patientId: patientId, }} query={{ - ...(encounter && { encounter: encounter.id }), + encounter: encounter?.id, }} > {() => ( From 3bb3d1c95a97a774f5a3321492df5afc3d2de670 Mon Sep 17 00:00:00 2001 From: Amjith Titus Date: Fri, 31 Jan 2025 12:34:30 +0530 Subject: [PATCH 3/9] Revert Allergy encounter filter --- .../Questionnaire/QuestionTypes/AllergyQuestion.tsx | 3 --- .../Questionnaire/QuestionTypes/QuestionInput.tsx | 7 +------ 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/src/components/Questionnaire/QuestionTypes/AllergyQuestion.tsx b/src/components/Questionnaire/QuestionTypes/AllergyQuestion.tsx index 640e2e77f2d..8270ae98c71 100644 --- a/src/components/Questionnaire/QuestionTypes/AllergyQuestion.tsx +++ b/src/components/Questionnaire/QuestionTypes/AllergyQuestion.tsx @@ -61,7 +61,6 @@ import { Question } from "@/types/questionnaire/question"; interface AllergyQuestionProps { patientId: string; - encounterId: string; question: Question; questionnaireResponse: QuestionnaireResponse; updateQuestionnaireResponseCB: ( @@ -117,7 +116,6 @@ export function AllergyQuestion({ updateQuestionnaireResponseCB, disabled, patientId, - encounterId, }: AllergyQuestionProps) { const allergies = (questionnaireResponse.values?.[0]?.value as AllergyIntoleranceRequest[]) || @@ -128,7 +126,6 @@ export function AllergyQuestion({ queryFn: query(allergyIntoleranceApi.getAllergy, { pathParams: { patientId }, queryParams: { - encounter: encounterId, limit: 100, }, }), diff --git a/src/components/Questionnaire/QuestionTypes/QuestionInput.tsx b/src/components/Questionnaire/QuestionTypes/QuestionInput.tsx index 867e47d401c..deec52da280 100644 --- a/src/components/Questionnaire/QuestionTypes/QuestionInput.tsx +++ b/src/components/Questionnaire/QuestionTypes/QuestionInput.tsx @@ -135,12 +135,7 @@ export function QuestionInput({ } return null; case "allergy_intolerance": - if (encounterId) { - return ( - - ); - } - return null; + return ; case "symptom": if (encounterId) { return ( From 8bedd7fc11f95988c3656f5501853483cecdb12f Mon Sep 17 00:00:00 2001 From: Amjith Titus Date: Fri, 31 Jan 2025 12:51:19 +0530 Subject: [PATCH 4/9] Revert Allergy encounter filter from list --- src/components/Patient/allergy/list.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/Patient/allergy/list.tsx b/src/components/Patient/allergy/list.tsx index 8e1a9686a90..33f05e0f652 100644 --- a/src/components/Patient/allergy/list.tsx +++ b/src/components/Patient/allergy/list.tsx @@ -40,7 +40,6 @@ export function AllergyList({ queryKey: ["allergies", patientId, encounterId], queryFn: query(allergyIntoleranceApi.getAllergy, { pathParams: { patientId }, - queryParams: encounterId ? { encounter: encounterId } : undefined, }), }); From 016f87f0503a93da21e53b20f280d4819045837e Mon Sep 17 00:00:00 2001 From: Amjith Titus Date: Fri, 31 Jan 2025 14:33:59 +0530 Subject: [PATCH 5/9] Missing data in Questionnaire Response View | Issue #10309 --- .../QuestionnaireResponsesList.tsx | 284 ++++++++++-------- 1 file changed, 166 insertions(+), 118 deletions(-) diff --git a/src/components/Facility/ConsultationDetails/QuestionnaireResponsesList.tsx b/src/components/Facility/ConsultationDetails/QuestionnaireResponsesList.tsx index 7972e41ff1b..e02eb46aa4e 100644 --- a/src/components/Facility/ConsultationDetails/QuestionnaireResponsesList.tsx +++ b/src/components/Facility/ConsultationDetails/QuestionnaireResponsesList.tsx @@ -3,6 +3,7 @@ import { useTranslation } from "react-i18next"; import CareIcon from "@/CAREUI/icons/CareIcon"; import PaginatedList from "@/CAREUI/misc/PaginatedList"; +import { Badge } from "@/components/ui/badge"; import { Card } from "@/components/ui/card"; import { CardListSkeleton } from "@/components/Common/SkeletonLoading"; @@ -18,14 +19,18 @@ interface Props { patientId: string; } -function formatValue(value: string, type: string): string { +function formatValue( + value: string, + type: string, + unit?: { display?: string }, +): string { switch (type) { case "dateTime": return formatDateTime(value); case "choice": return properCase(value); default: - return value; + return `${value}${unit?.display ? ` ${unit.display}` : ""}`; } } @@ -43,16 +48,8 @@ function QuestionResponseValue({ return (
-
- {question.text} - {question.code && ( - - ({question.code.display}) - - )} -
-
- {formatValue(String(value), question.type)} +
+ {formatValue(String(value), question.type, question.unit)} {response.note && ( ({response.note}) @@ -70,34 +67,67 @@ function QuestionGroup({ group: Question; responses: any[]; }) { - // If this is a nested group (like BP with systolic/diastolic) - if (group.questions?.some((q) => q.questions)) { - return ( -
-

- {group.text} - {group.code && ( - - ({group.code.display}) - - )} -

-
- {group.questions?.map((subGroup) => ( - - ))} + // Map the group.queswtions + if (group.questions) { + return group.questions?.map((q: Question) => { + if (q.questions) { + return ( +
+

+ {q.text} + {q.code && ( + + ({q.code.display}) + + )} +

+
+ {q.questions?.map((subGroup: Question) => ( + + ))} +
+
+ ); + } + + return ( +
+

+ {q.text} + {q.code && ( + + ({q.code.display}) + + )} +

+
+ {[q]?.map((question: Question) => { + const response = responses.find( + (r) => r.question_id === question.id, + ); + if (!response) return null; + return ( + + ); + })} +
-
- ); + ); + }); } - // Regular group with questions return ( -
+

{group.text} {group.code && ( @@ -109,7 +139,7 @@ function QuestionGroup({
- {group.questions?.map((question) => { + {[group]?.map((question: Question) => { const response = responses.find((r) => r.question_id === question.id); if (!response) return null; return ( @@ -125,6 +155,102 @@ function QuestionGroup({ ); } +function StructuredResponseBadge({ + type, + submitType, +}: { + type: string; + submitType: string; +}) { + const colors = { + symptom: "bg-yellow-100 text-yellow-800", + diagnosis: "bg-blue-100 text-blue-800", + medication_request: "bg-green-100 text-green-800", + }; + + return ( + + {submitType === "CREATE" ? "Created" : "Updated"}{" "} + {properCase(type.replace("_", " "))} + + ); +} + +function ResponseCard({ item }: { item: QuestionnaireResponse }) { + const isStructured = !item.questionnaire; + const structuredType = Object.keys(item.structured_responses || {})[0]; + + return ( + +
+
+
+

+ {item.questionnaire?.title || + Object.keys(item.structured_responses || {}).map((key) => + properCase(key.replace("_", " ")), + )} +

+ {isStructured && structuredType && ( + + )} +
+
+ + {formatDateTime(item.created_date)} + + + by {item.created_by?.first_name || ""}{" "} + {item.created_by?.last_name || ""} + {item.created_by?.user_type && ` (${item.created_by?.user_type})`} + +
+
+
+ + {item.questionnaire && ( +
+ {item.questionnaire?.questions.map((question: Question) => { + if (question.type === "structured") return null; + + const response = item.responses.find( + (r) => r.question_id === question.id, + ); + + if (question.type === "group") { + return ( + + ); + } + + if (!response) return null; + + return ( + + ); + })} +
+ )} +
+ ); +} + export default function QuestionnaireResponsesList({ encounter, patientId, @@ -138,7 +264,7 @@ export default function QuestionnaireResponsesList({ patientId: patientId, }} query={{ - encounter: encounter?.id, + ...(encounter && { encounter: encounter.id }), }} > {() => ( @@ -159,88 +285,10 @@ export default function QuestionnaireResponsesList({ className="grid gap-4"> - {(item) => ( - -
-
-
-

- {item.questionnaire?.title || - Object.keys(item.structured_responses || {}).map( - (key) => properCase(key), - )} -

-
- - {formatDateTime(item.created_date)} - - {!item.questionnaire && ( - <> - {Object.values( - item.structured_responses ?? {}, - )[0]?.submit_type === "CREATE" - ? "Created" - : "Updated"}{" "} - - )} - { - <> - by {item.created_by?.first_name || ""}{" "} - {item.created_by?.last_name || ""} - {item.created_by?.user_type && - ` (${item.created_by?.user_type})`} - - } - -
-
-
-
- - {item.questionnaire && ( -
-
- {item.questionnaire?.questions.map( - (question: Question) => { - // Skip structured questions for now as they need special handling - if (question.type === "structured") return null; - - const response = item.responses.find( - (r) => r.question_id === question.id, - ); - - if (question.type === "group") { - return ( - - ); - } - - if (!response) return null; - - return ( - - ); - }, - )} -
-
- )} -
- )} + {(item) => } -
+
From 944216788feba0522a2a45fa8d231355b5634e54 Mon Sep 17 00:00:00 2001 From: Amjith Titus Date: Fri, 31 Jan 2025 16:23:24 +0530 Subject: [PATCH 6/9] Missing data in Questionnaire Response View | Issue #10309 --- .../QuestionnaireResponsesList.tsx | 205 ++++++++---------- 1 file changed, 95 insertions(+), 110 deletions(-) diff --git a/src/components/Facility/ConsultationDetails/QuestionnaireResponsesList.tsx b/src/components/Facility/ConsultationDetails/QuestionnaireResponsesList.tsx index e02eb46aa4e..4903dc54c88 100644 --- a/src/components/Facility/ConsultationDetails/QuestionnaireResponsesList.tsx +++ b/src/components/Facility/ConsultationDetails/QuestionnaireResponsesList.tsx @@ -1,10 +1,11 @@ +import { t } from "i18next"; import { useTranslation } from "react-i18next"; -import CareIcon from "@/CAREUI/icons/CareIcon"; import PaginatedList from "@/CAREUI/misc/PaginatedList"; import { Badge } from "@/components/ui/badge"; import { Card } from "@/components/ui/card"; +import { Separator } from "@/components/ui/separator"; import { CardListSkeleton } from "@/components/Common/SkeletonLoading"; @@ -19,37 +20,50 @@ interface Props { patientId: string; } -function formatValue( - value: string, - type: string, - unit?: { display?: string }, -): string { +interface QuestionResponseProps { + question: Question; + response?: { + values: Array<{ + value?: any; + value_quantity?: { + value: number; + }; + }>; + note?: string; + question_id: string; + }; +} + +function formatValue(value: string | number, type: string): string { switch (type) { case "dateTime": - return formatDateTime(value); + return formatDateTime(value.toString()); case "choice": - return properCase(value); + return properCase(value.toString()); + case "decimal": + case "integer": + return value.toString(); default: - return `${value}${unit?.display ? ` ${unit.display}` : ""}`; + return value.toString(); } } -function QuestionResponseValue({ - question, - response, -}: { - question: Question; - response: any; -}) { +function QuestionResponseValue({ question, response }: QuestionResponseProps) { + if (!response) return null; + const value = response.values[0]?.value || response.values[0]?.value_quantity?.value; if (!value) return null; return ( -
+
+
{question.text}
- {formatValue(String(value), question.type, question.unit)} + {formatValue(value, question.type)} + {question.unit?.code && ( + {question.unit.code} + )} {response.note && ( ({response.note}) @@ -63,85 +77,54 @@ function QuestionResponseValue({ function QuestionGroup({ group, responses, + level = 0, }: { group: Question; responses: any[]; + level?: number; }) { - // Map the group.queswtions - if (group.questions) { - return group.questions?.map((q: Question) => { - if (q.questions) { - return ( -
-

- {q.text} - {q.code && ( - - ({q.code.display}) - - )} -

-
- {q.questions?.map((subGroup: Question) => ( - - ))} -
-
- ); - } + const hasResponses = responses.some((r) => + group.questions?.some((q) => q.id === r.question_id), + ); + + if (!hasResponses) return null; - return ( -
+ const containerClass = group.styling_metadata?.containerClasses || ""; + const classes = group.styling_metadata?.classes || ""; + + return ( +
+ {group.text && ( +

- {q.text} - {q.code && ( + {group.text} + {group.code && ( - ({q.code.display}) + ({group.code.display}) )}

-
- {[q]?.map((question: Question) => { - const response = responses.find( - (r) => r.question_id === question.id, - ); - if (!response) return null; - return ( - - ); - })} -
+ {level === 0 && }
- ); - }); - } + )} +
+ {group.questions?.map((question) => { + if (question.type === "group") { + return ( + + ); + } + + if (question.type === "structured") return null; - return ( -
-

- {group.text} - {group.code && ( - - ({group.code.display}) - - )} -

-
- {[group]?.map((question: Question) => { const response = responses.find((r) => r.question_id === question.id); if (!response) return null; + return ( {submitType === "CREATE" ? "Created" : "Updated"}{" "} - {properCase(type.replace("_", " "))} + {properCase(type.replace(/_/g, " "))} ); } @@ -187,31 +174,30 @@ function ResponseCard({ item }: { item: QuestionnaireResponse }) {
-
-

- {item.questionnaire?.title || - Object.keys(item.structured_responses || {}).map((key) => - properCase(key.replace("_", " ")), - )} -

- {isStructured && structuredType && ( - - )} -
- +
+ {isStructured && structuredType ? ( + + ) : ( +

+ {item.questionnaire?.title} {t("filed")} +

+ )} +
+ {t("at")} {formatDateTime(item.created_date)} - - - by {item.created_by?.first_name || ""}{" "} + {t("by")} +
+ {item.created_by?.first_name || ""}{" "} {item.created_by?.last_name || ""} {item.created_by?.user_type && ` (${item.created_by?.user_type})`} - +
@@ -221,10 +207,6 @@ function ResponseCard({ item }: { item: QuestionnaireResponse }) { {item.questionnaire?.questions.map((question: Question) => { if (question.type === "structured") return null; - const response = item.responses.find( - (r) => r.question_id === question.id, - ); - if (question.type === "group") { return ( r.question_id === question.id, + ); if (!response) return null; return ( From b6339f332e7de13d9d80fb4d311556219a16dae5 Mon Sep 17 00:00:00 2001 From: Amjith Titus Date: Fri, 31 Jan 2025 16:45:09 +0530 Subject: [PATCH 7/9] i18n and padding in Overview --- public/locale/en.json | 2 ++ src/components/Patient/diagnosis/list.tsx | 4 +++- src/components/Patient/symptoms/list.tsx | 4 +++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/public/locale/en.json b/public/locale/en.json index 470fc7b31ca..161a1140fd5 100644 --- a/public/locale/en.json +++ b/public/locale/en.json @@ -1323,6 +1323,7 @@ "no_country_found": "No country found", "no_data_found": "No data found", "no_departments_teams_found": "No Departments or Teams found", + "no_diagnoses_recorded": "No diagnoses recorded", "no_doctors_found": "No Doctors Found", "no_duplicate_facility": "You should not create duplicate facilities", "no_encounters_found": "No encounters found", @@ -1373,6 +1374,7 @@ "no_social_profile_details_available": "No Social Profile Details Available", "no_staff": "No staff found", "no_sub_organizations_found": "No sub-organizations found", + "no_symptoms_recorded": "No symptoms recorded", "no_tags_found": "No tags found", "no_tags_selected": "No tags selected", "no_tests_taken": "No tests taken", diff --git a/src/components/Patient/diagnosis/list.tsx b/src/components/Patient/diagnosis/list.tsx index d0e8c4acede..ca75a600e7a 100644 --- a/src/components/Patient/diagnosis/list.tsx +++ b/src/components/Patient/diagnosis/list.tsx @@ -63,7 +63,9 @@ export function DiagnosisList({ patientId={patientId} encounterId={encounterId} > -

{t("no_diagnoses_recorded")}

+

+ {t("no_diagnoses_recorded")} +

); } diff --git a/src/components/Patient/symptoms/list.tsx b/src/components/Patient/symptoms/list.tsx index 24f7a8142c8..9d3ca4b9c0e 100644 --- a/src/components/Patient/symptoms/list.tsx +++ b/src/components/Patient/symptoms/list.tsx @@ -62,7 +62,9 @@ export function SymptomsList({ patientId={patientId} encounterId={encounterId} > -

{t("no_symptoms_recorded")}

+

+ {t("no_symptoms_recorded")} +

); } From 95bf52387761d94dfdb8d7b7f00e36c68719953f Mon Sep 17 00:00:00 2001 From: Amjith Titus Date: Fri, 31 Jan 2025 17:20:56 +0530 Subject: [PATCH 8/9] Patient Tabs prop rename --- public/locale/en.json | 1 + .../Patient/PatientDetailsTab/Appointments.tsx | 8 ++++---- .../Patient/PatientDetailsTab/Demography.tsx | 6 +++--- .../Patient/PatientDetailsTab/EncounterHistory.tsx | 6 +++--- .../PatientDetailsTab/HealthProfileSummary.tsx | 14 ++++++++------ .../Patient/PatientDetailsTab/PatientUsers.tsx | 12 ++++++------ .../Patient/PatientDetailsTab/ResourceRequests.tsx | 8 ++++---- src/components/Patient/PatientDetailsTab/index.tsx | 2 +- .../Patient/PatientDetailsTab/patientUpdates.tsx | 2 +- src/components/Patient/PatientHome.tsx | 1 - 10 files changed, 31 insertions(+), 29 deletions(-) diff --git a/public/locale/en.json b/public/locale/en.json index 161a1140fd5..1768903d45f 100644 --- a/public/locale/en.json +++ b/public/locale/en.json @@ -1047,6 +1047,7 @@ "has_domestic_healthcare_support": "Has domestic healthcare support?", "has_sari": "Has SARI (Severe Acute Respiratory illness)?", "health-profile": "Health Profile", + "health_profile": "Health Profile", "hearing": "We are hearing you...", "help_confirmed": "There is sufficient diagnostic and/or clinical evidence to treat this as a confirmed condition.", "help_differential": "One of a set of potential (and typically mutually exclusive) diagnoses asserted to further guide the diagnostic process and preliminary treatment.", diff --git a/src/components/Patient/PatientDetailsTab/Appointments.tsx b/src/components/Patient/PatientDetailsTab/Appointments.tsx index 8b6228c4125..a2b4d77c6f7 100644 --- a/src/components/Patient/PatientDetailsTab/Appointments.tsx +++ b/src/components/Patient/PatientDetailsTab/Appointments.tsx @@ -23,14 +23,14 @@ import { formatDateTime, formatName } from "@/Utils/utils"; import scheduleApis from "@/types/scheduling/scheduleApis"; export const Appointments = (props: PatientProps) => { - const { patientData, facilityId, id } = props; + const { patientData, facilityId, patientId } = props; const { t } = useTranslation(); const { data } = useQuery({ - queryKey: ["patient-appointments", id], + queryKey: ["patient-appointments", patientId], queryFn: query(scheduleApis.appointments.list, { pathParams: { facility_id: facilityId }, - queryParams: { patient: id, limit: 100 }, + queryParams: { patient: patientId, limit: 100 }, }), }); @@ -65,7 +65,7 @@ export const Appointments = (props: PatientProps) => {

diff --git a/src/components/Patient/PatientDetailsTab/ResourceRequests.tsx b/src/components/Patient/PatientDetailsTab/ResourceRequests.tsx index 0df4ec5b404..8180bd75bcd 100644 --- a/src/components/Patient/PatientDetailsTab/ResourceRequests.tsx +++ b/src/components/Patient/PatientDetailsTab/ResourceRequests.tsx @@ -25,17 +25,17 @@ import { ResourceRequest } from "@/types/resourceRequest/resourceRequest"; import { PatientProps } from "."; export const ResourceRequests = (props: PatientProps) => { - const { patientData, facilityId, id } = props; + const { patientData, facilityId, patientId } = props; const { t } = useTranslation(); const { data: resourceRequests, isLoading: loading } = useQuery({ - queryKey: ["resourceRequests", id], + queryKey: ["resourceRequests", patientId], queryFn: query(routes.listResourceRequests, { queryParams: { - related_patient: id, + related_patient: patientId, }, }), - enabled: !!id, + enabled: !!patientId, }); const getStatusBadge = (status: ResourceRequest["status"]) => { diff --git a/src/components/Patient/PatientDetailsTab/index.tsx b/src/components/Patient/PatientDetailsTab/index.tsx index 8dbc367b8bf..8e7de28b091 100644 --- a/src/components/Patient/PatientDetailsTab/index.tsx +++ b/src/components/Patient/PatientDetailsTab/index.tsx @@ -13,7 +13,7 @@ import { ResourceRequests } from "./ResourceRequests"; export interface PatientProps { facilityId: string; - id: string; + patientId: string; patientData: Patient; } diff --git a/src/components/Patient/PatientDetailsTab/patientUpdates.tsx b/src/components/Patient/PatientDetailsTab/patientUpdates.tsx index baabad49ed9..f74707a1545 100644 --- a/src/components/Patient/PatientDetailsTab/patientUpdates.tsx +++ b/src/components/Patient/PatientDetailsTab/patientUpdates.tsx @@ -16,7 +16,7 @@ import { QuestionnaireResponse } from "@/types/questionnaire/questionnaireRespon import { PatientProps } from "."; export const Updates = (props: PatientProps) => { - const { facilityId, id: patientId } = props; + const { facilityId, patientId } = props; const { t } = useTranslation(); return ( diff --git a/src/components/Patient/PatientHome.tsx b/src/components/Patient/PatientHome.tsx index aae34f64434..e3b8e0b28d8 100644 --- a/src/components/Patient/PatientHome.tsx +++ b/src/components/Patient/PatientHome.tsx @@ -134,7 +134,6 @@ export const PatientHome = (props: { {Tab && ( From 62c08e0f01ad052b5969f1dd64c3c784af0b13a6 Mon Sep 17 00:00:00 2001 From: Amjith Titus Date: Fri, 31 Jan 2025 17:55:23 +0530 Subject: [PATCH 9/9] Replace text-muted-foreground with text-gray-500, Questionnaire view remove any type --- .../Common/Charts/ObservationChart.tsx | 4 +- .../Common/Charts/ObservationHistoryTable.tsx | 4 +- .../Common/ComboboxQuantityInput.tsx | 2 +- .../Common/SearchByMultipleFields.tsx | 2 +- .../Encounter/CreateEncounterForm.tsx | 2 +- .../ConsultationDetails/ObservationsList.tsx | 14 ++-- .../QuestionnaireResponseView.tsx | 10 +-- .../QuestionnaireResponsesList.tsx | 70 ++++++++++++++----- src/components/Facility/FacilityForm.tsx | 2 +- src/components/Facility/FacilityHome.tsx | 2 +- .../Medicine/MedicationRequestTable/index.tsx | 10 +-- src/components/Medicine/MedicationsTable.tsx | 2 +- .../Patient/LinkDepartmentsSheet.tsx | 4 +- .../Patient/MedicationStatementList.tsx | 2 +- .../PatientDetailsTab/patientUpdates.tsx | 8 +-- src/components/Patient/PatientIndex.tsx | 6 +- src/components/Patient/PatientInfoCard.tsx | 10 +-- .../Patient/allergy/AllergyTable.tsx | 4 +- src/components/Patient/allergy/list.tsx | 2 +- src/components/Patient/diagnosis/list.tsx | 4 +- src/components/Patient/symptoms/list.tsx | 4 +- .../Questionnaire/CloneQuestionnaireSheet.tsx | 4 +- .../ManageQuestionnaireOrganizationsSheet.tsx | 4 +- .../ManageQuestionnaireTagsSheet.tsx | 4 +- .../QuestionTypes/AppointmentQuestion.tsx | 2 +- .../QuestionTypes/DateTimeQuestion.tsx | 2 +- .../QuestionTypes/QuestionGroup.tsx | 4 +- .../Questionnaire/QuestionnaireEditor.tsx | 16 ++--- .../Questionnaire/QuestionnaireForm.tsx | 4 +- .../Questionnaire/QuestionnaireSearch.tsx | 6 +- src/components/Resource/ResourceCreate.tsx | 6 +- src/components/Resource/ResourceDetails.tsx | 24 +++---- src/components/ui/chart.tsx | 2 +- src/components/ui/date-picker.tsx | 2 +- src/components/ui/date-range-picker.tsx | 2 +- src/components/ui/date-time-picker.tsx | 2 +- src/components/ui/textarea.tsx | 2 +- src/pages/Encounters/EncounterList.tsx | 2 +- src/pages/Encounters/PrintPrescription.tsx | 4 +- src/pages/Facility/FacilitiesPage.tsx | 4 +- src/pages/Facility/FacilityDetailsPage.tsx | 2 +- .../Facility/components/FacilityCard.tsx | 2 +- src/pages/Facility/components/UserCard.tsx | 6 +- .../FacilityOrganizationIndex.tsx | 2 +- src/pages/Organization/OrganizationIndex.tsx | 2 +- src/pages/Patients/VerifyPatient.tsx | 4 +- .../PublicAppointments/PatientSelect.tsx | 4 +- src/pages/PublicAppointments/Schedule.tsx | 6 +- src/pages/UserDashboard.tsx | 10 +-- 49 files changed, 157 insertions(+), 145 deletions(-) diff --git a/src/components/Common/Charts/ObservationChart.tsx b/src/components/Common/Charts/ObservationChart.tsx index d210255a181..cb892d834ff 100644 --- a/src/components/Common/Charts/ObservationChart.tsx +++ b/src/components/Common/Charts/ObservationChart.tsx @@ -152,7 +152,7 @@ export const ObservationVisualizer = ({ {codeGroups.map((group, index) => (
No data available @@ -365,7 +365,7 @@ export const ObservationVisualizer = ({ details.note && (
{code.display}: diff --git a/src/components/Common/Charts/ObservationHistoryTable.tsx b/src/components/Common/Charts/ObservationHistoryTable.tsx index 240bfea2790..4a8fcee44d4 100644 --- a/src/components/Common/Charts/ObservationHistoryTable.tsx +++ b/src/components/Common/Charts/ObservationHistoryTable.tsx @@ -92,7 +92,7 @@ export const ObservationHistoryTable = ({ if (!data?.pages[0]?.results.length) { return ( -
+
No data available
); @@ -134,7 +134,7 @@ export const ObservationHistoryTable = ({ {name}
- + {observation.note} diff --git a/src/components/Common/ComboboxQuantityInput.tsx b/src/components/Common/ComboboxQuantityInput.tsx index 19674422d81..e28b246118e 100644 --- a/src/components/Common/ComboboxQuantityInput.tsx +++ b/src/components/Common/ComboboxQuantityInput.tsx @@ -120,7 +120,7 @@ export function ComboboxQuantityInput({ autoFocus={autoFocus} /> {selectedUnit && ( -
+
{selectedUnit.display}
)} diff --git a/src/components/Common/SearchByMultipleFields.tsx b/src/components/Common/SearchByMultipleFields.tsx index 531f5caf1b7..242266ae23e 100644 --- a/src/components/Common/SearchByMultipleFields.tsx +++ b/src/components/Common/SearchByMultipleFields.tsx @@ -365,7 +365,7 @@ const SearchByMultipleFields: React.FC = ({
@@ -348,7 +348,7 @@ export default function ResourceCreate(props: ResourceProps) {

{t("contact_information")}

-

+

{t("contact_information_description")}

diff --git a/src/components/Resource/ResourceDetails.tsx b/src/components/Resource/ResourceDetails.tsx index 8308935f197..b2ec9e613f4 100644 --- a/src/components/Resource/ResourceDetails.tsx +++ b/src/components/Resource/ResourceDetails.tsx @@ -38,7 +38,7 @@ function PatientCard({ patient }: { patient: PatientModel }) {

{t("name")}

-

{patient.name}

+

{patient.name}

@@ -61,12 +61,12 @@ function PatientCard({ patient }: { patient: PatientModel }) {
) : ( -

--

+

--

)}

{t("address")}

-

+

{[patient.address].filter(Boolean).join(", ") || "--"}

@@ -93,7 +93,7 @@ function FacilityCard({

{t("name")}

-

+

{facilityData?.name || "--"}

@@ -265,7 +265,7 @@ export default function ResourceDetails(props: { id: string }) {

{t("category")}

-

+

{RESOURCE_CATEGORY_CHOICES.find( (item) => item.id === data.category, )?.text || "--"} @@ -273,7 +273,7 @@ export default function ResourceDetails(props: { id: string }) {

{t("contact_person")}

-

+

{data.referring_facility_contact_name || "--"}

@@ -297,7 +297,7 @@ export default function ResourceDetails(props: { id: string }) {
) : ( -

--

+

--

)}
@@ -306,7 +306,7 @@ export default function ResourceDetails(props: { id: string }) {

{t("reason")}

-

+

{data.reason || "--"}

@@ -340,20 +340,20 @@ export default function ResourceDetails(props: { id: string }) { {data.created_by && (

{t("created_by")}

-

+

{formatName(data.created_by)}

-

+

{formatDateTime(data.created_date)}

)}

{t("last_modified_by")}

-

+

{formatName(data.updated_by)}

-

+

{formatDateTime(data.modified_date)}

diff --git a/src/components/ui/chart.tsx b/src/components/ui/chart.tsx index 11a65a13e9d..6ff21377000 100644 --- a/src/components/ui/chart.tsx +++ b/src/components/ui/chart.tsx @@ -50,7 +50,7 @@ const ChartContainer = React.forwardRef< data-chart={chartId} ref={ref} className={cn( - "flex aspect-video justify-center text-xs [&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-none [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-sector]:outline-none [&_.recharts-surface]:outline-none", + "flex aspect-video justify-center text-xs [&_.recharts-cartesian-axis-tick_text]:fill-gray-500 [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-none [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-sector]:outline-none [&_.recharts-surface]:outline-none", className, )} {...props} diff --git a/src/components/ui/date-picker.tsx b/src/components/ui/date-picker.tsx index 32d23132362..e8c5587fe2e 100644 --- a/src/components/ui/date-picker.tsx +++ b/src/components/ui/date-picker.tsx @@ -29,7 +29,7 @@ export function DatePicker({ date, onChange, disabled }: DatePickerProps) { variant="outline" className={cn( "w-full justify-start text-left font-normal", - !date && "text-muted-foreground", + !date && "text-gray-500", )} > diff --git a/src/components/ui/date-range-picker.tsx b/src/components/ui/date-range-picker.tsx index 18e467c58b0..ffbbf482bce 100644 --- a/src/components/ui/date-range-picker.tsx +++ b/src/components/ui/date-range-picker.tsx @@ -37,7 +37,7 @@ export function DateRangePicker({ variant={"outline"} className={cn( "justify-center text-left font-normal", - !date && "text-muted-foreground", + !date && "text-gray-500", )} > diff --git a/src/components/ui/date-time-picker.tsx b/src/components/ui/date-time-picker.tsx index 26c93552596..4603f606434 100644 --- a/src/components/ui/date-time-picker.tsx +++ b/src/components/ui/date-time-picker.tsx @@ -68,7 +68,7 @@ export function DateTimePicker({ variant="outline" className={cn( "w-full justify-start text-left font-normal", - !value && "text-muted-foreground", + !value && "text-gray-500", )} > diff --git a/src/components/ui/textarea.tsx b/src/components/ui/textarea.tsx index 9deb3cf02ec..cb3d1045e6c 100644 --- a/src/components/ui/textarea.tsx +++ b/src/components/ui/textarea.tsx @@ -9,7 +9,7 @@ const Textarea = React.forwardRef< return (