From 6126694ea90937003a0f85f2801a887546b33afd Mon Sep 17 00:00:00 2001 From: Shivank Kacker Date: Thu, 30 Jan 2025 03:29:10 +0530 Subject: [PATCH] Added care plan question --- public/locale/en.json | 11 + src/Routers/routes/ConsultationRoutes.tsx | 10 + .../QuestionTypes/CarePlanQuestion.tsx | 530 ++++++++++++++++++ .../QuestionTypes/QuestionInput.tsx | 40 +- .../Questionnaire/data/StructuredFormData.tsx | 21 + .../Questionnaire/structured/handlers.ts | 18 + .../Questionnaire/structured/types.ts | 3 + src/pages/CarePlan/CarePlan.tsx | 30 +- src/pages/CarePlan/CarePlanGoalPage.tsx | 188 +++++++ src/types/emr/careplan/careplan.ts | 57 +- src/types/emr/careplan/careplanApi.ts | 109 +++- src/types/questionnaire/form.ts | 7 +- src/types/questionnaire/question.ts | 3 +- 13 files changed, 981 insertions(+), 46 deletions(-) create mode 100644 src/components/Questionnaire/QuestionTypes/CarePlanQuestion.tsx create mode 100644 src/pages/CarePlan/CarePlanGoalPage.tsx diff --git a/public/locale/en.json b/public/locale/en.json index 5de2c398c1a..998b59df1df 100644 --- a/public/locale/en.json +++ b/public/locale/en.json @@ -289,12 +289,14 @@ "add_attachments": "Add Attachments", "add_beds": "Add Bed(s)", "add_beds_to_configure_presets": "Add beds to this location to configure presets for them.", + "add_care_plan": "Add Care Plan", "add_consultation": "Add consultation", "add_consultation_update": "Add Consultation Update", "add_details_of_patient": "Add Details of Patient", "add_exception": "Add Exception", "add_facility": "Add Facility", "add_files": "Add Files", + "add_goal": "Add Goal", "add_insurance_details": "Add Insurance Details", "add_location": "Add Location", "add_new_beds": "Add New Bed(s)", @@ -318,6 +320,7 @@ "add_skill": "Add Skill", "add_spoke": "Add Spoke Facility", "add_tags": "Add Tags", + "add_target": "Add Target", "add_user": "Add User", "additional_information": "Additional Information", "additional_instructions": "Additional Instructions", @@ -493,6 +496,9 @@ "care_backend": "Care Backend", "care_frontend": "Care Frontend", "care_plan": "Care Plan", + "care_plan_goal": "Care Plan Goal", + "careplan_intent": "Care Plan Intent", + "careplan_status": "Care Plan Status", "category": "Category", "category_description": "Choose the category that best describes the resource needed.", "caution": "Caution", @@ -896,6 +902,7 @@ "encounter_suggestion__R": "Consultation", "encounter_suggestion_edit_disallowed": "Not allowed to switch to this option in edit consultation", "encounters": "Encounters", + "end_date": "End Date", "end_datetime": "End Date/Time", "end_dose": "End Dose", "end_time": "End Time", @@ -1034,6 +1041,7 @@ "getting_location": "Getting Location...", "go_back": "Go Back", "goal": "Our goal is to continuously improve the quality and accessibility of public healthcare services using digital tools.", + "goals": "Goals", "granted_on": "Granted On", "has_allergies": "Has Allergies", "has_domestic_healthcare_support": "Has domestic healthcare support?", @@ -1161,6 +1169,7 @@ "license": "License", "licenses_description": "Third-party software is used in Care, including the respective licenses and versions.", "licenses_title": "Third-Party Software and Licenses", + "lifecycle_status": "Lifecycle Status", "link_abha_number": "Link ABHA Number", "link_abha_profile": "Link ABHA Profile", "link_camera_and_bed": "Link bed to Camera", @@ -1972,6 +1981,7 @@ "tag_slug": "Tag Slug", "taper_titrate_dosage": "Taper & Titrate Dosage", "target_dosage": "Target Dosage", + "targets": "Targets", "template_deleted": "Template has been deleted", "test_type": "Type of test done", "tested_on": "Tested on", @@ -1980,6 +1990,7 @@ "third_party_software_licenses": "Third Party Software Licenses", "time": "Time", "time_slot": "Time Slot", + "title": "Title", "title_of_request": "Title of Request", "titrate_dosage": "Titrate Dosage", "to": "to", diff --git a/src/Routers/routes/ConsultationRoutes.tsx b/src/Routers/routes/ConsultationRoutes.tsx index e58b913c343..2beb93bb1a9 100644 --- a/src/Routers/routes/ConsultationRoutes.tsx +++ b/src/Routers/routes/ConsultationRoutes.tsx @@ -4,6 +4,7 @@ import FileUploadPage from "@/components/Patient/FileUploadPage"; import { AppRoutes } from "@/Routers/AppRouter"; import CarePlan from "@/pages/CarePlan/CarePlan"; +import CarePlanGoalPage from "@/pages/CarePlan/CarePlanGoalPage"; import { EncounterShow } from "@/pages/Encounters/EncounterShow"; import { PrintPrescription } from "@/pages/Encounters/PrintPrescription"; @@ -87,6 +88,15 @@ const consultationRoutes: AppRoutes = { careplanId={careplanId} /> ), + "/facility/:facilityId/encounter/:encounterId/care-plan/:careplanId/goal/:goalId": + ({ facilityId, encounterId, careplanId, goalId }) => ( + + ), }; export default consultationRoutes; diff --git a/src/components/Questionnaire/QuestionTypes/CarePlanQuestion.tsx b/src/components/Questionnaire/QuestionTypes/CarePlanQuestion.tsx new file mode 100644 index 00000000000..7bde1f8c52c --- /dev/null +++ b/src/components/Questionnaire/QuestionTypes/CarePlanQuestion.tsx @@ -0,0 +1,530 @@ +import { DotsVerticalIcon, MinusCircledIcon } from "@radix-ui/react-icons"; +import { useTranslation } from "react-i18next"; + +import { Button } from "@/components/ui/button"; +import { DateTimePicker } from "@/components/ui/date-time-picker"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +import { Textarea } from "@/components/ui/textarea"; + +import { + CARE_PLAN_INTENT, + CARE_PLAN_LIFECYCLE_STATUS, + CARE_PLAN_STATUS, + CarePlanGoalRequest, + CarePlanRequest, + GoalTarget, +} from "@/types/emr/careplan/careplan"; +import { + QuestionnaireResponse, + ResponseValue, +} from "@/types/questionnaire/form"; +import { Question } from "@/types/questionnaire/question"; + +interface CarePlanQuestionProps { + question: Question; + questionnaireResponse: QuestionnaireResponse; + updateQuestionnaireResponseCB: ( + values: ResponseValue[], + questionId: string, + note?: string, + ) => void; + disabled?: boolean; + encounterId?: string; + patientId: string; + facilityId: string; +} + +const sampleCodes = [ + { + code: "8480-6", + system: "http://loinc.org", + display: "Systolic", + }, + { + code: "8462-4", + system: "http://loinc.org", + display: "Diastolic", + }, + { + code: "8867-4", + system: "http://loinc.org", + display: "Pulse", + }, + { + code: "8310-5", + system: "http://loinc.org", + display: "Temperature", + }, + { + code: "9279-1", + system: "http://loinc.org", + display: "Respiratory Rate", + }, +]; + +export default function CarePlanQuestion({ + questionnaireResponse, + updateQuestionnaireResponseCB, + disabled, + patientId, + encounterId, + facilityId, +}: CarePlanQuestionProps) { + const { t } = useTranslation(); + const careplans = + (questionnaireResponse.values?.[0] + ?.value as unknown as CarePlanRequest[]) || []; + + const handleUpdate = (index: number, updates: Partial) => { + const newCarePlans = careplans.map((careplan, i) => + i === index ? { ...careplan, ...updates } : careplan, + ); + + updateQuestionnaireResponseCB( + [{ type: "care_plan", value: newCarePlans }], + questionnaireResponse.question_id, + ); + }; + + const handleGoalUpdate = ( + cpIndex: number, + index: number, + updates: Partial, + ) => { + const newCarePlans = careplans.map((careplan, i) => + i === cpIndex + ? { + ...careplan, + goals: careplan.goals?.map((goal, j) => + j === index ? { ...goal, ...updates } : goal, + ), + } + : careplan, + ); + + updateQuestionnaireResponseCB( + [{ type: "care_plan", value: newCarePlans }], + questionnaireResponse.question_id, + ); + }; + + const handleGoalTargetUpdate = ( + cpIndex: number, + goalIndex: number, + index: number, + updates: Partial, + ) => { + const newCarePlans = careplans.map((careplan, i) => + i === cpIndex + ? { + ...careplan, + goals: careplan.goals?.map((goal, j) => + j === goalIndex + ? { + ...goal, + target: goal.target?.map((target, k) => + k === index ? { ...target, ...updates } : target, + ), + } + : goal, + ), + } + : careplan, + ); + + updateQuestionnaireResponseCB( + [{ type: "care_plan", value: newCarePlans }], + questionnaireResponse.question_id, + ); + }; + + return ( +
+
+ {careplans.map((careplan, i) => ( +
+
+ + + + + + { + const newCarePlans = careplans.filter((_, j) => j !== i); + updateQuestionnaireResponseCB( + [{ type: "care_plan", value: newCarePlans }], + questionnaireResponse.question_id, + ); + }} + > + + {t("remove")} + + + +
+
+
+ + handleUpdate(i, { title: e.target.value })} + disabled={disabled} + /> +
+
+
+ + +
+
+ + +
+
+
+ +